GNU bug report logs - #55764
29.0.50; sh-mode: Support mksh's alternate case brace syntax

Previous Next

Package: emacs;

Reported by: Visuwesh <visuweshm <at> gmail.com>

Date: Thu, 2 Jun 2022 13:35:02 UTC

Severity: wishlist

Tags: patch

Found in version 29.0.50

Done: Stefan Monnier <monnier <at> iro.umontreal.ca>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 55764 in the body.
You can then email your comments to 55764 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#55764; Package emacs. (Thu, 02 Jun 2022 13:35:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Visuwesh <visuweshm <at> gmail.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Thu, 02 Jun 2022 13:35:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Visuwesh <visuweshm <at> gmail.com>
To: bug-gnu-emacs <at> gnu.org
Subject: 29.0.50; sh-mode: Support mksh's alternate case brace syntax
Date: Thu, 02 Jun 2022 19:03:47 +0530
[Message part 1 (text/plain, inline)]
mksh and OpenBSD's ksh support an alternative case syntax for historical
reasons [1],

    case $i {
    *pattern) do ;;
    *pattern2) do2 ;;
    }


Currently, sh-mode cannot handle this and the easy way out of writing a
semicolon after $i is out since,

   % case "foo"; { *o) echo 1;; }
   /bin/mksh: syntax error: unexpected ';'

I came with the attached patch after a bit of trial and error but I'm
not sure if it is the right way to do it.

[mksh-braces.patch (text/x-diff, inline)]
diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el
index 4d2554c087..588d9038e5 100644
--- a/lisp/progmodes/sh-script.el
+++ b/lisp/progmodes/sh-script.el
@@ -1971,9 +1971,10 @@
                              (sh-var-value 'sh-indent-for-case-label)))
     (`(:before . ,(or "(" "{" "[" "while" "if" "for" "case"))
      (cond
-      ((and (equal token "{") (smie-rule-parent-p "for"))
+      ((and (equal token "{") (or (smie-rule-parent-p "for")
+                                  (smie-rule-parent-p "case")))
        (let ((data (smie-backward-sexp "in")))
-         (when (equal (nth 2 data) "for")
+         (when (member (nth 2 data) '("for" "case"))
            `(column . ,(smie-indent-virtual)))))
       ((not (smie-rule-prev-p "&&" "||" "|"))
        (when (smie-rule-hanging-p)
[Message part 3 (text/plain, inline)]
--

[1] Here's what the mksh manual says,

    For historical reasons, open and close braces may be used instead
    of in and esac, for example: “case $foo { (ba[rz]|blah) date ;; }”

and OpenBSD's ksh manual says,

    For historical reasons, open and close braces may be used instead of
    in and esac e.g. case $foo { *) echo bar; }.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#55764; Package emacs. (Thu, 02 Jun 2022 13:41:01 GMT) Full text and rfc822 format available.

Message #8 received at 55764 <at> debbugs.gnu.org (full text, mbox):

From: Lars Ingebrigtsen <larsi <at> gnus.org>
To: Visuwesh <visuweshm <at> gmail.com>
Cc: 55764 <at> debbugs.gnu.org, Stefan Monnier <monnier <at> iro.umontreal.ca>
Subject: Re: bug#55764: 29.0.50; sh-mode: Support mksh's alternate case
 brace syntax
Date: Thu, 02 Jun 2022 15:40:08 +0200
Visuwesh <visuweshm <at> gmail.com> writes:

> mksh and OpenBSD's ksh support an alternative case syntax for historical
> reasons [1],
>
>     case $i {
>     *pattern) do ;;
>     *pattern2) do2 ;;
>     }
>
> Currently, sh-mode cannot handle this and the easy way out of writing a
> semicolon after $i is out since,
>
>    % case "foo"; { *o) echo 1;; }
>    /bin/mksh: syntax error: unexpected ';'
>
> I came with the attached patch after a bit of trial and error but I'm
> not sure if it is the right way to do it.

I think that might make sense, but perhaps Stefan has some comments here
(added to the CCs).

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#55764; Package emacs. (Thu, 02 Jun 2022 14:02:02 GMT) Full text and rfc822 format available.

