emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] scratch/fix-33794-extend-electric-layout-mode 1173d50 6/6:


From: João Távora
Subject: [Emacs-diffs] scratch/fix-33794-extend-electric-layout-mode 1173d50 6/6: Slightly more powerful electric-layout-rules
Date: Sun, 23 Dec 2018 17:51:12 -0500 (EST)

branch: scratch/fix-33794-extend-electric-layout-mode
commit 1173d5092d1c832cf1fc5b5ca3a97203eb1142ff
Author: João Távora <address@hidden>
Commit: João Távora <address@hidden>

    Slightly more powerful electric-layout-rules
    
    * lisp/electric.el (electric-layout-rules): Expand slightly.
    (electric-layout-post-self-insert-function-1): Accept new rules.
    
    * test/lisp/electric-tests.el (electric-pair-mode-newline-between-parens)
    (electric-layout-mode-newline-between-parens-without-e-p-m): New
    (failing) tests.
---
 lisp/electric.el            |  34 ++++++++++---
 test/lisp/electric-tests.el | 116 +++++++++++++++++++++++++++++---------------
 2 files changed, 103 insertions(+), 47 deletions(-)

diff --git a/lisp/electric.el b/lisp/electric.el
index 9646807..fb0a913 100644
--- a/lisp/electric.el
+++ b/lisp/electric.el
@@ -363,9 +363,15 @@ use `electric-indent-local-mode'."
 (defvar electric-layout-rules nil
   "List of rules saying where to automatically insert newlines.
 
-Each rule has the form (CHAR . WHERE) where CHAR is the char that
-was just inserted and WHERE specifies where to insert newlines
-and can be:
+Each rule has the form (MATCHER . WHERE) where MATCHER examines
+the state of the buffer after a certain character was inserted
+and WHERE specifies where to insert newlines.
+
+MATCHER can be a character CHAR or a boolean function of no
+arguments.  The rule matches if the character just inserted was
+CHAR or if the function return non-nil.
+
+WHERE and can be:
 
 * one of the symbols `before', `after', `around' and `after-stay';
 
@@ -375,9 +381,10 @@ and can be:
 * a function of no arguments that returns one of the previous
   values.
 
-Each symbol specifies where in relation to CHAR the newline
-character(s) should be inserted.  `after-stay' means insert a
-newline after CHAR but stay in the same place.
+Each symbol specifies where, in relation to the position POS of
+the character inserted, the newline character(s) should be
+inserted.  `after-stay' means insert a newline after POS but stay
+in the same place.
 
 If multiple rules match, only first one is executed.")
 
