在emacs中以sh-mode打开zsh脚本

10

*.zsh文件以默认模式(对我来说是文本模式)打开。但是,sh-mode实际上包括了zshbash等多种行为方式。我该如何告诉Emacs在*.zsh文件中特别使用zsh风格的sh-mode


2
将一个条目添加到auto-mode-alist,将.zsh后缀映射到您想要的模式。 - Barmar
3个回答

13

sh-mode的味道是从shebang行(脚本的第一行)自动检测到的。如果您有“#!/bin/zsh”,则将假定为zsh,并且(例如)autoload将被识别为关键字。如果第一行是“#!/bin/bash”,则autoload将不被识别为这样。

要使emacs将*.zsh文件识别为shell脚本,只需将此添加到您的init文件中:

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

当您不想使用shebang时,选择口味的一种程序化方法是在sh-mode缓冲区中执行以下操作:

(sh-set-shell "zsh")

所以在你的情况下,除非你使用shebang,否则你需要更新auto-mode-alist如上所述,并

(add-hook 'sh-mode-hook
          (lambda ()
            (if (string-match "\\.zsh$" buffer-file-name)
                (sh-set-shell "zsh"))))

啊,谢谢,我知道可以调用sh-mode,但不知道它会自动检测类型。如果我没有sebang行,我还能让它自动工作吗? - PythonNut
你有没有想过为什么在我的emacs中(add-to-list 'auto-mode-alist'("\\.zsh\\'" . sh-mode))完全没有效果?sh-mode已经安装,我可以手动启动它,没有问题。 - marczellm

9
无论你的文件是否有#! shebang,你都可以使用文件模式行或本地变量部分来设置shell脚本模式。只要在你的脚本中有其中之一,即使你没有更新auto-mode-alist,Emacs也会做正确的事情,因此建议对于任何非标准的文件扩展名都这样做。
对于shell脚本,Emacs文件模式行是-*- mode: sh -*-。它应该在注释中,并且必须出现在第一行(如果第一行是shebang行,则为第二行)。
如果由于某种原因无法将其放在第一(第二)行上,则可以在文件末尾创建一个本地变量部分(在文件的最后3000个字符和最后一页上,根据手册)。
# Local Variables:
# mode: sh
# End:

请注意,仅设置Emacs模式仍将依赖于shebang行进行shell类型自动检测,如果未检测到shebang行,则默认为当前SHELL环境变量或sh-shell-file的值(如果已设置)。
如果无法使用shebang行,但希望选择正确的shell类型,则唯一的方法是在模式行或本地变量部分中使用eval。添加此内容将在每次将文件加载到Emacs时生成确认提示,因此通常不建议这样做,但在某些情况下可能是可接受的。 模式行应为-*- mode: sh; eval: (sh-set-shell "zsh") -*-,本地变量形式应为:
# Local Variables:
# mode: sh
# eval: (sh-set-shell "zsh")
# End:

谢谢!这非常酷!我正在构思如何使用这个功能的绝妙方法。 - PythonNut

-1

如果您使用shebang方法,一个更强大的形式是

#!/usr/bin/env zsh
# env will search the path for zsh.  Some distros may put it a different place.
# env is pretty much guaranteed to be in /usr/bin

这与问题无关。 - Neil Locketz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接