[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc
From: |
João Távora |
Subject: |
bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode |
Date: |
Fri, 21 Dec 2018 18:49:34 +0000 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (windows-nt) |
Beatrix Klebe <beeuhtricks@gmail.com> writes:
> I believe I saw your Stack Overflow answer about this while searching
> for the solution. electric-layout-mode works with some quirks, such as
> that if you put a space after parens in a function definition, the
> space gets carried on to the newline with that method, which is a bit
> annoying. What would be ideal, and what I'm looking for, is to get
> auto-pairing of brackets with braces being placed where they should be
> automatically and the insertion point getting put in between them at
> the correct indent level, such as what happens with Visual Studio, or
> Visual Studio Code, or several other editors with this functionality.
> Perhaps it is not emacslike to have such behavior be totally
> automated, but I am used to it and finds it decreases my ordinary
> levels of frustration when working with verbose and imperative
> languages. I am currently trying to write some insert specifiers for
> smartparens to do this, but it is proving more difficult to find an
> elegant solution than I had expected.
It is quite emacslike (though maybe not activated by default): you just
have to report the bugs to the Emacs developers as efficiently as
possible.
1. Though Alan possibly has already, I still cannot understand the
original problem. Can you start by describing what the buffer looked
like before, what you did, what it looked like afterwards, and what
you expected it to look like? If possible start with a clean Emacs
-Q recpe.
2. I have experimented with nicer-playing like alternatives like
electric-layout-mode. I came across a few quirks myself (though I'm
not sure if they are the same as yours). So I prepared a patch (in
branch scratch/fix-33794-extend-electric-layout-mode) and attached
it after the sig.
After loading this patch, in a simple Emacs -Q the configuration:
(electric-pair-mode)
(electric-layout-mode)
(add-hook 'c-mode-hook
(lambda ()
(setq-local electric-layout-rules
'((?\{ . after)
(?\{ . after-stay)))))
And, when visiting a C file, if I press `{' I get the expected
pair+layout+indent behaviour. Sor example opening a brace after
int main () gives me:
int main () {
<cursor here>
}
I, like Stefan, think cc-mode could/should set electric-layout-rules
buffer-locally to reflect whatever c-style the user has selected.
Thanks,
João
PS: Also, can you link to the the relevant to the stack overflow answer you
mentioned?
commit ab036bdedbb49ecc96d550b5e883e43bb03eaccc
Author: João Távora <joaotavora@gmail.com>
Date: Fri Dec 21 18:00:08 2018 +0000
Extend electric-layout-mode to handle more complex layouts
Also, have it play nice with electric-pair-mode.
Multiple matching entries in `electric-layout-rules' are executed in
order of appearance. When inserting a newline in the 'after-stay
rule, ensure electric-pair-open-newline-between-pairs is nil.
Arguably the logic behind electric-pair-open-newline-between-pairs
should be moved to electric-layout-mode, but the current rule-matching
engine doesn't allow for it. The current solution seems to be good
enough for the situations reported in bug#33794.
* lisp/electric.el (electric-layout-rules): Adjust docstring.
(electric-layout-post-self-insert-function): Loop through rules. Bind
electric-pair-open-newline-between-pairs to nil when handling
after-stay.
diff --git a/lisp/electric.el b/lisp/electric.el
index 6dbf46b80c..6a307a49b9 100644
--- a/lisp/electric.el
+++ b/lisp/electric.el
@@ -370,38 +370,43 @@ electric-layout-rules
The symbols specify 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.")
+newline after CHAR but stay in the same place.
+
+If multiple rules match, they are all executed in order of
+appearance.")
(defun electric-layout-post-self-insert-function ()
- (let* ((rule (cdr (assq last-command-event electric-layout-rules)))
- pos)
- (when (and rule
- (setq pos (electric--after-char-pos))
+ (let (pos)
+ (when (and (setq pos (electric--after-char-pos))
;; Not in a string or comment.
(not (nth 8 (save-excursion (syntax-ppss pos)))))
- (let ((end (point-marker))
- (sym (if (functionp rule) (funcall rule) rule)))
- (set-marker-insertion-type end (not (eq sym 'after-stay)))
- (goto-char pos)
- (pcase sym
- ;; FIXME: we used `newline' down here which called
- ;; self-insert-command and ran post-self-insert-hook recursively.
- ;; It happened to make electric-indent-mode work automatically with
- ;; electric-layout-mode (at the cost of re-indenting lines
- ;; 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))
- (newline 1 t))))
- ('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)))))
+ (goto-char pos)
+ (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)))
+ (pcase sym
+ ;; FIXME: we used `newline' down here which called
+ ;; self-insert-command and ran post-self-insert-hook recursively.
+ ;; It happened to make electric-indent-mode work automatically
with
+ ;; electric-layout-mode (at the cost of re-indenting lines
+ ;; 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))))
+ ('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)))))))
(put 'electric-layout-post-self-insert-function 'priority 40)
- bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode, Beatrix Klebe, 2018/12/18
- Message not available
- bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode, Alan Mackenzie, 2018/12/21
- bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode, João Távora, 2018/12/21
- bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode, Stefan Monnier, 2018/12/21
- bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode, Beatrix Klebe, 2018/12/21
- bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode,
João Távora <=
- bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode, Beatrix Klebe, 2018/12/21
- bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode, João Távora, 2018/12/21
- bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode, João Távora, 2018/12/21
- bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode, Beatrix Klebe, 2018/12/21
- bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode, João Távora, 2018/12/21
- bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode, João Távora, 2018/12/21
- bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode, Alan Mackenzie, 2018/12/21
- bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode, João Távora, 2018/12/21
- bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode, Beatrix Klebe, 2018/12/21
- bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode, João Távora, 2018/12/22