Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Open zsh scripts in sh-mode in emacs

Tags:

emacs

zsh

*.zsh files open in the default mode (text-mode for me). However, sh-mode is actually multiple modes including behaviours for zsh, bash, etc. How can I tell emacs to open *.zsh files specifically in the zsh flavor of sh-mode?

like image 219
PythonNut Avatar asked Dec 13 '13 03:12

PythonNut


2 Answers

The flavor of sh-mode is autodetected from the shebang line (first line of your script). If you have "#!/bin/zsh", zsh will be assumed and (for instance) autoload will be recognized as a keyword. autoload will be not recognized as such if first line is "#!/bin/bash"

To make emacs recognize *.zsh files as shell scripts, just add this to your init file:

(add-to-list 'auto-mode-alist '("\\.zsh\\'" . sh-mode))

A programmatic way of selecting a flavor when you don't want to use the shebang is doing this in a sh-mode buffer:

(sh-set-shell "zsh")

So in your case what you need (unless you use shebang) is to update the auto-mode-alist as above and

(add-hook 'sh-mode-hook
          (lambda ()
            (if (string-match "\\.zsh$" buffer-file-name)
                (sh-set-shell "zsh"))))
like image 63
juanleon Avatar answered Oct 19 '22 12:10

juanleon


Whether your file has a #! shebang or not, you can always use a file mode line or a local variables section to set shell-script mode. Having one of these in your script will allow Emacs to do the right thing even if you haven't updated the auto-mode-alist, so is recommended for any non-standard file extension.

The Emacs file mode line for shell scripts is -*- mode: sh -*-. It should be in a comment, and must appear on the first line (or the second line if the first one is a shebang line).

If you can't put it on the first (second) line for some reason, you can create a local variables section at the end of the file (in the last 3000 characters of the file, and on the last page, according to the manual):

# Local Variables:
# mode: sh
# End:

Note that just setting the Emacs mode will still rely on a shebang line for shell type autodetection, and if no shebang line is detected will default to the current SHELL environment variable or the value of sh-shell-file if set).

If you can't have a shebang line, but want the correct shell type to be selected, the only way to do this is with an eval in the mode line or local variables section. Adding this will generate a confirmation prompt every time the file is loaded into Emacs, so this is not generally recommended, but may be acceptable in some cases. The mode line would be -*- mode: sh; eval: (sh-set-shell "zsh") -*-, and the local variables form would be:

# Local Variables:
# mode: sh
# eval: (sh-set-shell "zsh")
# End:
like image 9
Alex Dupuy Avatar answered Oct 19 '22 14:10

Alex Dupuy