From ad02fc212b5a88d2ea793858d538809d9976b154 Mon Sep 17 00:00:00 2001 From: Mauro Aranda Date: Sat, 14 Oct 2023 09:05:35 -0300 Subject: [PATCH] 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. --- lisp/progmodes/sh-script.el | 13 ++++++++----- .../progmodes/sh-script-resources/sh-indents.erts | 7 +++++++ test/lisp/progmodes/sh-script-tests.el | 11 +++++++++++ 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el index cc521cb0591..de76e175a10 100644 --- a/lisp/progmodes/sh-script.el +++ b/lisp/progmodes/sh-script.el @@ -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 () diff --git a/test/lisp/progmodes/sh-script-resources/sh-indents.erts b/test/lisp/progmodes/sh-script-resources/sh-indents.erts index 1f92610b3aa..36f4e4c22ab 100644 --- a/test/lisp/progmodes/sh-script-resources/sh-indents.erts +++ b/test/lisp/progmodes/sh-script-resources/sh-indents.erts @@ -38,3 +38,10 @@ if test ;then fi other =-=-= + +Name: sh-indents5 + +=-= +for i do echo 1; done +for i; do echo 1; done +=-=-= diff --git a/test/lisp/progmodes/sh-script-tests.el b/test/lisp/progmodes/sh-script-tests.el index 52c1303c414..135d7afe3fe 100644 --- a/test/lisp/progmodes/sh-script-tests.el +++ b/test/lisp/progmodes/sh-script-tests.el @@ -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 -- 2.39.2