GNU bug report logs -
#55764
29.0.50; sh-mode: Support mksh's alternate case brace syntax
Previous Next
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.
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):
[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):
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):
[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):
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):
[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):
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):
>> 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.