Usr_43

Nvim :help 页面,生成源代码 使用 tree-sitter-vimdoc 解析器。


VIM 用户手册 - 作者 Bram Moolenaar
使用文件类型
当您编辑特定类型的文件时,例如 C 程序或 shell 脚本,您经常使用相同的选项设置和映射。您很快就会厌倦每次手动设置它们。本章解释如何自动执行此操作。
43.1 文件类型插件 43.2 添加文件类型
下一章:usr_44.txt 您的语法高亮 上一章:usr_42.txt 添加新菜单 目录:usr_toc.txt

文件类型插件 filetype-plugin

如何开始使用文件类型插件已在以下位置讨论:add-filetype-plugin。但您可能对默认设置不满意,因为它们保持了最小化。假设对于 C 文件,您想将 'softtabstop' 选项设置为 4 并定义一个映射来插入三行注释。您只需两个步骤即可完成。
your-runtime-dir
1. 创建您自己的运行时目录。在 Unix 上,这通常是 "~/.config/nvim"。在此目录中创建 "ftplugin" 目录
mkdir -p ~/.config/nvim/ftplugin
如果您不在 Unix 上,请检查 'runtimepath' 选项的值,以查看 Vim 将在何处查找 "ftplugin" 目录
set runtimepath?
您通常会使用第一个目录名称(第一个逗号之前)。如果您不喜欢默认值,您可能希望在 init.vim 文件中将目录名称添加到 'runtimepath' 选项的前面。
2. 创建文件 "~/.config/nvim/ftplugin/c.vim",内容如下
setlocal softtabstop=4
noremap <buffer> <LocalLeader>c o/**************<CR><CR>/<Esc>
let b:undo_ftplugin = "setl softtabstop< | unmap <buffer> <LocalLeader>c"
尝试编辑 C 文件。您应该注意到 'softtabstop' 选项已设置为 4。但是,当您编辑其他文件时,它将重置为默认的零。这是因为使用了 ":setlocal" 命令。这会将 'softtabstop' 选项仅设置为缓冲区的本地选项。只要您编辑另一个缓冲区,它就会设置为该缓冲区设置的值。对于新缓冲区,它将获得默认值或最后一个 ":set" 命令的值。
同样,"\c" 的映射在编辑另一个缓冲区时会消失。":map <buffer>" 命令创建了一个映射,该映射是当前缓冲区的本地映射。这适用于任何映射命令:":map!"、":vmap" 等。映射中的 <LocalLeader> 将被 "maplocalleader" 变量的值替换。
设置 b:undo_ftplugin 的行用于将文件类型设置为另一个值时。在这种情况下,您将希望撤消您的首选项。b:undo_ftplugin 变量将作为命令执行。注意字符串内具有特殊含义的字符,例如反斜杠。
您可以在此目录中找到文件类型插件的示例
$VIMRUNTIME/ftplugin/
有关编写文件类型插件的更多详细信息,请参见此处:write-plugin.

43.2 添加文件类型

如果您使用的是 Vim 不识别的文件类型,则以下是如何使其得到识别的。您需要一个自己的运行时目录。请参见上面的 your-runtime-dir
创建文件 "filetype.vim",其中包含您的文件类型的自动命令。(自动命令已在第 40.3 节中解释。)示例
augroup filetypedetect
au BufNewFile,BufRead *.xyz        setf xyz
augroup END
这将识别所有以 ".xyz" 结尾的文件作为 "xyz" 文件类型。":augroup" 命令将此自动命令放在 "filetypedetect" 组中。这允许在执行 ":filetype off" 时删除所有用于文件类型检测的自动命令。"setf" 命令将 'filetype' 选项设置为其参数,除非它已经设置。这将确保 'filetype' 不会被设置两次。
您可以使用多种不同的模式来匹配您的文件名。也可以包含目录名称。请参见 autocmd-pattern。例如,"/usr/share/scripts/" 下的所有文件都是 "ruby" 文件,但没有预期的文件名扩展名。将此添加到上面的示例中
augroup filetypedetect
au BufNewFile,BufRead *.xyz                        setf xyz
au BufNewFile,BufRead /usr/share/scripts/*        setf ruby
augroup END
但是,如果您现在编辑文件 /usr/share/scripts/README.txt,这不是 ruby 文件。以 "*" 结尾的模式的危险在于它很快就会匹配太多文件。为了避免此问题,将 filetype.vim 文件放在另一个目录中,该目录位于 'runtimepath' 的末尾。例如,对于 Unix,您可以使用 "~/.config/nvim/after/filetype.vim"。您现在将文本文件的检测放在 ~/.config/nvim/filetype.vim 中
augroup filetypedetect
au BufNewFile,BufRead *.txt                        setf text
augroup END
该文件首先在 'runtimepath' 中找到。然后在 ~/.config/nvim/after/filetype.vim 中使用此文件,该文件最后找到
augroup filetypedetect
au BufNewFile,BufRead /usr/share/scripts/*        setf ruby
augroup END
现在会发生的事情是,Vim 会在 'runtimepath' 中的每个目录中搜索 "filetype.vim" 文件。首先找到 ~/.config/nvim/filetype.vim。捕获 *.txt 文件的自动命令在那里定义。然后 Vim 找到 $VIMRUNTIME 中的 filetype.vim 文件,该文件位于 'runtimepath' 的中间位置。最后找到 ~/.config/nvim/after/filetype.vim,并添加用于检测 /usr/share/scripts 中的 ruby 文件的自动命令。当您现在编辑 /usr/share/scripts/README.txt 时,会按定义顺序检查自动命令。*.txt 模式匹配,因此执行 "setf text" 将文件类型设置为 "text"。ruby 的模式也匹配,并执行 "setf ruby"。但是,由于 'filetype' 已经设置为 "text",因此这里没有任何操作。当您编辑文件 /usr/share/scripts/foobar 时,会检查相同的自动命令。只有 ruby 的自动命令匹配,"setf ruby" 会将 'filetype' 设置为 ruby。

通过内容识别

如果您的文件无法通过文件名识别,您可能可以通过其内容识别它。例如,许多脚本文件以类似于以下行的行开头
#!/bin/xyz
要识别此脚本,请在您的运行时目录(与 filetype.vim 所在的相同位置)中创建一个文件 "scripts.vim"。它可能看起来像这样
if did_filetype()
  finish
endif
if getline(1) =~ '^#!.*[/\\]xyz\>'
  setf xyz
endif
使用 did_filetype() 的第一次检查是为了避免您检查已通过文件名检测到文件类型的文件的內容。这避免了在 "setf" 命令不会做任何事情的情况下浪费时间检查文件。scripts.vim 文件由默认 filetype.vim 文件中的自动命令源代码提供。因此,检查顺序为
1. 'runtimepath' 中 $VIMRUNTIME 之前的 filetype.vim 文件 2. $VIMRUNTIME/filetype.vim 的第一部分 3. 'runtimepath' 中的所有 scripts.vim 文件 4. $VIMRUNTIME/filetype.vim 的剩余部分 5. 'runtimepath' 中 $VIMRUNTIME 之后的 filetype.vim 文件
如果这还不够,请添加一个匹配所有文件的自动命令,并源代码一个脚本或执行一个函数来检查文件的内容。
下一章:usr_44.txt 您的语法高亮
版权:参见 manual-copyright vim:tw=78:ts=8:noet:ft=help:norl
主要
命令索引
快速参考