@@ -387,8 +394,19 @@ If multiple rules match, only first one is executed.")
 
 ;; for edebug's sake, a separate function
 (defun electric-layout-post-self-insert-function-1 ()
-  (let (pos
-        (rule (cdr (assq last-command-event electric-layout-rules))))
+  (let* (pos
+         probe
+         (rules electric-layout-rules)
+         (rule
+          (catch 'done
+            (while (setq probe (pop rules))
+              (cond ((and (consp probe)
+                          (or (eq (car probe) last-command-event)
+                              (and (functionp (car probe))
+                                   (funcall (car probe)))))
+                     (throw 'done (cdr probe)))
+                    ((functionp probe)
+                     (throw 'done (funcall probe))))))))
     (when (and rule
                (setq pos (electric--after-char-pos))
                ;; Not in a string or comment.
diff --git a/test/lisp/electric-tests.el b/test/lisp/electric-tests.el
index af27fab..71ff73b 100644
--- a/test/lisp/electric-tests.el
+++ b/test/lisp/electric-tests.el
@@ -816,51 +816,89 @@ baz\"\""
 ;;; tests for `electric-layout-mode'
 
 (ert-deftest electric-layout-int-main-kernel-style ()
-  (save-electric-modes
-    (ert-with-test-buffer ()
-      (c-mode)
-      (electric-layout-local-mode 1)
-      (electric-pair-local-mode 1)
-      (electric-indent-local-mode 1)
-      (setq-local electric-layout-rules
-              '((?\{ . (after-stay after))))
-      (insert "int main () ")
-      (let ((last-command-event ?\{))
-        (call-interactively (key-binding `[,last-command-event])))
-      (should (equal (buffer-string) "int main () {\n  \n}")))))
+  (ert-with-test-buffer ()
+    (c-mode)
+    (electric-layout-local-mode 1)
+    (electric-pair-local-mode 1)
+    (electric-indent-local-mode 1)
+    (setq-local electric-layout-rules
+                '((?\{ . (after-stay after))))
+    (insert "int main () ")
+    (let ((last-command-event ?\{))
+      (call-interactively (key-binding `[,last-command-event])))
+    (should (equal (buffer-string) "int main () {\n  \n}"))))
 
 (ert-deftest electric-layout-int-main-allman-style ()
-  (save-electric-modes
-    (ert-with-test-buffer ()
-      (c-mode)
-      (electric-layout-local-mode 1)
-      (electric-pair-local-mode 1)
-      (electric-indent-local-mode 1)
-      (setq-local electric-layout-rules
-              '((?\{ . (before after-stay after))))
-      (insert "int main () ")
-      (let ((last-command-event ?\{))
-        (call-interactively (key-binding `[,last-command-event])))
-      (should (equal (buffer-string) "int main ()\n{\n  \n}")))))
+  (ert-with-test-buffer ()
+    (c-mode)
+    (electric-layout-local-mode 1)
+    (electric-pair-local-mode 1)
+    (electric-indent-local-mode 1)
+    (setq-local electric-layout-rules
+                '((?\{ . (before after-stay after))))
+    (insert "int main () ")
+    (let ((last-command-event ?\{))
+      (call-interactively (key-binding `[,last-command-event])))
+    (should (equal (buffer-string) "int main ()\n{\n  \n}"))))
 
 (define-derived-mode plainer-c-mode c-mode "pC"
-  "A plainer C-mode")
+  "A plainer/saner C-mode with no internal electric machinery."
+  (c-toggle-electric-state -1)
+  (setq-local electric-indent-local-mode-hook nil)
+  (setq-local electric-indent-mode-hook nil)
+  (electric-indent-local-mode 1)
+  (dolist (key '(?\" ?\' ?\{ ?\} ?\( ?\) ?\[ ?\]))
+    (local-set-key (vector key) 'self-insert-command)))
 
 (ert-deftest electric-modes-in-c-mode-with-self-insert-command ()
-  (save-electric-modes
-    (ert-with-test-buffer ()
-      (plainer-c-mode)
-      (electric-layout-local-mode 1)
-      (electric-pair-local-mode 1)
-      (electric-indent-local-mode 1)
-      (dolist (key '(?\" ?\' ?\{ ?\} ?\( ?\) ?\[ ?\]))
-        (local-set-key (vector key) 'self-insert-command))
-      (setq-local electric-layout-rules
-              '((?\{ . (before after-stay after))))
-      (insert "int main () ")
-      (let ((last-command-event ?\{))
-        (call-interactively (key-binding `[,last-command-event])))
-      (should (equal (buffer-string) "int main ()\n{\n  \n}")))))
+  (ert-with-test-buffer ()
+    (plainer-c-mode)
+    (electric-layout-local-mode 1)
+    (electric-pair-local-mode 1)
+    (electric-indent-local-mode 1)
+    (setq-local electric-layout-rules
+                '((?\{ . (before after-stay after))))
+    (insert "int main () ")
+    (let ((last-command-event ?\{))
+      (call-interactively (key-binding `[,last-command-event])))
+    (should (equal (buffer-string) "int main ()\n{\n  \n}"))))
+
+;; FIXME: The two following tests fail, because the newline simulation
+;; fails to indent the new line.  Interactively, they work fine.
+;; Don't know why...
+(ert-deftest electric-pair-mode-newline-between-parens ()
+  :expected-result :failed
+  (ert-with-test-buffer (:name "electric-pair-mode-newline-between-parens")
+    (plainer-c-mode)
+    (electric-layout-local-mode -1) ;; ensure e-l-m mode is off
+    (electric-pair-local-mode 1)
+    (insert-before-markers "int main () {}")
+    (backward-char 1)
+    (let ((last-command-event ?\n))
+      (call-interactively (key-binding `[,last-command-event])))
+    (should (equal (buffer-string) "int main ()\n{\n  \n}"))))
+
+(ert-deftest electric-layout-mode-newline-between-parens-without-e-p-m ()
+  :expected-result :failed
+  (ert-with-test-buffer (:name "electric-pair-mode-newline-between-parens")
+    (plainer-c-mode)
+    (electric-layout-local-mode 1)
+    (electric-pair-local-mode -1) ;; ensure e-p-m mode is off
+    (electric-indent-local-mode 1)
+    (setq-local electric-layout-rules
+                '((?\n
+                   .
+                   (lambda ()
+                     (when (eq (save-excursion
+                                 (skip-chars-backward "\t\s")
+                                 (char-before (1- (point))))
+                               (matching-paren (char-after)))
+                       '(after-stay))))))
+    (insert "int main () {}")
+    (backward-char 1)
+    (let ((last-command-event ?\n))
+      (call-interactively (key-binding `[,last-command-event])))
+    (should (equal (buffer-string) "int main ()\n{\n  \n}"))))
 
 (provide 'electric-tests)
 ;;; electric-tests.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]