GNU bug report logs - #17842
sh-script's indentation gets confused by \;

Previous Next

Package: emacs;

Reported by: Stefan Monnier <monnier <at> iro.umontreal.ca>

Date: Tue, 24 Jun 2014 13:50:02 UTC

Severity: normal

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 17842 in the body.
You can then email your comments to 17842 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#17842; Package emacs. (Tue, 24 Jun 2014 13:50:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Stefan Monnier <monnier <at> iro.umontreal.ca>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Tue, 24 Jun 2014 13:50:03 GMT) Full text and rfc822 format available.

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

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: bug-gnu-emacs <at> gnu.org
Subject: sh-script's indentation gets confused by \;
Date: Tue, 24 Jun 2014 09:49:28 -0400
[Message part 1 (text/plain, inline)]
Splitting into another bug.

[Message part 2 (message/rfc822, inline)]
From: Reiner Steib <reiner.steib <at> gmx.de>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 17818 <at> debbugs.gnu.org
Subject: Re: bug#17818: 24.3.91; sh-learn-buffer-indent doesn't learn
	current indent anymore
Date: Mon, 23 Jun 2014 18:04:50 +0200
On Fri, 20 Jun 2014, Stefan Monnier <monnier <at> iro.umontreal.ca> wrote:

>> if true; do
>>   echo "My sh-basic-offset offset should be 2."
>> fi
>
> The above "do" should be "then", right?

Sure, sorry. (I corrected it in my test-script, but not in the mail).

> I installed the patch below which fixes some of the problem (the first
> hunk fixes an incorrect guess and the second fixes the code so the guess
> is actually activated).
>
> Please confirm that the result is OK for your use case.

Works much better, thanks.

However, I tested[1] the new code with the following script and found
some incorrect indents (see diff below, hope the whitespace doesn't
get changed).

Bye, Reiner.

[1] M-x sh-learn-buffer-indent RET, M-x mark-whole-buffer RET, M-x
     indent-region RET, M-x diff-buffer-with-file RET

#!/bin/bash

if true; then
   echo "My sh-basic-offset offset should be 2."
fi

for a in 1 2; do
   echo "My sh-basic-offset offset should be 2."
done

filter_1 ()
{
   tr -d '"' |
     awk -F\; '{ if ($7 == 0 || $7 == 1) { print $7 } ; \
       print $5 "," $1 }' |
     grep -v "^,"
}

filter_3 ()
{
   tr -d '"`' | tr '	' ' ' | \
     awk -F\; -f filter.awk | \
     grep -v "^," | sort -t, -k2,2
}

tail -q -n+2 assets-ws.csv | awk -F \; -f merge.awk \
   <( cat file1.csv file2.csv ) - | \
   filter_2 | $conv | \
   sed -f a.sed | sort -t\; -k3,3 -k1,1 > w.csv

# end



--- shell-script-test.sh
+++ #<buffer shell-script-test.sh>
@@ -12,21 +12,21 @@
  filter_1 ()
  {
    tr -d '"' |
-    awk -F\; '{ if ($7 == 0 || $7 == 1) { print $7 } ; \
+awk -F\; '{ if ($7 == 0 || $7 == 1) { print $7 } ; \
        print $5 "," $1 }' |
-    grep -v "^,"
+grep -v "^,"
  }

  filter_3 ()
  {
    tr -d '"`' | tr '	' ' ' | \
-    awk -F\; -f filter.awk | \
-    grep -v "^," | sort -t, -k2,2
+  awk -F\; -f filter.awk | \
+grep -v "^," | sort -t, -k2,2
  }

  tail -q -n+2 assets-ws.csv | awk -F \; -f merge.awk \
-  <( cat file1.csv file2.csv ) - | \
-  filter_2 | $conv | \
-  sed -f a.sed | sort -t\; -k3,3 -k1,1 > w.csv
+					  <( cat file1.csv file2.csv ) - | \
+					  filter_2 | $conv | \
+					  sed -f a.sed | sort -t\; -k3,3 -k1,1 > w.csv

  # end

Diff finished.  Mon Jun 23 17:56:00 2014


