emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Issue with bash new syntax.


From: Stefan Monnier
Subject: Re: Issue with bash new syntax.
Date: Tue, 26 Jan 2021 17:53:42 -0500
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)

> I am observing some issues with the indentation of the modern for loop
> syntax in bash:
>
> for ((it=0; it<${limit}; ++it)) 
>       {
>               echo "whatever $it"
>       }
>
>
> The question-issue comes in two parts.
>
> Question: How can I configure to remove the extra indentation before `{`?
>    In cc-mode there is a procedure, a bit cumbersome, but working. But
>    sh-mode does not have such a thing.

You can't really configure it easily, currently.
The patch below should take care of it, tho.

> Issue:
>    When this loop is nested inside an if or another for loop the
>    closing indentation seems to be broken
>
> for dim in ${dims[@]}; do
>          for bs in ${blocksizes[@]}; do
>                  if [ something ]; then
>                          for ((it=0; it<${ARGS[R]}; ++it)) 
>                                  {
>                                          whatever...
>                                  }
> -->                             else
>                                          somethingelse
> -->                     fi
> -->                     done
> -->                     done
>
> Should I report a bug for this?

Yes.  The problem is that sh expects `for` to be followed by `do...done`
before the loop is over, so as far as `sh-mode` is concerned we're still
in the part of the `for` loop before the `do...done`.  It's not trivial
to fix, so better make it a real bug report so it doesn't get lost.


        Stefan


diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el
index cc045a1b2d..a8e7c9f70e 100644
--- a/lisp/progmodes/sh-script.el
+++ b/lisp/progmodes/sh-script.el
@@ -1957,12 +1957,17 @@ sh-smie-sh-rules
     ('(:after . "case-)") (- (sh-var-value 'sh-indent-for-case-alt)
                              (sh-var-value 'sh-indent-for-case-label)))
     (`(:before . ,(or "(" "{" "[" "while" "if" "for" "case"))
-     (if (not (smie-rule-prev-p "&&" "||" "|"))
-         (when (smie-rule-hanging-p)
-           (smie-rule-parent))
+     (cond
+      ((and (equal token "{") (smie-rule-parent-p "for"))
+       (let ((data (smie-backward-sexp "in")))
+         `(column . ,(smie-indent-virtual))))
+      ((not (smie-rule-prev-p "&&" "||" "|"))
+       (when (smie-rule-hanging-p)
+         (smie-rule-parent)))
+      (t
        (unless (smie-rule-bolp)
         (while (equal "|" (nth 2 (smie-backward-sexp 'halfexp))))
-        `(column . ,(smie-indent-virtual)))))
+        `(column . ,(smie-indent-virtual))))))
     ;; FIXME: Maybe this handling of ;; should be made into
     ;; a smie-rule-terminator function that takes the substitute ";" as arg.
     (`(:before . ,(or ";;" ";&" ";;&"))




reply via email to

[Prev in Thread] Current Thread [Next in Thread]