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 6deb668 2/6:


From: João Távora
Subject: [Emacs-diffs] scratch/fix-33794-extend-electric-layout-mode 6deb668 2/6: Rework electric-layout-post-self-insert-function (bug#33794)
Date: Sun, 23 Dec 2018 17:51:11 -0500 (EST)

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

    Rework electric-layout-post-self-insert-function (bug#33794)
    
    This should now fix more problems reported in (bug#33794) regarding
    insertion of newlines before and after the opening brace.  Write two
    automated tests.
    
    Also provide a new electric-layout-local-mode for testing.
    
    * lisp/electric.el (electric-layout-post-self-insert-function-1):
    New function that does the work for
    electric-layout-post-self-insert-function-1.
    (electric-layout-local-mode): New minor mode.
    
    * test/lisp/electric-tests.el (electric-layout-int-main-kernel-style)
    (electric-layout-int-main-allman-style): Add two tests.
---
 lisp/electric.el            | 49 +++++++++++++++++++++++++++++++--------------
 test/lisp/electric-tests.el | 34 +++++++++++++++++++++++++++++++
 2 files changed, 68 insertions(+), 15 deletions(-)

diff --git a/lisp/electric.el b/lisp/electric.el
index 6a307a4..24c040d 100644
--- a/lisp/electric.el
+++ b/lisp/electric.el
@@ -376,17 +376,25 @@ If multiple rules match, they are all executed in order of
 appearance.")
 
 (defun electric-layout-post-self-insert-function ()
-  (let (pos)
+  (when electric-layout-mode
+    (electric-layout-post-self-insert-function-1)))
+
+;; for edebug's sake a separate function
+(defun electric-layout-post-self-insert-function-1 ()
+  (let (pos end)
     (when (and (setq pos (electric--after-char-pos))
                ;; Not in a string or comment.
                (not (nth 8 (save-excursion (syntax-ppss pos)))))
       (goto-char pos)
+      (setq end (point-marker))
       (dolist (rule electric-layout-rules)
         (when (eq last-command-event (car rule))
-          (let* ((end (point-marker))
-                 (rule (cdr rule))
-                 (sym (if (functionp rule) (funcall rule) rule)))
-            (set-marker-insertion-type end (not (eq sym 'after-stay)))
+          (let* ((rule (cdr rule))
+                 (sym (if (functionp rule) (funcall rule) rule))
+                 (nl (lambda ()
+                       (let ((electric-layout-mode nil)
+                             (electric-pair-open-newline-between-pairs nil))
+                               (newline 1 t)))))
             (pcase sym
               ;; FIXME: we used `newline' down here which called
               ;; self-insert-command and ran post-self-insert-hook recursively.
@@ -395,18 +403,16 @@ appearance.")
               ;; multiple times), but I'm not sure it's what we want.
               ;;
               ;; FIXME: check eolp before inserting \n?
-              ('before (goto-char (1- pos)) (skip-chars-backward " \t")
-                       (unless (bolp) (insert "\n")))
-              ('after  (insert "\n"))
-              ('after-stay (save-excursion
-                             (let ((electric-layout-rules nil)
-                                   (electric-pair-open-newline-between-pairs 
nil))
-                               (newline 1 t))))
+              ('before (save-excursion
+                         (goto-char (1- pos)) (skip-chars-backward " \t")
+                         (unless (bolp) (funcall nl))))
+              ('after  (funcall nl))
+              ('after-stay (save-excursion (funcall nl)))
               ('around (save-excursion
                          (goto-char (1- pos)) (skip-chars-backward " \t")
-                         (unless (bolp) (insert "\n")))
-                       (insert "\n")))      ; FIXME: check eolp before 
inserting \n?
-            (goto-char end)))))))
+                         (unless (bolp) (funcall nl)))
+                       (funcall nl)))      ; FIXME: check eolp before 
inserting \n?
+            ))))))
 
 (put 'electric-layout-post-self-insert-function 'priority  40)
 
@@ -424,6 +430,19 @@ The variable `electric-layout-rules' says when and how to 
insert newlines."
          (remove-hook 'post-self-insert-hook
                       #'electric-layout-post-self-insert-function))))
 
+;;;###autoload
+(define-minor-mode electric-layout-local-mode
+  "Toggle `electric-layout-mode' only in this buffer."
+  :variable (buffer-local-value 'electric-layout-mode (current-buffer))
+  (cond
+   ((eq electric-layout-mode (default-value 'electric-layout-mode))
+    (kill-local-variable 'electric-layout-mode))
+   ((not (default-value 'electric-layout-mode))
+    ;; Locally enabled, but globally disabled.
+    (electric-layout-mode 1)             ; Setup the hooks.
+    (setq-default electric-layout-mode nil) ; But keep it globally disabled.
+    )))
+
 ;;; Electric quoting.
 
 (defcustom electric-quote-comment t
diff --git a/test/lisp/electric-tests.el b/test/lisp/electric-tests.el
index a665d2e..971c3e9 100644
--- a/test/lisp/electric-tests.el
+++ b/test/lisp/electric-tests.el
@@ -812,5 +812,39 @@ baz\"\""
   :bindings '((comment-start . "<!--") (comment-use-syntax . t))
   :test-in-comments nil :test-in-strings nil)
 
+
+;;; 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)
+                (?\{ . after-stay)))
+      (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)
+                (?\{ . after-stay)))
+      (insert "int main () ")
+      (let ((last-command-event ?\{))
+        (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]