Information forwarded to reiner.steib <at> gmx.de, bug-gnu-emacs <at> gnu.org:
bug#17842; Package emacs. (Tue, 24 Jun 2014 20:11:01 GMT) Full text and rfc822 format available.

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

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: 17842 <at> debbugs.gnu.org
Subject: Re: sh-script's indentation gets confused by \;
Date: Tue, 24 Jun 2014 16:10:00 -0400
> However, I tested[1] the new code with the following script and found
> some incorrect indents (see diff below, hope the whitespace doesn't
> get changed).

These are due to the new indentation code.

> --- shell-script-test.sh
> +++ #<buffer shell-script-test.sh>
> @@ -12,21 +12,21 @@
>   filter_1 ()
>   {
>     tr -d '"' |
> -    awk -F\; '{ if ($7 == 0 || $7 == 1) { print $7 } ; \
> +awk -F\; '{ if ($7 == 0 || $7 == 1) { print $7 } ; \
>         print $5 "," $1 }' |
> -    grep -v "^,"
> +grep -v "^,"
>   }

>   filter_3 ()
>   {
>     tr -d '"`' | tr '	' ' ' | \
> -    awk -F\; -f filter.awk | \
> -    grep -v "^," | sort -t, -k2,2
> +  awk -F\; -f filter.awk | \
> +grep -v "^," | sort -t, -k2,2
>   }

>   tail -q -n+2 assets-ws.csv | awk -F \; -f merge.awk \
> -  <( cat file1.csv file2.csv ) - | \
> -  filter_2 | $conv | \
> -  sed -f a.sed | sort -t\; -k3,3 -k1,1 > w.csv
> +					  <( cat file1.csv file2.csv ) - | \
> +					  filter_2 | $conv | \
> +					  sed -f a.sed | sort -t\; -k3,3 -k1,1 > w.csv

I installed the patch below which fixes the problem with \;
and also with the indentation after "a | b |".

The "<(cat...)" line is still not indented as you want it because you
expect a different logic from the one followed by the current
indentation code (the current code indents multi-line elements connected
by \ as multi line constructs rather than "one long wrapped line", so
the <(...) gets aligned with the other arguments to the "sort" command).


        Stefan


=== modified file 'lisp/progmodes/sh-script.el'
--- lisp/progmodes/sh-script.el	2014-06-20 14:23:30 +0000
+++ lisp/progmodes/sh-script.el	2014-06-24 19:55:01 +0000
@@ -466,6 +466,9 @@
 	?~ "_"
 	?, "_"
 	?= "."
+	?\; "."
+	?| "."
+	?& "."
 	?< "."
 	?> ".")
   "The syntax table to use for Shell-Script mode.
@@ -1837,6 +1840,40 @@
    ((equal tok "in") (sh-smie--sh-keyword-in-p))
    (t (sh-smie--keyword-p))))
 
