From 370ceb22102e02a25516e43a61da0c9a9d6e1579 Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Tue, 24 Jun 2014 16:16:10 -0400 Subject: [PATCH] Fix some indentation problem with \; and pipes. * lisp/progmodes/sh-script.el (sh-mode-syntax-table): Set syntax of ;|&. (sh-smie--default-forward-token, sh-smie--default-backward-token): New functions. (sh-smie-sh-forward-token, sh-smie-sh-backward-token) (sh-smie-rc-forward-token, sh-smie-rc-backward-token): Use them. (sh-smie-sh-rules): Fix indentation of a pipe at BOL. Fixes: debbugs:17842 --- lisp/ChangeLog | 10 ++++++ lisp/progmodes/sh-script.el | 76 +++++++++++++++++++++++++++++++++++---------- test/indent/shell.sh | 7 +++++ 3 files changed, 76 insertions(+), 17 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 379e5ed4d30..da8d49ae0a9 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,13 @@ +2014-06-24 Stefan Monnier + + Fix some indentation problem with \; and pipes (bug#17842). + * progmodes/sh-script.el (sh-mode-syntax-table): Set syntax of ;|&. + (sh-smie--default-forward-token, sh-smie--default-backward-token): + New functions. + (sh-smie-sh-forward-token, sh-smie-sh-backward-token) + (sh-smie-rc-forward-token, sh-smie-rc-backward-token): Use them. + (sh-smie-sh-rules): Fix indentation of a pipe at BOL. + 2014-06-24 Eli Zaretskii * international/fontset.el (script-representative-chars): diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el index 4db462594dc..1601b6c81ae 100644 --- a/lisp/progmodes/sh-script.el +++ b/lisp/progmodes/sh-script.el @@ -466,6 +466,9 @@ the car and cdr are the same symbol.") ?~ "_" ?, "_" ?= "." + ?\; "." + ?| "." + ?& "." ?< "." ?> ".") "The syntax table to use for Shell-Script mode. @@ -1837,6 +1840,40 @@ Does not preserve point." ((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 @@ Does not preserve point." 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 @@ Does not preserve point." (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 @@ May return nil if the line should not be treated as continued." (`(: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 - (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))))) + ;; 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)))) + (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 @@ May return nil if the line should not be treated as continued." (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 @@ Point should be before the newline." ;; 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 @@ Point should be before the newline." ;; (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) diff --git a/test/indent/shell.sh b/test/indent/shell.sh index 8e831bb8f11..4a30739e2d9 100755 --- a/test/indent/shell.sh +++ b/test/indent/shell.sh @@ -41,6 +41,13 @@ for foo in bar; do # bug#17721 } done +filter_3 () # bug#17842 +{ + tr -d '"`' | tr ' ' ' ' | \ + awk -F\; -f filter.awk | \ + grep -v "^," | sort -t, -k2,2 +} + echo -n $(( 5 << 2 )) # This should not be treated as a heredoc (bug#12770). 2 -- 2.11.4.GIT