Message #11 received at 55764 <at> debbugs.gnu.org (full text, mbox):

From: Visuwesh <visuweshm <at> gmail.com>
To: Lars Ingebrigtsen <larsi <at> gnus.org>
Cc: 55764 <at> debbugs.gnu.org, Stefan Monnier <monnier <at> iro.umontreal.ca>
Subject: Re: bug#55764: 29.0.50; sh-mode: Support mksh's alternate case
 brace syntax
Date: Thu, 02 Jun 2022 19:31:18 +0530
[Message part 1 (text/plain, inline)]
[வியாழன் ஜூன் 02, 2022] Lars Ingebrigtsen wrote:

> Visuwesh <visuweshm <at> gmail.com> writes:
>
>> mksh and OpenBSD's ksh support an alternative case syntax for historical
>> reasons [1],
>>
>>     case $i {
>>     *pattern) do ;;
>>     *pattern2) do2 ;;
>>     }
>>
>> Currently, sh-mode cannot handle this and the easy way out of writing a
>> semicolon after $i is out since,
>>
>>    % case "foo"; { *o) echo 1;; }
>>    /bin/mksh: syntax error: unexpected ';'
>>
>> I came with the attached patch after a bit of trial and error but I'm
>> not sure if it is the right way to do it.
>
> I think that might make sense, but perhaps Stefan has some comments here
> (added to the CCs).

To no one's surprise, the patch is not the right approach.  IIUC, when I
use braces, *pattern) thingies are not recognised as "case-)" anymore so
sh-indent-for-case-label does not get applied.  I tried a bit more but I
only got it to respect the first line but still it is definitely not the
right approach,

