From debbugs-submit-bounces@debbugs.gnu.org Tue Dec 18 12:47:10 2018 Received: (at submit) by debbugs.gnu.org; 18 Dec 2018 17:47:10 +0000 Received: from localhost ([127.0.0.1]:53644 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gZJSX-0002rg-2Y for submit@debbugs.gnu.org; Tue, 18 Dec 2018 12:47:09 -0500 Received: from eggs.gnu.org ([208.118.235.92]:48929) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gZJKj-0002dm-PK for submit@debbugs.gnu.org; Tue, 18 Dec 2018 12:39:06 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gZJKd-00018O-23 for submit@debbugs.gnu.org; Tue, 18 Dec 2018 12:39:00 -0500 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=0.8 required=5.0 tests=BAYES_50,FREEMAIL_FROM autolearn=disabled version=3.3.2 Received: from lists.gnu.org ([2001:4830:134:3::11]:48503) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gZJKc-00018D-R7 for submit@debbugs.gnu.org; Tue, 18 Dec 2018 12:38:58 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58536) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gZJKb-0007pp-C8 for bug-gnu-emacs@gnu.org; Tue, 18 Dec 2018 12:38:58 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gZJKY-00011d-Su for bug-gnu-emacs@gnu.org; Tue, 18 Dec 2018 12:38:57 -0500 Received: from mail-ot1-x32c.google.com ([2607:f8b0:4864:20::32c]:33331) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gZJKY-0000tq-KY for bug-gnu-emacs@gnu.org; Tue, 18 Dec 2018 12:38:54 -0500 Received: by mail-ot1-x32c.google.com with SMTP id i20so16492818otl.0 for ; Tue, 18 Dec 2018 09:38:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:reply-to:from:date:message-id:subject:to; bh=Soy28tKiEcIQCPe65ilSaayYE92xhjluoSqRCF9VtNw=; b=UxnXpo2yneh8RDJYosbmhjxUkOjo8i9E1xG3qRmr3mcSwnd52f1qkVrgg/1YvfoSB1 TTLtik1k9E3YDxf2cxGHYaCYzbuG7q8bHWIRtpVftCMzJqgQCKGi2piuxOX52pb2kFPo nMcko3t+At0b/89N6dZxaUD4ifY0YOcJzJ1GaMTXR/4q06Hz9EJ2EV1YYW3kMnLGN/DK kPfEF6vWEabLPxVkcm6Z5YCqsU2muURFa3oKxnp8uuLqNxUjBEReMknLqowUkSEFyRIB +uN+FP0qzYUWplxTPJ/QMmKUijoOfqd2WhVk0B7IrzJHiRpJ4TRVBjq7/F2JLsRugirY y2Tw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:reply-to:from:date:message-id :subject:to; bh=Soy28tKiEcIQCPe65ilSaayYE92xhjluoSqRCF9VtNw=; b=E0deO9EkUDsHHnf2JEi1cwbY6m6TNkTMnbQaul8GCUP3G1ySOc3nzV4BUOipwNOVLN 2AvZjT4gtcUlU8Z1vxkcBBRKPjbQGyXHl+SQzkznWPYeQcl/xGygbjy/d2y1FSKJA1Ye mcxAV2lyd83R3Xk2L/6jCvqXHks4IHcKTnUqCIYKwzdjUETKkrklYVEQqEGtXnEzJwFt QTVnZAH6rG+rqdcS4MJ7fVngIw/iLFh+hfhyiKcqkiUjAwFzuLll46Clc1ncZO8tH7uo 30ytQ2/Pqj03l7autP+dMigjOTKHT09unzsScGeaVUHRlQBEiFtT3UChbHnoCYuNXk11 Y5Xg== X-Gm-Message-State: AA+aEWZWMd2Pi+OPLwrE9O8wrLn/ncFfNHfTZm3//JQL/keCM8hbds8y Vbns9Vq/5qXvRDyfnPFLFGh6kIsUMndDmAhxKtbH7gLt X-Google-Smtp-Source: AFSGD/USCdK8Zp5WuvVFr4PtgAqBgEtKSpIy42bddmVr1YJz0cQe39eFe0keOQb7JO+sKhRQD8ScoygaUzOXNCNBfr0= X-Received: by 2002:a05:6830:c7:: with SMTP id x7mr1021331oto.31.1545154732427; Tue, 18 Dec 2018 09:38:52 -0800 (PST) MIME-Version: 1.0 From: Beatrix Klebe Date: Tue, 18 Dec 2018 12:38:41 -0500 Message-ID: Subject: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode To: bug-gnu-emacs@gnu.org Content-Type: text/plain; charset="UTF-8" X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-Received-From: 2001:4830:134:3::11 X-Spam-Score: -4.0 (----) X-Debbugs-Envelope-To: submit X-Mailman-Approved-At: Tue, 18 Dec 2018 12:47:07 -0500 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: bea@klebe.blog Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) 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)) From debbugs-submit-bounces@debbugs.gnu.org Fri Dec 21 08:48:33 2018 Received: (at 33794) by debbugs.gnu.org; 21 Dec 2018 13:48:33 +0000 Received: from localhost ([127.0.0.1]:57235 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gaLAH-0003AP-6p for submit@debbugs.gnu.org; Fri, 21 Dec 2018 08:48:33 -0500 Received: from colin.muc.de ([193.149.48.1]:14581 helo=mail.muc.de) by debbugs.gnu.org with smtp (Exim 4.84_2) (envelope-from ) id 1gaLAF-0003AH-9f for 33794@debbugs.gnu.org; Fri, 21 Dec 2018 08:48:31 -0500 Received: (qmail 29136 invoked by uid 3782); 21 Dec 2018 13:48:29 -0000 Date: 21 Dec 2018 13:48:29 -0000 Message-ID: <20181221134829.29135.qmail@mail.muc.de> From: Alan Mackenzie To: bea@klebe.blog Subject: Re: bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode Organization: muc.de e.V. In-Reply-To: X-Newsgroups: gnu.emacs.bug User-Agent: tin/2.4.2-20171224 ("Lochhead") (UNIX) (FreeBSD/11.2-RELEASE-p4 (amd64)) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: -0.0 (/) X-Debbugs-Envelope-To: 33794 Cc: 33794@debbugs.gnu.org, =?UTF-8?Q?Jo=C3=A3o_T=C3=A1vora?= X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Hello, Beatrix. In article 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 styl= e > 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=C3=A3o: 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... --=20 Alan Mackenzie (Nuremberg, Germany). From debbugs-submit-bounces@debbugs.gnu.org Fri Dec 21 08:57:39 2018 Received: (at 33794) by debbugs.gnu.org; 21 Dec 2018 13:57:40 +0000 Received: from localhost ([127.0.0.1]:57249 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gaLJ5-0003Oo-NC for submit@debbugs.gnu.org; Fri, 21 Dec 2018 08:57:39 -0500 Received: from mail-qk1-f175.google.com ([209.85.222.175]:33140) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gaLJ4-0003OZ-IS for 33794@debbugs.gnu.org; Fri, 21 Dec 2018 08:57:38 -0500 Received: by mail-qk1-f175.google.com with SMTP id o89so3112940qko.0 for <33794@debbugs.gnu.org>; Fri, 21 Dec 2018 05:57:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=MG27Gzo1pD9ih49gTqkRksZO2BowmN74MMU8xx2C4BA=; b=K4oRug7cETke4/7oaiyhw6p2Vw2OY1y1H7g+6+oXiUJ5wsS1OuwzRHJS8CHuKnWPxW QjSG8DoqSHW92kHBeRtuZkTKsAhbkL6fqAoIUc4OkvghpYLsc1eU77wl/P3NEF34DRhX Hejv7c8ywTSQXfZeTEAGvorL8oGW/bedZdyNu92qxI0jWfJVuS9UEBL1Vo9e7bogtlMU hkQNQ+JY6Goi0L8+OXQdqEKXw7AHraOmwUmKMnq7g3BlJjVXgyK617Mye06Q69dS7xE2 hbczJauErGgPCEh+vhoPo1ScVhPrTTu3jiMR7QF+KDpzb59JDOD5miNtfATBDRfjrO0h qLcA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=MG27Gzo1pD9ih49gTqkRksZO2BowmN74MMU8xx2C4BA=; b=M5BtSU0QOGt104WHZ7F4Gu4qitHQtLBAS1mJGMZdHoI4WNILTlup3+ia9RbOqxv1k9 OJHu/Ok6SERArzp7ngdeiFTaj61KmDhc2OkDsvrvjaH/rq9hx0B/fwrAqqn5ls0ULC5e fTIX/0WiHE7L38bFDcNyirDwOAcrzHeFdp+UW+pdeN8JlSROkDmiRko93N4jBEMNXyw6 cvvfnvBDR1TYhuRmIA/6LDsZK+3+fe4X21pdgPsu099OZ+K/WjtuyQaZJiyxsvUxXkIn 7qW8EeWqogzUUsNF5Y72A0l5xtexthxES65cRqi1TLOlMh4ZaYmmEM4al2gMov3/vt9+ IWUQ== X-Gm-Message-State: AJcUukdTqSUR/W+pIiuuwJXjpiyusKVhpwj+T9HmYxdKcZteLLYMmo5u bWyLK/cPt/0pp8MYIrqMeSGb3tlADktON4K5+B0= X-Google-Smtp-Source: ALg8bN7MkH3LaJZkwmQl0QecklVoMHN6RJNA+NORfZA3bUH80jJSKstO5jiytQUhN0lKKkDZPUpfl4GyK28/aTR5Mes= X-Received: by 2002:a37:5e85:: with SMTP id s127mr2305455qkb.234.1545400652970; Fri, 21 Dec 2018 05:57:32 -0800 (PST) MIME-Version: 1.0 References: <20181221134829.29135.qmail@mail.muc.de> In-Reply-To: <20181221134829.29135.qmail@mail.muc.de> From: =?UTF-8?B?Sm/Do28gVMOhdm9yYQ==?= Date: Fri, 21 Dec 2018 13:57:21 +0000 Message-ID: Subject: Re: bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode To: Alan Mackenzie Content-Type: multipart/alternative; boundary="000000000000f4bfee057d88a04c" X-Spam-Score: 0.1 (/) X-Debbugs-Envelope-To: 33794 Cc: bea@klebe.blog, 33794@debbugs.gnu.org, Stefan Monnier X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.9 (/) --000000000000f4bfee057d88a04c Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Fri, Dec 21, 2018 at 1:48 PM Alan Mackenzie wrote: > Hello, Beatrix. > > In article 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 styl= e > > 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=C3=A3o: 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=C3=A3o --000000000000f4bfee057d88a04c Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
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. Thi= s
> is relevant to the formatting of C# code with the Allman/BSD brace sty= le
> in particular, though it would be nice if these modes specifically did=
> work together.

