如何让 Vim 从 shebang 行检测文件类型?

42

有时候我会写没有文件扩展名的脚本,例如:

#!/usr/bin/env node

console.log('hello world!');

我希望Vim能够从shebang行中检测出文件类型(例如#!/usr/bin/env nodejavascript)。我应该在filetype.vim中放置什么内容?


7
为什么不添加第二个或最后一行modeline # vim: ft=javascript,因为Vim已经检查了modeline,而不是重复发明轮子? - Swaroop C H
15
为什么不像任何一款真正的编辑器那样,从文件中已有包含必要信息的行中解析信息呢?这样做可以避免以特定于编辑器的方式重复冗余信息,从而不会给使用其他编辑器的用户带来困扰。*/我穿上了防火服* - Brian Campbell
4个回答

37

按照:help new-filetype-scripts中列出的指示, 在用户运行时目录(Unix类系统上为~/.vim/)中创建scripts.vim文件,并在其中编写以下脚本:

if did_filetype()
    finish
endif
if getline(1) =~# '^#!.*/bin/env\s\+node\>'
    setfiletype javascript
endif

3
另请参阅整个“:help new-filetype”部分,值得一读。 - ib.
1
为什么不需要对前斜杠进行转义? /bin/env - Lai Yu-Hsuan
2
@LaiYu-Hsuan:根据Vim正则表达式的语法,斜杠字符不是特殊符号。当然,它可以被转义为\/,但只有在正向搜索命令(/)或替换命令(:s)中使用斜杠作为模式分隔符时才需要这样做。 - ib.
1
你也可以使用 autocmd 将这些行放入 .vimrc 中,可能需要使用 bufread 触发该函数。 - Yosh

11

创建文件 ~/.vim/ftdetect/node.vim,内容如下

fun! s:DetectNode()
    if getline(1) == '#!/usr/bin/env node'
        set ft=javascript
    endif
endfun

autocmd BufNewFile,BufRead * call s:DetectNode()

5
实际上,使用 "ft=javascript" 更有可能起作用。大多数人确实已经定义了 "javascript",而没有定义 "node"。 - Dave Dopson
autocmd BufNewFile,BufRead * if getline(1) == '#!/usr/bin/env node' | set ft=javascript | endif - Erik Lievaart

3
如果你对插件感兴趣,确实存在一个插件:https://github.com/vitalk/vim-shebang。其中包含一种用于node -> javascript高亮的模式。
AddShebangPattern! javascript ^#!.*\s\+node\>

0
略有些晚,但是 Node.vim 会为你处理检测这类 JavaScript 文件的任务,还有更多其他功能。:-)

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