* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode @ 2018-12-18 17:38 Beatrix Klebe [not found] ` <mailman.5894.1545155289.1284.bug-gnu-emacs@gnu.org> 0 siblings, 1 reply; 37+ messages in thread From: Beatrix Klebe @ 2018-12-18 17:38 UTC (permalink / raw) To: 33794 When using cc-mode, turning on electric-pair-mode causes the auto-newline minor mode to stop inserting newlines where expected. This is relevant to the formatting of C# code with the Allman/BSD brace style in particular, though it would be nice if these modes specifically did work together. In GNU Emacs 26.1 (build 1, x86_64-apple-darwin14.5.0, NS appkit-1348.17 Version 10.10.5 (Build 14F2511)) of 2018-05-30 built on builder10-10.porkrind.org Windowing system distributor 'Apple', version 10.3.1671 Recent messages: Saving file /Users/bea/.emacs.d/lisp/dotnet.el... Wrote /Users/bea/.emacs.d/lisp/dotnet.el ; expected Undo! ; expected Undo! [2 times] ; expected Auto-saving... ; expected [2 times] Making completion list... Configured using: 'configure --with-ns '--enable-locallisppath=/Library/Application Support/Emacs/${version}/site-lisp:/Library/Application Support/Emacs/site-lisp' --with-modules' Configured features: NOTIFY ACL GNUTLS LIBXML2 ZLIB TOOLKIT_SCROLL_BARS NS MODULES THREADS Important settings: value of $LANG: en_US.UTF-8 locale-coding-system: utf-8-unix Major mode: C#//la Minor modes in effect: smartparens-global-strict-mode: t smartparens-strict-mode: t smartparens-mode: t diff-auto-refine-mode: t projectile-mode: t omnisharp-mode: t rainbow-delimiters-mode: t delete-selection-mode: t global-flycheck-mode: t flycheck-mode: t global-company-mode: t company-mode: t global-hl-line-mode: t global-display-line-numbers-mode: t display-line-numbers-mode: t override-global-mode: t tooltip-mode: t global-eldoc-mode: t eldoc-mode: t electric-indent-mode: t mouse-wheel-mode: t menu-bar-mode: t file-name-shadow-mode: t global-font-lock-mode: t font-lock-mode: t auto-composition-mode: t auto-encryption-mode: t auto-compression-mode: t size-indication-mode: t column-number-mode: t line-number-mode: t transient-mark-mode: t Load-path shadows: None found. Features: (shadow sort mail-extr emacsbug sendmail smartparens-config warnings smartparens-text smartparens-ruby smartparens autoload radix-tree lisp-mnt tar-mode mm-archive message format-spec rfc822 mml mml-sec epa derived epg gnus-util rmail rmail-loaddefs mailabbrev gmm-utils mailheader mm-decode mm-bodies mm-encode mail-utils network-stream starttls url-http tls gnutls mail-parse rfc2231 rfc2047 rfc2045 mm-util ietf-drums mail-prsvr url-gw nsm rmc puny url-cache url-auth url url-proxy url-privacy url-expand url-methods url-history url-cookie url-domsuf url-util mailcap pp cus-edit cus-start cus-load wid-edit vc-git diff-mode projectile grep ibuf-ext ibuffer ibuffer-loaddefs omnisharp omnisharp-unit-test-actions omnisharp-code-structure omnisharp-server-installation omnisharp-format-actions omnisharp-solution-actions omnisharp-helm-integration omnisharp-navigation-actions omnisharp-current-symbol-actions omnisharp-auto-complete-actions omnisharp-server-actions omnisharp-http-utils omnisharp-utils omnisharp-server-management omnisharp-settings f s popup dired dired-loaddefs thingatpt ido csharp-mode imenu compile comint ansi-color cc-mode cc-fonts cc-guess cc-menus cc-cmds cc-styles cc-align cc-engine cc-vars cc-defs parinfer-ext parinfer ediff-merg ediff-wind ediff-diff ediff-mult ediff-help ediff-init ediff-util ediff mode-local parinferlib rainbow-delimiters windows-config macos-config exec-path-from-shell org-mode-config development proof-general-config dotnet elec-pair ocaml backup editor delsel flycheck-config flycheck json map find-func rx subr-x company-config delight advice company-oddmuse company-keywords company-etags etags xref project ring company-gtags company-dabbrev-code company-dabbrev company-files company-capf company-cmake company-xcode company-clang company-semantic company-eclim company-template company-bbdb company edmacro kmacro pcase ui hl-line display-line-numbers zenburn-theme package-config auto-package-update dash use-package use-package-ensure use-package-delight use-package-diminish use-package-bind-key bind-key easy-mmode use-package-core cl-extra help-mode finder-inf proof-site proof-autoloads pg-vars info package easymenu epg-config url-handlers url-parse auth-source cl-seq eieio eieio-core cl-macs eieio-loaddefs password-cache url-vars seq byte-opt bytecomp byte-compile cconv cl gv cl-loaddefs cl-lib time-date tooltip eldoc electric uniquify ediff-hook vc-hooks lisp-float-type mwheel term/ns-win ns-win ucs-normalize mule-util term/common-win tool-bar dnd fontset image regexp-opt fringe tabulated-list replace newcomment text-mode elisp-mode lisp-mode prog-mode register page menu-bar rfn-eshadow isearch timer select scroll-bar mouse jit-lock font-lock syntax facemenu font-core term/tty-colors frame cl-generic cham georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao korean japanese eucjp-ms cp51932 hebrew greek romanian slovak czech european ethiopic indian cyrillic chinese composite charscript charprop case-table epa-hook jka-cmpr-hook help simple abbrev obarray minibuffer cl-preloaded nadvice loaddefs button faces cus-face macroexp files text-properties overlay sha1 md5 base64 format env code-pages mule custom widget hashtable-print-readable backquote kqueue cocoa ns multi-tty make-network-process emacs) Memory information: ((conses 16 500415 57879) (symbols 48 41866 532) (miscs 40 198 1263) (strings 32 116702 6337) (string-bytes 1 3303823) (vectors 16 61571) (vector-slots 8 1021437 30984) (floats 8 135 577) (intervals 56 1409 585) (buffers 992 21)) ^ permalink raw reply [flat|nested] 37+ messages in thread
[parent not found: <mailman.5894.1545155289.1284.bug-gnu-emacs@gnu.org>]
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode [not found] ` <mailman.5894.1545155289.1284.bug-gnu-emacs@gnu.org> @ 2018-12-21 13:48 ` Alan Mackenzie 2018-12-21 13:57 ` João Távora 2018-12-23 14:48 ` Alan Mackenzie 1 sibling, 1 reply; 37+ messages in thread From: Alan Mackenzie @ 2018-12-21 13:48 UTC (permalink / raw) To: bea; +Cc: 33794, João Távora Hello, Beatrix. In article <mailman.5894.1545155289.1284.bug-gnu-emacs@gnu.org> you wrote: > When using cc-mode, turning on electric-pair-mode causes the > auto-newline minor mode to stop inserting newlines where expected. This > is relevant to the formatting of C# code with the Allman/BSD brace style > in particular, though it would be nice if these modes specifically did > work together. Yes. What is happening, from the viewpoint of CC Mode, is that on inserting a {, electric-pair-mode is prematurely inserting its }, before the processing for the { is complete. Also, due to the way } gets inserted, the CC Mode processing for the } isn't done at all. @João: I think electric pair mode is intended to simulate the manual insertion of a matching paren, etc., when a paren, etc., is typed. Would it therefore be possible, rather than having a crude insertion on post-self-insert-hook, to use something like post-command-hook to allow the insertion of the { first to complete? Then, rather than using the brutal self-insert-command for } in electric-pair--insert, use the command to which the key } is bound? This should allow CC Mode's auto-newline facility to work, and also more closely simulate the manual insertion of the closing delimiter. > In GNU Emacs 26.1 (build 1, x86_64-apple-darwin14.5.0, NS > appkit-1348.17 Version 10.10.5 (Build 14F2511)) > of 2018-05-30 built on builder10-10.porkrind.org > Windowing system distributor 'Apple', version 10.3.1671 > Recent messages: > Saving file /Users/bea/.emacs.d/lisp/dotnet.el... > Wrote /Users/bea/.emacs.d/lisp/dotnet.el > ; expected > Undo! > ; expected > Undo! [2 times] > ; expected > Auto-saving... > ; expected [2 times] > Making completion list... -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode 2018-12-21 13:48 ` Alan Mackenzie @ 2018-12-21 13:57 ` João Távora 2018-12-21 14:12 ` Stefan Monnier 2018-12-21 21:50 ` Alan Mackenzie 0 siblings, 2 replies; 37+ messages in thread From: João Távora @ 2018-12-21 13:57 UTC (permalink / raw) To: Alan Mackenzie; +Cc: bea, 33794, Stefan Monnier [-- Attachment #1: Type: text/plain, Size: 1960 bytes --] On Fri, Dec 21, 2018 at 1:48 PM Alan Mackenzie <acm@muc.de> wrote: > Hello, Beatrix. > > In article <mailman.5894.1545155289.1284.bug-gnu-emacs@gnu.org> you wrote: > > When using cc-mode, turning on electric-pair-mode causes the > > auto-newline minor mode to stop inserting newlines where expected. This > > is relevant to the formatting of C# code with the Allman/BSD brace style > > in particular, though it would be nice if these modes specifically did > > work together. > > Yes. What is happening, from the viewpoint of CC Mode, is that on > inserting a {, electric-pair-mode is prematurely inserting its }, before > the processing for the { is complete. Also, due to the way } gets > inserted, the CC Mode processing for the } isn't done at all. > > @João: I think electric pair mode is intended to simulate the manual > insertion of a matching paren, etc., when a paren, etc., is typed. > > Would it therefore be possible, rather than having a crude insertion on > post-self-insert-hook, to use something like post-command-hook to allow > the insertion of the { first to complete? Then, rather than using the > brutal self-insert-command for } in electric-pair--insert, use the > command to which the key } is bound? This should allow CC Mode's > auto-newline facility to work, and also more closely simulate the manual > insertion of the closing delimiter. I don't know. We better ask Stefan (CC'ed) who I believe designed the original strategy of inserting closing delimiters in the previous electric-pair-mode. That didn't change in my redesign. FWIW, I think cc-mode should rather use post-self-insert-hook instead of redefining commands for keys whose expected behaviour is (with minor variations presumably covered by abundant hookage) self-insertion. If you place your specific cc-mode processing late enough in the hook then its insertion will be "complete" for all practical purposes. João [-- Attachment #2: Type: text/html, Size: 2569 bytes --] ^ permalink raw reply [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode 2018-12-21 13:57 ` João Távora @ 2018-12-21 14:12 ` Stefan Monnier 2018-12-21 16:00 ` Beatrix Klebe 2018-12-21 20:11 ` Alan Mackenzie 2018-12-21 21:50 ` Alan Mackenzie 1 sibling, 2 replies; 37+ messages in thread From: Stefan Monnier @ 2018-12-21 14:12 UTC (permalink / raw) To: João Távora; +Cc: Alan Mackenzie, bea, 33794 >> Yes. What is happening, from the viewpoint of CC Mode, is that on >> inserting a {, electric-pair-mode is prematurely inserting its }, before >> the processing for the { is complete. Since it's done from post-self-insert-hook, it's done at the very end of inserting { so I'm not sure what you mean by "before the processing for the { is complete". >> Also, due to the way } gets inserted, the CC Mode processing for >> the } isn't done at all. I think you meant "due to the way CC-Mode hooks itself into the } processing, ..." ;-) >> Would it therefore be possible, rather than having a crude insertion on >> post-self-insert-hook, to use something like post-command-hook to allow >> the insertion of the { first to complete? Then, rather than using the >> brutal self-insert-command for } in electric-pair--insert, use the >> command to which the key } is bound? Talking about brutal: how could electric-pair-mode run whichever command is bound to } without taking the risk of running a much more brutal command than one that inserts a character? > FWIW, I think cc-mode should rather use post-self-insert-hook instead > of redefining commands for keys whose expected behaviour is > (with minor variations presumably covered by abundant hookage) > self-insertion. IIRC it should be able to just use electric-layout-mode for that (tho maybe electric-layout's featureset doesn't currently cover 100% that of CC-mode's auto-newline, in which case it would be nice to extend electric-layout accordingly). For things like electric-pair, electric-indent, and electric-layout to work correctly together, they need to agree on some convention. Note that CC-mode can also side-step that convention and use `insert` instead of self-insert-command. Stefan ^ permalink raw reply [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode 2018-12-21 14:12 ` Stefan Monnier @ 2018-12-21 16:00 ` Beatrix Klebe 2018-12-21 18:49 ` João Távora 2019-01-01 19:27 ` Alan Mackenzie 2018-12-21 20:11 ` Alan Mackenzie 1 sibling, 2 replies; 37+ messages in thread From: Beatrix Klebe @ 2018-12-21 16:00 UTC (permalink / raw) To: Stefan Monnier Cc: Alan Mackenzie, Mx. Beatrix Klebe, João Távora, 33794 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. On Fri, Dec 21, 2018 at 10:54 AM Stefan Monnier <monnier@iro.umontreal.ca> wrote: > > >> Yes. What is happening, from the viewpoint of CC Mode, is that on > >> inserting a {, electric-pair-mode is prematurely inserting its }, before > >> the processing for the { is complete. > > Since it's done from post-self-insert-hook, it's done at the very end of > inserting { so I'm not sure what you mean by "before the processing for > the { is complete". > > >> Also, due to the way } gets inserted, the CC Mode processing for > >> the } isn't done at all. > > I think you meant "due to the way CC-Mode hooks itself into the } > processing, ..." ;-) > > >> Would it therefore be possible, rather than having a crude insertion on > >> post-self-insert-hook, to use something like post-command-hook to allow > >> the insertion of the { first to complete? Then, rather than using the > >> brutal self-insert-command for } in electric-pair--insert, use the > >> command to which the key } is bound? > > Talking about brutal: how could electric-pair-mode run whichever command > is bound to } without taking the risk of running a much more brutal > command than one that inserts a character? > > > FWIW, I think cc-mode should rather use post-self-insert-hook instead > > of redefining commands for keys whose expected behaviour is > > (with minor variations presumably covered by abundant hookage) > > self-insertion. > > IIRC it should be able to just use electric-layout-mode for that (tho > maybe electric-layout's featureset doesn't currently cover 100% that of > CC-mode's auto-newline, in which case it would be nice to extend > electric-layout accordingly). > > For things like electric-pair, electric-indent, and electric-layout to > work correctly together, they need to agree on some convention. > > Note that CC-mode can also side-step that convention and use `insert` > instead of self-insert-command. > > > Stefan ^ permalink raw reply [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode 2018-12-21 16:00 ` Beatrix Klebe @ 2018-12-21 18:49 ` João Távora 2018-12-21 19:06 ` Beatrix Klebe 2019-01-01 19:27 ` Alan Mackenzie 1 sibling, 1 reply; 37+ messages in thread From: João Távora @ 2018-12-21 18:49 UTC (permalink / raw) To: Beatrix Klebe; +Cc: Alan Mackenzie, bea, Stefan Monnier, 33794 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) ^ permalink raw reply related [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode 2018-12-21 18:49 ` João Távora @ 2018-12-21 19:06 ` Beatrix Klebe 2018-12-21 19:20 ` João Távora 0 siblings, 1 reply; 37+ messages in thread From: Beatrix Klebe @ 2018-12-21 19:06 UTC (permalink / raw) To: João Távora Cc: Alan Mackenzie, Mx. Beatrix Klebe, Stefan Monnier, 33794 Here's the link, I believe it was Stefan that answered it: https://emacs.stackexchange.com/questions/2837/automatically-formatting-brackets/2853#2853 I have tried this with emacs -Q and it does not fix the issue, which is as follows. Ordinarily in cc-mode when you have auto-newline-mode activated, and as far as I can tell, a cc-mode configuration that supports it, (which csharp-mode contains), the following happens when opening a block (pipe is the cursor): void Main() {| // opening bracket is typed becomes void Main { | when c-toggle-auto-newline is activated. However, if you also want your braces automatically paired, with electric-pair-mode, instead the following occurs: void Main() {| // opening bracket is typed void Main() {|} // electric-pair-mode closes the open bracket, but auto-newline-mode does not appear to do anything. void Main() { | } // user hits return, inserting the cursor at the correct indent level, but leaving the opening brace where it is. The ideal/desired behavior is: void Main() {| // opening bracket is typed void Main() { | } // user hits return key, electric-pair-mode pairs up the brackets, and auto-newline-mode formats the braces correctly It would also probably suffice to format with the newline before hitting enter as well, although I think I prefer hitting enter to open the block. I'm quite curious as to the internals of these formatting systems and would be happy to help with a fix/feature if that would be desired, I am mostly an OCaml programmer but C# is my day job and I've just recently gotten deeper into Emacs Lisp. On Fri, Dec 21, 2018 at 1:49 PM João Távora <joaotavora@gmail.com> wrote: > > 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) > ^ permalink raw reply [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode 2018-12-21 19:06 ` Beatrix Klebe @ 2018-12-21 19:20 ` João Távora 2018-12-21 19:24 ` João Távora 2018-12-21 19:43 ` Beatrix Klebe 0 siblings, 2 replies; 37+ messages in thread From: João Távora @ 2018-12-21 19:20 UTC (permalink / raw) To: bea; +Cc: Alan Mackenzie, Stefan Monnier, 33794 [-- Attachment #1: Type: text/plain, Size: 10419 bytes --] Hi Beatrix, The solution I propose involves introducing the hotpatch I attached to fix electric-layout-mode in your emacs, so I wouldn't expect it to work if you haven't done that. Do you know how to do it? Though Alan will probably suggest otherwise, I'd also steer away from c-specific functionality and keep to the triad electric-indent-mode, electric-pair-mode and electric-indent-mode, at least while we try to extend/fix these modes to accommodate your needs. After such a solution is evaluated, you can select to keep it or move to something else. João On Fri, Dec 21, 2018, 19:06 Beatrix Klebe <beeuhtricks@gmail.com wrote: > Here's the link, I believe it was Stefan that answered it: > > https://emacs.stackexchange.com/questions/2837/automatically-formatting-brackets/2853#2853 > > I have tried this with emacs -Q and it does not fix the issue, which > is as follows. > > Ordinarily in cc-mode when you have auto-newline-mode activated, and > as far as I can tell, a cc-mode configuration that supports it, (which > csharp-mode contains), the following happens when opening a block > (pipe is the cursor): > > void Main() {| // opening bracket is typed > > becomes > > void Main > { > | > > when c-toggle-auto-newline is activated. However, if you also want > your braces automatically paired, with electric-pair-mode, instead the > following occurs: > > void Main() {| // opening bracket is typed > > void Main() {|} // electric-pair-mode closes the open bracket, but > auto-newline-mode does not appear to do anything. > > void Main() { > | > } // user hits return, inserting the cursor at the correct indent > level, but leaving the opening brace where it is. > > The ideal/desired behavior is: > > void Main() {| // opening bracket is typed > > void Main() > { > | > } // user hits return key, electric-pair-mode pairs up the brackets, > and auto-newline-mode formats the braces correctly > > It would also probably suffice to format with the newline before > hitting enter as well, although I think I prefer hitting enter to open > the block. I'm quite curious as to the internals of these formatting > systems and would be happy to help with a fix/feature if that would be > desired, I am mostly an OCaml programmer but C# is my day job and I've > just recently gotten deeper into Emacs Lisp. > > On Fri, Dec 21, 2018 at 1:49 PM João Távora <joaotavora@gmail.com> wrote: > > > > 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) > > > [-- Attachment #2: Type: text/html, Size: 13115 bytes --] ^ permalink raw reply [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode 2018-12-21 19:20 ` João Távora @ 2018-12-21 19:24 ` João Távora 2018-12-21 19:43 ` Beatrix Klebe 1 sibling, 0 replies; 37+ messages in thread From: João Távora @ 2018-12-21 19:24 UTC (permalink / raw) To: bea; +Cc: Alan Mackenzie, Stefan Monnier, 33794 [-- Attachment #1: Type: text/plain, Size: 11050 bytes --] By the way, Stefan, this patch is only an idea, and maybe not a very good one since it may break backward compatibility in electric-layout-rules. After having seen Beatrix's link to your so answer, I see that two separate rules on two separate chars should also work for this. João On Fri, Dec 21, 2018, 19:20 João Távora <joaotavora@gmail.com wrote: > Hi Beatrix, > > The solution I propose involves introducing the hotpatch I attached to fix > electric-layout-mode in your emacs, so I wouldn't expect it to work if you > haven't done that. > > Do you know how to do it? > > Though Alan will probably suggest otherwise, I'd also steer away from > c-specific functionality and keep to the triad electric-indent-mode, > electric-pair-mode and electric-indent-mode, at least while we try to > extend/fix these modes to accommodate your needs. > > After such a solution is evaluated, you can select to keep it or move to > something else. > > João > > On Fri, Dec 21, 2018, 19:06 Beatrix Klebe <beeuhtricks@gmail.com wrote: > >> Here's the link, I believe it was Stefan that answered it: >> >> https://emacs.stackexchange.com/questions/2837/automatically-formatting-brackets/2853#2853 >> >> I have tried this with emacs -Q and it does not fix the issue, which >> is as follows. >> >> Ordinarily in cc-mode when you have auto-newline-mode activated, and >> as far as I can tell, a cc-mode configuration that supports it, (which >> csharp-mode contains), the following happens when opening a block >> (pipe is the cursor): >> >> void Main() {| // opening bracket is typed >> >> becomes >> >> void Main >> { >> | >> >> when c-toggle-auto-newline is activated. However, if you also want >> your braces automatically paired, with electric-pair-mode, instead the >> following occurs: >> >> void Main() {| // opening bracket is typed >> >> void Main() {|} // electric-pair-mode closes the open bracket, but >> auto-newline-mode does not appear to do anything. >> >> void Main() { >> | >> } // user hits return, inserting the cursor at the correct indent >> level, but leaving the opening brace where it is. >> >> The ideal/desired behavior is: >> >> void Main() {| // opening bracket is typed >> >> void Main() >> { >> | >> } // user hits return key, electric-pair-mode pairs up the brackets, >> and auto-newline-mode formats the braces correctly >> >> It would also probably suffice to format with the newline before >> hitting enter as well, although I think I prefer hitting enter to open >> the block. I'm quite curious as to the internals of these formatting >> systems and would be happy to help with a fix/feature if that would be >> desired, I am mostly an OCaml programmer but C# is my day job and I've >> just recently gotten deeper into Emacs Lisp. >> >> On Fri, Dec 21, 2018 at 1:49 PM João Távora <joaotavora@gmail.com> wrote: >> > >> > 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) >> > >> > [-- Attachment #2: Type: text/html, Size: 13841 bytes --] ^ permalink raw reply [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode 2018-12-21 19:20 ` João Távora 2018-12-21 19:24 ` João Távora @ 2018-12-21 19:43 ` Beatrix Klebe 2018-12-22 1:08 ` João Távora 1 sibling, 1 reply; 37+ messages in thread From: Beatrix Klebe @ 2018-12-21 19:43 UTC (permalink / raw) To: João Távora Cc: Alan Mackenzie, Mx. Beatrix Klebe, Stefan Monnier, 33794 I know how to do hotpaches but that doesn't appear to solve the problem I'm having here, unless I've missed something. The problem is with moving the opening bracket, not the insertion point. On Fri, Dec 21, 2018 at 2:20 PM João Távora <joaotavora@gmail.com> wrote: > > Hi Beatrix, > > The solution I propose involves introducing the hotpatch I attached to fix electric-layout-mode in your emacs, so I wouldn't expect it to work if you haven't done that. > > Do you know how to do it? > > Though Alan will probably suggest otherwise, I'd also steer away from c-specific functionality and keep to the triad electric-indent-mode, electric-pair-mode and electric-indent-mode, at least while we try to extend/fix these modes to accommodate your needs. > > After such a solution is evaluated, you can select to keep it or move to something else. > > João > > On Fri, Dec 21, 2018, 19:06 Beatrix Klebe <beeuhtricks@gmail.com wrote: >> >> Here's the link, I believe it was Stefan that answered it: >> https://emacs.stackexchange.com/questions/2837/automatically-formatting-brackets/2853#2853 >> >> I have tried this with emacs -Q and it does not fix the issue, which >> is as follows. >> >> Ordinarily in cc-mode when you have auto-newline-mode activated, and >> as far as I can tell, a cc-mode configuration that supports it, (which >> csharp-mode contains), the following happens when opening a block >> (pipe is the cursor): >> >> void Main() {| // opening bracket is typed >> >> becomes >> >> void Main >> { >> | >> >> when c-toggle-auto-newline is activated. However, if you also want >> your braces automatically paired, with electric-pair-mode, instead the >> following occurs: >> >> void Main() {| // opening bracket is typed >> >> void Main() {|} // electric-pair-mode closes the open bracket, but >> auto-newline-mode does not appear to do anything. >> >> void Main() { >> | >> } // user hits return, inserting the cursor at the correct indent >> level, but leaving the opening brace where it is. >> >> The ideal/desired behavior is: >> >> void Main() {| // opening bracket is typed >> >> void Main() >> { >> | >> } // user hits return key, electric-pair-mode pairs up the brackets, >> and auto-newline-mode formats the braces correctly >> >> It would also probably suffice to format with the newline before >> hitting enter as well, although I think I prefer hitting enter to open >> the block. I'm quite curious as to the internals of these formatting >> systems and would be happy to help with a fix/feature if that would be >> desired, I am mostly an OCaml programmer but C# is my day job and I've >> just recently gotten deeper into Emacs Lisp. >> >> On Fri, Dec 21, 2018 at 1:49 PM João Távora <joaotavora@gmail.com> wrote: >> > >> > 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) >> > ^ permalink raw reply [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode 2018-12-21 19:43 ` Beatrix Klebe @ 2018-12-22 1:08 ` João Távora 2018-12-22 2:16 ` João Távora 0 siblings, 1 reply; 37+ messages in thread From: João Távora @ 2018-12-22 1:08 UTC (permalink / raw) To: Beatrix Klebe; +Cc: Alan Mackenzie, bea, Stefan Monnier, 33794 Beatrix Klebe <beeuhtricks@gmail.com> writes: > I know how to do hotpaches but that doesn't appear to solve the > problem I'm having here, unless I've missed something. The problem is > with moving the opening bracket, not the insertion point. Beatrix, I think you may have missed the fact that I am suggesting alternatives that: * involve cc-mode, or one of its derived modes; * don't involve M-x c-toggle-auto-newline (turning on what you call auto-newline-mode); * involve turning on the global electric-layout-mode and a thin customization for it in the buffers where you think it's relevant (presumably cc-mode); * may involve multiple fixed/patched versions of lisp/electric.el as I understand your problem(s); As it stands, the last patch I sent you passes my only test which is this: given a file 33794.el which is just: (electric-pair-mode) (electric-layout-mode) (add-hook 'c-mode-hook (lambda () (setq-local electric-layout-rules '((?\{ . after) (?\{ . after-stay))))) then running this from a shell: $ emacs -Q -l 33794.el something.c Opens a new c-mode buffer. Type 'int main ()' and then an opening brace. You should get: int main () { <cursor> } Can you reproduce these results? If you can come up with more of these tests written in this or a similarly simple and exact manner it's easier for me to understand what's going on (it's also easier to write automated tests). João > > > On Fri, Dec 21, 2018 at 2:20 PM João Távora <joaotavora@gmail.com> wrote: >> >> Hi Beatrix, >> >> The solution I propose involves introducing the hotpatch I attached >> to fix electric-layout-mode in your emacs, so I wouldn't expect it >> to work if you haven't done that. >> >> Do you know how to do it? >> >> Though Alan will probably suggest otherwise, I'd also steer away >> from c-specific functionality and keep to the triad >> electric-indent-mode, electric-pair-mode and electric-indent-mode, >> at least while we try to extend/fix these modes to accommodate your >> needs. >> >> After such a solution is evaluated, you can select to keep it or move to something else. >> >> João >> >> On Fri, Dec 21, 2018, 19:06 Beatrix Klebe <beeuhtricks@gmail.com wrote: >>> >>> Here's the link, I believe it was Stefan that answered it: >>> https://emacs.stackexchange.com/questions/2837/automatically-formatting-brackets/2853#2853 >>> >>> I have tried this with emacs -Q and it does not fix the issue, which >>> is as follows. >>> >>> Ordinarily in cc-mode when you have auto-newline-mode activated, and >>> as far as I can tell, a cc-mode configuration that supports it, (which >>> csharp-mode contains), the following happens when opening a block >>> (pipe is the cursor): >>> >>> void Main() {| // opening bracket is typed >>> >>> becomes >>> >>> void Main >>> { >>> | >>> >>> when c-toggle-auto-newline is activated. However, if you also want >>> your braces automatically paired, with electric-pair-mode, instead the >>> following occurs: >>> >>> void Main() {| // opening bracket is typed >>> >>> void Main() {|} // electric-pair-mode closes the open bracket, but >>> auto-newline-mode does not appear to do anything. >>> >>> void Main() { >>> | >>> } // user hits return, inserting the cursor at the correct indent >>> level, but leaving the opening brace where it is. >>> >>> The ideal/desired behavior is: >>> >>> void Main() {| // opening bracket is typed >>> >>> void Main() >>> { >>> | >>> } // user hits return key, electric-pair-mode pairs up the brackets, >>> and auto-newline-mode formats the braces correctly >>> >>> It would also probably suffice to format with the newline before >>> hitting enter as well, although I think I prefer hitting enter to open >>> the block. I'm quite curious as to the internals of these formatting >>> systems and would be happy to help with a fix/feature if that would be >>> desired, I am mostly an OCaml programmer but C# is my day job and I've >>> just recently gotten deeper into Emacs Lisp. >>> >>> On Fri, Dec 21, 2018 at 1:49 PM João Távora <joaotavora@gmail.com> wrote: >>> > >>> > 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) >>> > ^ permalink raw reply [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode 2018-12-22 1:08 ` João Távora @ 2018-12-22 2:16 ` João Távora 2018-12-22 2:41 ` Alan Mackenzie 0 siblings, 1 reply; 37+ messages in thread From: João Távora @ 2018-12-22 2:16 UTC (permalink / raw) To: Beatrix Klebe; +Cc: Alan Mackenzie, bea, Stefan Monnier, 33794 [-- Attachment #1: Type: text/plain, Size: 570 bytes --] Hi again Beatrix, In the latest version of the patch I am preparing, if you do (add-hook 'c-mode-hook (lambda () (setq-local electric-layout-rules '((?\{ . before}) (?\{ . after) (?\{ . after-stay))))) You should arive at Allman C-style electric layouts. So typing int main () <spaces> then brace should give you: int main () { <cursor here> } I attach the two patches for convenience, which you can also find in the scratch/fix-33794-extend-electric-layout-mode branch. João [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0001-Extend-electric-layout-mode-to-handle-more-complex-l.patch --] [-- Type: text/x-diff, Size: 4754 bytes --] From ab036bdedbb49ecc96d550b5e883e43bb03eaccc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20T=C3=A1vora?= <joaotavora@gmail.com> Date: Fri, 21 Dec 2018 18:00:08 +0000 Subject: [PATCH 1/2] 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. --- lisp/electric.el | 61 ++++++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 28 deletions(-) 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) -- 2.20.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #3: 0002-Rework-electric-layout-post-self-insert-function-bug.patch --] [-- Type: text/x-diff, Size: 6250 bytes --] From dfc19a04f5f455051d158648a963cb1fd8b91c67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20T=C3=A1vora?= <joaotavora@gmail.com> Date: Sat, 22 Dec 2018 01:52:08 +0000 Subject: [PATCH 2/2] 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 6a307a49b9..24c040d05b 100644 --- a/lisp/electric.el +++ b/lisp/electric.el @@ -376,17 +376,25 @@ electric-layout-rules 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 @@ electric-layout-post-self-insert-function ;; 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 @@ electric-layout-mode (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 a665d2eb28..971c3e9567 100644 --- a/test/lisp/electric-tests.el +++ b/test/lisp/electric-tests.el @@ -812,5 +812,39 @@ electric-quote-markdown-in-code :bindings '((comment-start . "<!--") (comment-use-syntax . t)) :test-in-comments nil :test-in-strings nil) +\f +;;; 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 -- 2.20.0 [-- Attachment #4: Type: text/plain, Size: 12953 bytes --] João Távora <joaotavora@gmail.com> writes: > Beatrix Klebe <beeuhtricks@gmail.com> writes: > >> I know how to do hotpaches but that doesn't appear to solve the >> problem I'm having here, unless I've missed something. The problem is >> with moving the opening bracket, not the insertion point. > > Beatrix, > > I think you may have missed the fact that I am suggesting alternatives > that: > > * involve cc-mode, or one of its derived modes; > > * don't involve M-x c-toggle-auto-newline (turning on what you call > auto-newline-mode); > > * involve turning on the global electric-layout-mode and a thin > customization for it in the buffers where you think it's relevant > (presumably cc-mode); > > * may involve multiple fixed/patched versions of lisp/electric.el as I > understand your problem(s); > > As it stands, the last patch I sent you passes my only test which is > this: given a file 33794.el which is just: > > (electric-pair-mode) > (electric-layout-mode) > > (add-hook 'c-mode-hook > (lambda () > (setq-local electric-layout-rules > '((?\{ . after) > (?\{ . after-stay))))) > > > then running this from a shell: > > $ emacs -Q -l 33794.el something.c > > Opens a new c-mode buffer. Type 'int main ()' and then an opening > brace. You should get: > > int main () { > <cursor> > } > > Can you reproduce these results? If you can come up with more of these > tests written in this or a similarly simple and exact manner it's easier > for me to understand what's going on (it's also easier to write > automated tests). > > João > >> >> >> On Fri, Dec 21, 2018 at 2:20 PM João Távora <joaotavora@gmail.com> wrote: >>> >>> Hi Beatrix, >>> >>> The solution I propose involves introducing the hotpatch I attached >>> to fix electric-layout-mode in your emacs, so I wouldn't expect it >>> to work if you haven't done that. >>> >>> Do you know how to do it? >>> >>> Though Alan will probably suggest otherwise, I'd also steer away >>> from c-specific functionality and keep to the triad >>> electric-indent-mode, electric-pair-mode and electric-indent-mode, >>> at least while we try to extend/fix these modes to accommodate your >>> needs. >>> >>> After such a solution is evaluated, you can select to keep it or move to something else. >>> >>> João >>> >>> On Fri, Dec 21, 2018, 19:06 Beatrix Klebe <beeuhtricks@gmail.com wrote: >>>> >>>> Here's the link, I believe it was Stefan that answered it: >>>> https://emacs.stackexchange.com/questions/2837/automatically-formatting-brackets/2853#2853 >>>> >>>> I have tried this with emacs -Q and it does not fix the issue, which >>>> is as follows. >>>> >>>> Ordinarily in cc-mode when you have auto-newline-mode activated, and >>>> as far as I can tell, a cc-mode configuration that supports it, (which >>>> csharp-mode contains), the following happens when opening a block >>>> (pipe is the cursor): >>>> >>>> void Main() {| // opening bracket is typed >>>> >>>> becomes >>>> >>>> void Main >>>> { >>>> | >>>> >>>> when c-toggle-auto-newline is activated. However, if you also want >>>> your braces automatically paired, with electric-pair-mode, instead the >>>> following occurs: >>>> >>>> void Main() {| // opening bracket is typed >>>> >>>> void Main() {|} // electric-pair-mode closes the open bracket, but >>>> auto-newline-mode does not appear to do anything. >>>> >>>> void Main() { >>>> | >>>> } // user hits return, inserting the cursor at the correct indent >>>> level, but leaving the opening brace where it is. >>>> >>>> The ideal/desired behavior is: >>>> >>>> void Main() {| // opening bracket is typed >>>> >>>> void Main() >>>> { >>>> | >>>> } // user hits return key, electric-pair-mode pairs up the brackets, >>>> and auto-newline-mode formats the braces correctly >>>> >>>> It would also probably suffice to format with the newline before >>>> hitting enter as well, although I think I prefer hitting enter to open >>>> the block. I'm quite curious as to the internals of these formatting >>>> systems and would be happy to help with a fix/feature if that would be >>>> desired, I am mostly an OCaml programmer but C# is my day job and I've >>>> just recently gotten deeper into Emacs Lisp. >>>> >>>> On Fri, Dec 21, 2018 at 1:49 PM João Távora <joaotavora@gmail.com> wrote: >>>> > >>>> > 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) >>>> > ^ permalink raw reply related [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode 2018-12-22 2:16 ` João Távora @ 2018-12-22 2:41 ` Alan Mackenzie 2018-12-22 3:22 ` João Távora 0 siblings, 1 reply; 37+ messages in thread From: Alan Mackenzie @ 2018-12-22 2:41 UTC (permalink / raw) To: Beatrix Klebe; +Cc: bea, 33794, Stefan Monnier, João Távora Hello, Beatrix. As maintainer of CC Mode, I earnestly recommend you NOT to follow João's suggestion. It will not work, and will waste your time. Even if it appears to work, you will end up picking out bugs for an indeterminate period. Basically, electric-pair-mode as it is currently built is incompatible with CC Mode, as I have pointed out here, albeit somewhat undiplomatically. I suggest you do nothing until tempers amongst Emacs developers have cooled down, and hopefully a genuine solution to the bug has been worked out and implemented. -- Alan Mackenzie (Nuremberg, Germany). On Sat, Dec 22, 2018 at 02:16:03 +0000, João Távora wrote: > Hi again Beatrix, > In the latest version of the patch I am preparing, if you do > (add-hook 'c-mode-hook > (lambda () > (setq-local electric-layout-rules > '((?\{ . before}) > (?\{ . after) > (?\{ . after-stay))))) > You should arive at Allman C-style electric layouts. So typing > int main () <spaces> then brace should give you: > int main () > { > <cursor here> > } > I attach the two patches for convenience, which you can also find in the > scratch/fix-33794-extend-electric-layout-mode branch. > João ^ permalink raw reply [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode 2018-12-22 2:41 ` Alan Mackenzie @ 2018-12-22 3:22 ` João Távora 2018-12-22 4:41 ` Beatrix Klebe 2018-12-22 12:33 ` Alan Mackenzie 0 siblings, 2 replies; 37+ messages in thread From: João Távora @ 2018-12-22 3:22 UTC (permalink / raw) To: Alan Mackenzie; +Cc: Beatrix Klebe, bea, Stefan Monnier, 33794 Alan Mackenzie <acm@muc.de> writes: > Hello, Beatrix. > > As maintainer of CC Mode, I earnestly recommend you NOT to follow João's > suggestion. It will not work, and will waste your time. What, exactly, will not work? > Even if it appears to work, you will end up picking out bugs for an > indeterminate period. What bugs? If you know of any, it would be good to report them, right? > Basically, electric-pair-mode as it is currently built is incompatible > with CC Mode, as I have pointed out here, albeit somewhat > undiplomatically. > > I suggest you do nothing until tempers amongst Emacs developers have > cooled down, and hopefully a genuine solution to the bug has been worked > out and implemented. If you don't like electric-layout-mode, don't use it. I'm trying to develop an alternative to c-toggle-auto-newline within the electric-*-mode frame. It's an experiment which I don't even know if Stefan will agree to, but it seems to work. If Beatrix wants to cooperate, why shouldn't she? I'm not asking you to nuke c-toggle-auto-newline or anything, but should we all be forced to use it? I don't think it's sensible in a free software project, Alan (and my temper is quite cool when saying this :-)) Again, I said I don't have anything against making eletric-pair-mode compatible with c-toggle-auto-newline if someone comes up with a good solution that doesn't break e-p-m for other modes. I will not invest time in looking into that solution, but you or someone else may, of course. In the meantime let people explore alternatives, right? João ^ permalink raw reply [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode 2018-12-22 3:22 ` João Távora @ 2018-12-22 4:41 ` Beatrix Klebe 2018-12-22 10:02 ` João Távora 2018-12-22 12:33 ` Alan Mackenzie 1 sibling, 1 reply; 37+ messages in thread From: Beatrix Klebe @ 2018-12-22 4:41 UTC (permalink / raw) To: João Távora; +Cc: Alan Mackenzie, bea, 33794, Stefan Monnier [-- Attachment #1: Type: text/plain, Size: 3075 bytes --] I didn’t intend to kick the hornet’s nest of ideological factions here, I was honestly just wondering if this was actually expected behavior of these two modes together and if not if the fix was trivial. The answer seems to be that it is indeed a bug and the fix is non-trivial, and furthermore while I appreciate attempts to hotfix it, those are not solutions of the quality I was expecting, (I encountered those already while doing my own research before I filed this bug report and I found them unsatisfactory both then and now) and furthermore I feel like I should be open in stating that I feel somewhat condescended to. I know what c-toggle-auto-newline is, I also know that functions prefixed with “toggle” are functions that toggle a mode or setting internally, in this case a minor mode called auto-newline ( https://www.gnu.org/software/emacs/manual/html_node/ccmode/Auto_002dnewlines.html) I was about five minutes away from diving into the source of these two packages to fix it myself, as I have spent probably 10 hours reasearching this problem at this point. I’m sorry if I misunderstood something, I was mainly looking for clarification that what I was experiencing was a bug, and it is beginning to seem like there is none to be had here. My apologies. On Fri, Dec 21, 2018 at 10:22 PM João Távora <joaotavora@gmail.com> wrote: > Alan Mackenzie <acm@muc.de> writes: > > > Hello, Beatrix. > > > > As maintainer of CC Mode, I earnestly recommend you NOT to follow João's > > suggestion. It will not work, and will waste your time. > > What, exactly, will not work? > > > Even if it appears to work, you will end up picking out bugs for an > > indeterminate period. > > What bugs? If you know of any, it would be good to report them, right? > > > Basically, electric-pair-mode as it is currently built is incompatible > > with CC Mode, as I have pointed out here, albeit somewhat > > undiplomatically. > > > > I suggest you do nothing until tempers amongst Emacs developers have > > cooled down, and hopefully a genuine solution to the bug has been worked > > out and implemented. > > If you don't like electric-layout-mode, don't use it. I'm trying to > develop an alternative to c-toggle-auto-newline within the > electric-*-mode frame. It's an experiment which I don't even know if > Stefan will agree to, but it seems to work. If Beatrix wants to > cooperate, why shouldn't she? > > I'm not asking you to nuke c-toggle-auto-newline or anything, but should > we all be forced to use it? I don't think it's sensible in a free > software project, Alan (and my temper is quite cool when saying this > :-)) > > Again, I said I don't have anything against making eletric-pair-mode > compatible with c-toggle-auto-newline if someone comes up with a good > solution that doesn't break e-p-m for other modes. I will not invest > time in looking into that solution, but you or someone else may, of > course. > > In the meantime let people explore alternatives, right? > > João > [-- Attachment #2: Type: text/html, Size: 3654 bytes --] ^ permalink raw reply [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode 2018-12-22 4:41 ` Beatrix Klebe @ 2018-12-22 10:02 ` João Távora 0 siblings, 0 replies; 37+ messages in thread From: João Távora @ 2018-12-22 10:02 UTC (permalink / raw) To: Beatrix Klebe; +Cc: Alan Mackenzie, bea, 33794, Stefan Monnier Beatrix Klebe <beeuhtricks@gmail.com> writes: > I didn’t intend to kick the hornet’s nest of ideological factions You kinda did, but it's in their nature to be kicked. > here, I was honestly just wondering if this was actually expected > behavior of these two modes together and if not if the fix was > trivial. The answer seems to be that it is indeed a bug and the fix is > non-trivial, All correct. > and furthermore while I appreciate attempts to hotfix it, those are > not solutions of the quality I was expecting Can you specify what is missing in terms of quality? > , (I encountered those already while doing my own research before I > filed this bug report and I found them unsatisfactory both then and > now) and furthermore I feel like I should be open in stating that I > feel somewhat condescended to. I'm very sorry about that, it was never my intention (please read below). > I know what c-toggle-auto-newline is, I also know that functions > prefixed with “toggle” are functions that toggle a mode or setting > internally, in this case a minor mode called auto-newline > (https://www.gnu.org/software/emacs/manual/html_node/ccmode/Auto_002dnewlines.html) After following the link you gave me: I see the misunderstanding. You see, even though CC-mode's manual says "auto-newline" is a minor mode, it's not. It's just a variation on the major-mode's behaviour (in fact the CC-mode manual clarifies it here[1] as a "minor-mode-like feature", but the misunderstanding remained). There's no M-x auto-newline-mode to be invoked and no (define-minor-mode auto-newline-mode...) to be found in the code. Mentions to this as a minor mode are only found in the manual (a documentation bug, in my opinion). So this is why I was so specific with M-x c-toggle-auto-newline, becausen that's the actual command that someone who doesn't use it needs to turn on that pseudo-minor-mode: Without it, I couldn't observe the behaviour that you reported. With it, you couldn't experience the solution I was giving you. > I was about five minutes away from diving into the source of these two > packages to fix it myself, as I have spent probably 10 hours > reasearching this problem at this point. I’m sorry if I misunderstood > something, I was mainly looking for clarification that what I was > experiencing was a bug, and it is beginning to seem like there is none > to be had here. OK I'll clarify: There is a bug: there are two diverging views on how to fix it because there are diverging views about where it lies in Emacs: * The only available fix so far (mine) is still experimental. I would appreciate your feedback but it's perfectly OK to go spend your time elsewhere because there's a risk that it won't make it in the end. In this fix, I'm not targetting Alan's code: I am extending an existing, separate feature that could render some of CC-mode's functionality, specifically the peudo auto-newline-mode, obsolete. * The other fix isn't available yet, in experimental or final form. Presumably it would target electric-pair-mode. If Alan, you, or someone else wants to work on it, that's quite alright, but beware that electric-pair-mode must work for all major modes (including things like minibuffers and REPLs), not just CC-mode. Regards, João [1]: https://www.gnu.org/software/emacs/manual/html_node/ccmode/Minor-Modes.html#Minor-Modes > > On Fri, Dec 21, 2018 at 10:22 PM João Távora <joaotavora@gmail.com> wrote: > > Alan Mackenzie <acm@muc.de> writes: > > > Hello, Beatrix. > > > > As maintainer of CC Mode, I earnestly recommend you NOT to follow João's > > suggestion. It will not work, and will waste your time. > > What, exactly, will not work? > > > Even if it appears to work, you will end up picking out bugs for an > > indeterminate period. > > What bugs? If you know of any, it would be good to report them, right? > > > Basically, electric-pair-mode as it is currently built is incompatible > > with CC Mode, as I have pointed out here, albeit somewhat > > undiplomatically. > > > > I suggest you do nothing until tempers amongst Emacs developers have > > cooled down, and hopefully a genuine solution to the bug has been worked > > out and implemented. > > If you don't like electric-layout-mode, don't use it. I'm trying to > develop an alternative to c-toggle-auto-newline within the > electric-*-mode frame. It's an experiment which I don't even know if > Stefan will agree to, but it seems to work. If Beatrix wants to > cooperate, why shouldn't she? > > I'm not asking you to nuke c-toggle-auto-newline or anything, but should > we all be forced to use it? I don't think it's sensible in a free > software project, Alan (and my temper is quite cool when saying this > :-)) > > Again, I said I don't have anything against making eletric-pair-mode > compatible with c-toggle-auto-newline if someone comes up with a good > solution that doesn't break e-p-m for other modes. I will not invest > time in looking into that solution, but you or someone else may, of > course. > > In the meantime let people explore alternatives, right? > > João ^ permalink raw reply [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode 2018-12-22 3:22 ` João Távora 2018-12-22 4:41 ` Beatrix Klebe @ 2018-12-22 12:33 ` Alan Mackenzie 1 sibling, 0 replies; 37+ messages in thread From: Alan Mackenzie @ 2018-12-22 12:33 UTC (permalink / raw) To: João Távora; +Cc: Stefan Monnier, 33794 Hello, João. On Sat, Dec 22, 2018 at 03:22:47 +0000, João Távora wrote: > Alan Mackenzie <acm@muc.de> writes: > > Hello, Beatrix. > > As maintainer of CC Mode, I earnestly recommend you NOT to follow João's > > suggestion. It will not work, and will waste your time. > What, exactly, will not work? Can't say exactly, but a quick hack on some minor mode which violates and attempts to duplicate the conventions of the major mode, not intensively tested, is not going to work. > > Even if it appears to work, you will end up picking out bugs for an > > indeterminate period. > What bugs? If you know of any, it would be good to report them, right? See above. > > Basically, electric-pair-mode as it is currently built is incompatible > > with CC Mode, as I have pointed out here, albeit somewhat > > undiplomatically. > > I suggest you do nothing until tempers amongst Emacs developers have > > cooled down, and hopefully a genuine solution to the bug has been worked > > out and implemented. > If you don't like electric-layout-mode, don't use it. I'm trying to > develop an alternative to c-toggle-auto-newline .... Which is the wrong thing to do. > .... within the electric-*-mode frame. It's an experiment which I > don't even know if Stefan will agree to, but it seems to work. If > Beatrix wants to cooperate, why shouldn't she? My reading of the situation is that Beatrix reported a bug, expecting/hoping for it to be fixed, so that she can get on with her work more effectively. I don't think she wants to spend lots of time debugging (which is our job). > I'm not asking you to nuke c-toggle-auto-newline or anything, .... It looks rather that we to me, I must say. > .... but should we all be forced to use it? I don't think it's > sensible in a free software project, Alan (and my temper is quite cool > when saying this :-)) Eh?? The auto-newline facility is there and is optional. It is an integral part of CC Mode. Where is this "forcing" you're referring to? I think the situation is that the various electric-... facilities can only work with major modes designed in a particular restricted fashion - they are not universal. Your answer is to try and impose these restrictions on all major modes. That can't work, since we don't control all such modes, and imposing restrictions is a Bad Thing generally. > Again, I said I don't have anything against making eletric-pair-mode > compatible with c-toggle-auto-newline if someone comes up with a good > solution that doesn't break e-p-m for other modes. I will not invest > time in looking into that solution, but you or someone else may, of > course. As I've said elsewhere, the key to the fix is fixing the breakage of self-insert-command. That is going to involve extensive changes to electric-pair-mode, but will fix the problem rather than trying to work around it. My idea at the moment is to change from using post-self-insert-hook to using post-command-hook, thus fixing self-insert-command. There should also be a buffer local variable holding the function to insert the matching paren with, defaulting to self-insert-command, or similar. Would this work, and if not, where would it fail? Is there any documentation for the connections between electric-pair-mode and the other electric-... facilities? As I've also said elsewhere, the fundamental root of the current problem is social: somebody inventing facilities which impose constraints on Emacs in general, and imposing these on Emacs without public discussion. That cannot end well, and it hasn't ended well. > In the meantime let people explore alternatives, right? It does not lie within my power to stop them. ;-) > João -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode 2018-12-21 16:00 ` Beatrix Klebe 2018-12-21 18:49 ` João Távora @ 2019-01-01 19:27 ` Alan Mackenzie 2019-01-15 16:10 ` Alan Mackenzie 1 sibling, 1 reply; 37+ messages in thread From: Alan Mackenzie @ 2019-01-01 19:27 UTC (permalink / raw) To: bea; +Cc: 33794 Hello, Beatrix, Happy New Year! On Fri, Dec 21, 2018 at 11:00:10 -0500, Beatrix Klebe wrote: > 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. I think the following patch to CC Mode gives you nearly everything you want, if not actually everything. It turned out that the amendment didn't require any modification to electric-pair-mode, so apologies to João. I don't know how much you've explored electric-pair-mode, but if the answer is "not very much", can I suggest you try setting electric-pair-skip-whitespace to 'chomp? The following editing pattern is then available. With electric-pair-mode and c-auto-newline mode enabled: ("|" represents point.) At the end of the line if (foo)| foo = bar; , type {. This will give you something like: if (foo) { | } foo = bar; . Type in a statement ending with a semicolon: if (foo) { foo = bar; | } foo = bar; . Now type in }. The effect is to "chomp" the space to the next }, and CC Mode's auto-newline then inserts an empty line after the brace: if (foo) { foo = bar; } | foo = bar; . So, please try out the patch, and please let us all know how well it corresponds with what you were looking for. Also please let me know about any bugs you notice, so that I can fix them. Thanks for such an interesting problem! Here's the patch, which should apply cleanly to the emacs-26.1 source: diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el index 65b44339bc..8038f29d3e 100644 --- a/lisp/progmodes/cc-cmds.el +++ b/lisp/progmodes/cc-cmds.el @@ -47,6 +47,7 @@ ;; Silence the compiler. (cc-bytecomp-defvar filladapt-mode) ; c-fill-paragraph contains a kludge ; which looks at this. +(cc-bytecomp-defun electric-pair-post-self-insert-function) \f ;; Indentation / Display syntax functions (defvar c-fix-backslashes t) @@ -503,7 +504,8 @@ c-electric-pound (eq (char-before) ?\\)))) (c-in-literal))) ;; do nothing special - (self-insert-command (prefix-numeric-value arg)) + (let (post-self-insert-hook) ; Disable random functionality. + (self-insert-command (prefix-numeric-value arg))) ;; place the pound character at the left edge (let ((pos (- (point-max) (point))) (bolp (bolp))) @@ -694,6 +696,134 @@ c-try-one-liner t)))) (goto-char (- (point-max) pos)))))) +(defun c-do-brace-electrics (before after) + ;; Point is just after a brace. Indent the various lines, add any required + ;; auto newlines, and apply pertinent clean ups. It is assumed that the + ;; caller has checked that point is at EOL if need be, and that the brace is + ;; not in a comment or string, and suchlike. + ;; + ;; BEFORE and AFTER qualify the newlines required before and after the + ;; brace as follows: + ;; If + ;; o - nil: insert a newline or not according to `c-hanging-braces-alist'. + ;; o - 'ignore: don't insert a newline. + ;; o - 'assume: insert a newline. + ;; + ;; The return value has no significance. + (let (;; shut this up too + (c-echo-syntactic-information-p nil) + newlines + ln-syntax br-syntax syntax) ; Syntactic context of the original line, + ; of the brace itself, of the line the + ; brace ends up on. + (c-save-buffer-state ((c-syntactic-indentation-in-macros t) + (c-auto-newline-analysis t)) + (setq ln-syntax (c-guess-basic-syntax))) + (if c-syntactic-indentation + (c-indent-line ln-syntax)) + + (when c-auto-newline + (backward-char) + (setq br-syntax (c-point-syntax) + newlines (c-brace-newlines br-syntax)) + + ;; Insert the BEFORE newline, if wanted, and reindent the newline. + (if (or (and (null before) (memq 'before newlines) + (> (current-column) (current-indentation))) + (eq before 'assume)) + (if c-syntactic-indentation + ;; Only a plain newline for now - it's indented + ;; after the cleanups when the line has its final + ;; appearance. + (newline) + (c-newline-and-indent))) + (forward-char) + + ;; `syntax' is the syntactic context of the line which ends up + ;; with the brace on it. + (setq syntax (if (memq 'before newlines) br-syntax ln-syntax)) + + ;; Do all appropriate clean ups + (let ((here (point)) + (pos (- (point-max) (point))) + mbeg mend + ) + + ;; `}': clean up empty defun braces + (when (c-save-buffer-state () + (and (memq 'empty-defun-braces c-cleanup-list) + (eq (c-last-command-char) ?\}) + (c-intersect-lists '(defun-close class-close inline-close) + syntax) + (progn + (forward-char -1) + (c-skip-ws-backward) + (eq (char-before) ?\{)) + ;; make sure matching open brace isn't in a comment + (not (c-in-literal)))) + (delete-region (point) (1- here)) + (setq here (- (point-max) pos))) + (goto-char here) + + ;; `}': compact to a one-liner defun? + (save-match-data + (when + (and (eq (c-last-command-char) ?\}) + (memq 'one-liner-defun c-cleanup-list) + (c-intersect-lists '(defun-close) syntax) + (c-try-one-liner)) + (setq here (- (point-max) pos)))) + + ;; `{': clean up brace-else-brace and brace-elseif-brace + (when (eq (c-last-command-char) ?\{) + (cond + ((and (memq 'brace-else-brace c-cleanup-list) + (re-search-backward + (concat "}" + "\\([ \t\n]\\|\\\\\n\\)*" + "else" + "\\([ \t\n]\\|\\\\\n\\)*" + "{" + "\\=") + nil t)) + (delete-region (match-beginning 0) (match-end 0)) + (insert-and-inherit "} else {")) + ((and (memq 'brace-elseif-brace c-cleanup-list) + (progn + (goto-char (1- here)) + (setq mend (point)) + (c-skip-ws-backward) + (setq mbeg (point)) + (eq (char-before) ?\))) + (zerop (c-save-buffer-state nil (c-backward-token-2 1 t))) + (eq (char-after) ?\() + (re-search-backward + (concat "}" + "\\([ \t\n]\\|\\\\\n\\)*" + "else" + "\\([ \t\n]\\|\\\\\n\\)+" + "if" + "\\([ \t\n]\\|\\\\\n\\)*" + "\\=") + nil t)) + (delete-region mbeg mend) + (goto-char mbeg) + (insert ?\ )))) + + (goto-char (- (point-max) pos)) + + ;; Indent the line after the cleanups since it might + ;; very well indent differently due to them, e.g. if + ;; c-indent-one-line-block is used together with the + ;; one-liner-defun cleanup. + (when c-syntactic-indentation + (c-indent-line))) + + ;; does a newline go after the brace? + (if (or (and (null after) (memq 'after newlines)) + (eq after 'assume)) + (c-newline-and-indent))))) + (defun c-electric-brace (arg) "Insert a brace. @@ -716,7 +846,10 @@ c-electric-brace ;; We want to inhibit blinking the paren since this would be ;; most disruptive. We'll blink it ourselves later on. (old-blink-paren blink-paren-function) - blink-paren-function case-fold-search) + blink-paren-function case-fold-search + (at-eol (looking-at "[ \t]*\\\\?$")) + (active-region (and (fboundp 'use-region-p) (use-region-p))) + got-pair-} electric-pair-deletion) (c-save-buffer-state () (setq safepos (c-safe-position (point) (c-parse-state)) @@ -724,128 +857,36 @@ c-electric-brace ;; Insert the brace. Note that expand-abbrev might reindent ;; the line here if there's a preceding "else" or something. - (self-insert-command (prefix-numeric-value arg)) - - (when (and c-electric-flag (not literal) (not arg)) - (if (not (looking-at "[ \t]*\\\\?$")) - (if c-syntactic-indentation - (indent-according-to-mode)) - - (let ( ;; shut this up too - (c-echo-syntactic-information-p nil) - newlines - ln-syntax br-syntax syntax) ; Syntactic context of the original line, - ; of the brace itself, of the line the brace ends up on. - (c-save-buffer-state ((c-syntactic-indentation-in-macros t) - (c-auto-newline-analysis t)) - (setq ln-syntax (c-guess-basic-syntax))) - (if c-syntactic-indentation - (c-indent-line ln-syntax)) - - (when c-auto-newline - (backward-char) - (setq br-syntax (c-point-syntax) - newlines (c-brace-newlines br-syntax)) - - ;; Insert the BEFORE newline, if wanted, and reindent the newline. - (if (and (memq 'before newlines) - (> (current-column) (current-indentation))) - (if c-syntactic-indentation - ;; Only a plain newline for now - it's indented - ;; after the cleanups when the line has its final - ;; appearance. - (newline) - (c-newline-and-indent))) + (let (post-self-insert-hook) ; the only way to get defined functionality + ; from `self-insert-command'. + (self-insert-command (prefix-numeric-value arg))) + + ;; Emulate `electric-pair-mode'. + (when (and (boundp 'electric-pair-mode) + electric-pair-mode) + (let ((size (buffer-size)) + (c-in-electric-pair-functionality t) + post-self-insert-hook) + (electric-pair-post-self-insert-function) + (setq got-pair-} (and at-eol + (eq (c-last-command-char) ?{) + (eq (char-after) ?})) + electric-pair-deletion (< (buffer-size) size)))) + + ;; Perform any required CC Mode electric actions. + (cond + ((or literal arg (not c-electric-flag) active-region)) + ((not at-eol) + (c-indent-line)) + (electric-pair-deletion + (c-indent-line) + (c-do-brace-electrics 'ignore nil)) + (t (c-do-brace-electrics nil nil) + (when got-pair-} + (save-excursion (forward-char) - - ;; `syntax' is the syntactic context of the line which ends up - ;; with the brace on it. - (setq syntax (if (memq 'before newlines) br-syntax ln-syntax)) - - ;; Do all appropriate clean ups - (let ((here (point)) - (pos (- (point-max) (point))) - mbeg mend - ) - - ;; `}': clean up empty defun braces - (when (c-save-buffer-state () - (and (memq 'empty-defun-braces c-cleanup-list) - (eq (c-last-command-char) ?\}) - (c-intersect-lists '(defun-close class-close inline-close) - syntax) - (progn - (forward-char -1) - (c-skip-ws-backward) - (eq (char-before) ?\{)) - ;; make sure matching open brace isn't in a comment - (not (c-in-literal)))) - (delete-region (point) (1- here)) - (setq here (- (point-max) pos))) - (goto-char here) - - ;; `}': compact to a one-liner defun? - (save-match-data - (when - (and (eq (c-last-command-char) ?\}) - (memq 'one-liner-defun c-cleanup-list) - (c-intersect-lists '(defun-close) syntax) - (c-try-one-liner)) - (setq here (- (point-max) pos)))) - - ;; `{': clean up brace-else-brace and brace-elseif-brace - (when (eq (c-last-command-char) ?\{) - (cond - ((and (memq 'brace-else-brace c-cleanup-list) - (re-search-backward - (concat "}" - "\\([ \t\n]\\|\\\\\n\\)*" - "else" - "\\([ \t\n]\\|\\\\\n\\)*" - "{" - "\\=") - nil t)) - (delete-region (match-beginning 0) (match-end 0)) - (insert-and-inherit "} else {")) - ((and (memq 'brace-elseif-brace c-cleanup-list) - (progn - (goto-char (1- here)) - (setq mend (point)) - (c-skip-ws-backward) - (setq mbeg (point)) - (eq (char-before) ?\))) - (zerop (c-save-buffer-state nil (c-backward-token-2 1 t))) - (eq (char-after) ?\() - ; (progn - ; (setq tmp (point)) - (re-search-backward - (concat "}" - "\\([ \t\n]\\|\\\\\n\\)*" - "else" - "\\([ \t\n]\\|\\\\\n\\)+" - "if" - "\\([ \t\n]\\|\\\\\n\\)*" - "\\=") - nil t);) - ;(eq (match-end 0) tmp); - ) - (delete-region mbeg mend) - (goto-char mbeg) - (insert ?\ )))) - - (goto-char (- (point-max) pos)) - - ;; Indent the line after the cleanups since it might - ;; very well indent differently due to them, e.g. if - ;; c-indent-one-line-block is used together with the - ;; one-liner-defun cleanup. - (when c-syntactic-indentation - (c-indent-line))) - - ;; does a newline go after the brace? - (if (memq 'after newlines) - (c-newline-and-indent)) - )))) + (c-do-brace-electrics 'assume 'ignore)) + (c-indent-line)))) ;; blink the paren (and (eq (c-last-command-char) ?\}) @@ -903,7 +944,8 @@ c-electric-slash c-electric-flag (eq (c-last-command-char) ?/) (eq (char-before) (if literal ?* ?/)))) - (self-insert-command (prefix-numeric-value arg)) + (let (post-self-insert-hook) ; Disable random functionality. + (self-insert-command (prefix-numeric-value arg))) (if indentp (indent-according-to-mode)))) @@ -916,7 +958,8 @@ c-electric-star this indentation is inhibited." (interactive "*P") - (self-insert-command (prefix-numeric-value arg)) + (let (post-self-insert-hook) ; Disable random functionality. + (self-insert-command (prefix-numeric-value arg))) ;; if we are in a literal, or if arg is given do not reindent the ;; current line, unless this star introduces a comment-only line. (if (c-save-buffer-state () @@ -963,7 +1006,8 @@ c-electric-semi&comma (setq lim (c-most-enclosing-brace (c-parse-state)) literal (c-in-literal lim))) - (self-insert-command (prefix-numeric-value arg)) + (let (post-self-insert-hook) ; Disable random functionality. + (self-insert-command (prefix-numeric-value arg))) (if (and c-electric-flag (not literal) (not arg)) ;; do all cleanups and newline insertions if c-auto-newline is on. @@ -1032,7 +1076,8 @@ c-electric-colon newlines is-scope-op ;; shut this up (c-echo-syntactic-information-p nil)) - (self-insert-command (prefix-numeric-value arg)) + (let (post-self-insert-hook) ; Disable random functionality. + (self-insert-command (prefix-numeric-value arg))) ;; Any electric action? (if (and c-electric-flag (not literal) (not arg)) ;; Unless we're at EOL, only re-indentation happens. @@ -1125,7 +1170,8 @@ c-electric-lt-gt (let ((c-echo-syntactic-information-p nil) final-pos found-delim case-fold-search) - (self-insert-command (prefix-numeric-value arg)) + (let (post-self-insert-hook) ; Disable random functionality. + (self-insert-command (prefix-numeric-value arg))) (setq final-pos (point)) ;;;; 2010-01-31: There used to be code here to put a syntax-table text @@ -1190,7 +1236,9 @@ c-electric-paren ;; shut this up (c-echo-syntactic-information-p nil) case-fold-search) - (self-insert-command (prefix-numeric-value arg)) + (let (post-self-insert-hook) ; The only way to get defined functionality + ; from `self-insert-command'. + (self-insert-command (prefix-numeric-value arg))) (if (and (not arg) (not literal)) (let* ( ;; We want to inhibit blinking the paren since this will @@ -1239,6 +1287,12 @@ c-electric-paren (delete-region (match-beginning 0) (match-end 0)) (insert-and-inherit "} catch ("))) + ;; Apply `electric-pair-mode' stuff. + (when (and (boundp 'electric-pair-mode) + electric-pair-mode) + (let (post-self-insert-hook) + (electric-pair-post-self-insert-function))) + ;; Check for clean-ups at function calls. These two DON'T need ;; `c-electric-flag' or `c-syntactic-indentation' set. ;; Point is currently just after the inserted paren. -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply related [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode 2019-01-01 19:27 ` Alan Mackenzie @ 2019-01-15 16:10 ` Alan Mackenzie 0 siblings, 0 replies; 37+ messages in thread From: Alan Mackenzie @ 2019-01-15 16:10 UTC (permalink / raw) To: bea; +Cc: João Távora, 33794-done Hello, Beatrix. I have committed the patch from two weeks ago (to the Emacs master branch), and I'm closing the bug as fixed. -- Alan Mackenzie (Nuremberg, Germany). On Tue, Jan 01, 2019 at 19:27:29 +0000, Alan Mackenzie wrote: > Hello, Beatrix, > Happy New Year! > On Fri, Dec 21, 2018 at 11:00:10 -0500, Beatrix Klebe wrote: > > 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. > I think the following patch to CC Mode gives you nearly everything you > want, if not actually everything. > It turned out that the amendment didn't require any modification to > electric-pair-mode, so apologies to João. > I don't know how much you've explored electric-pair-mode, but if the > answer is "not very much", can I suggest you try setting > electric-pair-skip-whitespace to 'chomp? The following editing pattern > is then available. With electric-pair-mode and c-auto-newline mode > enabled: > ("|" represents point.) > At the end of the line > if (foo)| > foo = bar; > , type {. This will give you something like: > if (foo) > { > | > } > foo = bar; > . Type in a statement ending with a semicolon: > if (foo) > { > foo = bar; > | > } > foo = bar; > . Now type in }. The effect is to "chomp" the space to the next }, and > CC Mode's auto-newline then inserts an empty line after the brace: > if (foo) > { > foo = bar; > } > | > foo = bar; > . So, please try out the patch, and please let us all know how well it > corresponds with what you were looking for. Also please let me know > about any bugs you notice, so that I can fix them. Thanks for such an > interesting problem! > Here's the patch, which should apply cleanly to the emacs-26.1 source: [ snip patch ]. ^ permalink raw reply [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode 2018-12-21 14:12 ` Stefan Monnier 2018-12-21 16:00 ` Beatrix Klebe @ 2018-12-21 20:11 ` Alan Mackenzie 2018-12-22 0:45 ` João Távora 1 sibling, 1 reply; 37+ messages in thread From: Alan Mackenzie @ 2018-12-21 20:11 UTC (permalink / raw) To: Stefan Monnier; +Cc: bea, João Távora, 33794 Hello, Stefan. On Fri, Dec 21, 2018 at 09:12:49 -0500, Stefan Monnier wrote: > >> Yes. What is happening, from the viewpoint of CC Mode, is that on > >> inserting a {, electric-pair-mode is prematurely inserting its }, before > >> the processing for the { is complete. > Since it's done from post-self-insert-hook, it's done at the very end of > inserting { so I'm not sure what you mean by "before the processing for > the { is complete". c-electric-brace calls self-insert-function then performs the rest of its processing. > >> Also, due to the way } gets inserted, the CC Mode processing for > >> the } isn't done at all. > I think you meant "due to the way CC-Mode hooks itself into the } > processing, ..." ;-) No, not at all. CC Mode has been working for several decades, and works well. electric-pair-mode is the new kid on the block, just a few years old, and was apparently hacked together without regard to some well established conventions. It should have provided interfaces to allow existing software to connect to it - for example a variable to contain a function to insert the electric character, or something like that. Maybe. It should have been considered, but apparently wasn't. > >> Would it therefore be possible, rather than having a crude insertion on > >> post-self-insert-hook, to use something like post-command-hook to allow > >> the insertion of the { first to complete? Then, rather than using the > >> brutal self-insert-command for } in electric-pair--insert, use the > >> command to which the key } is bound? > Talking about brutal: how could electric-pair-mode run whichever command > is bound to } without taking the risk of running a much more brutal > command than one that inserts a character? That isn't a risk. It's a user decision. > > FWIW, I think cc-mode should rather use post-self-insert-hook instead > > of redefining .... There's no "redefining". There's definition of functions bound to keys, and these definitions are several decades old and work well. Such software construction is recommended by the Emacs manual (page "Major Modes"). > > .... commands for keys whose expected behaviour is (with minor > > variations presumably covered by abundant hookage) self-insertion. post-self-insert-hook smells bad. I can't quite put my finger on what's wrong with it, but it definitely doesn't feel good. Anyhow, it's too new for CC Mode. And it would involve a lot of work for no increase in functionality. The fault lies in electric-pair-mode's failure to provide appropriate interfaces for existing code to use it. > IIRC it should be able to just use electric-layout-mode for that (tho > maybe electric-layout's featureset doesn't currently cover 100% that of > CC-mode's auto-newline, in which case it would be nice to extend > electric-layout accordingly). electric-layout-mode seems to be a reinvention of the wheel, incomptible, sadly, with the original in CC Mode. That original works well. The copy likely works less well, though I admit not having examined it in any great detail. > For things like electric-pair, electric-indent, and electric-layout to > work correctly together, they need to agree on some convention. Yes. I've searched the emacs-devel archives briefly, and found no attempt there to sketch out and discuss such a convention, and definitely no attempt to reach any agreement. Maybe I've missed something, but given how recent these electric-.. things are (2010), it's likely I would have been involved in such discussion had it taken place, and it's likely electric-pair-mode wouldn't now be clashing with CC Mode. > Note that CC-mode can also side-step that convention and use `insert` > instead of self-insert-command. That wouldn't help electric-pair-mode work in CC Mode, I think. > Stefan -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode 2018-12-21 20:11 ` Alan Mackenzie @ 2018-12-22 0:45 ` João Távora 2018-12-22 10:20 ` Alan Mackenzie 0 siblings, 1 reply; 37+ messages in thread From: João Távora @ 2018-12-22 0:45 UTC (permalink / raw) To: Alan Mackenzie; +Cc: bea, Stefan Monnier, 33794 Hi Alan, I will be replying to the two emails you sent me in this single message. Alan Mackenzie <acm@muc.de> writes: > No, not at all. CC Mode has been working for several decades, and works > well. electric-pair-mode is the new kid on the block, just a few years > old, and was apparently hacked together without regard to some well > established conventions. It should have provided interfaces to allow > existing software to connect to it - for example a variable to contain a > function to insert the electric character, or something like that. > Maybe. It should have been considered, but apparently wasn't. First, I think you'll agree that antiquity is a poor measure of the merits of software. Here's a characteristic of electric-pair-mode that I think is an actual merit: it works for every mode in Emacs.. Also, I don't know if you understand the history of electric-pair-mode. It has two generations: One, before 24.4, which I believe Stefan wrote, where it was a simpler mode to automatically insert parenthesis and quotes as described in electric-pair-pairs. Then, in 24.4, I borrowed code from my reasonably popular autopair.el extension and e-p-m became a mode that automatically infers what characters to pair from the syntax table of each mode. Furthermore, in the new version, it also makes educated guesses about when to pair or when not to pair based, again on the information collected from the buffer and its syntax table by syntax-ppss. The use of post-self-insert-hook was a requirement at the time, since that is how the pre-24.4 electric-pair-mode, electric-indent-mode and electric-layout-mode already worked. I welcomed this requirement, and it was what encouraged me to kill autopair.el and migrate to the new framework, since in autopair.el I had to rebind the parenthesis keys, which is akward (much like c-electric-brace and c-electric-paren are akward IMO). This simplified the code tremendously. So these "well established conventions" are, with all due respect, nothing more than personal opinions based on a narrow experience with a subset of modes (maybe "mode" singular), tried and tested as it may be. If I abandon the post-self-insert-hook convention for e-p-m, I'll probably be breaking the e-p-m interaction with electric-indent-mode, electric-layout-mode, etc. If there are existing problems with these interactions they should be fixed, but I will not fix e-p-m for interaction a specific part of cc-mode, unless you provide retro-compatible fix that guarantees existing behaviour outside cc-mode. I would rather declare e-p-m incompatible with that part of cc-mode and invest some time in providing alternatives based on electric-layout-mode, fixing Beatrix's problem by replacing bits of cc-mode-specific initialization in her init file with bits that works for all modes, including cc-mode. João ^ permalink raw reply [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode 2018-12-22 0:45 ` João Távora @ 2018-12-22 10:20 ` Alan Mackenzie 2018-12-22 13:47 ` João Távora 0 siblings, 1 reply; 37+ messages in thread From: Alan Mackenzie @ 2018-12-22 10:20 UTC (permalink / raw) To: João Távora; +Cc: bea, Stefan Monnier, 33794 Hello, João On Sat, Dec 22, 2018 at 00:45:20 +0000, João Távora wrote: > Hi Alan, > I will be replying to the two emails you sent me in this single message. > Alan Mackenzie <acm@muc.de> writes: > > No, not at all. CC Mode has been working for several decades, and works > > well. electric-pair-mode is the new kid on the block, just a few years > > old, and was apparently hacked together without regard to some well > > established conventions. It should have provided interfaces to allow > > existing software to connect to it - for example a variable to contain a > > function to insert the electric character, or something like that. > > Maybe. It should have been considered, but apparently wasn't. > First, I think you'll agree that antiquity is a poor measure of the > merits of software. Here we have antiquity, combined with software actually being used combined with a lack of bugs. (I'm talking about CC Mode's auto-newline facility, here). This SW is good. > Here's a characteristic of electric-pair-mode that I think is an > actual merit: it works for every mode in Emacs.. This clearly isn't true at the moment. Have you tested it with, for example, Cperl Mode, or Vera Mode? That characteristic is an aspiration, which is laudable. > Also, I don't know if you understand the history of electric-pair-mode. > It has two generations: One, before 24.4, which I believe Stefan wrote, > where it was a simpler mode to automatically insert parenthesis and > quotes as described in electric-pair-pairs. Then, in 24.4, I borrowed > code from my reasonably popular autopair.el extension and e-p-m became a > mode that automatically infers what characters to pair from the syntax > table of each mode. Furthermore, in the new version, it also makes > educated guesses about when to pair or when not to pair based, again on > the information collected from the buffer and its syntax table by > syntax-ppss. I think that what is missing from this history is the stage where the idea with proposed solution is first discussed on emacs-devel, where conceptual problems can be identified and resolved. As a result, e-p-m is only compatible with some major modes; it is incompatible with those that explicitly call self-insert-function as part of a command bound to a key which is usually self-inserting. There are quite a few such modes. > The use of post-self-insert-hook was a requirement at the time, since > that is how the pre-24.4 electric-pair-mode, electric-indent-mode and > electric-layout-mode already worked. I welcomed this requirement, and > it was what encouraged me to kill autopair.el and migrate to the new > framework, since in autopair.el I had to rebind the parenthesis keys, > which is akward (much like c-electric-brace and c-electric-paren are > akward IMO). This simplified the code tremendously. Have a look at the doc string for self-insert-command, and ask yourself what should happen on this call: (self-insert-command 1 &{) . The answer is, of course, that "{" should be inserted into the buffer. With electric-pair-mode-enabled, what actually happens is that "{}" gets inserted instead. This is broken. I ask you to consider this paragraph very carefully rather than reacting emotionally against it. self-insert-command is broken, and this is the cause of the current bug. What you seem to be suggesting is that rather than fix this breakage, major modes like CC Mode (and there are quite a few) should have to work around it. > So these "well established conventions" are, with all due respect, > nothing more than personal opinions based on a narrow experience with a > subset of modes (maybe "mode" singular), tried and tested as it may be. > If I abandon the post-self-insert-hook convention for e-p-m, I'll > probably be breaking the e-p-m interaction with electric-indent-mode, > electric-layout-mode, etc. If there are existing problems with these > interactions they should be fixed, but I will not fix e-p-m for > interaction a specific part of cc-mode, unless you provide > retro-compatible fix that guarantees existing behaviour outside cc-mode. Again, you're much more familiar with electric-indent-mode, and friends. Do they also break self-insert-command? > I would rather declare e-p-m incompatible with that part of cc-mode and > invest some time in providing alternatives based on > electric-layout-mode, fixing Beatrix's problem by replacing bits of > cc-mode-specific initialization in her init file with bits that works > for all modes, including cc-mode. You're trying to replace core CC Mode functionality. Trying to do that with a few quick hacks can only lead to frustration all round, and to tears. electric-layout-mode is incompatible with CC Mode. This would have come up in the discussion on emacs-devel and a resolution found if that discussion had taken place. Sadly it didn't, hence the incompatibility. The same applies to electric-pair-mode. We're having that discussion now, sort of. In CC Mode (and Cperl Mode, and Vera Mode,....), on insertion of a {, the processing associated with the insertion needs to be allowed to complete before the insertion of the mating }. Above all, self-insert-command needs to behave correctly, according to its documentation. It is surely not beyond us to fix these problems. > João -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode 2018-12-22 10:20 ` Alan Mackenzie @ 2018-12-22 13:47 ` João Távora 0 siblings, 0 replies; 37+ messages in thread From: João Távora @ 2018-12-22 13:47 UTC (permalink / raw) To: Alan Mackenzie; +Cc: bea, Stefan Monnier, 33794 Hello Alan, I will be, again, responding to your two emails in one. Alan Mackenzie <acm@muc.de> writes: > This clearly isn't true at the moment. Have you tested it with, for > example, Cperl Mode, or Vera Mode? That characteristic is an > aspiration, which is laudable. Fair enough. But what are the bugs in those modes? I've just tested it briefly there and it seems to work. I type parenthesis of various kinds and they get autopaired and autoskipped. > I think that what is missing from this history is the stage where the > idea with proposed solution is first discussed on emacs-devel, where > conceptual problems can be identified and resolved. As a result, e-p-m > is only compatible with some major modes; it is incompatible with those > that explicitly call self-insert-function as part of a command bound to > a key which is usually self-inserting. There are quite a few such > modes. I think, but I'm not sure, that anycommand that eventually calls post-self-insert-hook would also work. > The answer is, of course, that "{" should be inserted into the buffer. > With electric-pair-mode-enabled, what actually happens is that "{}" > gets inserted instead. This is broken. I ask you to consider this > paragraph very carefully rather than reacting emotionally against it. Alan, OK, that is your opinion, but please don't tell me which part of my brain to use when reacting to something, that's a wee bit too arrogant... > Again, you're much more familiar with electric-indent-mode, and friends. > Do they also break self-insert-command? No idea. And I'm not very familiar with them, no. Look, the framework for inserting extra things in post-self-insert-hook was already in place when I joined the party. Be it space for indent or newlines for layout or delimiters for pairing. I just followed those tracks, which apparently cause you dismay. And I enjoyed it, hehehe, sorry :-) it really did make coding easier. > with a few quick hacks can only lead to frustration all round, and to > tears. My tears, certainly, because I'm such an emotional trainwreck :-) > self-insert-command needs to behave correctly, according to its > documentation. It is surely not beyond us to fix these problems. Of course there are different ways to solve problems. I think the way I am exploring is the best. You think otherwise, that's OK. > Can't say exactly, but a quick hack on some minor mode which violates > and attempts to duplicate the conventions of the major mode, not > intensively tested, is not going to work. Who convened where to decide this that you call "convention"? And exactly what conventions is electric-layout-mode breaking (btw, you should be aware that electric-layout-mode exists since 2010: Again, long before I joined the party). >> What bugs? If you know of any, it would be good to report them, right? > See above. I did, but I don't see any reports of flawed behaviour there. I'm not saying there aren't any bugs: I'm just saying you should first look to indications or traces of these bugs before publically stating that there are. > Which is the wrong thing to do. Did you see The Big Lebowsky by the Cohen brothers? :-) There's a nice riposte there, apropos opinions. > I don't think she wants to spend lots of time debugging (which is our > job). Yes, maybe. It's up to her, of course. But it's not my "job", it's something I do for fun. And Alan, I have some experience in dealing with user's reports too (neatly over a decade long, since that seems to matter to you) and some users are more cooperative than others, and that's fine. > Eh?? The auto-newline facility is there and is optional. It is an > integral part of CC Mode. Where is this "forcing" you're referring > to? Fair enough, no "forcing". It sounded like you were suggesting to Beatrix that she stay away from any solution except yours, for no reason other than your authority as CC-mode maintainer and some unsubstantiated prophecies of disaster. > Is there any documentation for the connections between > electric-pair-mode and the other electric-... facilities? I don't think so: unless you count comments. The interfaces they adhere to to work together is post-self-insert-hook, with a few hacks here and there marked FIXME by Stefan. > is social: somebody inventing facilities which impose constraints on > Emacs in general, and imposing these on Emacs without public > discussion. That cannot end well, and it hasn't ended well. There's something here that doesn't make sense: you repudiate "constraints", but you laud "convention". But, in my view, pieces of software uses "interfaces" to work together. We're just discussing here who violated them, that's all. João PS: Without public discussion??? This discussion _is_ public! :-) ^ permalink raw reply [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode 2018-12-21 13:57 ` João Távora 2018-12-21 14:12 ` Stefan Monnier @ 2018-12-21 21:50 ` Alan Mackenzie 2018-12-22 16:22 ` Stefan Monnier 1 sibling, 1 reply; 37+ messages in thread From: Alan Mackenzie @ 2018-12-21 21:50 UTC (permalink / raw) To: João Távora; +Cc: bea, 33794, Stefan Monnier Hello, João. On Fri, Dec 21, 2018 at 13:57:21 +0000, João Távora wrote: > On Fri, Dec 21, 2018 at 1:48 PM Alan Mackenzie <acm@muc.de> wrote: > > Hello, Beatrix. > > In article <mailman.5894.1545155289.1284.bug-gnu-emacs@gnu.org> you wrote: > > > When using cc-mode, turning on electric-pair-mode causes the > > > auto-newline minor mode to stop inserting newlines where expected. This > > > is relevant to the formatting of C# code with the Allman/BSD brace style > > > in particular, though it would be nice if these modes specifically did > > > work together. > > Yes. What is happening, from the viewpoint of CC Mode, is that on > > inserting a {, electric-pair-mode is prematurely inserting its }, before > > the processing for the { is complete. Also, due to the way } gets > > inserted, the CC Mode processing for the } isn't done at all. > > @João: I think electric pair mode is intended to simulate the manual > > insertion of a matching paren, etc., when a paren, etc., is typed. > > Would it therefore be possible, rather than having a crude insertion on > > post-self-insert-hook, to use something like post-command-hook to allow > > the insertion of the { first to complete? Then, rather than using the > > brutal self-insert-command for } in electric-pair--insert, use the > > command to which the key } is bound? This should allow CC Mode's > > auto-newline facility to work, and also more closely simulate the manual > > insertion of the closing delimiter. > I don't know. We better ask Stefan (CC'ed) who I believe designed the > original strategy of inserting closing delimiters in the previous > electric-pair-mode. That didn't change in my redesign. > FWIW, I think cc-mode should rather use post-self-insert-hook instead > of redefining commands for keys whose expected behaviour is > (with minor variations presumably covered by abundant hookage) > self-insertion. If you place your specific cc-mode processing late > enough in the hook then its insertion will be "complete" for all > practical purposes. I think I've worked out what I don't like about such (ab)use of post-self-insert-hook. There are 113 uses of self-insert-command in our sources, and it seems most of them expect self-insert-command to do just that, with possible things like refilling. If one makes additional buffer changes, one will foul up many of these 113 uses of s-i-c. It is a bit like before/after-change-functions. Although it is not written in tablets of stone anywhere (as fas as I'm aware), there's an understanding that you don't make buffer changes inside b/a-c-f. The same should apply to post-self-insert-hook, which is a sort of change hook, for the same reasons. > João -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode 2018-12-21 21:50 ` Alan Mackenzie @ 2018-12-22 16:22 ` Stefan Monnier 2018-12-22 16:34 ` Beatrix Klebe 0 siblings, 1 reply; 37+ messages in thread From: Stefan Monnier @ 2018-12-22 16:22 UTC (permalink / raw) To: Alan Mackenzie; +Cc: bea, João Távora, 33794 > I think I've worked out what I don't like about such (ab)use of > post-self-insert-hook. Great. I'm not sure how it helps us fix the problem, tho. Stefan ^ permalink raw reply [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode 2018-12-22 16:22 ` Stefan Monnier @ 2018-12-22 16:34 ` Beatrix Klebe 2018-12-22 17:12 ` Stefan Monnier 0 siblings, 1 reply; 37+ messages in thread From: Beatrix Klebe @ 2018-12-22 16:34 UTC (permalink / raw) To: Stefan Monnier; +Cc: Alan Mackenzie, bea, 33794, João Távora [-- Attachment #1: Type: text/plain, Size: 1242 bytes --] To clarify João, I make no judgment about the utility or morality of quick hacks broadly. However, as someone who spends the majority of their time in languages and systems which generally take a dim view of pervasive mutable state, I am intensely wary of doing things to my configuration which risk making it incompatible with future updates in dependent parts. Should this problem ever be resolved more generally, it is quite possible I will not hear about it, and your quick hack will start causing unexpected behavior that I will then have to fix myself down the line. Indeed, I have oft mused about creating an Emacslike programming environment in which packages are pure and persistent and upgrades are done in a way that can be provably reversed, like nix-pkgs does for system packages, purely because of my historical frustration with things breaking when they shouldn’t and me not being able to reliably isolate the cause of their failure. On Sat, Dec 22, 2018 at 11:22 AM Stefan Monnier <monnier@iro.umontreal.ca> wrote: > > I think I've worked out what I don't like about such (ab)use of > > post-self-insert-hook. > > Great. I'm not sure how it helps us fix the problem, tho. > > > Stefan > [-- Attachment #2: Type: text/html, Size: 1533 bytes --] ^ permalink raw reply [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode 2018-12-22 16:34 ` Beatrix Klebe @ 2018-12-22 17:12 ` Stefan Monnier 2018-12-22 17:34 ` Beatrix Klebe 0 siblings, 1 reply; 37+ messages in thread From: Stefan Monnier @ 2018-12-22 17:12 UTC (permalink / raw) To: Beatrix Klebe; +Cc: Alan Mackenzie, bea, 33794, João Távora > hear about it, and your quick hack will start causing unexpected behavior > that I will then have to fix myself down the line. Indeed, I have oft mused I believe there's a misunderstand here: his quick hack is intended to figure out how to provide a long term solution. IOW he's not proposing it as a solution for you, but is rather asking you to help us write a long term fix by testing design points. Stefan ^ permalink raw reply [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode 2018-12-22 17:12 ` Stefan Monnier @ 2018-12-22 17:34 ` Beatrix Klebe 2018-12-22 21:19 ` João Távora 0 siblings, 1 reply; 37+ messages in thread From: Beatrix Klebe @ 2018-12-22 17:34 UTC (permalink / raw) To: Stefan Monnier; +Cc: Alan Mackenzie, bea, 33794, João Távora [-- Attachment #1: Type: text/plain, Size: 1384 bytes --] Well, in that case, I am flattered that my opinion is given much weight in this. What I will say is that it seems like the first order of business is to disambiguate what has which responsibilities in this case, and where the line falls between major modes, electric-layout, and electric-pair. It seems like this area of the electric modes is suffering from a bit of fragmentation as well as differing perspectives on what constitutes “electric” behavior. Things such as c-toggle-auto-newline, for example, almost seem in this case that they might be better delegated to electric-layout-mode, with cc-mode specifying different electric-layout constraints for its different formatting styles. It seems this is close to what João was suggesting? And I suspect what Alan disagrees with? I apologize for any misunderstanding. On Sat, Dec 22, 2018 at 12:12 PM Stefan Monnier <monnier@iro.umontreal.ca> wrote: > > hear about it, and your quick hack will start causing unexpected behavior > > that I will then have to fix myself down the line. Indeed, I have oft > mused > > I believe there's a misunderstand here: his quick hack is intended to > figure out how to provide a long term solution. IOW he's not proposing > it as a solution for you, but is rather asking you to help us write > a long term fix by testing design points. > > > Stefan > [-- Attachment #2: Type: text/html, Size: 1675 bytes --] ^ permalink raw reply [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode 2018-12-22 17:34 ` Beatrix Klebe @ 2018-12-22 21:19 ` João Távora 2018-12-22 22:15 ` Alan Mackenzie 0 siblings, 1 reply; 37+ messages in thread From: João Távora @ 2018-12-22 21:19 UTC (permalink / raw) To: Beatrix Klebe; +Cc: Alan Mackenzie, bea, Stefan Monnier, 33794 Beatrix Klebe <beeuhtricks@gmail.com> writes: > Well, in that case, I am flattered that my opinion is given much > weight in this. It's supposed to work like that everyday in the Emacs bug tracker. If it flatters you, so much the better :-) > Things such as c-toggle-auto-newline, for example, almost seem in this > case that they might be better delegated to electric-layout-mode, with > cc-mode specifying different electric-layout constraints for its > different formatting styles. It seems this is close to what João was > suggesting? Yes, that is precisely what I am suggesting. I am happy that this point made it across. Though there is not any need to give up on c-toggle-auto-newline if you don't use electric-pair-mode, or if you use some other tool like smartparens, or perhaps even my older tool autopair.el (tho those tools might have other drawbacks that I don't known) > And I suspect what Alan disagrees with? I apologize for any > misunderstanding. Yes, Alan disagrees with this. In his view, electric- modes are abusing the semantics of post-self-insert-hook. Well, at least in my view of his views :-) João PS: I'm cleaning up the implementation of the more powerful electric-layout mode in branch scratch/fix-33794-extend-electric-layout-mode. I'll let you know if/when it is merged. ^ permalink raw reply [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode 2018-12-22 21:19 ` João Távora @ 2018-12-22 22:15 ` Alan Mackenzie 2018-12-22 22:55 ` João Távora 2018-12-23 14:43 ` Stefan Monnier 0 siblings, 2 replies; 37+ messages in thread From: Alan Mackenzie @ 2018-12-22 22:15 UTC (permalink / raw) To: João Távora, Beatrix Klebe; +Cc: bea, Stefan Monnier, 33794 Hello, Beatrix and João. On Sat, Dec 22, 2018 at 21:19:22 +0000, João Távora wrote: > Beatrix Klebe <beeuhtricks@gmail.com> writes: > > Well, in that case, I am flattered that my opinion is given much > > weight in this. > It's supposed to work like that everyday in the Emacs bug tracker. If > it flatters you, so much the better :-) > > Things such as c-toggle-auto-newline, for example, almost seem in this > > case that they might be better delegated to electric-layout-mode, with > > cc-mode specifying different electric-layout constraints for its > > different formatting styles. It seems this is close to what João was > > suggesting? This is what I oppose. Given how well CC Mode's auto-newline works, such a change would almost certainly be a negative step in quality, portability, and would be a lot of unrewarding work to do. CC Mode isn't broken, here. It doesn't need fixing, here. > Yes, that is precisely what I am suggesting. I am happy that this point > made it across. > Though there is not any need to give up on c-toggle-auto-newline if you > don't use electric-pair-mode, or if you use some other tool like > smartparens, or perhaps even my older tool autopair.el (tho those tools > might have other drawbacks that I don't known) If electric-pair-mode was fixed, it would work perfectly well with CC Mode. > > And I suspect what Alan disagrees with? I apologize for any > > misunderstanding. One of the things, yes. CC Mode has, for years, been under constant attack from people who want to make Emacs major modes work only the way they think modes should. CC Mode works differently, for good reasons. To adapt CC Mode the way these people want would have significant disadvantages, including some lost functionality. Right now, João's direction of travel seems to be to cement electric-pair-mode's unusability in modes like CC Mode, of which there are quite a few. I hope I've misunderstood this and I'm mistaken. > Yes, Alan disagrees with this. In his view, electric- modes are abusing > the semantics of post-self-insert-hook. Well, at least in my view of > his views :-) Please don't misrepresent me like that. The point is that the electric-... modes abuse not so much the post-self-insert-hook (although they do), but they totally break self-insert-command. You have had several hours to contest this, but by your silence appear to have accepted it. electric-pair-mode breaks self-insert-command. self-insert-command is (or was) a general purpose command for inserting typed characters into a buffer. With electric-pair-mode enabled, it ceases to be general purpose, being usable only in contexts blessed by the electric-... functionality. This is why CC Mode's auto-newline broke. It will stay broken until electric-pair-mode's breaking of that function gets fixed. > João [ .... ] -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode 2018-12-22 22:15 ` Alan Mackenzie @ 2018-12-22 22:55 ` João Távora 2018-12-23 20:21 ` Alan Mackenzie [not found] ` <20181223202143.GA6658@ACM> 2018-12-23 14:43 ` Stefan Monnier 1 sibling, 2 replies; 37+ messages in thread From: João Távora @ 2018-12-22 22:55 UTC (permalink / raw) To: Alan Mackenzie; +Cc: Beatrix Klebe, bea, Stefan Monnier, 33794 Alan Mackenzie <acm@muc.de> writes: > Right now, João's direction of travel seems to be to cement > electric-pair-mode's unusability in modes like CC Mode, of which there > are quite a few. I hope I've misunderstood this and I'm mistaken. You are. In fact, I'm coming up with alternatives so that electric-pair-mode works with CC-Mode, even if the user or some other mode customizes it to not use c-electric-{brace,paren}. You may say that I am not working actively to make e-p-m work with c-toggle-auto-newline, which *in my opinion* is a part of CC-mode that could and should someday be fulfilled by electric-layout-mode. That is 100% true. But I am not preventing anyone from taking on that task, or even suggesting it's trivial or very hard. I just don't know, and I have no interest in studying this alternative. That is quite different from "cementing an unusability".Have a look at my recent commits in scratch/fix-33794-extend-electric-layout-mode and you will see that I have done 0 changes to e-p-m. Also, can you once and for all describe the "unusabilities" in other modes you keep talking about??? >> Yes, Alan disagrees with this. In his view, electric- modes are abusing >> the semantics of post-self-insert-hook. Well, at least in my view of >> his views :-) > > Please don't misrepresent me like that. Really, I didn't. But OK, I will think thrice before writing "Alan thinks" sentences. > The point is that the electric-... modes abuse not so much the > post-self-insert-hook (although they do), So, in reality I didn't misrepresent you. > but they totally break self-insert-command. You have had several > hours to contest this, but by your silence appear to have accepted it. How can I contest or accept that which I have no opinion of? I'm not an expert in the teleology of self-insert-command! Find someone who is to discuss this! Frankly: "my silence"... I'm not taking that bait, OK? Really, Alan, please please understand that I am only trying to make electric-layout-mode work a bit better, and not even touching any of its basic functioning vis-a-vis self-insert-command. João ^ permalink raw reply [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode 2018-12-22 22:55 ` João Távora @ 2018-12-23 20:21 ` Alan Mackenzie [not found] ` <20181223202143.GA6658@ACM> 1 sibling, 0 replies; 37+ messages in thread From: Alan Mackenzie @ 2018-12-23 20:21 UTC (permalink / raw) To: João Távora; +Cc: Beatrix Klebe, bea, Stefan Monnier, 33794 Hello, João. On Sat, Dec 22, 2018 at 22:55:32 +0000, João Távora wrote: > Alan Mackenzie <acm@muc.de> writes: > > Right now, João's direction of travel seems to be to cement > > electric-pair-mode's unusability in modes like CC Mode, of which there > > are quite a few. I hope I've misunderstood this and I'm mistaken. > You are. In fact, I'm coming up with alternatives so that > electric-pair-mode works with CC-Mode, even if the user or some other > mode customizes it to not use c-electric-{brace,paren}. CC Mode is not customisable in this way, any more than any other major mode. Ripping out and replacing the innards of Lisp code is called "hacking", not "customisation". At the moment, electric-pair-mode does not work with c-electric-brace and c-electric-paren. This is the bug reported by Beatrix, the OP. You are telling me you are not working on fixing the part of this problem which is in e-p-m. Please understand me being somewhat frustrated by this. If I were to dig in to e-p-m, make fixes, and commit them, I suspect you would be somewhat annoyed. > You may say that I am not working actively to make e-p-m work with > c-toggle-auto-newline, which *in my opinion* is a part of CC-mode that > could and should someday be fulfilled by electric-layout-mode. I think you really mean c-electric-{brace,paren} here, not c-toggle-auto-newline. electric-layout-mode won't be superseding those functions any time soon. > That is 100% true. But I am not preventing anyone from taking on that > task, or even suggesting it's trivial or very hard. I just don't > know, and I have no interest in studying this alternative. But you're posting in the thread for bug #33794. I'm disappointed you're not cooperating with me to fix this bug. > That is quite different from "cementing an unusability".Have a look at > my recent commits in scratch/fix-33794-extend-electric-layout-mode and > you will see that I have done 0 changes to e-p-m. I'm not interested in that branch, I'm afraid. electric-layout-mode has no relevance to CC Mode. I'm more interested in bug #33794. > Also, can you once and for all describe the "unusabilities" in other > modes you keep talking about??? Yes. These other modes call self-insert-command. self-insert-command, because of the way post-self-insert-hook is (ab)used, has no definite function. Sometimes it does what the doc says (inserting N copies of the last character typed), other times it does other things. The only safe way for a mode to call self-insert-command is by binding post-self-insert-hook to a known value, usually nil. This prevents all electric-pair-mode processing. I would very much like c-electric-brace, etc., to be able to use e-p-m functionality, rather than partially duplicating it inside cc-cmds.el, as I did in the patch I sent to Beatrix, Cc: to yourself, earlier on today. > >> Yes, Alan disagrees with this. In his view, electric- modes are > >> abusing the semantics of post-self-insert-hook. Well, at least in > >> my view of his views :-) > > Please don't misrepresent me like that. > Really, I didn't. But OK, I will think thrice before writing "Alan > thinks" sentences. Sorry, you didn't really, that's true. But you did put the emphasis on the wrong point. > > The point is that the electric-... modes abuse not so much the > > post-self-insert-hook (although they do), > So, in reality I didn't misrepresent you. > > but they totally break self-insert-command. You have had several > > hours to contest this, but by your silence appear to have accepted it. > How can I contest or accept that which I have no opinion of? I'm not an > expert in the teleology of self-insert-command! Find someone who is to > discuss this! You're working on #33794. You must surely have some notion of the cause of the bug. I've said what my idea is, and I'm somewhat disappointed you've failed to comment on this central point. Without understanding the cause of a bug, any fix is going to be suboptimal. > Frankly: "my silence"... I'm not taking that bait, OK? Really, Alan, > please please understand that I am only trying to make > electric-layout-mode work a bit better, and not even touching any of its > basic functioning vis-a-vis self-insert-command. But you're commenting on this thread, which is about a bug concerning the interaction of e-p-m with CC Mode, not e-l-m. > João -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 37+ messages in thread
[parent not found: <20181223202143.GA6658@ACM>]
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode [not found] ` <20181223202143.GA6658@ACM> @ 2018-12-23 21:38 ` João Távora 2018-12-23 21:46 ` Alan Mackenzie 2018-12-28 12:44 ` Alan Mackenzie 0 siblings, 2 replies; 37+ messages in thread From: João Távora @ 2018-12-23 21:38 UTC (permalink / raw) To: Alan Mackenzie; +Cc: Beatrix Klebe, bea, Stefan Monnier, 33794 Hello Alan, Alan Mackenzie <acm@muc.de> writes: > Hello, João. > CC Mode is not customisable in this way, any more than any other major > mode. Ripping out and replacing the innards of Lisp code is called > "hacking", not "customisation". Very well, if you consider my personal customization counts a hack, I will just have to live with that weight on my shoulders. I will not report bugs about CC-mode based on my customization, only Emacs -Q. Hmmm, come to think of it, I don't think I ever did. > At the moment, electric-pair-mode does not work with c-electric-brace > and c-electric-paren. This is the bug reported by Beatrix, the OP. You > are telling me you are not working on fixing the part of this problem > which is in e-p-m. Please understand me being somewhat frustrated by > this. If I were to dig in to e-p-m, make fixes, and commit them, I > suspect you would be somewhat annoyed. If you propose changes to e-p-m that: * don't break any (more) unit tests; * don't introduce new interfaces to special case cc-mode; * Stefan accepts, since the self-insert-command-hook part was his responsibility entirely, (as I have tried to explain a million times.) Then I don't see why I would be annoyed. (You could of course come to the faint realization that maybe there is the off-chance that there exists a glimmer of possibility that in a remote part of the multiverse it is quite possible that a minute part the problem lies in cc-mode. But no, that is preposterous! let us not even consider that heresy! It's decades old after all, it MUST be correct, forever and absolutely!) > But you're posting in the thread for bug #33794. I'm disappointed > you're not cooperating with me to fix this bug. I'm posting here because you summoned me, remember? And now I am replying to you. After analysing the problem of Beatrix, I offered an alternative solution to her actual problem using electric-layout-mode. (as have you in the meantime). Seeing as electric-layout-mode was manifestly insufficient to fix her problem I started working on making it better. >> Also, can you once and for all describe the "unusabilities" in other >> modes you keep talking about??? > Yes. These other modes call self-insert-command. self-insert-command, > because of the way post-self-insert-hook is (ab)used, has no definite > function. Sometimes it does what the doc says (inserting N copies of > the last character typed), other times it does other things. Again philosophical elucubrations? Say one concrete thing that is broken in these modes! No far-fetched hypotheticals. Here's a template for your report: Emacs -Q M-x electric-pair-mode M-x horribly-broken-mode-that-only-you-know-about some legitimate user input some horribly wrong result I'm not saying there aren't such bugs, but why are you evading the question? Or just say you haven't really witnessed any such bugs and let's be done with the farce. > You're working on #33794. You must surely have some notion of the cause > of the bug. I've said what my idea is, and I'm somewhat disappointed > you've failed to comment on this central point. Without understanding > the cause of a bug, any fix is going to be suboptimal. Look, I haven't looked into this and I don't want to go into a discussion with you about it because frankly, very frankly indeed, it would be no fun. You've already decided long ago that the world is wrong. Any comment I could make about how CC-mode could be changed would just prompt some comment about how it's "always worked", "for decades" and "look at how fluffy the whiskers on this gray old Gandalf of a mode are", and "look at this young arriviste e-p-m rascal causing all the mischief". In a great part I symphatize immensely with your ardent defense of your work, if it were literature or art I would definitely be on your side, the patron saint of idiosyncrasies. On the other hand, seeing as this is software, I would find myself having to point out that these arguments have no bearing on reality. I'll say this: consider that it is not a bug: e-p-m's contract is: works for every mode, except cc-mode, where mileage may vary. Mileage is indeed slightly shorter on cc-mode with c-toggle-auto-newline: let's live with it and move on. > But you're commenting on this thread, which is about a bug concerning > the interaction of e-p-m with CC Mode, not e-l-m. If you're suggesting I stop replying to these emails, then maybe you have a point. I'm a little tired. Merry Christmas, Alan João ^ permalink raw reply [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode 2018-12-23 21:38 ` João Távora @ 2018-12-23 21:46 ` Alan Mackenzie 2018-12-28 12:44 ` Alan Mackenzie 1 sibling, 0 replies; 37+ messages in thread From: Alan Mackenzie @ 2018-12-23 21:46 UTC (permalink / raw) To: João Távora; +Cc: Stefan Monnier, 33794 Hello, João. On Sun, Dec 23, 2018 at 21:38:29 +0000, João Távora wrote: > Hello Alan, [ .... ] > Merry Christmas, Alan And a Merry Christmas to you too! :-) > João -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode 2018-12-23 21:38 ` João Távora 2018-12-23 21:46 ` Alan Mackenzie @ 2018-12-28 12:44 ` Alan Mackenzie 1 sibling, 0 replies; 37+ messages in thread From: Alan Mackenzie @ 2018-12-28 12:44 UTC (permalink / raw) To: João Távora; +Cc: Beatrix Klebe, bea, Stefan Monnier, 33794 Hello, João. On Sun, Dec 23, 2018 at 21:38:29 +0000, João Távora wrote: > Alan Mackenzie <acm@muc.de> writes: > > If I were to dig in to e-p-m, make fixes, and commit them, I suspect > > you would be somewhat annoyed. > If you propose changes to e-p-m that: > * don't break any (more) unit tests; > * don't introduce new interfaces to special case cc-mode; > * Stefan accepts, since the self-insert-command-hook part was his > responsibility entirely, (as I have tried to explain a million times.) > Then I don't see why I would be annoyed. > (You could of course come to the faint realization that maybe there is > the off-chance that there exists a glimmer of possibility that in a > remote part of the multiverse it is quite possible that a minute part > the problem lies in cc-mode. But no, that is preposterous! let us not > even consider that heresy! It's decades old after all, it MUST be > correct, forever and absolutely!) The problem we're dealing with is in the interface between CC Mode and electric-pair-mode. Naturally, both sides of this putative interface will need adapting. From my point of view, what is missing from e-p-m is an interface usable by functions which call self-insert-command programmatically, as CC Mode does. A function to insert the matching character and otherwise process it. Or something like that, I haven't fully worked it out. Sadly, at the moment it's looking like the easiest way to fix bug #33794 would be to duplicate the functionality of electric-pair-mode inside CC Mode, as I've already done partially. I really don't want to do that, and you probably don't want me to do that either. [ .... ] > João -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode 2018-12-22 22:15 ` Alan Mackenzie 2018-12-22 22:55 ` João Távora @ 2018-12-23 14:43 ` Stefan Monnier 1 sibling, 0 replies; 37+ messages in thread From: Stefan Monnier @ 2018-12-23 14:43 UTC (permalink / raw) To: Alan Mackenzie; +Cc: Beatrix Klebe, bea, João Távora, 33794 > Right now, João's direction of travel seems to be to cement > electric-pair-mode's unusability in modes like CC Mode, of which there > are quite a few. Actually, there aren't many modes "like CC mode" in my experience. But really, I don't see why you're complaining about João's attempt to improve electric-layout-mode. CC-mode doesn't even use that code, so it's completely unaffected (at least until you decide to start using electric-layout-mode). Stefan ^ permalink raw reply [flat|nested] 37+ messages in thread
* bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode [not found] ` <mailman.5894.1545155289.1284.bug-gnu-emacs@gnu.org> 2018-12-21 13:48 ` Alan Mackenzie @ 2018-12-23 14:48 ` Alan Mackenzie 1 sibling, 0 replies; 37+ messages in thread From: Alan Mackenzie @ 2018-12-23 14:48 UTC (permalink / raw) To: bea; +Cc: 33794, João Távora Hello again, Beatrix. In article <mailman.5894.1545155289.1284.bug-gnu-emacs@gnu.org> you wrote: > When using cc-mode, turning on electric-pair-mode causes the > auto-newline minor mode to stop inserting newlines where expected. This > is relevant to the formatting of C# code with the Allman/BSD brace style > in particular, though it would be nice if these modes specifically did > work together. > In GNU Emacs 26.1 (build 1, x86_64-apple-darwin14.5.0, NS > appkit-1348.17 Version 10.10.5 (Build 14F2511)) > of 2018-05-30 built on builder10-10.porkrind.org > Windowing system distributor 'Apple', version 10.3.1671 > Recent messages: > Saving file /Users/bea/.emacs.d/lisp/dotnet.el... > Wrote /Users/bea/.emacs.d/lisp/dotnet.el > ; expected > Undo! > ; expected > Undo! [2 times] > ; expected > Auto-saving... > ; expected [2 times] > Making completion list... I think the following workaround will give you a lot of what you want. I've tried it out only on C Mode, however. The pertinent file is in .../emacs/lisp/progmodes/. Sadly it is only a workaround, since there doesn't seem to be any interface to electric-pair-mode usable by programs. However, it should help, whilst we at Emacs negotiate amongst ourselves. Happy Christmas, if you celebrate it! (And a good time, otherwise!). diff -r 7ec0a318802a cc-cmds.el --- a/cc-cmds.el Thu Dec 20 12:07:55 2018 +0000 +++ b/cc-cmds.el Sun Dec 23 14:34:51 2018 +0000 @@ -721,7 +721,9 @@ ;; Insert the brace. Note that expand-abbrev might reindent ;; the line here if there's a preceding "else" or something. - (self-insert-command (prefix-numeric-value arg)) + (let (post-self-insert-hook) ; the only way to get dependable + ; functionality from self-insert-command. + (self-insert-command (prefix-numeric-value arg))) (when (and c-electric-flag (not literal) (not arg)) (if (not (looking-at "[ \t]*\\\\?$")) @@ -844,6 +846,15 @@ (c-newline-and-indent)) )))) + ;; Emulate `electric-pair-mode'. + (when (and (boundp 'electric-pair-mode) + electric-pair-mode + (eq last-command-event ?{)) + (save-excursion + (newline) + (let ((last-command-event ?})) + (c-electric-brace nil)))) + ;; blink the paren (and (eq (c-last-command-char) ?\}) (not executing-kbd-macro) -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 37+ messages in thread
end of thread, other threads:[~2019-01-15 16:10 UTC | newest] Thread overview: 37+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2018-12-18 17:38 bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode Beatrix Klebe [not found] ` <mailman.5894.1545155289.1284.bug-gnu-emacs@gnu.org> 2018-12-21 13:48 ` Alan Mackenzie 2018-12-21 13:57 ` João Távora 2018-12-21 14:12 ` Stefan Monnier 2018-12-21 16:00 ` Beatrix Klebe 2018-12-21 18:49 ` João Távora 2018-12-21 19:06 ` Beatrix Klebe 2018-12-21 19:20 ` João Távora 2018-12-21 19:24 ` João Távora 2018-12-21 19:43 ` Beatrix Klebe 2018-12-22 1:08 ` João Távora 2018-12-22 2:16 ` João Távora 2018-12-22 2:41 ` Alan Mackenzie 2018-12-22 3:22 ` João Távora 2018-12-22 4:41 ` Beatrix Klebe 2018-12-22 10:02 ` João Távora 2018-12-22 12:33 ` Alan Mackenzie 2019-01-01 19:27 ` Alan Mackenzie 2019-01-15 16:10 ` Alan Mackenzie 2018-12-21 20:11 ` Alan Mackenzie 2018-12-22 0:45 ` João Távora 2018-12-22 10:20 ` Alan Mackenzie 2018-12-22 13:47 ` João Távora 2018-12-21 21:50 ` Alan Mackenzie 2018-12-22 16:22 ` Stefan Monnier 2018-12-22 16:34 ` Beatrix Klebe 2018-12-22 17:12 ` Stefan Monnier 2018-12-22 17:34 ` Beatrix Klebe 2018-12-22 21:19 ` João Távora 2018-12-22 22:15 ` Alan Mackenzie 2018-12-22 22:55 ` João Távora 2018-12-23 20:21 ` Alan Mackenzie [not found] ` <20181223202143.GA6658@ACM> 2018-12-23 21:38 ` João Távora 2018-12-23 21:46 ` Alan Mackenzie 2018-12-28 12:44 ` Alan Mackenzie 2018-12-23 14:43 ` Stefan Monnier 2018-12-23 14:48 ` Alan Mackenzie
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).