Yes.=C2=A0 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.=C2=A0 Also, due to the way } gets
inserted, the CC Mode processing for the } isn't done at all.

@Jo=C3=A3o: 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?=C2=A0 Then, rather than using the=
brutal self-insert-command for } in electric-pair--insert, use the
command to which the key } is bound?=C2=A0 This should allow CC Mode's<= br> auto-newline facility to work, and also more closely simulate the manual insertion of the closing delimiter.

I don&#= 39;t know.=C2=A0 We better ask Stefan (CC'ed) who I believe designed th= e
original strategy of inserting closing delimiters in the p= revious
electric-pair-mode.=20 That didn't change in my redesign.

FWIW, I thi= nk cc-mode should rather use post-self-insert-hook instead
o= f redefining commands for keys whose expected behaviour is
(w= ith minor variations presumably covered by abundant hookage)
= self-insertion.=C2=A0 If you place your specific cc-mode processing late
enough in the hook then its insertion will be "complete&q= uot; for all
practical purposes.

Jo= =C3=A3o



--000000000000f4bfee057d88a04c-- From debbugs-submit-bounces@debbugs.gnu.org Fri Dec 21 09:12:55 2018 Received: (at 33794) by debbugs.gnu.org; 21 Dec 2018 14:12:55 +0000 Received: from localhost ([127.0.0.1]:57255 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gaLXr-00042E-2Q for submit@debbugs.gnu.org; Fri, 21 Dec 2018 09:12:55 -0500 Received: from chene.dit.umontreal.ca ([132.204.246.20]:52187) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gaLXp-000423-5n for 33794@debbugs.gnu.org; Fri, 21 Dec 2018 09:12:54 -0500 Received: from pastel.home (lechon.iro.umontreal.ca [132.204.27.242]) by chene.dit.umontreal.ca (8.14.7/8.14.1) with ESMTP id wBLECnP7006885; Fri, 21 Dec 2018 09:12:49 -0500 Received: by pastel.home (Postfix, from userid 20848) id 5B7A76AAB6; Fri, 21 Dec 2018 09:12:49 -0500 (EST) From: Stefan Monnier To: =?windows-1252?B?Sm/jbyBU4XZvcmE=?= Subject: Re: bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode Message-ID: References: <20181221134829.29135.qmail@mail.muc.de> Date: Fri, 21 Dec 2018 09:12:49 -0500 In-Reply-To: (=?windows-1252?Q?=22Jo=E3o_T=E1vora=22's?= message of "Fri, 21 Dec 2018 13:57:21 +0000") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-NAI-Spam-Flag: NO X-NAI-Spam-Threshold: 5 X-NAI-Spam-Score: 0 X-NAI-Spam-Rules: 2 Rules triggered EDT_SA_DN_PASS=0, RV6444=0 X-NAI-Spam-Version: 2.3.0.9418 : core <6444> : inlines <6988> : streams <1807775> : uri <2767939> X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 33794 Cc: Alan Mackenzie , bea@klebe.blog, 33794@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) >> 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 From debbugs-submit-bounces@debbugs.gnu.org Fri Dec 21 11:00:29 2018 Received: (at 33794) by debbugs.gnu.org; 21 Dec 2018 16:00:29 +0000 Received: from localhost ([127.0.0.1]:58682 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gaNDw-0007Tn-Qe for submit@debbugs.gnu.org; Fri, 21 Dec 2018 11:00:28 -0500 Received: from mail-ot1-f47.google.com ([209.85.210.47]:42596) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gaNDv-0007TS-Id for 33794@debbugs.gnu.org; Fri, 21 Dec 2018 11:00:27 -0500 Received: by mail-ot1-f47.google.com with SMTP id v23so5493097otk.9 for <33794@debbugs.gnu.org>; Fri, 21 Dec 2018 08:00:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:reply-to:from:date:message-id :subject:to:cc; bh=m+QpFOnKUU40uMgA3yNm42wrVQenSbHLJOB02TBIhIE=; b=L30h7XSl1ioU4J26BiqGUcZuUCND8d7YOkDnmZqBLLjvy2DgtkuXu5yTi5+6fHBu58 5GmvXd4Tf5i8KntIFKFd4bqU77O6DudgaZ5aCxBMT1w8J5ql5zIwB2wE0DBO+wHR3Mc1 HqOFjJisxBfcDCqosCkiHgYzfSw1EUZBF6M8s6lhNqoYo+92gsLF4QWKF1RSqB72Qxob YvHopCv1AfgpRkqHc+h+xLD+VLSjj9iUWhiIFVJ+BFNBhf0r9LMiVtHjH6t6JvMtF+oC dJBLkx5jgMJDO8ihK2HH3szmzgVlgOIWOyLqBGdnhixp5wiRiNxgTooLvEVUMiOINa9P CLrw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:reply-to :from:date:message-id:subject:to:cc; bh=m+QpFOnKUU40uMgA3yNm42wrVQenSbHLJOB02TBIhIE=; b=ggHGkZnzMhfBcvTtrWawhjXcf8SrW8jF5bn5VmTWUq/I6FT8GfrTIp6BV7toHCdLjq NucXPlqQiqc9RUDNPxF4gXXp43bD2O1EKde33YF6tXvx604ZnMQOrwbt32axKMfUFjGR ELcM9Wvgc3hQdgrPlTPlAUw0rvRcM9OhSeRQ7T722y6k3sUKbQjf4O2NCJMokMrpe6iS 8l3pG9U5jPMWwl9FqPARv4d9gLsKVNrbJDvNgwtwh/8ugcB6syB0S1Lz/mBhu7qI/mxT Ei0XzXdB9GenvVQiS+F4vk2yYM7SlRavCn+/GtwrFCbOblpyrrpPb/k3y7wj85efO+XE P3aA== X-Gm-Message-State: AJcUukf1SvFIPXSNTFDe+DzAuuoaLF1nNpGV07nLWZSwhfiMA2UKFfcX 2batJeAHs3jX9YPCxOZA1ASi7StPVsxGHNV3GO8= X-Google-Smtp-Source: ALg8bN7KK2fGJ7P55aFgMkNacwRiur0cH+kvA/k3d3Ht3xrclhbbIEwaRgnj7rH+7ZVF5d9lHyc2EM43zGQzubTDRzU= X-Received: by 2002:a9d:3d42:: with SMTP id a60mr1952671otc.285.1545408021618; Fri, 21 Dec 2018 08:00:21 -0800 (PST) MIME-Version: 1.0 References: <20181221134829.29135.qmail@mail.muc.de> In-Reply-To: From: Beatrix Klebe Date: Fri, 21 Dec 2018 11:00:10 -0500 Message-ID: Subject: Re: bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode To: Stefan Monnier Content-Type: text/plain; charset="UTF-8" X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 33794 Cc: Alan Mackenzie , "Mx. Beatrix Klebe" , =?UTF-8?B?Sm/Do28gVMOhdm9yYQ==?= , 33794@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: bea@klebe.blog Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) 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 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 From debbugs-submit-bounces@debbugs.gnu.org Fri Dec 21 13:49:48 2018 Received: (at 33794) by debbugs.gnu.org; 21 Dec 2018 18:49:48 +0000 Received: from localhost ([127.0.0.1]:58786 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gaPro-0005El-Fm for submit@debbugs.gnu.org; Fri, 21 Dec 2018 13:49:48 -0500 Received: from mail-wr1-f52.google.com ([209.85.221.52]:40295) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gaPrm-0005EW-SV for 33794@debbugs.gnu.org; Fri, 21 Dec 2018 13:49:47 -0500 Received: by mail-wr1-f52.google.com with SMTP id p4so6289408wrt.7 for <33794@debbugs.gnu.org>; Fri, 21 Dec 2018 10:49:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-transfer-encoding; bh=EJQe19l/SbMZVxfbn+OxSSj2rioe/40hCotwzyqsSWk=; b=EUSrpNH9q6v9f1JwraCh2HEK4gTcHV/DgQBVPFYokCSlQ8zPs1XxNyrnM48jgw4TUT U5Qu7EVPX1b9AkBrOyK5PuFkXCzXuaUMbx/tv2ZyOH8M7ThzB+IaZutcOU2kUENc8ie5 QC6XFihmYaLAHp6e/5ABpGIUb7Qx5MrRt3Oa+8eLyS/Ym3Unr/8aK6jIfXguGBWc9Izt gcdz9E+cnFopsnNAvj+KWoS2bm8O9Et617VpSDkpwT5z54n/axpfQ4cYC7jP7VFn4EbV ZlmbZJkGJtiH5xeeV3tUuubO9BWae7otzUShKPxcOvvJmIYnXuzJAoWC5+1bs/3co7WF C80A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=EJQe19l/SbMZVxfbn+OxSSj2rioe/40hCotwzyqsSWk=; b=cTEMCD3Atjh5KJwYUxGZNibezOIAkmPrLOqSuiLXLDN08UPJ8LhBMy6xRS9RuGcGEn 621iyB2Fz5NUM0Z50gv0W/3ur9U/TXghpzJob9rAt9Y9GwOx0OXcJJEj4sbrCHsLEs2D kOOAGSEw1bKRnZp3MvPfnbAMMxlxE1KmVGor7InzpUv4xIkoOww+jxGAffiG4KNJGx+n Th5mQc4K9HKYbp8pfV+xQK85SioOSfrQJEGqrmASGQY++A0otGG1bXaTqcGUNrK6bt8v lF7/qVpVMbYlOK6WdukXXhkeubyi0ceojBcZ1XpA2GF29QgTHltZIl2ls0rXYCOCClSz r/Lg== X-Gm-Message-State: AJcUukeCrzq5Xva5q0Q5Rrxmn2Tz8mbNtJuJxeyy6MxXvVLow338PbNj //wIDzB/Nw5I/hdc1LgcihY+bX/D X-Google-Smtp-Source: ALg8bN6GB7E6B9T+5ycAKOvRgrNFcs1faD+92+3Z7KiN6PxUfJSC53JDicBySm7bj3iUt5eJvLtk3Q== X-Received: by 2002:a5d:628a:: with SMTP id k10mr3668848wru.254.1545418180594; Fri, 21 Dec 2018 10:49:40 -0800 (PST) Received: from GONDOMAR.yourcompany.com (mail3.siscog.pt. [195.23.29.18]) by smtp.gmail.com with ESMTPSA id u10sm10773382wrr.33.2018.12.21.10.49.39 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 21 Dec 2018 10:49:39 -0800 (PST) From: =?iso-8859-1?Q?Jo=E3o_T=E1vora?= To: Beatrix Klebe Subject: Re: bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode References: <20181221134829.29135.qmail@mail.muc.de> Date: Fri, 21 Dec 2018 18:49:34 +0000 In-Reply-To: (Beatrix Klebe's message of "Fri, 21 Dec 2018 11:00:10 -0500") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (windows-nt) MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable X-Antivirus: AVG (VPS 181221-6, 21-12-2018), Outbound message X-Antivirus-Status: Clean X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 33794 Cc: Alan Mackenzie , bea@klebe.blog, Stefan Monnier , 33794@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Beatrix Klebe 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) =20=20=20=20 (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 () { } 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=E3o PS: Also, can you link to the the relevant to the stack overflow answer you mentioned? commit ab036bdedbb49ecc96d550b5e883e43bb03eaccc Author: Jo=C3=A3o T=C3=A1vora Date: Fri Dec 21 18:00:08 2018 +0000 Extend electric-layout-mode to handle more complex layouts =20=20=20=20 Also, have it play nice with electric-pair-mode. =20=20=20=20 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. =20=20=20=20 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. =20=20=20=20 * 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 =20 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.") =20 (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 w= ith - ;; 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 inserti= ng \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 recursi= vely. + ;; It happened to make electric-indent-mode work automatical= ly 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-pai= rs 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 ins= erting \n? + (goto-char end))))))) =20 (put 'electric-layout-post-self-insert-function 'priority 40) =20 From debbugs-submit-bounces@debbugs.gnu.org Fri Dec 21 14:06:53 2018 Received: (at 33794) by debbugs.gnu.org; 21 Dec 2018 19:06:53 +0000 Received: from localhost ([127.0.0.1]:58790 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gaQ8K-0005dr-WF for submit@debbugs.gnu.org; Fri, 21 Dec 2018 14:06:53 -0500 Received: from mail-oi1-f172.google.com ([209.85.167.172]:43337) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gaQ8I-0005da-Tm for 33794@debbugs.gnu.org; Fri, 21 Dec 2018 14:06:51 -0500 Received: by mail-oi1-f172.google.com with SMTP id u18so5595647oie.10 for <33794@debbugs.gnu.org>; Fri, 21 Dec 2018 11:06:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:reply-to:from:date:message-id :subject:to:cc:content-transfer-encoding; bh=255PxEUP1HzE41Vq0L+cWpALLQ8Oup2+0ycfq2Ckw08=; b=dywRS+UMKIDbIljMe3z93EUmhrlbLPZsNE7qAGOb63hUTs97cMYcdvdhCdUGjUCSc4 3l8/+TnhQpfJVpAMv4He5MMPhgeWPQNxT6+TTj/ASJcVSzSiw3UDhqiK6qpdzE/G77sU A9PVbIvm2ATyaczMq3iaczbLNKZqZk2ZIvbzrviwaM3ODGpQ3yALXNMeLR0OHBhgAFzO HKKLH3jZakFhNwORjrxRLqjRmVuMXyOL4KG8Kj5wxWyNjWcf4ecIXmuc3b0ukN6Wp0oJ WrwynrhY3MXYUqefz7qjrIdzg5a+ZOYjbeQYPFNb0Pl7pWEVN9TNruQNAksc+vAFuUC5 vzZg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:reply-to :from:date:message-id:subject:to:cc:content-transfer-encoding; bh=255PxEUP1HzE41Vq0L+cWpALLQ8Oup2+0ycfq2Ckw08=; b=HYmhf6sQCZhPSxF4lfn8jSGy68tQzT1u0EzQd5LeWe24SurXlfdggGFTDteMkfzq50 XIbyUyY5r6C4vpK8yGacQoQhIuU63TDqeUJtY1wb1y4iKSQZNhp7Zb4NKWHStsC1DO/1 g/47SAzoK+tTvOICyP2sehY5N6Fm42yXuB0cz68KrgK2Tsc0h3NAZMgnrb1ktBbHSvsV ATdsMGhIOv1LeORuPwPmOIr4oINc0COcx5hfkHIEEXlrGjeMkzqZzRPy4MQ0tNgaLneB ho3W5JrRpyTi8mv6c79ZFUHxcTQFUzi3pWp1vH61KkM2x49McADb4UovEiXCfsF1qZpP MHTA== X-Gm-Message-State: AA+aEWZp/6p2KYg2VUq2SYS1M/2fxLcfrAKzwKTMVZbEIJl3pOmtPPag 3fMIhOqqBbRcQhaLHw/OzwZoRgYNGnsnNOiGODQ= X-Google-Smtp-Source: AFSGD/UAIioC/GSZX9WctxKdA0jCHll8ySC+YwEVr2GAWs4OCxFeRQEaqvxej9H1A0VnuupLWxc8o4chDIJo1I6TLM0= X-Received: by 2002:aca:f18:: with SMTP id 24mr2064925oip.310.1545419205003; Fri, 21 Dec 2018 11:06:45 -0800 (PST) MIME-Version: 1.0 References: <20181221134829.29135.qmail@mail.muc.de> In-Reply-To: From: Beatrix Klebe Date: Fri, 21 Dec 2018 14:06:34 -0500 Message-ID: Subject: Re: bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode To: =?UTF-8?B?Sm/Do28gVMOhdm9yYQ==?= Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 33794 Cc: Alan Mackenzie , "Mx. Beatrix Klebe" , Stefan Monnier , 33794@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: bea@klebe.blog Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Here's the link, I believe it was Stefan that answered it: https://emacs.stackexchange.com/questions/2837/automatically-formatting-bra= ckets/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=C3=A3o T=C3=A1vora wrote: > > Beatrix Klebe 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 () { > > } > > 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=C3=A3o > > PS: Also, can you link to the the relevant to the stack overflow answer y= ou > mentioned? > > commit ab036bdedbb49ecc96d550b5e883e43bb03eaccc > Author: Jo=C3=83=C2=A3o T=C3=83=C2=A1vora > 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-matchin= g > 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. Bin= d > 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 recursive= ly. > - ;; 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 inser= ting \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 recur= sively. > + ;; It happened to make electric-indent-mode work automatic= ally 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-p= airs 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 i= nserting \n? > + (goto-char end))))))) > > (put 'electric-layout-post-self-insert-function 'priority 40) > From debbugs-submit-bounces@debbugs.gnu.org Fri Dec 21 14:21:05 2018 Received: (at 33794) by debbugs.gnu.org; 21 Dec 2018 19:21:05 +0000 Received: from localhost ([127.0.0.1]:58801 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gaQM5-0005yt-1x for submit@debbugs.gnu.org; Fri, 21 Dec 2018 14:21:05 -0500 Received: from mail-qt1-f176.google.com ([209.85.160.176]:44433) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gaQM3-0005y3-D3 for 33794@debbugs.gnu.org; Fri, 21 Dec 2018 14:21:04 -0500 Received: by mail-qt1-f176.google.com with SMTP id n32so6871021qte.11 for <33794@debbugs.gnu.org>; Fri, 21 Dec 2018 11:21:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=Yc8gjtbBo5EAU7ErcCyoylKHqymiqQt1rKDds70jF5c=; b=jeWnKktPesLrseTMBbbPJq7vxKLY3V87c7YSI4g2htGxo2HPzLOU0Qs8l9JOlMv/e5 YXk5xdRkeokTqFJzf25H8wOsTOIF1ywI7JOjv3nzZ67XBs4DJU1KfTzzZL7+TN9nMrpE vTofGwsRXPcwM1C0wYmm9whHRB9UtR6GLck3vshBNKdcjLo71kUg0cD/nSTMWaqCywNy cyckHEydQwofLrvyOnnsbecW9/vc3vEXjtPig16MxkrgBIaqlYi/qLIKIKbNEsBxjVnQ t6MXjToGKaRcExcG1ORytfkdNYzQebk57zh5BYdOrICKg9uJk5iZQ5KFQ1PXoaezV4Yf 7cIg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=Yc8gjtbBo5EAU7ErcCyoylKHqymiqQt1rKDds70jF5c=; b=AF8RHxuxOeO6zFpbgugz0htMS/ii5PirLtMWG2myPS4nsrDwELTViW0WCdmHXR51p2 Yi4TR0fNNHHvcVQJaxETuBRkk5qLUa60vbRoDqgzZgcMcKsxM2Akkttx0ftgXjE3zT6r plTQ4rQrT46UsXr+icMT14uFQb/Th90LmikkbecqbzjOr9OVkJmSowt7Mi8nIAnbgQmo eNzB49fy4ZN2eIXTmOsW6lhMz6i4x0DZHIttQ+OoaWa5jNXY+/0bd2gEf6M9B0lkcnsN lcFUkGNUCtjyPLRZuhbIG5d87IPWDbB6yscZUSimdrZq1TRseyWCiPQtWzgqRbdO7yru m7Tw== X-Gm-Message-State: AA+aEWZPNF9x8OY6M1E/CyEYu2I8j+Z10OoaT110IVIAvO7oSbjubjUI MXRBbtjP6zov2ROnXkgSgODnj+9wb5DTmOByFFw= X-Google-Smtp-Source: ALg8bN4XdfPbWvTcgrjYO6aDT5oENzq8MoZmmDgJd5zPIj0hlC5eFYjZchvBXxtmLqx+t/wl9e90vU898FwxiQkjjYc= X-Received: by 2002:ac8:88:: with SMTP id c8mr3747920qtg.218.1545420057779; Fri, 21 Dec 2018 11:20:57 -0800 (PST) MIME-Version: 1.0 References: <20181221134829.29135.qmail@mail.muc.de> In-Reply-To: From: =?UTF-8?B?Sm/Do28gVMOhdm9yYQ==?= Date: Fri, 21 Dec 2018 19:20:38 +0000 Message-ID: Subject: Re: bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode To: bea@klebe.blog Content-Type: multipart/alternative; boundary="00000000000092a1f0057d8d252b" X-Spam-Score: 0.1 (/) X-Debbugs-Envelope-To: 33794 Cc: Alan Mackenzie , Stefan Monnier , 33794@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.9 (/) --00000000000092a1f0057d8d252b Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable 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=C3=A3o On Fri, Dec 21, 2018, 19:06 Beatrix Klebe Here's the link, I believe it was Stefan that answered it: > > https://emacs.stackexchange.com/questions/2837/automatically-formatting-b= rackets/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=C3=A3o T=C3=A1vora wrote: > > > > Beatrix Klebe writes: > > > > > I believe I saw your Stack Overflow answer about this while searching > > > for the solution. electric-layout-mode works with some quirks, such a= s > > > 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 b= e > > > 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 looke= d > > 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 () { > > > > } > > > > 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=C3=A3o > > > > PS: Also, can you link to the the relevant to the stack overflow answer > you > > mentioned? > > > > commit ab036bdedbb49ecc96d550b5e883e43bb03eaccc > > Author: Jo=C3=83=C2=A3o T=C3=83=C2=A1vora > > 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 i= n > > 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 lin= es > > + ;; 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) > > > --00000000000092a1f0057d8d252b Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi Beatrix,

The solution I propose involves introducing the hotpatch I attac= hed 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 s= teer away from c-specific functionality and keep to the triad electric-inde= nt-mode, electric-pair-mode and electric-indent-mode, at least while we try= to extend/fix these modes to accommodate your needs.=C2=A0=C2=A0
After such a solution is evaluate= d, you can select to keep it or move to something else.

Jo=C3=A3o

=
= 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-br= ackets/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
{
=C2=A0 =C2=A0 |

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() {
=C2=A0 =C2=A0 |
} // 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()
{
=C2=A0 =C2=A0 |
} // 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<= br> just recently gotten deeper into Emacs Lisp.

On Fri, Dec 21, 2018 at 1:49 PM Jo=C3=A3o T=C3=A1vora <joaotavora@gmai= l.com> wrote:
>
> Beatrix Klebe <beeuhtricks@gmail.com> writes:
>
> > I believe I saw your Stack Overflow answer about this while searc= hing
> > for the solution. electric-layout-mode works with some quirks, su= ch as
> > that if you put a space after parens in a function definition, th= e
> > 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 t= o get
> > auto-pairing of brackets with braces being placed where they shou= ld 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 functional= ity.
> > 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 jus= t
> have to report the bugs to the Emacs developers as efficiently as
> possible.
>
> 1. Though Alan possibly has already, I still cannot understand the
>=C2=A0 =C2=A0 original problem.=C2=A0 Can you start by describing what = the buffer looked
>=C2=A0 =C2=A0 like before, what you did, what it looked like afterwards= , and what
>=C2=A0 =C2=A0 you expected it to look like?=C2=A0 If possible start wit= h a clean Emacs
>=C2=A0 =C2=A0 -Q recpe.
>
> 2. I have experimented with nicer-playing like alternatives like
>=C2=A0 =C2=A0 electric-layout-mode.=C2=A0 I came across a few quirks my= self (though I'm
>=C2=A0 =C2=A0 not sure if they are the same as yours). So I prepared a = patch (in
>=C2=A0 =C2=A0 branch scratch/fix-33794-extend-electric-layout-mode) and= attached
>=C2=A0 =C2=A0 it after the sig.
>
> After loading this patch, in a simple Emacs -Q the configuration:
>
>=C2=A0 =C2=A0 (electric-pair-mode)
>=C2=A0 =C2=A0 (electric-layout-mode)
>
>=C2=A0 =C2=A0 (add-hook 'c-mode-hook
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(lambda ()
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(setq-local electric-la= yout-rules
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0'((?\{ . after)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0(?\{ . after-stay)))))
>
> And, when visiting a C file, if I press `{' I get the expected
> pair+layout+indent behaviour.=C2=A0 Sor example opening a brace after<= br> > int main () gives me:
>
>=C2=A0 =C2=A0 =C2=A0int main () {
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0<cursor here>
>=C2=A0 =C2=A0 =C2=A0}
>
> 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=C3=A3o
>
> PS: Also, can you link to the the relevant to the stack overflow answe= r you
> mentioned?
>
> commit ab036bdedbb49ecc96d550b5e883e43bb03eaccc
> Author: Jo=C3=83=C2=A3o T=C3=83=C2=A1vora <joaotavora@gmail.com>
> Date:=C2=A0 =C2=A0Fri Dec 21 18:00:08 2018 +0000
>
>=C2=A0 =C2=A0 =C2=A0Extend electric-layout-mode to handle more complex = layouts
>
>=C2=A0 =C2=A0 =C2=A0Also, have it play nice with electric-pair-mode. >
>=C2=A0 =C2=A0 =C2=A0Multiple matching entries in `electric-layout-rules= ' are executed in
>=C2=A0 =C2=A0 =C2=A0order of appearance.=C2=A0 When inserting a newline= in the 'after-stay
>=C2=A0 =C2=A0 =C2=A0rule, ensure electric-pair-open-newline-between-pai= rs is nil.
>
>=C2=A0 =C2=A0 =C2=A0Arguably the logic behind electric-pair-open-newlin= e-between-pairs
>=C2=A0 =C2=A0 =C2=A0should be moved to electric-layout-mode, but the cu= rrent rule-matching
>=C2=A0 =C2=A0 =C2=A0engine doesn't allow for it.=C2=A0 The current = solution seems to be good
>=C2=A0 =C2=A0 =C2=A0enough for the situations reported in bug#33794. >
>=C2=A0 =C2=A0 =C2=A0* lisp/electric.el (electric-layout-rules): Adjust = docstring.
>=C2=A0 =C2=A0 =C2=A0(electric-layout-post-self-insert-function): Loop t= hrough rules.=C2=A0 Bind
>=C2=A0 =C2=A0 =C2=A0electric-pair-open-newline-between-pairs to nil whe= n handling
>=C2=A0 =C2=A0 =C2=A0after-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
>
>=C2=A0 The symbols specify where in relation to CHAR the newline
>=C2=A0 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.")
>
>=C2=A0 (defun electric-layout-post-self-insert-function ()
> -=C2=A0 (let* ((rule (cdr (assq last-command-event electric-layout-rul= es)))
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0pos)
> -=C2=A0 =C2=A0 (when (and rule
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(setq pos (ele= ctric--after-char-pos))
> +=C2=A0 (let (pos)
> +=C2=A0 =C2=A0 (when (and (setq pos (electric--after-char-pos))
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0;; Not in= a string or comment.
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(not (nth= 8 (save-excursion (syntax-ppss pos)))))
> -=C2=A0 =C2=A0 =C2=A0 (let ((end (point-marker))
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (sym (if (functionp rule) (= funcall rule) rule)))
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 (set-marker-insertion-type end (not (eq s= ym 'after-stay)))
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 (goto-char pos)
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 (pcase sym
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; FIXME: we used `newline' do= wn here which called
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; self-insert-command and ran pos= t-self-insert-hook recursively.
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; It happened to make electric-in= dent-mode work automatically with
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; electric-layout-mode (at the co= st of re-indenting lines
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; multiple times), but I'm no= t sure it's what we want.
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;;
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; FIXME: check eolp before insert= ing \n?
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ('before (goto-char (1- pos)) = (skip-chars-backward " \t")
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= (unless (bolp) (insert "\n")))
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ('after=C2=A0 (insert "\n= "))
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ('after-stay (save-excursion > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0(let ((electric-layout-rules nil))
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0(newline 1 t))))
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ('around (save-excursion
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0(goto-char (1- pos)) (skip-chars-backward " \t")
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0(unless (bolp) (insert "\n")))
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= (insert "\n")))=C2=A0 =C2=A0 =C2=A0 ; FIXME: check eolp before in= serting \n?
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 (goto-char end)))))
> +=C2=A0 =C2=A0 =C2=A0 (goto-char pos)
> +=C2=A0 =C2=A0 =C2=A0 (dolist (rule electric-layout-rules)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (when (eq last-command-event (car rule))<= br> > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (let* ((end (point-marker))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(rule (= cdr rule))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(sym (i= f (functionp rule) (funcall rule) rule)))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (set-marker-insertion-type = end (not (eq sym 'after-stay)))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (pcase sym
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; FIXME: we used `n= ewline' down here which called
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; self-insert-comma= nd and ran post-self-insert-hook recursively.
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; It happened to ma= ke electric-indent-mode work automatically with
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; electric-layout-m= ode (at the cost of re-indenting lines
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; multiple times), = but I'm not sure it's what we want.
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; FIXME: check eolp= before inserting \n?
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ('before (goto-c= har (1- pos)) (skip-chars-backward " \t")
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0(unless (bolp) (insert "\n")))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ('after=C2=A0 (i= nsert "\n"))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ('after-stay (sa= ve-excursion
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(let ((electric-layout-rules nil)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(electric-pair-open= -newline-between-pairs nil))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(newline 1 t))))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ('around (save-e= xcursion
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0(goto-char (1- pos)) (skip-chars-backward " \t&qu= ot;)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0(unless (bolp) (insert "\n")))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0(insert "\n")))=C2=A0 =C2=A0 =C2=A0 ; FIXME: check = eolp before inserting \n?
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (goto-char end)))))))
>
>=C2=A0 (put 'electric-layout-post-self-insert-function 'priorit= y=C2=A0 40)
>
--00000000000092a1f0057d8d252b-- From debbugs-submit-bounces@debbugs.gnu.org Fri Dec 21 14:24:22 2018 Received: (at 33794) by debbugs.gnu.org; 21 Dec 2018 19:24:22 +0000 Received: from localhost ([127.0.0.1]:58805 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gaQPF-00063h-Oc for submit@debbugs.gnu.org; Fri, 21 Dec 2018 14:24:22 -0500 Received: from mail-qt1-f182.google.com ([209.85.160.182]:40170) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gaQPE-00063T-Aj for 33794@debbugs.gnu.org; Fri, 21 Dec 2018 14:24:20 -0500 Received: by mail-qt1-f182.google.com with SMTP id k12so6910833qtf.7 for <33794@debbugs.gnu.org>; Fri, 21 Dec 2018 11:24:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=E9fI04p6v9RHYFcFWxNsgf7V5p3ghkdBsbcWbfkDpek=; b=i/yoSyPSCUM3kFN9EdPgZ2RXsCTVjqlcFBzGYmFH4fQzxJ7KJa3FqTavanaAdRJoLP wRof58sUjyWMWaRYi/asqjDUUjZk3lDfFjkKX+jjXLM4kgrPme+bW8hEFr1kKPUWoM+u gfCZCZN8cLI1KoAd/EdI8trpw7O9sKudIeJYQDg92rEHnUir9PRdDLoiQg4n6jo2iMxW QQpVs5BAhWpi1hmch2qQx4t8xsQHuwYJz0R0ZUkxjogkpqOvgPrKiDE1xlNqiaLiRXR5 iTT8RdIUuabBLVFGaKkwAmrVwjqU35qFUErm+447JGEjk4AEkT/3/AJMhbSp0DKxf72X +VFQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=E9fI04p6v9RHYFcFWxNsgf7V5p3ghkdBsbcWbfkDpek=; b=guk+s7sAdVbdsGnQyP6Mzuos1M4nle+veRn5cdA6haHBtqHQO2MvSh4+5H9fWoUvyG BFL53LHJy00KdYWGaI3UdMbofMpjUpVtB+Vl9fPDVwILz1//74vKU/awHT6yiRJtb2/h ya8pm/2R8uNqTO9AnSKOqZX3YO+SnmP+2diU1WlQVAFTkD8MRHL92OdCZ4O6jYpRmqgR pTheNNp9fsl4IExADaSjSDdiZ8RThFFqgCHwqPzZC5nov1AKKvWlCUIAux7PU+ayyWLc /saykbCyA1rMdHH//sItZFp6teq2ir45Wj6MekKHoyEEGEiC11VPGcbRhJr67vtj62cO 6o2A== X-Gm-Message-State: AA+aEWYGrLG2oiUG0u6+SzBSoLe2LHtKW7WzrlOz4gfEhabPJQgXGmfr Ivx1O4rwMjIazfSiE0hgttLEw47C8RJEb4UkFw88UQ== X-Google-Smtp-Source: ALg8bN5I27OqCsGNWMfMke8J0hdAWqR0rUQmcQg5sWsFc/IeTpP0njSLQ9OHD2pIKvmU5W5EuBNOFhcE65mm8Xis5PY= X-Received: by 2002:ac8:3e91:: with SMTP id y17mr3779916qtf.390.1545420254925; Fri, 21 Dec 2018 11:24:14 -0800 (PST) MIME-Version: 1.0 References: <20181221134829.29135.qmail@mail.muc.de> In-Reply-To: From: =?UTF-8?B?Sm/Do28gVMOhdm9yYQ==?= Date: Fri, 21 Dec 2018 19:24:02 +0000 Message-ID: Subject: Re: bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode To: bea@klebe.blog Content-Type: multipart/alternative; boundary="00000000000052db56057d8d31dc" X-Spam-Score: 0.1 (/) X-Debbugs-Envelope-To: 33794 Cc: Alan Mackenzie , Stefan Monnier , 33794@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.9 (/) --00000000000052db56057d8d31dc Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable 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=C3=A3o On Fri, Dec 21, 2018, 19:20 Jo=C3=A3o T=C3=A1vora Hi Beatrix, > > The solution I propose involves introducing the hotpatch I attached to fi= x > electric-layout-mode in your emacs, so I wouldn't expect it to work if yo= u > 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=C3=A3o > > On Fri, Dec 21, 2018, 19:06 Beatrix Klebe >> 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=C3=A3o T=C3=A1vora wrote: >> > >> > Beatrix Klebe writes: >> > >> > > I believe I saw your Stack Overflow answer about this while searchin= g >> > > 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 bi= t >> > > 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, o= r >> > > 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 jus= t >> > 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 look= ed >> > 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 () { >> > >> > } >> > >> > 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=C3=A3o >> > >> > PS: Also, can you link to the the relevant to the stack overflow answe= r >> you >> > mentioned? >> > >> > commit ab036bdedbb49ecc96d550b5e883e43bb03eaccc >> > Author: Jo=C3=83=C2=A3o T=C3=83=C2=A1vora >> > 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 goo= d >> > 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 befor= e >> inserting \n? >> > + (goto-char end))))))) >> > >> > (put 'electric-layout-post-self-insert-function 'priority 40) >> > >> > --00000000000052db56057d8d31dc Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
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.=C2=A0 After having seen Beatrix's link to your so answer,= I see that two separate rules on two separate chars should also work for t= his.

Jo=C3=A3o

=
Hi Beatrix,

The= solution I propose involves introducing the hotpatch I attached to fix ele= ctric-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, elect= ric-pair-mode and electric-indent-mode, at least while we try to extend/fix= these modes to accommodate your needs.=C2=A0=C2=A0
=
After such a solution is evaluated, you can sel= ect to keep it or move to something else.

=
Jo=C3=A3o

On Fri, Dec 21= , 2018, 19:06 Beatrix Klebe <beeuhtricks@gmail.com wrote:
Here's the link, I believe it was Stef= an that answered it:
https://emacs.stackexchange.com/questions/2837/automatically-fo= rmatting-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
{
=C2=A0 =C2=A0 |

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() {
=C2=A0 =C2=A0 |
} // 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()
{
=C2=A0 =C2=A0 |
} // 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<= br> just recently gotten deeper into Emacs Lisp.

On Fri, Dec 21, 2018 at 1:49 PM Jo=C3=A3o T=C3=A1vora <joao= tavora@gmail.com> wrote:
>
> Beatrix Klebe <beeuhtricks@gmail.com> writes:<= br> >
> > I believe I saw your Stack Overflow answer about this while searc= hing
> > for the solution. electric-layout-mode works with some quirks, su= ch as
> > that if you put a space after parens in a function definition, th= e
> > 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 t= o get
> > auto-pairing of brackets with braces being placed where they shou= ld 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 functional= ity.
> > 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 jus= t
> have to report the bugs to the Emacs developers as efficiently as
> possible.
>
> 1. Though Alan possibly has already, I still cannot understand the
>=C2=A0 =C2=A0 original problem.=C2=A0 Can you start by describing what = the buffer looked
>=C2=A0 =C2=A0 like before, what you did, what it looked like afterwards= , and what
>=C2=A0 =C2=A0 you expected it to look like?=C2=A0 If possible start wit= h a clean Emacs
>=C2=A0 =C2=A0 -Q recpe.
>
> 2. I have experimented with nicer-playing like alternatives like
>=C2=A0 =C2=A0 electric-layout-mode.=C2=A0 I came across a few quirks my= self (though I'm
>=C2=A0 =C2=A0 not sure if they are the same as yours). So I prepared a = patch (in
>=C2=A0 =C2=A0 branch scratch/fix-33794-extend-electric-layout-mode) and= attached
>=C2=A0 =C2=A0 it after the sig.
>
> After loading this patch, in a simple Emacs -Q the configuration:
>
>=C2=A0 =C2=A0 (electric-pair-mode)
>=C2=A0 =C2=A0 (electric-layout-mode)
>
>=C2=A0 =C2=A0 (add-hook 'c-mode-hook
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(lambda ()
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(setq-local electric-la= yout-rules
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0'((?\{ . after)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0(?\{ . after-stay)))))
>
> And, when visiting a C file, if I press `{' I get the expected
> pair+layout+indent behaviour.=C2=A0 Sor example opening a brace after<= br> > int main () gives me:
>
>=C2=A0 =C2=A0 =C2=A0int main () {
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0<cursor here>
>=C2=A0 =C2=A0 =C2=A0}
>
> 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=C3=A3o
>
> PS: Also, can you link to the the relevant to the stack overflow answe= r you
> mentioned?
>
> commit ab036bdedbb49ecc96d550b5e883e43bb03eaccc
> Author: Jo=C3=83=C2=A3o T=C3=83=C2=A1vora <joaotavora@= gmail.com>
> Date:=C2=A0 =C2=A0Fri Dec 21 18:00:08 2018 +0000
>
>=C2=A0 =C2=A0 =C2=A0Extend electric-layout-mode to handle more complex = layouts
>
>=C2=A0 =C2=A0 =C2=A0Also, have it play nice with electric-pair-mode. >
>=C2=A0 =C2=A0 =C2=A0Multiple matching entries in `electric-layout-rules= ' are executed in
>=C2=A0 =C2=A0 =C2=A0order of appearance.=C2=A0 When inserting a newline= in the 'after-stay
>=C2=A0 =C2=A0 =C2=A0rule, ensure electric-pair-open-newline-between-pai= rs is nil.
>
>=C2=A0 =C2=A0 =C2=A0Arguably the logic behind electric-pair-open-newlin= e-between-pairs
>=C2=A0 =C2=A0 =C2=A0should be moved to electric-layout-mode, but the cu= rrent rule-matching
>=C2=A0 =C2=A0 =C2=A0engine doesn't allow for it.=C2=A0 The current = solution seems to be good
>=C2=A0 =C2=A0 =C2=A0enough for the situations reported in bug#33794. >
>=C2=A0 =C2=A0 =C2=A0* lisp/electric.el (electric-layout-rules): Adjust = docstring.
>=C2=A0 =C2=A0 =C2=A0(electric-layout-post-self-insert-function): Loop t= hrough rules.=C2=A0 Bind
>=C2=A0 =C2=A0 =C2=A0electric-pair-open-newline-between-pairs to nil whe= n handling
>=C2=A0 =C2=A0 =C2=A0after-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
>
>=C2=A0 The symbols specify where in relation to CHAR the newline
>=C2=A0 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.")
>
>=C2=A0 (defun electric-layout-post-self-insert-function ()
> -=C2=A0 (let* ((rule (cdr (assq last-command-event electric-layout-rul= es)))
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0pos)
> -=C2=A0 =C2=A0 (when (and rule
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(setq pos (ele= ctric--after-char-pos))
> +=C2=A0 (let (pos)
> +=C2=A0 =C2=A0 (when (and (setq pos (electric--after-char-pos))
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0;; Not in= a string or comment.
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(not (nth= 8 (save-excursion (syntax-ppss pos)))))
> -=C2=A0 =C2=A0 =C2=A0 (let ((end (point-marker))
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (sym (if (functionp rule) (= funcall rule) rule)))
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 (set-marker-insertion-type end (not (eq s= ym 'after-stay)))
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 (goto-char pos)
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 (pcase sym
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; FIXME: we used `newline' do= wn here which called
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; self-insert-command and ran pos= t-self-insert-hook recursively.
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; It happened to make electric-in= dent-mode work automatically with
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; electric-layout-mode (at the co= st of re-indenting lines
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; multiple times), but I'm no= t sure it's what we want.
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;;
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; FIXME: check eolp before insert= ing \n?
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ('before (goto-char (1- pos)) = (skip-chars-backward " \t")
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= (unless (bolp) (insert "\n")))
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ('after=C2=A0 (insert "\n= "))
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ('after-stay (save-excursion > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0(let ((electric-layout-rules nil))
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0(newline 1 t))))
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ('around (save-excursion
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0(goto-char (1- pos)) (skip-chars-backward " \t")
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0(unless (bolp) (insert "\n")))
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= (insert "\n")))=C2=A0 =C2=A0 =C2=A0 ; FIXME: check eolp before in= serting \n?
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 (goto-char end)))))
> +=C2=A0 =C2=A0 =C2=A0 (goto-char pos)
> +=C2=A0 =C2=A0 =C2=A0 (dolist (rule electric-layout-rules)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (when (eq last-command-event (car rule))<= br> > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (let* ((end (point-marker))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(rule (= cdr rule))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(sym (i= f (functionp rule) (funcall rule) rule)))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (set-marker-insertion-type = end (not (eq sym 'after-stay)))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (pcase sym
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; FIXME: we used `n= ewline' down here which called
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; self-insert-comma= nd and ran post-self-insert-hook recursively.
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; It happened to ma= ke electric-indent-mode work automatically with
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; electric-layout-m= ode (at the cost of re-indenting lines
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; multiple times), = but I'm not sure it's what we want.
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; FIXME: check eolp= before inserting \n?
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ('before (goto-c= har (1- pos)) (skip-chars-backward " \t")
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0(unless (bolp) (insert "\n")))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ('after=C2=A0 (i= nsert "\n"))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ('after-stay (sa= ve-excursion
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(let ((electric-layout-rules nil)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(electric-pair-open= -newline-between-pairs nil))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(newline 1 t))))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ('around (save-e= xcursion
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0(goto-char (1- pos)) (skip-chars-backward " \t&qu= ot;)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0(unless (bolp) (insert "\n")))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0(insert "\n")))=C2=A0 =C2=A0 =C2=A0 ; FIXME: check = eolp before inserting \n?
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (goto-char end)))))))
>
>=C2=A0 (put 'electric-layout-post-self-insert-function 'priorit= y=C2=A0 40)
>
--00000000000052db56057d8d31dc-- From debbugs-submit-bounces@debbugs.gnu.org Fri Dec 21 14:44:00 2018 Received: (at 33794) by debbugs.gnu.org; 21 Dec 2018 19:44:00 +0000 Received: from localhost ([127.0.0.1]:58810 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gaQiF-0006e8-L1 for submit@debbugs.gnu.org; Fri, 21 Dec 2018 14:43:59 -0500 Received: from mail-ot1-f54.google.com ([209.85.210.54]:38249) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gaQiD-0006dv-QB for 33794@debbugs.gnu.org; Fri, 21 Dec 2018 14:43:58 -0500 Received: by mail-ot1-f54.google.com with SMTP id e12so6135305otl.5 for <33794@debbugs.gnu.org>; Fri, 21 Dec 2018 11:43:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:reply-to:from:date:message-id :subject:to:cc:content-transfer-encoding; bh=KxKIr7H6hgiAsqfgwi2L/Jb2NlDZ+mrcfe/LqjX61EM=; b=qUaO3JXULg/yOT3mg74zsTtIe/4BCA1bGeytjPQyG4gb2Ctfd2bfYX0ndRcH6Wf/oc 0eCKRcfG2X2ZgbrviwDRHhtu698dNLT2CVUbgItkL2vonp6TZ5S/zqFq4UaC4orVfuyz o2/jx8ViLQ2h7yFbE1ufhO4vs6cCAZoWmGiCeK0uEd2zT3/HalmO2uKE1tuzRGM3ZJls DJ+SiYORTHpYMCqrdRY59EmSLw3NFcH+vGaDwAVCgY+sNPofRd1N2UpD2SID+slhFNC2 EZD7Av2lmqeuul8GSX2KQhFOIqftPc6F5dz+xqDieVoNutPZJNEDZwt6rjA0i3KAkUU1 +Z3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:reply-to :from:date:message-id:subject:to:cc:content-transfer-encoding; bh=KxKIr7H6hgiAsqfgwi2L/Jb2NlDZ+mrcfe/LqjX61EM=; b=ELtw/oQTDFP4qQbwme8MWKDtUoYZJDpZZQBxT4o2suL/Nw6iLf4SqS/tVIm4YvGzY5 e7W/W0PrZfD3iy9kXhf9vXmYPGXQLM+6NIjglEfr2K+cXIpHvFY8jNT09x786ljJNxt9 o1ZCiUY+PInYZ+WazQg93dBq56ELe93TkF6OBUk/y+g/SdT/h4dFrWnTMu4aa+1pnyLO q3j3d9GVKPX5aaeonYLoPsSs9OnWSCEDrVNs+Fma7CFjpnDsonWAMs+Cy57p8S0BY1pn 60wC8sWd6/XB46wt2bglFgjXsnOE22JAJUNn/K0Kmy6o/qjBsq0/E6HNKWpNO5z6rNhy V25w== X-Gm-Message-State: AJcUukdiPPHcNIb677VxUHgy15QdEbtBVPKVLwKZlkwNAOal+L7XswpE 3B+DH/zbfLnQ3QFlMbKa8+I1iv8dw5Jwwgx19ls= X-Google-Smtp-Source: ALg8bN5dtIF3J1dnCyX8N1zeZnjU81NkUSlTyN7dGu6BfPhn6ZPdg+VZcmRvZJ1n5Mf7xki3Jr0ui4AxmnYSzx+fpkk= X-Received: by 2002:a9d:4c88:: with SMTP id m8mr2626817otf.360.1545421432015; Fri, 21 Dec 2018 11:43:52 -0800 (PST) MIME-Version: 1.0 References: <20181221134829.29135.qmail@mail.muc.de> In-Reply-To: From: Beatrix Klebe Date: Fri, 21 Dec 2018 14:43:41 -0500 Message-ID: Subject: Re: bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode To: =?UTF-8?B?Sm/Do28gVMOhdm9yYQ==?= Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 33794 Cc: Alan Mackenzie , "Mx. Beatrix Klebe" , Stefan Monnier , 33794@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: bea@klebe.blog Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) 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=C3=A3o T=C3=A1vora wrote: > > Hi Beatrix, > > The solution I propose involves introducing the hotpatch I attached to fi= x electric-layout-mode in your emacs, so I wouldn't expect it to work if yo= u haven't done that. > > Do you know how to do it? > > Though Alan will probably suggest otherwise, I'd also steer away from c-s= pecific functionality and keep to the triad electric-indent-mode, electric-= pair-mode and electric-indent-mode, at least while we try to extend/fix the= se modes to accommodate your needs. > > After such a solution is evaluated, you can select to keep it or move to = something else. > > Jo=C3=A3o > > On Fri, Dec 21, 2018, 19:06 Beatrix Klebe > >> 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=C3=A3o T=C3=A1vora wrote: >> > >> > Beatrix Klebe writes: >> > >> > > I believe I saw your Stack Overflow answer about this while searchin= g >> > > 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 bi= t >> > > 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, o= r >> > > 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 jus= t >> > 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 look= ed >> > 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 () { >> > >> > } >> > >> > 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=C3=A3o >> > >> > PS: Also, can you link to the the relevant to the stack overflow answe= r you >> > mentioned? >> > >> > commit ab036bdedbb49ecc96d550b5e883e43bb03eaccc >> > Author: Jo=C3=83=C2=A3o T=C3=83=C2=A1vora >> > 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-matc= hing >> > engine doesn't allow for it. The current solution seems to be goo= d >> > 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 recurs= ively. >> > - ;; It happened to make electric-indent-mode work automatica= lly 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 in= serting \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 re= cursively. >> > + ;; It happened to make electric-indent-mode work automa= tically with >> > + ;; electric-layout-mode (at the cost of re-indenting li= nes >> > + ;; 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-betwee= n-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 befor= e inserting \n? >> > + (goto-char end))))))) >> > >> > (put 'electric-layout-post-self-insert-function 'priority 40) >> > From debbugs-submit-bounces@debbugs.gnu.org Fri Dec 21 15:17:46 2018 Received: (at 33794) by debbugs.gnu.org; 21 Dec 2018 20:17:46 +0000 Received: from localhost ([127.0.0.1]:58830 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gaREv-0007b1-Td for submit@debbugs.gnu.org; Fri, 21 Dec 2018 15:17:46 -0500 Received: from colin.muc.de ([193.149.48.1]:48148 helo=mail.muc.de) by debbugs.gnu.org with smtp (Exim 4.84_2) (envelope-from ) id 1gaREt-0007as-9A for 33794@debbugs.gnu.org; Fri, 21 Dec 2018 15:17:44 -0500 Received: (qmail 7514 invoked by uid 3782); 21 Dec 2018 20:17:41 -0000 Received: from acm.muc.de (p2E5D5AAE.dip0.t-ipconnect.de [46.93.90.174]) by colin.muc.de (tmda-ofmipd) with ESMTP; Fri, 21 Dec 2018 21:17:40 +0100 Received: (qmail 18666 invoked by uid 1000); 21 Dec 2018 20:11:06 -0000 Date: Fri, 21 Dec 2018 20:11:06 +0000 To: Stefan Monnier Subject: Re: bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode Message-ID: <20181221201106.GB16032@ACM> References: <20181221134829.29135.qmail@mail.muc.de> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) X-Delivery-Agent: TMDA/1.1.12 (Macallan) From: Alan Mackenzie X-Primary-Address: acm@muc.de X-Spam-Score: -0.0 (/) X-Debbugs-Envelope-To: 33794 Cc: bea@klebe.blog, =?iso-8859-1?Q?Jo=E3o_T=E1vora?= , 33794@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) 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). From debbugs-submit-bounces@debbugs.gnu.org Fri Dec 21 16:57:23 2018 Received: (at 33794) by debbugs.gnu.org; 21 Dec 2018 21:57:23 +0000 Received: from localhost ([127.0.0.1]:58869 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gaSnL-0001UK-7h for submit@debbugs.gnu.org; Fri, 21 Dec 2018 16:57:23 -0500 Received: from colin.muc.de ([193.149.48.1]:53943 helo=mail.muc.de) by debbugs.gnu.org with smtp (Exim 4.84_2) (envelope-from ) id 1gaSnI-0001UB-Od for 33794@debbugs.gnu.org; Fri, 21 Dec 2018 16:57:21 -0500 Received: (qmail 44342 invoked by uid 3782); 21 Dec 2018 21:57:19 -0000 Received: from acm.muc.de (p2E5D5AAE.dip0.t-ipconnect.de [46.93.90.174]) by colin.muc.de (tmda-ofmipd) with ESMTP; Fri, 21 Dec 2018 22:57:17 +0100 Received: (qmail 19158 invoked by uid 1000); 21 Dec 2018 21:50:42 -0000 Date: Fri, 21 Dec 2018 21:50:42 +0000 To: =?iso-8859-1?Q?Jo=E3o_T=E1vora?= Subject: Re: bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode Message-ID: <20181221215042.GC16032@ACM> References: <20181221134829.29135.qmail@mail.muc.de> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) X-Delivery-Agent: TMDA/1.1.12 (Macallan) From: Alan Mackenzie X-Primary-Address: acm@muc.de X-Spam-Score: -0.0 (/) X-Debbugs-Envelope-To: 33794 Cc: bea@klebe.blog, 33794@debbugs.gnu.org, Stefan Monnier X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) 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 wrote: > > Hello, Beatrix. > > In article 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). From debbugs-submit-bounces@debbugs.gnu.org Fri Dec 21 19:45:33 2018 Received: (at 33794) by debbugs.gnu.org; 22 Dec 2018 00:45:33 +0000 Received: from localhost ([127.0.0.1]:59001 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gaVQ5-0007ef-Bb for submit@debbugs.gnu.org; Fri, 21 Dec 2018 19:45:33 -0500 Received: from mail-wm1-f48.google.com ([209.85.128.48]:54220) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gaVQ2-0007eR-4x for 33794@debbugs.gnu.org; Fri, 21 Dec 2018 19:45:31 -0500 Received: by mail-wm1-f48.google.com with SMTP id d15so6773465wmb.3 for <33794@debbugs.gnu.org>; Fri, 21 Dec 2018 16:45:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-transfer-encoding; bh=2upcAe+BT9CXXOap8s2uqLIgk1IS6JThU7tsnZMoWoo=; b=kcp3smW0a/h+XFiHMAsvOnEIGfiLHJH1+yGlvTHvVCoeyzfjRlseOd50mjxYn6exGI nYOX5BWxSOjbOVRxRUCqEy5v7YuhVlzRKxN34ou24iKfphqVjA6/yIWqfAB1LpRJhJn5 CcjCl+OeRdO4bsS/LCqc4jwYl7soVmIwkg+a20ilXeVzEn73frgpLZIjhnl1ztDgKBNN Q3hqo2mif/TIp8RPalwwjLoqQB/G2KMx6pzAN3XOfa/7SEeLWnJTG0RmN5TcAOAhr4y7 oJX3buyplPyHSqY9iTWHHMyKd+WZXQn8vSoxXpwV6l9cZZPJ3JKsCMchZnQ4MLMz1SLN 5IXg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=2upcAe+BT9CXXOap8s2uqLIgk1IS6JThU7tsnZMoWoo=; b=kldh9ab94nntkCP7a/gaS/2lsnTh8ik9uqL+rqgvAClyinW6PcsPz9qk3XzMlVRU22 eRNG+dsDJe3TYWfvedV4gcKMHcmji2yy9gS5UVkTWnMyqSZvjhltp6yEubo18F3Yt2f2 P6ZgJ3WT6gFpSN7vo/3rwqYHfmWfNhzeXMjSLFyFU6pNKHCJbVKK0TjFCtrpZaUAh/6J 0XJBFE7IkA8D4o0XftNPAhWUEHbGlnX3I7w07ZuAXPYfA5FRAut9E1/Jnkh5MJhYYOmR tJCU3eY4EYsm9WAK1faBnswR3Z3hEMO7UEe1kuRjCz5NqgKbkOWzD4R6VQ5prrnR7pvv Srow== X-Gm-Message-State: AJcUukfSf4ATcMXyYpf2Jsl4hZlvKjzBvbnqOCJtm3WGOEPMtJrl8abZ kU5bgLpxBRkt/ZC7mX54wGHFO/6V X-Google-Smtp-Source: ALg8bN4tXZq+139xEJsgDOvyQfq/2DxiDXU3jML4M+XDC0bBPkvx0Sb2I3x0aumR/zKlfc/wXpVTkA== X-Received: by 2002:a7b:ce8e:: with SMTP id q14mr4922387wmj.10.1545439523973; Fri, 21 Dec 2018 16:45:23 -0800 (PST) Received: from lolita.yourcompany.com (188.139.62.94.rev.vodafone.pt. [94.62.139.188]) by smtp.gmail.com with ESMTPSA id o8sm11723536wrx.15.2018.12.21.16.45.22 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 21 Dec 2018 16:45:23 -0800 (PST) From: =?utf-8?B?Sm/Do28gVMOhdm9yYQ==?= To: Alan Mackenzie Subject: Re: bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode References: <20181221134829.29135.qmail@mail.muc.de> <20181221201106.GB16032@ACM> Date: Sat, 22 Dec 2018 00:45:20 +0000 In-Reply-To: <20181221201106.GB16032@ACM> (Alan Mackenzie's message of "Fri, 21 Dec 2018 20:11:06 +0000") Message-ID: <87y38iqti7.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.1 (/) X-Debbugs-Envelope-To: 33794 Cc: bea@klebe.blog, Stefan Monnier , 33794@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.9 (/) Hi Alan, I will be replying to the two emails you sent me in this single message. Alan Mackenzie 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=C3=A3o From debbugs-submit-bounces@debbugs.gnu.org Fri Dec 21 20:09:06 2018 Received: (at 33794) by debbugs.gnu.org; 22 Dec 2018 01:09:06 +0000 Received: from localhost ([127.0.0.1]:59007 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gaVms-0008G6-FQ for submit@debbugs.gnu.org; Fri, 21 Dec 2018 20:09:06 -0500 Received: from mail-wr1-f49.google.com ([209.85.221.49]:38872) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gaVmp-0008Fc-Vk for 33794@debbugs.gnu.org; Fri, 21 Dec 2018 20:09:04 -0500 Received: by mail-wr1-f49.google.com with SMTP id v13so6935910wrw.5 for <33794@debbugs.gnu.org>; Fri, 21 Dec 2018 17:09:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-transfer-encoding; bh=581E8+kM/qOdAxOb1kC0z9spzWR1dLLC76SnY7KgCj8=; b=Uwb8sI+Azea5z6i/jr/PCeShP+pFDbNdBfCLAqAMzDWNCYMUsAzMPMvbruLgzE4h4n hjwCPlZXqOtPW4h2dQ7WtpDM9wxpunh+oSqBLedm6qTLxCvWuJXlYUf84wcE14KDvPHL J/RCgIzPMummCO6JZmV4SxbLloesGDeKhBXIs4yhePa0Hag9J0AR3T4mVCnou6KKGnIY yKO7CMUZKi0+HkH7//azT3GkRCVEMwGx4iUs+2jmsjV1cz7+UFMnStp4RUKiHLVQ9ibm IaabcciBwHVLSheWPmnB+e7DDyNnjX+Dd7ThHUb/z2VQNaq46V/yrUG4EETVz58+D9XJ DPPw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=581E8+kM/qOdAxOb1kC0z9spzWR1dLLC76SnY7KgCj8=; b=tTIIUxCnk0lHmDBXcT6d12W7O5+NBdf/Z9fXQrVMcXiFdqKtvCopt21m5vLisj6FR8 77EzeMefzJZaMz/Pk0hLH9qOFLndk4y1LrHG5puUo1xo2a1jMQAAh/mipvc2b1XNyN0j tIMNlFE5UjPr49yxxL3DGAznuN1V6/Mvgr1gT3LXStJqyl7JkLXTX9D1Y2q4KT1IRjEb dhlGcKRuaD6hw0uTnbXPXQPgBl7+GKjP5WuWaNYUmcZ+F51pWCyz5RaRQ5p3WkO+HwyB 6/EBpizzvBlkReREmBiDRY/F7+MYelTsrDF5JbhpiaRU+nwrq04ONK2waBnq0btwrnP4 8tsg== X-Gm-Message-State: AJcUukeABLMPdQclJj8oc5kAr/1Hfg9fkUllwnQONz0zHqI5d4VstapZ hScFYPCHO1GozoTxQo+DXf7Rc3GH X-Google-Smtp-Source: ALg8bN40OhJRV6Sj0gqQ+dJ1xwWVwKeH+Nlux7sNMLigzEpRfEGHP3ohDV1hFsL61QDoXXlBfYG0iw== X-Received: by 2002:adf:e8c1:: with SMTP id k1mr4299904wrn.104.1545440937828; Fri, 21 Dec 2018 17:08:57 -0800 (PST) Received: from lolita.yourcompany.com (188.139.62.94.rev.vodafone.pt. [94.62.139.188]) by smtp.gmail.com with ESMTPSA id c9sm16896797wmh.27.2018.12.21.17.08.56 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 21 Dec 2018 17:08:56 -0800 (PST) From: =?utf-8?B?Sm/Do28gVMOhdm9yYQ==?= To: Beatrix Klebe Subject: Re: bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode References: <20181221134829.29135.qmail@mail.muc.de> Date: Sat, 22 Dec 2018 01:08:54 +0000 In-Reply-To: (Beatrix Klebe's message of "Fri, 21 Dec 2018 14:43:41 -0500") Message-ID: <87tvj68j15.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.1 (/) X-Debbugs-Envelope-To: 33794 Cc: Alan Mackenzie , bea@klebe.blog, Stefan Monnier , 33794@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.9 (/) Beatrix Klebe 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) =20=20=20=20 (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 () { } 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=C3=A3o > > > On Fri, Dec 21, 2018 at 2:20 PM Jo=C3=A3o T=C3=A1vora 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=C3=A3o >> >> On Fri, Dec 21, 2018, 19:06 Beatrix Klebe >> >>> 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=C3=A3o T=C3=A1vora wrote: >>> > >>> > Beatrix Klebe writes: >>> > >>> > > I believe I saw your Stack Overflow answer about this while searchi= ng >>> > > 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 b= it >>> > > 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 functionalit= y. >>> > > 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 ju= st >>> > 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 loo= ked >>> > 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 () { >>> > >>> > } >>> > >>> > 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=C3=A3o >>> > >>> > PS: Also, can you link to the the relevant to the stack overflow answ= er you >>> > mentioned? >>> > >>> > commit ab036bdedbb49ecc96d550b5e883e43bb03eaccc >>> > Author: Jo=C3=83=C2=A3o T=C3=83=C2=A1vora >>> > 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-mat= ching >>> > engine doesn't allow for it. The current solution seems to be go= od >>> > 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 recur= sively. >>> > - ;; It happened to make electric-indent-mode work automatic= ally 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 i= nserting \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 r= ecursively. >>> > + ;; It happened to make electric-indent-mode work autom= atically with >>> > + ;; electric-layout-mode (at the cost of re-indenting l= ines >>> > + ;; 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-betwe= en-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 befo= re inserting \n? >>> > + (goto-char end))))))) >>> > >>> > (put 'electric-layout-post-self-insert-function 'priority 40) >>> > From debbugs-submit-bounces@debbugs.gnu.org Fri Dec 21 21:16:15 2018 Received: (at 33794) by debbugs.gnu.org; 22 Dec 2018 02:16:15 +0000 Received: from localhost ([127.0.0.1]:59013 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gaWpq-0001ON-QE for submit@debbugs.gnu.org; Fri, 21 Dec 2018 21:16:15 -0500 Received: from mail-wr1-f41.google.com ([209.85.221.41]:35396) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gaWpo-0001O8-QW for 33794@debbugs.gnu.org; Fri, 21 Dec 2018 21:16:13 -0500 Received: by mail-wr1-f41.google.com with SMTP id 96so7019356wrb.2 for <33794@debbugs.gnu.org>; Fri, 21 Dec 2018 18:16:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=2TYjsuh1OhtZaxXBAVYGO6/oefaKcu0CTZYmtgMoCMU=; b=EWUSz64bvRXUdib9eIH+TR3CAuOrDLfmeyMR6G/Ka+w/2981/uIhAxBF1lu6lWZ7Dg jftObpRtgfCuDIHLwWSGVrBxcZmaPf0qVPBb0yvQLn0yy2mx/dcW902XZDOPslO9Y+17 L3i62Agl95QauVEuNVaaeW9tCmQzF/gfb9BfO2mA7o2ILOm6psNrfyB3BQtp8aw9sL5u zw0JUNWqRxPAkp87ptLDVI0kXV5MOOLDIQGJ/g/aIcDLt8igs4qpAaPuwr4GhPVfRv8k TX4po6l4takUVrmTxuzKwTjg0+VUJsesAjjBTz08bl6i8PVCsROVEwcIflT4+37gU8fJ K6+w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=2TYjsuh1OhtZaxXBAVYGO6/oefaKcu0CTZYmtgMoCMU=; b=ai73vHB5pslQokKgfxwLRhKQRmPZ6sUUw039mJTmU9uOJovGuwPmgMGj9dAz2rAziT c7ng0J5lkVlKiICen5zKGf5nEZaIglgTO/QelndxlFuNHBYBiWYr/t/FCEbD4C6jzIZa 8Ndp9WeNOdd6fh6I2C1qaTbHSJ3bvWX4P2qv8AgBK1vToGB6o7XBsMHZD6a7ez7iM65+ otzsLXbm9xXjX454fQg1ClULsjpX3gdXFeV3eg6YTQgVrc2S1R0tUUU8cceXYjTnGWrU eZe6A1qiqANlWjDXuNoeOh4aD21Nfq3RGHMNld0uYhcoBkpBNerXZoFL4yOJ3gaqN4mY LVLg== X-Gm-Message-State: AJcUukfHaiXNGAwf6NgLUU/F9YcfxmG6TYdVo9hmFVP5Q5AVbowN51nT xb3snynUTeLIx5YsVWrWP5+Wj65h X-Google-Smtp-Source: ALg8bN5Y3X8/s8z9rtBjISXRVcRwXc6Um2t5DF62J199Lmn3HzJd4IGaFz2IvxaZMc+wG3xaExYluw== X-Received: by 2002:a5d:4d46:: with SMTP id a6mr4754543wru.28.1545444966857; Fri, 21 Dec 2018 18:16:06 -0800 (PST) Received: from lolita.yourcompany.com (188.139.62.94.rev.vodafone.pt. [94.62.139.188]) by smtp.gmail.com with ESMTPSA id d4sm16306468wrp.89.2018.12.21.18.16.04 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 21 Dec 2018 18:16:05 -0800 (PST) From: =?utf-8?B?Sm/Do28gVMOhdm9yYQ==?= To: Beatrix Klebe Subject: Re: bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode References: <20181221134829.29135.qmail@mail.muc.de> <87tvj68j15.fsf@gmail.com> Date: Sat, 22 Dec 2018 02:16:03 +0000 In-Reply-To: <87tvj68j15.fsf@gmail.com> (=?utf-8?Q?=22Jo=C3=A3o_T=C3=A1vor?= =?utf-8?Q?a=22's?= message of "Sat, 22 Dec 2018 01:08:54 +0000") Message-ID: <87pntu8fx8.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Spam-Score: 0.1 (/) X-Debbugs-Envelope-To: 33794 Cc: Alan Mackenzie , bea@klebe.blog, Stefan Monnier , 33794@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.9 (/) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable 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 () then brace should give you: int main () { } I attach the two patches for convenience, which you can also find in the scratch/fix-33794-extend-electric-layout-mode branch. Jo=C3=A3o --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=0001-Extend-electric-layout-mode-to-handle-more-complex-l.patch >From ab036bdedbb49ecc96d550b5e883e43bb03eaccc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20T=C3=A1vora?= 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 --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=0002-Rework-electric-layout-post-self-insert-function-bug.patch >From dfc19a04f5f455051d158648a963cb1fd8b91c67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20T=C3=A1vora?= 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 . "