Package: emacs;
To reply to this bug, email your comments to 78159 AT debbugs.gnu.org.
Toggle the display of automated, internal messages from the tracker.
View this report as an mbox folder, status mbox, maintainer mbox
bug-gnu-emacs <at> gnu.org
:bug#78159
; Package emacs
.
(Wed, 30 Apr 2025 06:57:02 GMT) Full text and rfc822 format available.john.ciolfi.32 <at> gmail.com
:bug-gnu-emacs <at> gnu.org
.
(Wed, 30 Apr 2025 06:57:02 GMT) Full text and rfc822 format available.Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
From: John Ciolfi <john.ciolfi.32 <at> gmail.com> To: <bug-gnu-emacs <at> gnu.org> Subject: shell-script indent regression in Emacs 30 Date: Tue, 29 Apr 2025 15:02:11 -0400
Hi In the following shell-script, the use of subshell, in this case, wrapping the "id" command in parens, causes Emacs 30 to incorrectly indent the lines that follow use of subshells. Notice if you remove the parens from id indentation is correct. The behavior is correct in Emacs 29, but not Emacs 30. This issue can shift all lines in a shell script following the use of a subshell. ---- example.sh ---- #!/bin/bash haveid1 () { (id) 2> /dev/null 1>&2 if [ $? -eq 0 ]; then echo "haveid1: yes" else echo "haveid1: no" fi } haveid2 () { id 2> /dev/null 1>&2 if [ $? -eq 0 ]; then echo "haveid2: yes" else echo "haveid2: no" fi } In GNU Emacs 30.1 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.38, cairo version 1.16.0) of 2025-04-04, modified by Debian built on sbuild Windowing system distributor 'The X.Org Foundation', version 11.0.12101006 System Description: Debian GNU/Linux 12 (bookworm) Configured using: 'configure --build x86_64-linux-gnu --prefix=/usr --sharedstatedir=/var/lib --libexecdir=/usr/libexec --localstatedir=/var/lib --infodir=/usr/share/info --mandir=/usr/share/man --with-libsystemd --with-pop=yes --enable-locallisppath=/etc/emacs:/usr/local/share/emacs/30.1/site-lisp:/usr/local/share/emacs/site-lisp:/usr/share/emacs/30.1/site-lisp:/usr/share/emacs/site-lisp --with-sound=alsa --without-gconf --with-mailutils --build x86_64-linux-gnu --prefix=/usr --sharedstatedir=/var/lib --libexecdir=/usr/libexec --localstatedir=/var/lib --infodir=/usr/share/info --mandir=/usr/share/man --with-libsystemd --with-pop=yes --enable-locallisppath=/etc/emacs:/usr/local/share/emacs/30.1/site-lisp:/usr/local/share/emacs/site-lisp:/usr/share/emacs/30.1/site-lisp:/usr/share/emacs/site-lisp --with-sound=alsa --without-gconf --with-mailutils --with-cairo --with-x=yes --with-x-toolkit=gtk3 --with-toolkit-scroll-bars 'CFLAGS=-g -O2 -ffile-prefix-map=/build/reproducible-path/emacs-30.1+1=. -fstack-protector-strong -Wformat -Werror=format-security -Wall' 'CPPFLAGS=-Wdate-time -D_FORTIFY_SOURCE=2' LDFLAGS=-Wl,-z,relro' Configured features: ACL CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GPM GSETTINGS HARFBUZZ JPEG LCMS2 LIBOTF LIBSELINUX LIBSYSTEMD LIBXML2 M17N_FLT MODULES NATIVE_COMP NOTIFY INOTIFY PDUMPER PNG RSVG SECCOMP SOUND SQLITE3 THREADS TIFF TOOLKIT_SCROLL_BARS TREE_SITTER WEBP X11 XDBE XIM XINPUT2 XPM GTK3 ZLIB Important settings: value of $LANG: en_US.UTF-8 locale-coding-system: utf-8-unix Major mode: Shell-script Minor modes in effect: sh-electric-here-document-mode: t tooltip-mode: t global-eldoc-mode: t show-paren-mode: t electric-indent-mode: t mouse-wheel-mode: t tool-bar-mode: t menu-bar-mode: t file-name-shadow-mode: t global-font-lock-mode: t font-lock-mode: t blink-cursor-mode: t minibuffer-regexp-mode: t line-number-mode: t indent-tabs-mode: t transient-mark-mode: t auto-composition-mode: t auto-encryption-mode: t auto-compression-mode: t Load-path shadows: None found. Features: (shadow sort mail-extr emacsbug pulse color xref project oc-basic org-element org-persist org-id org-refile org-element-ast inline avl-tree generator ol-eww eww xdg url-queue mm-url ol-rmail ol-mhe ol-irc ol-info ol-gnus nnselect gnus-art mm-uu mml2015 mm-view mml-smime smime gnutls dig gnus-sum shr pixel-fill kinsoku url-file svg dom gnus-group gnus-undo gnus-start gnus-dbus dbus compile comp-run xml gnus-cloud nnimap nnmail browse-url url url-proxy url-privacy url-expand url-methods url-history url-cookie generate-lisp-file url-domsuf url-util url-parse auth-source cl-seq eieio eieio-core cl-macs json map url-vars mail-source utf7 nnoo parse-time gnus-spec gnus-int gnus-range message sendmail mailcap yank-media puny rfc822 mml mml-sec password-cache epa derived epg rfc6068 epg-config mm-decode mm-bodies mm-encode mail-parse rfc2231 rfc2047 rfc2045 ietf-drums mailabbrev gmm-utils mailheader gnus-win gnus nnheader gnus-util mail-utils range mm-util mail-prsvr wid-edit ol-docview doc-view filenotify image-mode exif dired dired-loaddefs ol-bibtex bibtex iso8601 ol-bbdb ol-w3m ol-doi org-link-doi org ob ob-tangle ob-ref ob-lob ob-table ob-exp org-macro org-src ob-comint org-pcomplete pcomplete comint ansi-osc ansi-color ring org-list org-footnote org-faces org-entities noutline outline icons org-version ob-emacs-lisp ob-core ob-eval org-cycle org-table ol org-fold org-fold-core org-keys oc org-loaddefs cal-menu calendar cal-loaddefs org-compat org-macs format-spec misearch multi-isearch cl-print byte-opt gv bytecomp byte-compile time-date subr-x pcase edebug debug backtrace jka-compr cl-extra shortdoc text-property-search comp-common help-fns radix-tree help-mode thingatpt find-func sh-script rx smie treesit cl-loaddefs cl-lib executable rmc iso-transl tooltip cconv eldoc paren electric uniquify ediff-hook vc-hooks lisp-float-type elisp-mode mwheel term/x-win x-win term/common-win x-dnd touch-screen tool-bar dnd fontset image regexp-opt fringe tabulated-list replace newcomment text-mode lisp-mode prog-mode register page tab-bar menu-bar rfn-eshadow isearch easymenu timer select scroll-bar mouse jit-lock font-lock syntax font-core term/tty-colors frame minibuffer nadvice seq simple cl-generic indonesian philippine 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 emoji-zwj charscript charprop case-table epa-hook jka-cmpr-hook help abbrev obarray oclosure cl-preloaded button loaddefs theme-loaddefs faces cus-face macroexp files window text-properties overlay sha1 md5 base64 format env code-pages mule custom widget keymap hashtable-print-readable backquote threads dbusbind inotify lcms2 dynamic-setting system-font-setting font-render-setting cairo gtk x-toolkit xinput2 x multi-tty move-toolbar make-network-process native-compile emacs) Memory information: ((conses 16 434138 109987) (symbols 48 22590 4) (strings 32 107934 6084) (string-bytes 1 3306214) (vectors 16 63088) (vector-slots 8 1428105 82431) (floats 8 870 285) (intervals 56 6273 2078) (buffers 992 21))
bug-gnu-emacs <at> gnu.org
:bug#78159
; Package emacs
.
(Wed, 30 Apr 2025 14:08:03 GMT) Full text and rfc822 format available.Message #8 received at 78159 <at> debbugs.gnu.org (full text, mbox):
From: John C <john.ciolfi.32 <at> gmail.com> To: 78159 <at> debbugs.gnu.org Subject: RE: shell-script indent regression in Emacs 30 Date: Wed, 30 Apr 2025 08:49:28 -0400
[Message part 1 (text/plain, inline)]
Hi I debugged this a little and see the regression occurred when sh-script.el sh-font-lock-paren was changed in Emacs 30 to have: ;; Also recognize OpenBSD's case X { ... } (bug#55764). (and (looking-at ";\\(?:;&?\\|[&|]\\)\\|\\_<in\\|.{") where the Emacs 29 had: (and (looking-at ";[;&]\\|\\_<in") when I modify Emacs 30 sh-script.el to revert this one line back to the Emacs 29 content, we get the correct answer. I suspect reverting this line is not the right thing to do. Rather, I hope it helps someone find the solution. Thanks John
[Message part 2 (text/html, inline)]
bug-gnu-emacs <at> gnu.org
:bug#78159
; Package emacs
.
(Wed, 30 Apr 2025 14:08:03 GMT) Full text and rfc822 format available.Message #11 received at 78159 <at> debbugs.gnu.org (full text, mbox):
From: John C <john.ciolfi.32 <at> gmail.com> To: 78159 <at> debbugs.gnu.org Subject: Re: shell-script indent regression in Emacs 30 Date: Wed, 30 Apr 2025 09:15:59 -0400
[Message part 1 (text/plain, inline)]
Hi One more observation is that it's the subshell, code in parens, that's not handled correctly. In the following example, the indentation in haveid3 is incorrect so the issue is not due to the std handle redirects. #!/bin/bash haveid1 () { (id) 2> /dev/null 1>&2 if [ $? -eq 0 ]; then echo "haveid1: yes" else echo "haveid1: no" fi x = 1 } haveid2 () { id 2> /dev/null 1>&2 if [ $? -eq 0 ]; then echo "haveid2: yes" else echo "haveid2: no" fi } haveid3 () { (id) if [ $? -eq 0 ]; then echo "haveid2: yes" else echo "haveid2: no" fi } On Wed, Apr 30, 2025 at 8:49 AM John C <john.ciolfi.32 <at> gmail.com> wrote: > Hi > > I debugged this a little and see the regression occurred when > sh-script.el sh-font-lock-paren was changed in Emacs 30 to have: > > ;; Also recognize OpenBSD's case X { ... } (bug#55764). > (and (looking-at ";\\(?:;&?\\|[&|]\\)\\|\\_<in\\|.{") > > where the Emacs 29 had: > > > (and (looking-at ";[;&]\\|\\_<in") > > when I modify Emacs 30 sh-script.el to revert this one line back to the > Emacs 29 content, we get the correct answer. I suspect reverting this line > is not the right thing to do. Rather, I hope it helps someone find the > solution. > > Thanks > John >
[Message part 2 (text/html, inline)]
bug-gnu-emacs <at> gnu.org
:bug#78159
; Package emacs
.
(Wed, 30 Apr 2025 14:24:01 GMT) Full text and rfc822 format available.Message #14 received at 78159 <at> debbugs.gnu.org (full text, mbox):
From: Eli Zaretskii <eliz <at> gnu.org> To: John C <john.ciolfi.32 <at> gmail.com>, Stefan Monnier <monnier <at> iro.umontreal.ca> Cc: 78159 <at> debbugs.gnu.org Subject: Re: bug#78159: shell-script indent regression in Emacs 30 Date: Wed, 30 Apr 2025 17:23:03 +0300
> From: John C <john.ciolfi.32 <at> gmail.com> > Date: Wed, 30 Apr 2025 08:49:28 -0400 > > I debugged this a little and see the regression occurred when sh-script.el sh-font-lock-paren was changed > in Emacs 30 to have: > > ;; Also recognize OpenBSD's case X { ... } (bug#55764). > (and (looking-at ";\\(?:;&?\\|[&|]\\)\\|\\_<in\\|.{") > > where the Emacs 29 had: > > (and (looking-at ";[;&]\\|\\_<in") > > when I modify Emacs 30 sh-script.el to revert this one line back to the Emacs 29 content, we get the correct > answer. I suspect reverting this line is not the right thing to do. Rather, I hope it helps someone find the > solution. Stefan, any suggestions?
bug-gnu-emacs <at> gnu.org
:bug#78159
; Package emacs
.
(Thu, 01 May 2025 21:26:02 GMT) Full text and rfc822 format available.Message #17 received at 78159 <at> debbugs.gnu.org (full text, mbox):
From: Stefan Monnier <monnier <at> iro.umontreal.ca> To: John Ciolfi <john.ciolfi.32 <at> gmail.com> Cc: 78159 <at> debbugs.gnu.org Subject: Re: bug#78159: shell-script indent regression in Emacs 30 Date: Thu, 01 May 2025 17:24:54 -0400
> > haveid1 () { > (id) 2> /dev/null 1>&2 > if [ $? -eq 0 ]; then > echo "haveid1: yes" > else > echo "haveid1: no" > fi > } > > haveid2 () { > id 2> /dev/null 1>&2 > if [ $? -eq 0 ]; then > echo "haveid2: yes" > else > echo "haveid2: no" > fi > } Oh, yes, it's due to the change to accept: case FOO { (id) ...;; (other) ...;; } The previous code accepted only case FOO in (id) ...;; (other) ...;; esac and it checked only the presence of `in` without checking that it's part of a case statement, which was sufficient because `in` doesn't seem to ever occur elsewhere than in case statements. The new code similarly fails to check that the `{` is part of a case statement but `{` doesn't enjoy this same property as `in`, hence the bug you're seeing. A crude hack could be something like the patch below, but we should try to do a more thorough job of deciding if this `{` is part of case statement or not. Stefan diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el index 287f0501350..b5ccc5507e5 100644 --- a/lisp/progmodes/sh-script.el +++ b/lisp/progmodes/sh-script.el @@ -1065,14 +1065,19 @@ sh-font-lock-paren ;; a normal command rather than the real `in' keyword. ;; I.e. we should look back to try and find the ;; corresponding `case'. - ;; Also recognize OpenBSD's case X { ... } (bug#55764). - (and (looking-at ";\\(?:;&?\\|[&|]\\)\\|\\_<in\\|.{") - ;; ";; esac )" is a case that looks - ;; like a case-pattern but it's really just a close - ;; paren after a case statement. I.e. if we skipped - ;; over `esac' just now, we're not looking - ;; at a case-pattern. - (not (looking-at "..[ \t\n]+esac[^[:word:]_]")))) + (cond + ((looking-at ";\\(?:;&?\\|[&|]\\)\\|\\_<in") + ;; ";; esac )" is a case that looks + ;; like a case-pattern but it's really just a close + ;; paren after a case statement. I.e. if we skipped + ;; over `esac' just now, we're not looking + ;; at a case-pattern. + (not (looking-at "..[ \t\n]+esac[^[:word:]_]"))) + ;; Also recognize OpenBSD's case X { ... } (bug#55764). + ((looking-at ".{") + (save-excursion + ;; Try and make sure this is a case statement! + (re-search-backward "esac" (pos-bol) t))))) (progn (when open (put-text-property open (1+ open) 'syntax-table sh-st-punc))
bug-gnu-emacs <at> gnu.org
:bug#78159
; Package emacs
.
(Thu, 08 May 2025 06:26:03 GMT) Full text and rfc822 format available.Message #20 received at 78159 <at> debbugs.gnu.org (full text, mbox):
From: John C <john.ciolfi.32 <at> gmail.com> To: Stefan Monnier <monnier <at> iro.umontreal.ca> Cc: 78159 <at> debbugs.gnu.org Subject: Re: bug#78159: shell-script indent regression in Emacs 30 Date: Wed, 7 May 2025 15:48:09 -0400
[Message part 1 (text/plain, inline)]
I tried the patch on Emacs 30.1 sh-script.el and it doesn't seem to work? Here's what I get: #!/bin/bash haveid1 () { (id) 2> /dev/null 1>&2 if [ $? -eq 0 ]; then echo "haveid1: yes" else echo "haveid1: no" fi } haveid2 () { id 2> /dev/null 1>&2 if [ $? -eq 0 ]; then echo "haveid2: yes" else echo "haveid2: no" fi } haveid3 () { (id) if [ $? -eq 0 ]; then echo "haveid1: yes" else echo "haveid1: no" fi } On Thu, May 1, 2025 at 5:25 PM Stefan Monnier <monnier <at> iro.umontreal.ca> wrote: > > > > haveid1 () { > > (id) 2> /dev/null 1>&2 > > if [ $? -eq 0 ]; then > > echo "haveid1: yes" > > else > > echo "haveid1: no" > > fi > > } > > > > haveid2 () { > > id 2> /dev/null 1>&2 > > if [ $? -eq 0 ]; then > > echo "haveid2: yes" > > else > > echo "haveid2: no" > > fi > > } > > Oh, yes, it's due to the change to accept: > > case FOO { > (id) ...;; > (other) ...;; > } > > The previous code accepted only > > case FOO in > (id) ...;; > (other) ...;; > esac > > and it checked only the presence of `in` without checking that it's part > of a case statement, which was sufficient because `in` doesn't seem to > ever occur elsewhere than in case statements. > > The new code similarly fails to check that the `{` is part of a case > statement but `{` doesn't enjoy this same property as `in`, hence the > bug you're seeing. > > A crude hack could be something like the patch below, but we should try > to do a more thorough job of deciding if this `{` is part of case > statement or not. > > > Stefan > > > diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el > index 287f0501350..b5ccc5507e5 100644 > --- a/lisp/progmodes/sh-script.el > +++ b/lisp/progmodes/sh-script.el > @@ -1065,14 +1065,19 @@ sh-font-lock-paren > ;; a normal command rather than the real `in' keyword. > ;; I.e. we should look back to try and find the > ;; corresponding `case'. > - ;; Also recognize OpenBSD's case X { ... } > (bug#55764). > - (and (looking-at ";\\(?:;&?\\|[&|]\\)\\|\\_<in\\|.{") > - ;; ";; esac )" is a case that looks > - ;; like a case-pattern but it's really just a > close > - ;; paren after a case statement. I.e. if we > skipped > - ;; over `esac' just now, we're not looking > - ;; at a case-pattern. > - (not (looking-at "..[ \t\n]+esac[^[:word:]_]")))) > + (cond > + ((looking-at ";\\(?:;&?\\|[&|]\\)\\|\\_<in") > + ;; ";; esac )" is a case that looks > + ;; like a case-pattern but it's really just a close > + ;; paren after a case statement. I.e. if we skipped > + ;; over `esac' just now, we're not looking > + ;; at a case-pattern. > + (not (looking-at "..[ \t\n]+esac[^[:word:]_]"))) > + ;; Also recognize OpenBSD's case X { ... } > (bug#55764). > + ((looking-at ".{") > + (save-excursion > + ;; Try and make sure this is a case statement! > + (re-search-backward "esac" (pos-bol) t))))) > (progn > (when open > (put-text-property open (1+ open) 'syntax-table > sh-st-punc)) > >
[Message part 2 (text/html, inline)]
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.