[mksh-braces.patch (text/x-diff, inline)]
diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el
index 4d2554c087..96ff8e8627 100644
--- a/lisp/progmodes/sh-script.el
+++ b/lisp/progmodes/sh-script.el
@@ -1971,9 +1971,9 @@ sh-smie-sh-rules
                              (sh-var-value 'sh-indent-for-case-label)))
     (`(:before . ,(or "(" "{" "[" "while" "if" "for" "case"))
      (cond
-      ((and (equal token "{") (smie-rule-parent-p "for"))
+      ((and (equal token "{") (smie-rule-parent-p "for" "case"))
        (let ((data (smie-backward-sexp "in")))
-         (when (equal (nth 2 data) "for")
+         (when (member (nth 2 data) '("for" "case"))
            `(column . ,(smie-indent-virtual)))))
       ((not (smie-rule-prev-p "&&" "||" "|"))
        (when (smie-rule-hanging-p)
@@ -2021,10 +2021,13 @@ sh-smie-sh-rules
     ('(:after . "in") (sh-var-value 'sh-indent-for-case-label))
     ;; sh-indent-for-continuation: Line continuations are handled differently.
     (`(:after . ,(or "(" "{" "["))
-     (if (not (looking-at ".[ \t]*[^\n \t#]"))
-         (sh-var-value 'sh-indent-after-open)
-       (goto-char (1- (match-end 0)))
-       `(column . ,(current-column))))
+     (cond
+      ((smie-rule-parent-p "case")
+       (sh-var-value 'sh-indent-for-case-label))
+      ((not (looking-at ".[ \t]*[^\n \t#]"))
+       (sh-var-value 'sh-indent-after-open))
+      (t (goto-char (1- (match-end 0)))
+         `(column . ,(current-column)))))
     ;; sh-indent-after-function: we don't handle it differently.
     ))
 

Severity set to 'wishlist' from 'normal' Request was from Stefan Kangas <stefan <at> marxist.se> to control <at> debbugs.gnu.org. (Sun, 19 Jun 2022 13:54:04 GMT) Full text and rfc822 format available.

Added tag(s) patch. Request was from Stefan Kangas <stefan <at> marxist.se> to control <at> debbugs.gnu.org. (Tue, 28 Jun 2022 21:21:03 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#55764; Package emacs. (Sun, 01 Oct 2023 02:32:01 GMT) Full text and rfc822 format available.

Message #18 received at 55764 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Kangas <stefankangas <at> gmail.com>
To: Visuwesh <visuweshm <at> gmail.com>
Cc: Lars Ingebrigtsen <larsi <at> gnus.org>, 55764 <at> debbugs.gnu.org,
 Stefan Monnier <monnier <at> iro.umontreal.ca>
Subject: Re: bug#55764: 29.0.50;
 sh-mode: Support mksh's alternate case brace syntax
Date: Sat, 30 Sep 2023 19:30:53 -0700
Visuwesh <visuweshm <at> gmail.com> writes:

> [வியாழன் ஜூன் 02, 2022] Lars Ingebrigtsen wrote:
>
>> Visuwesh <visuweshm <at> gmail.com> writes:
>>
>>> mksh and OpenBSD's ksh support an alternative case syntax for historical
>>> reasons [1],
>>>
>>>     case $i {
>>>     *pattern) do ;;
>>>     *pattern2) do2 ;;
>>>     }
>>>
>>> Currently, sh-mode cannot handle this and the easy way out of writing a
>>> semicolon after $i is out since,
>>>
>>>    % case "foo"; { *o) echo 1;; }
>>>    /bin/mksh: syntax error: unexpected ';'
>>>
>>> I came with the attached patch after a bit of trial and error but I'm
>>> not sure if it is the right way to do it.
>>
>> I think that might make sense, but perhaps Stefan has some comments here
>> (added to the CCs).
>
> To no one's surprise, the patch is not the right approach.  IIUC, when I
> use braces, *pattern) thingies are not recognised as "case-)" anymore so
> sh-indent-for-case-label does not get applied.  I tried a bit more but I
> only got it to respect the first line but still it is definitely not the
> right approach,

Did you make any further progress here?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#55764; Package emacs. (Sun, 01 Oct 2023 03:38:01 GMT) Full text and rfc822 format available.

Message #21 received at 55764 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Visuwesh <visuweshm <at> gmail.com>
Cc: Lars Ingebrigtsen <larsi <at> gnus.org>, 55764 <at> debbugs.gnu.org
Subject: Re: bug#55764: 29.0.50; sh-mode: Support mksh's alternate case
 brace syntax
Date: Sat, 30 Sep 2023 23:37:28 -0400
[Message part 1 (text/plain, inline)]
> To no one's surprise, the patch is not the right approach.  IIUC, when I
> use braces, *pattern) thingies are not recognised as "case-)" anymore so
> sh-indent-for-case-label does not get applied.  I tried a bit more but I
> only got it to respect the first line but still it is definitely not the
> right approach,

The first part of the puzzle is to fix the syntax-category of the `)` so
it's recognized as a "case-)" rather than a normal ("matched") paren.

The patch below seems to do the trick.


        Stefan


[openbsd-case.patch (text/x-diff, inline)]
diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el
index cc521cb0591..b34be83367a 100644
--- a/lisp/progmodes/sh-script.el
+++ b/lisp/progmodes/sh-script.el
@@ -1053,7 +1053,8 @@ 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'.
-                    (and (looking-at ";\\(?:;&?\\|[&|]\\)\\|\\_<in")
+                    ;; 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
@@ -2053,9 +2054,9 @@ sh-smie-sh-rules
                              (sh-var-value 'sh-indent-for-case-label)))
     (`(:before . ,(or "(" "{" "[" "while" "if" "for" "case"))
      (cond
-      ((and (equal token "{") (smie-rule-parent-p "for"))
+      ((and (equal token "{") (smie-rule-parent-p "for" "case"))
        (let ((data (smie-backward-sexp "in")))
-         (when (equal (nth 2 data) "for")
+         (when (member (nth 2 data) '("for" "case"))
            `(column . ,(smie-indent-virtual)))))
       ((not (smie-rule-prev-p "&&" "||" "|"))
        (when (smie-rule-hanging-p)
diff --git a/test/manual/indent/shell.sh b/test/manual/indent/shell.sh
index 5b3fb0e66fb..42a981d312e 100755
--- a/test/manual/indent/shell.sh
+++ b/test/manual/indent/shell.sh
@@ -189,3 +189,10 @@ bar ()
 
     fi
 }
+
+case $i {                       # Bug#55764
+    *pattern)
+        (cd .; echo hi);
+        do1 ;;
+    *pattern2) do2 ;;
+}

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#55764; Package emacs. (Wed, 10 Jan 2024 22:25:01 GMT) Full text and rfc822 format available.

Message #24 received at 55764 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Kangas <stefankangas <at> gmail.com>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: Lars Ingebrigtsen <larsi <at> gnus.org>, 55764 <at> debbugs.gnu.org,
 Visuwesh <visuweshm <at> gmail.com>
Subject: Re: bug#55764: 29.0.50;
 sh-mode: Support mksh's alternate case brace syntax
Date: Wed, 10 Jan 2024 14:24:34 -0800
Stefan Monnier <monnier <at> iro.umontreal.ca> writes:

>> To no one's surprise, the patch is not the right approach.  IIUC, when I
>> use braces, *pattern) thingies are not recognised as "case-)" anymore so
>> sh-indent-for-case-label does not get applied.  I tried a bit more but I
>> only got it to respect the first line but still it is definitely not the
>> right approach,
>
> The first part of the puzzle is to fix the syntax-category of the `)` so
> it's recognized as a "case-)" rather than a normal ("matched") paren.
>
> The patch below seems to do the trick.

If you think it looks good, then please install.  Nothing stood out
when I read it over, FWIW.

>
>
>         Stefan
>
>
> diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el
> index cc521cb0591..b34be83367a 100644
> --- a/lisp/progmodes/sh-script.el
> +++ b/lisp/progmodes/sh-script.el
> @@ -1053,7 +1053,8 @@ 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'.
> -                    (and (looking-at ";\\(?:;&?\\|[&|]\\)\\|\\_<in")
> +                    ;; 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
> @@ -2053,9 +2054,9 @@ sh-smie-sh-rules
>                               (sh-var-value 'sh-indent-for-case-label)))
>      (`(:before . ,(or "(" "{" "[" "while" "if" "for" "case"))
>       (cond
> -      ((and (equal token "{") (smie-rule-parent-p "for"))
> +      ((and (equal token "{") (smie-rule-parent-p "for" "case"))
>         (let ((data (smie-backward-sexp "in")))
> -         (when (equal (nth 2 data) "for")
> +         (when (member (nth 2 data) '("for" "case"))
>             `(column . ,(smie-indent-virtual)))))
>        ((not (smie-rule-prev-p "&&" "||" "|"))
>         (when (smie-rule-hanging-p)
> diff --git a/test/manual/indent/shell.sh b/test/manual/indent/shell.sh
> index 5b3fb0e66fb..42a981d312e 100755
> --- a/test/manual/indent/shell.sh
> +++ b/test/manual/indent/shell.sh
> @@ -189,3 +189,10 @@ bar ()
>
>      fi
>  }
> +
> +case $i {                       # Bug#55764
> +    *pattern)
> +        (cd .; echo hi);
> +        do1 ;;
> +    *pattern2) do2 ;;
> +}




Reply sent to Stefan Monnier <monnier <at> iro.umontreal.ca>:
You have taken responsibility. (Fri, 12 Jan 2024 03:14:01 GMT) Full text and rfc822 format available.

Notification sent to Visuwesh <visuweshm <at> gmail.com>:
bug acknowledged by developer. (Fri, 12 Jan 2024 03:14:01 GMT) Full text and rfc822 format available.

Message #29 received at 55764-done <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Stefan Kangas <stefankangas <at> gmail.com>
Cc: Lars Ingebrigtsen <larsi <at> gnus.org>, 55764-done <at> debbugs.gnu.org,
 Visuwesh <visuweshm <at> gmail.com>
Subject: Re: bug#55764: 29.0.50; sh-mode: Support mksh's alternate case
 brace syntax
Date: Thu, 11 Jan 2024 22:13:10 -0500
>> The patch below seems to do the trick.
> If you think it looks good, then please install.  Nothing stood out
> when I read it over, FWIW.

Thanks for the reminder.  Pushed.
Closing,


        Stefan





bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Fri, 09 Feb 2024 12:24:14 GMT) Full text and rfc822 format available.

This bug report was last modified 1 year and 92 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.