Fix indentation and fontification in shell-script (Bug#26217)

* lisp/progmodes/sh-script.el (sh-smie--sh-keyword-p): Treat "do" as
special, like we treat "in".
(sh-smie--sh-keyword-in-p): Change signature.  Take the token to
decide correctly if it's a keyword.
(sh-font-lock-keywords-var-1): Add do.

* test/lisp/progmodes/sh-script-resources/sh-indents.erts: New test.
* test/lisp/progmodes/sh-script-tests.el
(sh-script-test-do-fontification): New test.
This commit is contained in:
Mauro Aranda 2023-10-14 09:05:35 -03:00 committed by Stefan Monnier
parent 1f95f91d85
commit ad02fc212b
3 changed files with 26 additions and 5 deletions

View file

@ -869,7 +869,7 @@ See `sh-feature'.")
"Default expressions to highlight in Shell Script modes. See `sh-feature'.")
(defvar sh-font-lock-keywords-var-1
'((sh "[ \t]in\\>"))
'((sh "[ \t]\\(in\\|do\\)\\>"))
"Subdued level highlighting for Shell Script modes.")
(defvar sh-font-lock-keywords-var-2 ()
@ -1809,8 +1809,8 @@ before the newline and in that case point should be just before the token."
(concat "\\(?:^\\|[^\\]\\)\\(?:\\\\\\\\\\)*"
"\\(" sh-smie--sh-operators-re "\\)"))
(defun sh-smie--sh-keyword-in-p ()
"Assuming we're looking at \"in\", return non-nil if it's a keyword.
(defun sh-smie--sh-keyword-in/do-p (tok)
"When looking at TOK (either \"in\" or \"do\"), non-nil if TOK is a keyword.
Does not preserve point."
(let ((forward-sexp-function nil)
(words nil) ;We've seen words.
@ -1832,7 +1832,10 @@ Does not preserve point."
((equal prev ";")
(if words (setq newline t)
(setq res 'keyword)))
((member prev '("case" "for" "select")) (setq res 'keyword))
((member prev (if (string= tok "in")
'("case" "for" "select")
'("for" "select")))
(setq res 'keyword))
((assoc prev smie-grammar) (setq res 'word))
(t
(if newline
@ -1844,7 +1847,7 @@ Does not preserve point."
"Non-nil if TOK (at which we're looking) really is a keyword."
(cond
((looking-at "[[:alnum:]_]+=") nil)
((equal tok "in") (sh-smie--sh-keyword-in-p))
((member tok '("in" "do")) (sh-smie--sh-keyword-in/do-p tok))
(t (sh-smie--keyword-p))))
(defun sh-smie--default-forward-token ()

View file

@ -38,3 +38,10 @@ if test ;then
fi
other
=-=-=
Name: sh-indents5
=-=
for i do echo 1; done
for i; do echo 1; done
=-=-=

View file

@ -87,4 +87,15 @@
(should-not (test-sh-back "foo;bar"))
(should (test-sh-back "foo#zot")))
(ert-deftest sh-script-test-do-fontification ()
"Test that \"do\" gets fontified correctly, even with no \";\"."
(with-temp-buffer
(shell-script-mode)
(insert "for i do echo 1; done")
(font-lock-ensure)
(goto-char (point-min))
(search-forward "do")
(forward-char -1)
(should (equal (get-text-property (point) 'face) 'font-lock-keyword-face))))
;;; sh-script-tests.el ends here