+(defun sh-smie--default-forward-token ()
+  (forward-comment (point-max))
+  (buffer-substring-no-properties
+   (point)
+   (progn (if (zerop (skip-syntax-forward "."))
+              (while (progn (skip-syntax-forward "w_'")
+                            (looking-at "\\\\"))
+                (forward-char 2)))
+          (point))))
+
+(defun sh-smie--default-backward-token ()
+  (forward-comment (- (point)))
+  (let ((pos (point))
+        (n (skip-syntax-backward ".")))
+    (if (or (zerop n)
+            (and (eq n -1)
+                 (let ((p (point)))
+                   (if (eq -1 (% (skip-syntax-backward "\\") 2))
+                       t
+                     (goto-char p)
+                     nil))))
+        (while
+            (progn (skip-syntax-backward "w_'")
+                   (or (not (zerop (skip-syntax-backward "\\")))
+                       (when (eq ?\\ (char-before (1- (point))))
+                         (let ((p (point)))
+                           (forward-char -1)
+                           (if (eq -1 (% (skip-syntax-backward "\\") 2))
+                               t
+                             (goto-char p)
+                             nil))))))
+      (goto-char (- (point) (% (skip-syntax-backward "\\") 2))))
+    (buffer-substring-no-properties (point) pos)))
+
 (defun sh-smie-sh-forward-token ()
   (if (and (looking-at "[ \t]*\\(?:#\\|\\(\\s|\\)\\|$\\)")
            (save-excursion
@@ -1865,7 +1902,7 @@
         tok))
      (t
       (let* ((pos (point))
-             (tok (smie-default-forward-token)))
+             (tok (sh-smie--default-forward-token)))
         (cond
          ((equal tok ")") "case-)")
          ((equal tok "(") "case-(")
@@ -1909,7 +1946,7 @@
       (goto-char (match-beginning 1))
       (match-string-no-properties 1))
      (t
-      (let ((tok (smie-default-backward-token)))
+      (let ((tok (sh-smie--default-backward-token)))
         (cond
          ((equal tok ")") "case-)")
          ((equal tok "(") "case-(")
@@ -1939,18 +1976,18 @@
     (`(:after . "case-)") (- (sh-var-value 'sh-indent-for-case-alt)
                              (sh-var-value 'sh-indent-for-case-label)))
     ((and `(:before . ,_)
-          (guard (when sh-indent-after-continuation
-                   (save-excursion
+          ;; After a line-continuation, make sure the rest is indented.
+          (guard sh-indent-after-continuation)
+          (guard (save-excursion
                      (ignore-errors
                        (skip-chars-backward " \t")
-                       (sh-smie--looking-back-at-continuation-p))))))
-     ;; After a line-continuation, make sure the rest is indented.
-     (let* ((sh-indent-after-continuation nil)
-            (indent (smie-indent-calculate))
-            (initial (sh-smie--continuation-start-indent)))
-       (when (and (numberp indent) (numberp initial)
-                  (<= indent initial))
-         `(column . ,(+ initial sh-indentation)))))
+                     (sh-smie--looking-back-at-continuation-p))))
+          (let initial (sh-smie--continuation-start-indent))
+          (guard (let* ((sh-indent-after-continuation nil)
+                        (indent (smie-indent-calculate)))
+                   (and (numberp indent) (numberp initial)
+                        (<= indent initial)))))
+     `(column . ,(+ initial sh-indentation)))
     (`(:before . ,(or `"(" `"{" `"["))
      (when (smie-rule-hanging-p)
        (if (not (smie-rule-prev-p "&&" "||" "|"))
@@ -1974,7 +2011,12 @@
                             (smie-rule-bolp))))
                  (current-column)
                (smie-indent-calculate)))))
-    (`(:after . ,(or `"|" `"&&" `"||")) (if (smie-rule-parent-p token) nil 4))
+    (`(:before . ,(or `"|" `"&&" `"||"))
+     (unless (smie-rule-parent-p token)
+       (smie-backward-sexp token)
+       `(column . ,(+ (funcall smie-rules-function :elem 'basic)
+                      (smie-indent-virtual)))))
+
     ;; Attempt at backward compatibility with the old config variables.
     (`(:before . "fi") (sh-var-value 'sh-indent-for-fi))
     (`(:before . "done") (sh-var-value 'sh-indent-for-done))
@@ -2095,7 +2137,7 @@
      ;;    tok))
      (t
       (let* ((pos (point))
-             (tok (smie-default-forward-token)))
+             (tok (sh-smie--default-forward-token)))
         (cond
          ;; ((equal tok ")") "case-)")
          ((and tok (string-match "\\`[a-z]" tok)
@@ -2136,7 +2178,7 @@
      ;;  (goto-char (match-beginning 1))
      ;;  (match-string-no-properties 1))
      (t
-      (let ((tok (smie-default-backward-token)))
+      (let ((tok (sh-smie--default-backward-token)))
         (cond
          ;; ((equal tok ")") "case-)")
          ((and tok (string-match "\\`[a-z]" tok)





bug closed, send any further explanations to 17842 <at> debbugs.gnu.org and Stefan Monnier <monnier <at> iro.umontreal.ca> Request was from Stefan Monnier <monnier <at> iro.umontreal.ca> to control <at> debbugs.gnu.org. (Tue, 08 Jul 2014 18:57:02 GMT) Full text and rfc822 format available.

bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Wed, 06 Aug 2014 11:24:04 GMT) Full text and rfc822 format available.

This bug report was last modified 10 years and 326 days ago.

Previous Next


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