From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Michal Nazarewicz Newsgroups: gmane.emacs.bugs Subject: bug#18730: [PATCHv2 2/2] tildify.el: Add `auto-tildify' and `auto-tildify-mode'. Date: Thu, 16 Oct 2014 17:34:12 +0200 Message-ID: <1413473652-26262-2-git-send-email-mina86@mina86.com> References: <1413473652-26262-1-git-send-email-mina86@mina86.com> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Trace: ger.gmane.org 1413473738 28629 80.91.229.3 (16 Oct 2014 15:35:38 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Thu, 16 Oct 2014 15:35:38 +0000 (UTC) Cc: Milan Zamazal To: Stefan Monnier , 18730@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Thu Oct 16 17:35:29 2014 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Xen5J-0007h7-6G for geb-bug-gnu-emacs@m.gmane.org; Thu, 16 Oct 2014 17:35:25 +0200 Original-Received: from localhost ([::1]:50919 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Xen5I-0002R1-Nb for geb-bug-gnu-emacs@m.gmane.org; Thu, 16 Oct 2014 11:35:24 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:52305) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Xen54-0002DJ-JQ for bug-gnu-emacs@gnu.org; Thu, 16 Oct 2014 11:35:15 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Xen4y-0003E8-KP for bug-gnu-emacs@gnu.org; Thu, 16 Oct 2014 11:35:10 -0400 Original-Received: from debbugs.gnu.org ([140.186.70.43]:54556) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Xen4y-0003Dn-Hh for bug-gnu-emacs@gnu.org; Thu, 16 Oct 2014 11:35:04 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.80) (envelope-from ) id 1Xen4y-0001WD-70 for bug-gnu-emacs@gnu.org; Thu, 16 Oct 2014 11:35:04 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Michal Nazarewicz Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 16 Oct 2014 15:35:04 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 18730 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 18730-submit@debbugs.gnu.org id=B18730.14134736665749 (code B ref 18730); Thu, 16 Oct 2014 15:35:04 +0000 Original-Received: (at 18730) by debbugs.gnu.org; 16 Oct 2014 15:34:26 +0000 Original-Received: from localhost ([127.0.0.1]:46115 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Xen4K-0001Ud-Qv for submit@debbugs.gnu.org; Thu, 16 Oct 2014 11:34:25 -0400 Original-Received: from mail-wg0-f73.google.com ([74.125.82.73]:56343) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Xen4H-0001UF-4H for 18730@debbugs.gnu.org; Thu, 16 Oct 2014 11:34:22 -0400 Original-Received: by mail-wg0-f73.google.com with SMTP id m15so282474wgh.2 for <18730@debbugs.gnu.org>; Thu, 16 Oct 2014 08:34:20 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-type:content-transfer-encoding; bh=RQ/o7EKam+fJJuEJVC/HjUIadTIolGQ+tWIr2HUYhOc=; b=TSPYRUWUztXK+gJTV50SgnUYSaW71VZsdVvX5H7Jj/AfGvVKCuHneh15KFrHJkDq74 3Pe9ZiJBtIIayZrGbH/hUbUz3ajLNwjvOY4W6VzE4SThdyuGXIP/RHoWuRQ9yNFU47X6 hzVKM9MncQxd054yb/XKUMZdhQer7K4OZq+cVrumJh1AnM3rD0voA9LUFRZkbYDlfMY8 i7W3KyGZ/1hy2s+9yVGVR+oKVAae28KuD07w1XzU02TBhKRbe7Ca2wONdG5Gy8mmIutZ J3lzNv/d3fam930s4OI5bojzk9JjMIwbpHdRro0YamJWTMaESBHKDfXv22qNnwiox2ir yFAg== X-Gm-Message-State: ALoCoQm4r4Mdvfr5Dxkol2y9mkgdsVH0sjCoBQ9SL/R1/OLhuuC4q2lcgAhVtM9cGzJqZjn1X4RiywhxRL/RdMy7CK7rnsipOnYUAJh59yeZyr3vM9+EqgeBeiqSk7eXEErpaxTvuCyTXaG857On1LVAuti0fy6tr20rpxpSZ4qBY+PGM7KZJ5w= X-Received: by 10.180.76.42 with SMTP id h10mr1073695wiw.6.1413473660210; Thu, 16 Oct 2014 08:34:20 -0700 (PDT) Original-Received: from corpmail-nozzle1-1.eem.corp.google.com (corpmail-nozzle1-1.eem.corp.google.com [172.25.144.12]) by gmr-mx.google.com with ESMTPS id gk3si117925wib.1.2014.10.16.08.34.20 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 16 Oct 2014 08:34:20 -0700 (PDT) Original-Received: from mpn.zrh.corp.google.com ([172.16.113.113]) by corpmail-nozzle1-1.eem.corp.google.com with ESMTP id WG1GlW1b.1; Thu, 16 Oct 2014 08:34:20 -0700 Original-Received: by mpn.zrh.corp.google.com (Postfix, from userid 126942) id AE7C41E00E5; Thu, 16 Oct 2014 17:34:19 +0200 (CEST) X-Mailer: git-send-email 2.1.0.rc2.206.gedb03e5 In-Reply-To: <1413473652-26262-1-git-send-email-mina86@mina86.com> X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:94632 The `auto-tildify' function can be used as a `post-self-insert-hook' to automatically convert spaces into hard spaces. It is configured via two new customize variables: `auto-tildify-pattern-alist' and `auto-tildify-check-envs'. `auto-tildify-mode' makes use of that function to enable eletric behaviour of space character. --- etc/NEWS | 5 +++ lisp/textmodes/tildify.el | 96 +++++++++++++++++++++++++++++++++++= +++++- test/automated/tildify-tests.el | 32 ++++++++++++++ 3 files changed, 132 insertions(+), 1 deletion(-) diff --git a/etc/NEWS b/etc/NEWS index 36f1d9d..b6d4055 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -269,6 +269,11 @@ These emulations of old editors are believed to be n= o longer relevant =0C * New Modes and Packages in Emacs 25.1 =20 +** `tildify-mode' automatically hardens spaces as one types the text. +Breaking line after a single-character words is forbidden by Czech and P= olish +typography. `tildify-mode' makes creating a typographically-correct mar= kup in +formats such as HTML, LaTeX, Markdown, etc. + =0C * Incompatible Lisp Changes in Emacs 25.1 =20 diff --git a/lisp/textmodes/tildify.el b/lisp/textmodes/tildify.el index 91f5a38..33067a6 100644 --- a/lisp/textmodes/tildify.el +++ b/lisp/textmodes/tildify.el @@ -4,7 +4,7 @@ =20 ;; Author: Milan Zamazal ;; Michal Nazarewicz -;; Version: 4.5.4 +;; Version: 4.6 ;; Keywords: text, TeX, SGML, wp =20 ;; This file is part of GNU Emacs. @@ -344,6 +344,100 @@ replacements done and response is one of symbols: t= (all right), nil (t t)))))) =20 =20 +;;; *** Auto Tildify *** + +(defcustom tildify-space-pattern-alist + '((t . "[,:;(][ \t]*[a]\\|\\<[AIKOSUVWZikosuvwz]")) + "Alist specifying whether a hard space is required at point. + +Each alist item is of the form (MAJOR-MODE . REGEXP) or +\(MAJOR-MODE . SYMBOL). + +MAJOR-MODE defines major mode, for which the item applies. It can be ei= ther: +- a symbol equal to the major mode of the buffer to be fixed +- t for default item, this applies to all major modes not defined in ano= ther + alist item + +REGEXP is a regular expression matching the part of a text that +needs a hard space to be inserted instead of a space. The regexp +is always case sensitive, regardless of the current +`case-fold-search' setting. + +The form (MAJOR-MODE . SYMBOL) defines alias item for MAJOR-MODE. For t= his +mode, the item for the mode SYMBOL is looked up in the alist instead." + :group 'tildify + :type '(repeat (cons (choice (const :tag "Default" t) + (symbol :tag "For mode ")) + (choice (regexp :tag "Regexp ") + (symbol :tag "Like mode"))))) + +(defcustom tildify-space-check-envs t + "Should `tildify-space' check if point is inside ignored environment." + :group 'tildify + :type 'boolean) + + +(defun tildify-space () + "Convert space before point into a hard space if the context is right. + +If + * character before point is a space character, + * character before that has =E2=80=9Cw=E2=80=9D character syntax (i.e. = it's a word + constituent), + * pattern from `tildify-space-pattern-alist' matches when `looking-back= ' (no + more than 10 characters) from before the space character, and + * `tildify-space-check-envs' is nil or point is not inside of an enviro= nment to + ignore +replace the space character with a hard space specified in +`tildify-string-alist'. + +Return t if conversion happened, nil otherwise. + +This function is meant to be used as a `post-self-insert-hook'." + (let ((p (point)) case-fold-search space pattern) + (when (and (> (- p (point-min)) 2) + (eq (preceding-char) ?\s) + (eq (char-syntax (char-before (1- p))) ?w) + (setq space (tildify--pick-alist-entry tildify-string-ali= st)) + (not (string-equal " " space)) + (setq pattern (tildify--pick-alist-entry + tildify-space-pattern-alist)) + (save-excursion + (goto-char (1- p)) + (looking-back pattern (max (point-min) (- p 10)))) + (or (not tildify-space-check-envs) + (catch 'found + (tildify-foreach-region-outside-env (- p 2) (1- p) + (lambda (beg end) (throw 'found t)))))) + (delete-char -1) + (insert space) + t))) + +;;;###autoload +(define-minor-mode tildify-mode + "Adds electric behaviour to space character. + +When space is inserted into a buffer in a position where hard +space is required instead, that space character is replaced by +a hard space correct for given mode. + +Converting of the space is done by `tildify-space'." + nil " ~" nil + (when tildify-mode + (when (let ((space (tildify--pick-alist-entry tildify-string-alist))= ) + (or (not space) (string-equal " " space))) + (message (concat "Hard space for %s is a single space character, " + "tildify won't have any effect.") major-mode) + (setq tildify-mode nil)) + (when (not (tildify--pick-alist-entry tildify-space-pattern-alist)) + (message (concat "No pattern defined for %s, " + "tildify won't have any effect.") major-mode) + (setq tildify-mode nil))) + (if tildify-mode + (add-hook 'post-self-insert-hook 'tildify-space nil t) + (remove-hook 'post-self-insert-hook 'tildify-space t))) + + ;;; *** Announce *** =20 (provide 'tildify) diff --git a/test/automated/tildify-tests.el b/test/automated/tildify-tes= ts.el index 53c2e62..7ba270a 100644 --- a/test/automated/tildify-tests.el +++ b/test/automated/tildify-tests.el @@ -132,6 +132,38 @@ latter is missing, SENTENCE will be used in all plac= eholder positions." (should (string-equal "close-foo" (tildify-find-env beg-re pairs))= )))) =20 =20 +(defun tildify-space-test--test (modes nbsp env-open) + (with-temp-buffer + (dolist (mode modes) + (erase-buffer) + (funcall mode) + (let ((header (concat "Testing `tildify-space' in " + (symbol-name mode) "\n"))) + (insert header "Lorem v ") + (should (tildify-space)) + (should (string-equal (concat header "Lorem v" nbsp) (buffer-str= ing)))) + (erase-buffer) + (let ((header (concat "Testing `tildify-space' in " + (symbol-name mode) "\n"))) + (insert header env-open "Lorem v ") + (should (not (tildify-space))) + (should (string-equal (concat header env-open "Lorem v ") + (buffer-string))))))) + +(ert-deftest tildify-space-test-html () + "Tests auto-tildification in an HTML document" + (tildify-space-test--test '(html-mode sgml-mode) " " "
"))
+
+(ert-deftest tildify-space-test-xml ()
+  "Tests auto-tildification in an XML document"
+  (tildify-space-test--test '(nxml-mode) " " "