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 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 ";\\(?:;&?\\|[&|]\\)\\|\\_ - ;; ";; 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 ";\\(?:;&?\\|[&|]\\)\\|\\_ + ;; ";; 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)) > >