From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: =?UTF-8?Q?Jo=C3=A3o_?= =?UTF-8?Q?T=C3=A1vora?= Newsgroups: gmane.emacs.bugs Subject: bug#33794: 26.1; electric-pair-mode breaks auto-newline minor mode of cc-mode Date: Fri, 21 Dec 2018 18:49:34 +0000 Message-ID: References: <20181221134829.29135.qmail@mail.muc.de> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable X-Trace: blaine.gmane.org 1545418088 1758 195.159.176.226 (21 Dec 2018 18:48:08 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Fri, 21 Dec 2018 18:48:08 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (windows-nt) Cc: Alan Mackenzie , bea@klebe.blog, Stefan Monnier , 33794@debbugs.gnu.org To: Beatrix Klebe Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Fri Dec 21 19:48:03 2018 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gaPq6-0000IN-JA for geb-bug-gnu-emacs@m.gmane.org; Fri, 21 Dec 2018 19:48:02 +0100 Original-Received: from localhost ([::1]:47267 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gaPsD-0000uH-91 for geb-bug-gnu-emacs@m.gmane.org; Fri, 21 Dec 2018 13:50:13 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:44569) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gaPs6-0000th-K1 for bug-gnu-emacs@gnu.org; Fri, 21 Dec 2018 13:50:07 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gaPs3-0006g3-Be for bug-gnu-emacs@gnu.org; Fri, 21 Dec 2018 13:50:06 -0500 Original-Received: from debbugs.gnu.org ([208.118.235.43]:54528) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gaPs3-0006fj-52; Fri, 21 Dec 2018 13:50:03 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1gaPs2-0005FG-6i; Fri, 21 Dec 2018 13:50:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: =?UTF-8?Q?Jo=C3=A3o_?= =?UTF-8?Q?T=C3=A1vora?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org, bug-cc-mode@gnu.org Resent-Date: Fri, 21 Dec 2018 18:50:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 33794 X-GNU-PR-Package: emacs,cc-mode X-GNU-PR-Keywords: Original-Received: via spool by 33794-submit@debbugs.gnu.org id=B33794.154541818820139 (code B ref 33794); Fri, 21 Dec 2018 18:50:02 +0000 Original-Received: (at 33794) by debbugs.gnu.org; 21 Dec 2018 18:49:48 +0000 Original-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 Original-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 Original-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) Original-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) In-Reply-To: (Beatrix Klebe's message of "Fri, 21 Dec 2018 11:00:10 -0500") X-Antivirus: AVG (VPS 181221-6, 21-12-2018), Outbound message X-Antivirus-Status: Clean X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:153694 Archived-At: 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