From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Beatrix Klebe 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 14:43:41 -0500 Message-ID: References: <20181221134829.29135.qmail@mail.muc.de> Reply-To: bea@klebe.blog NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Trace: blaine.gmane.org 1545423929 10162 195.159.176.226 (21 Dec 2018 20:25:29 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Fri, 21 Dec 2018 20:25:29 +0000 (UTC) Cc: Alan Mackenzie , "Mx. Beatrix Klebe" , Stefan Monnier , 33794@debbugs.gnu.org To: =?UTF-8?Q?Jo=C3=A3o_?= =?UTF-8?Q?T=C3=A1vora?= Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Fri Dec 21 21:25:24 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 1gaRMK-0002Wm-1l for geb-bug-gnu-emacs@m.gmane.org; Fri, 21 Dec 2018 21:25:24 +0100 Original-Received: from localhost ([::1]:47744 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gaROQ-0003zX-Sf for geb-bug-gnu-emacs@m.gmane.org; Fri, 21 Dec 2018 15:27:34 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:41349) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gaROJ-0003zM-Ho for bug-gnu-emacs@gnu.org; Fri, 21 Dec 2018 15:27:28 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gaROI-0001m9-9r for bug-gnu-emacs@gnu.org; Fri, 21 Dec 2018 15:27:27 -0500 Original-Received: from debbugs.gnu.org ([208.118.235.43]:54552) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gaQiI-000052-NX; Fri, 21 Dec 2018 14:52:43 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1gaQiI-0006eV-9L; Fri, 21 Dec 2018 14:44:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Beatrix Klebe Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org, bug-cc-mode@gnu.org Resent-Date: Fri, 21 Dec 2018 19:44: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.154542144025556 (code B ref 33794); Fri, 21 Dec 2018 19:44:02 +0000 Original-Received: (at 33794) by debbugs.gnu.org; 21 Dec 2018 19:44:00 +0000 Original-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 Original-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 Original-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) In-Reply-To: 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:153701 Archived-At: 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) >> >