On Wed, May 15, 2019 at 2:19 PM Stefan Monnier 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