1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-15 10:30:25 -08:00

Make bash-ts-mode fall back to sh-mode if the file isn't in Bash

* lisp/progmodes/sh-script.el (sh--guess-shell): Take out into a new
function.
(sh-base-mode): Use the new function.
(bash-ts-mode): Update docstring.
(sh--redirect-recursing): New variable.
(sh--redirect-bash-ts-mode): New function.
This commit is contained in:
Yuan Fu 2022-11-26 15:31:48 -08:00
parent bd10c3cfa2
commit 3fe5fc3dc1
No known key found for this signature in database
GPG key ID: 56E19BC57664A442

View file

@ -1468,6 +1468,25 @@ When the region is active, send the region instead."
(defvar sh-mode--treesit-settings)
(defun sh--guess-shell ()
"Guess the shell used in the current buffer.
Return the name of the shell suitable for `sh-set-shell'."
(cond ((save-excursion
(goto-char (point-min))
(looking-at auto-mode-interpreter-regexp))
(match-string 2))
((not buffer-file-name) sh-shell-file)
;; Checks that use `buffer-file-name' follow.
((string-match "\\.m?spec\\'" buffer-file-name) "rpm")
((string-match "[.]sh\\>" buffer-file-name) "sh")
((string-match "[.]bash\\(rc\\)?\\>" buffer-file-name) "bash")
((string-match "[.]ksh\\>" buffer-file-name) "ksh")
((string-match "[.]mkshrc\\>" buffer-file-name) "mksh")
((string-match "[.]t?csh\\(rc\\)?\\>" buffer-file-name) "csh")
((string-match "[.]zsh\\(rc\\|env\\)?\\>" buffer-file-name) "zsh")
((equal (file-name-nondirectory buffer-file-name) ".profile") "sh")
(t sh-shell-file)))
;;;###autoload
(define-derived-mode sh-base-mode prog-mode "Shell-script"
"Generic major mode for editing shell scripts.
@ -1519,23 +1538,7 @@ implementations. Currently there are two: `sh-mode' and
"\\")))
;; Parse or insert magic number for exec, and set all variables depending
;; on the shell thus determined.
(sh-set-shell
(cond ((save-excursion
(goto-char (point-min))
(looking-at auto-mode-interpreter-regexp))
(match-string 2))
((not buffer-file-name) sh-shell-file)
;; Checks that use `buffer-file-name' follow.
((string-match "\\.m?spec\\'" buffer-file-name) "rpm")
((string-match "[.]sh\\>" buffer-file-name) "sh")
((string-match "[.]bash\\(rc\\)?\\>" buffer-file-name) "bash")
((string-match "[.]ksh\\>" buffer-file-name) "ksh")
((string-match "[.]mkshrc\\>" buffer-file-name) "mksh")
((string-match "[.]t?csh\\(rc\\)?\\>" buffer-file-name) "csh")
((string-match "[.]zsh\\(rc\\|env\\)?\\>" buffer-file-name) "zsh")
((equal (file-name-nondirectory buffer-file-name) ".profile") "sh")
(t sh-shell-file))
nil nil)
(sh-set-shell (sh--guess-shell) nil nil)
(add-hook 'flymake-diagnostic-functions #'sh-shellcheck-flymake nil t)
(add-hook 'hack-local-variables-hook
#'sh-after-hack-local-variables nil t))
@ -1605,7 +1608,9 @@ with your script for an edit-interpret-debug cycle."
;;;###autoload
(define-derived-mode bash-ts-mode sh-base-mode "Bash"
"Major mode for editing Bash shell scripts."
"Major mode for editing Bash shell scripts.
This mode automatically falls back to `sh-mode' if the buffer is
not written in Bash or sh."
(when (treesit-ready-p 'bash)
(setq-local treesit-font-lock-feature-list
'(( comment function)
@ -1616,6 +1621,23 @@ with your script for an edit-interpret-debug cycle."
sh-mode--treesit-settings)
(treesit-major-mode-setup)))
(advice-add 'bash-ts-mode :around #'sh--redirect-bash-ts-mode
;; Give it lower precedence than normal advice, so other
;; advices take precedence over it.
'((depth . 50)))
(defvar sh--redirect-recursing nil)
(defun sh--redirect-bash-ts-mode (oldfn)
"Redirect to `sh-mode' if the current file is not written in Bash.
OLDFN should be `bash-ts-mode'."
(let ((sh--redirect-recursing sh--redirect-recursing))
(funcall (if (or delay-mode-hooks sh--redirect-recursing)
oldfn
(setq sh--redirect-recursing t)
(if (member (file-name-base (sh--guess-shell)) '("bash" "sh"))
oldfn
#'sh-mode)))))
(defun sh-font-lock-keywords (&optional keywords)
"Function to get simple fontification based on `sh-font-lock-keywords'.
This adds rules for comments and assignments."