bug-gnu-emacs
[Top][All Lists]
Advanced

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

bug#35254: 27.0.50; cc-mode/electric-pair-mode/electric-layout-mode: bad


From: João Távora
Subject: bug#35254: 27.0.50; cc-mode/electric-pair-mode/electric-layout-mode: bad trailing whitespace behavior in cc-mode
Date: Wed, 15 May 2019 14:55:09 +0100

On Wed, May 15, 2019 at 2:19 PM Stefan Monnier <monnier@iro.umontreal.ca> wrote:
> I've just come across the bug myself, and it is indeed annoying.
> Can you check if this patch, which seems the simplest, serves
> all purposes?

FWIW, I find it rather ugly (makes the two minor modes too tightly
intertwined).

It's no work of art. But the modes are already intertwined.
(And the code within a mode ain't no work of art, too :-))

> It also adds a test to prevent future regressions

Another approach might be to do the whitespace erasure in
electric-indent without paying any attention to electric-layout/pair,
and then in electric-pair to explicitly cause (re)indentation
after moving point to between the opened pair?

Maybe, I don't have time to implement that, and it looks like it
could hold surprises.  But if you do it and it passes the existing
tests and the new one, nothing against
 
Yet another option is to tell electric-indent about the final position
of point and have it refrain from deleting whitespace before that final
position, as in the patch below.  WDYT?

It looks a little like an elaboration of a third abstraction to basically
create another intertwining between e-p-m and e-i-m. Sure it's the
best? Anyway, if it passes all  tests, new and old, great, push it!

(but why are you deleting plainer-c-mode in test/lisp/electric-tests.el?)

João


 


        Stefan


diff --git a/lisp/elec-pair.el b/lisp/elec-pair.el
index 3be09d87b4..a14efff241 100644
--- a/lisp/elec-pair.el
+++ b/lisp/elec-pair.el
@@ -551,7 +551,8 @@ electric-pair-post-self-insert-function
                          (goto-char pos)
                          (funcall electric-pair-inhibit-predicate
                                   last-command-event)))))
-         (save-excursion (electric-pair--insert pair)))))
+         (let ((electric-indent--destination (point-marker)))
+           (save-excursion (electric-pair--insert pair))))))
       (_
        (when (and (if (functionp electric-pair-open-newline-between-pairs)
                       (funcall electric-pair-open-newline-between-pairs)
diff --git a/lisp/electric.el b/lisp/electric.el
index 07da2f1d9e..71ebb9cf45 100644
--- a/lisp/electric.el
+++ b/lisp/electric.el
@@ -231,6 +231,14 @@ electric-indent-functions-without-reindent
 not try to reindent lines.  It is normally better to make the major
 mode set `electric-indent-inhibit', but this can be used as a workaround.")

+(defun electric-indent--inhibited-p ()
+  (or electric-indent-inhibit
+      (memq indent-line-function
+            electric-indent-functions-without-reindent)))
+
+(defvar electric-indent--destination nil
+  "If non-nil, position to which point will be later restored.")
+
 (defun electric-indent-post-self-insert-function ()
   "Function that `electric-indent-mode' adds to `post-self-insert-hook'.
 This indents if the hook `electric-indent-functions' returns non-nil,
@@ -272,26 +280,26 @@ electric-indent-post-self-insert-function
           (when at-newline
             (let ((before (copy-marker (1- pos) t)))
               (save-excursion
-                (unless
-                    (or (memq indent-line-function
-                              electric-indent-functions-without-reindent)
-                        electric-indent-inhibit)
+                (unless (electric-indent--inhibited-p)
                   ;; Don't reindent the previous line if the
                   ;; indentation function is not a real one.
                   (goto-char before)
                   (condition-case-unless-debug ()
                       (indent-according-to-mode)
-                    (error (throw 'indent-error nil)))
-                  ;; The goal here will be to remove the trailing
-                  ;; whitespace after reindentation of the previous line
-                  ;; because that may have (re)introduced it.
-                  (goto-char before)
-                  ;; We were at EOL in marker `before' before the call
-                  ;; to `indent-according-to-mode' but after we may
-                  ;; not be (Bug#15767).
-                  (when (and (eolp))
-                    (delete-horizontal-space t))))))
-          (unless (and electric-indent-inhibit
+                    (error (throw 'indent-error nil))))
+                ;; The goal here will be to remove the trailing
+                ;; whitespace after reindentation of the previous line
+                ;; because that may have (re)introduced it.
+                (goto-char before)
+                ;; We were at EOL in marker `before' before the call
+                ;; to `indent-according-to-mode' but after we may
+                ;; not be (Bug#15767).
+                (when (and (eolp)
+                           ;; Don't delete "trailing space" before point!
+                           (not (and electric-indent--destination
+                                     (= (point) electric-indent--destination))))
+                  (delete-horizontal-space t)))))
+          (unless (and (electric-indent--inhibited-p)
                        (not at-newline))
             (condition-case-unless-debug ()
                 (indent-according-to-mode)
diff --git a/test/lisp/electric-tests.el b/test/lisp/electric-tests.el
index 4f1e5729be..0b67fb3f1f 100644
--- a/test/lisp/electric-tests.el
+++ b/test/lisp/electric-tests.el
@@ -876,15 +876,6 @@ electric-layout-for-c-style-du-jour
       (call-interactively (key-binding `[,last-command-event])))
     (should (equal (buffer-string) "int main () {\n  \n}"))))

-(define-derived-mode plainer-c-mode c-mode "pC"
-  "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-int-main-allman-style ()
   (ert-with-test-buffer ()
     (plainer-c-mode)



--
João Távora

reply via email to

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