emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 3fe5fc3dc1 6/7: Make bash-ts-mode fall back to sh-mode if the fil


From: Yuan Fu
Subject: master 3fe5fc3dc1 6/7: Make bash-ts-mode fall back to sh-mode if the file isn't in Bash
Date: Sat, 26 Nov 2022 21:36:30 -0500 (EST)

branch: master
commit 3fe5fc3dc164fbc12c7716d6b5430f2b85833290
Author: Yuan Fu <casouri@gmail.com>
Commit: Yuan Fu <casouri@gmail.com>

    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.
---
 lisp/progmodes/sh-script.el | 58 +++++++++++++++++++++++++++++++--------------
 1 file changed, 40 insertions(+), 18 deletions(-)

diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el
index e11fb42fc8..fee86dde7b 100644
--- a/lisp/progmodes/sh-script.el
+++ b/lisp/progmodes/sh-script.el
@@ -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."



reply via email to

[Prev in Thread] Current Thread [Next in Thread]