autocmd CursorHold *.tex,*.md w
但是,随着这些文件的自定义设置的增加,我将它们拆分为
ftplugin/tex.vim
和ftplugin/markdown.vim
:" ftplugin/tex.vim
autocmd CursorHold *.tex w
" ftplugin/markdown.vim
autocmd CursorHold *.md w
现在,这些文件仅作为适当文件的来源,因此模式匹配是多余的。显然,
autocmd
可以是局部于缓冲区的。来自:h autocmd-buffer-local
: Buffer-local autocommands are attached to a specific buffer. They are useful
if the buffer does not have a name and when the name does not match a specific
pattern. But it also means they must be explicitly added to each buffer.
Instead of a pattern buffer-local autocommands use one of these forms:
<buffer> current buffer
<buffer=99> buffer number 99
<buffer=abuf> using <abuf> (only when executing autocommands)
<abuf>
这似乎是用于这种用法。现在,
ftplugin/tex.vim
和ftplugin/markdown.vim
都可以拥有:担心*.md
和*.markdown
以及适用于Markdown的其他任何扩展名。<buffer>
的这种用法正确吗?我应该注意哪些陷阱?如果我擦除缓冲区并打开另一个缓冲区,事情会变得凌乱吗(希望数字不会冲突,但是…)?#1 楼
正如您所解释的,特殊模式
<buffer>
允许您依靠内置的文件类型检测机制来实现在文件$VIMRUNTIME/filetype.vim
中。在该文件中,您可以找到Vim的内置autocmds,它们负责为任何给定的缓冲区设置正确的文件类型。例如,对于markdown:" Markdown
au BufNewFile,BufRead *.markdown,*.mdown,*.mkd,*.mkdn,*.mdwn,*.md setf markdown
在文件类型插件中,您可以为安装的每个autocmd复制相同的模式。例如,要在几秒钟内光标没有移动时自动保存缓冲区,请执行以下操作:
/>
au CursorHold *.markdown,*.mdown,*.mkd,*.mkdn,*.mdwn,*.md update
此外,如果某天另一扩展名有效,并且
<buffer>
已更新为包含该扩展名,则不会通知您的autocmds。而且,您必须在文件类型插件中更新其所有模式。如果我擦除缓冲区并打开另一个缓冲区(希望
,数字不会冲突,但是...)?
我不确定,但我不认为Vim可以重用已擦除缓冲区的缓冲区号。 >我从帮助中找不到相关的部分,但是我从vim.wikia.com找到了该段:已删除的缓冲区,用于
新缓冲区。 Vim将始终为新缓冲区分配下一个顺序号。
此外,如@ Tumbler41所述,擦除缓冲区时,其autocmds也将被删除。来自
$VIMRUNTIME/filetype.vim
:清除缓冲区后,其缓冲区本地自动命令当然也
不见了。
如果要检查自己,可以通过将Vim的详细级别提高到6来进行。您可以使用
:h autocmd-buflocal
修饰符仅针对一个命令临时进行检查。因此,可以在markdown缓冲区内执行:au CursorHold <buffer> update
然后,如果您查看Vim的消息: br />您应该会看到这样的一行:
:6verbose bwipe
其中
:verbose
是减价缓冲区的编号。 > 我应该注意任何陷阱吗?
有3种情况我会被视为陷阱,并且涉及特殊模式
42
。在其中两个中,<buffer>
可能是一个问题,在另一个中,这是一个解决方案。首先,您应谨慎使用以下方法清除augroup您的本地缓冲区autocmds。您必须熟悉以下代码段:
:messages
因此,您可能会想将其用于未经修改的本地缓冲区autocmds,如下所示:
auto-removing autocommand: CursorHold <buffer=42>
但这会产生不良影响。第一次加载降价缓冲区时,我们将其称为
<buffer>
,其autocmd将被正确安装。然后,当您重新加载A
时,将删除autocmd(由于A
),然后重新安装。因此,augroup将正确地防止autocmd的重复。 augroup的所有autocmds将被清除:即autocmd!
的autocmd和B
的autocmd之一。然后,将为A
安装SINGLE autocmd。因此,当您对
B
进行一些更改并等待几秒钟以触发B
时,它将被自动保存。但是,如果返回B
并执行相同的操作,则不会保存该缓冲区。这是因为上次加载降价缓冲区时,删除的内容和添加的内容之间不平衡。您删除的内容比添加的内容要多。 > augroup your_group_name
autocmd!
autocmd Event pattern command
augroup END
请注意,您可以用星号替换
CursorHold
以匹配删除autocmds的行中的任何事件:您不需要指定要清除augroup时autocmds监听的所有事件。但是这次不是问题,而是解决方案。当在文件类型插件中包含本地选项时,您可能会这样做:
/>
这将对缓冲区本地选项按预期工作,但对窗口本地选项并非始终如此。为了说明问题,您可以尝试以下实验。创建文件
A
,并在其中写入:augroup my_markdown
autocmd!
autocmd CursorHold <buffer> update
augroup END
此文件将自动为扩展名为
<buffer>
的任何文件设置文件类型:autocmd!
。您不需要将其包装在augroup中,因为对于这种特定类型的文件,Vim会自动执行它(请参阅CursorHold
)。您可以创建它们。接下来,创建文件类型插件
<buffer>
,并在其中写入:augroup my_markdown
autocmd! CursorHold <buffer>
autocmd CursorHold <buffer> update
augroup END
默认情况下,在
~/.vim/after/ftdetect/potion.vim
文件中,此设置将导致制表符显示为potion
,行尾显示为.pn
。现在,创建一个最小的:h ftdetect
;在~/.vim/after/ftplugin/potion.vim
内写:augroup my_markdown
autocmd! * <buffer>
autocmd CursorHold <buffer> update
augroup END
...启用文件类型插件。
还要创建一个药水文件
potion
和一个随机文件^I
。在药水文件中,写一些东西:setlocal option1=value
setlocal option2
在随机文件中,写药水文件的路径
$
:autocmd BufNewFile,BufRead *.pn setfiletype potion
现在,以最少的初始化启动Vim,仅采购
vimrc
,然后在垂直视口中打开两个文件:setlocal list
您应该看到2垂直视口。左侧的药水文件显示带有美元符号的行的结尾,右侧的随机文件完全不显示它们。
将焦点移至随机文件,然后按
/tmp/vimrc
显示路径位于光标下的药水文件。现在,您会在右侧视口中看到相同的药水缓冲液,但是这次,行尾没有显示美元符号。如果键入/tmp/pn.pn
,Vim应该回答/tmp/file
:整个事件链: /> ...没有发生,因为当您按下
/tmp/pn.pn
时没有出现第一个vimrc
。缓冲区已被加载。这似乎是意外的,因为当您在药水文件类型插件中添加
gf
时,您可能认为它会在任何显示药水缓冲区的窗口中启用:setlocal list?
选项。 br /> 问题不是特定于此新的
nolist
文件类型的。您也可以通过BufRead
文件来体验它。也不仅仅针对
gf
选项。您可以通过其他本地窗口设置来体验它,例如setlocal list
,'list'
,potion
,markdown
,...您可以通过其他命令来更改当前窗口中显示的缓冲区,以体验它:全局标记,'list'
(在窗口本地跳转列表中向后移动),'conceallevel'
,... 总而言之,在以下情况下,将正确设置窗口本地选项:
在当前Vim会话期间未读取文件(因为必须启动
'foldmethod'
) )文件显示在已经正确设置了窗口本地选项的窗口中
使用诸如
'foldexpr'
之类的命令创建新窗口(在这种情况下,它应该继承窗口本地选项否则,可能无法正确设置窗口本地选项。
可能的解决方案是不直接从窗口设置它们一个文件类型插件,但来自后者中安装的autocmd,它将监听
'foldtitle'
。每次在窗口中显示缓冲区时都会触发此事件。因此,例如,不要编写以下代码:
filetype plugin on
您会这样写:
foo
bar
baz
在这里,您再次找到特殊模式
gf
。 陷阱3
如果更改缓冲区的文件类型,则autocmds将保留。如果要删除它们,则需要配置
C-o
(请参阅:b {buffer_number}
),并在其中包括以下命令:/tmp/pn.pn
但是,请勿尝试删除它们。 augroup本身,因为里面仍然会有一些带有autocmd的markdown缓冲区。
FWIW,这是我用来设置
BufRead
的UltiSnips代码段: 这是我在
:split
中拥有的价值的一个示例:问这个问题,因为当我查找在Vim的默认文件中使用特殊模式BufWinEnter
的所有行时:$ vim -Nu /tmp/vimrc -O /tmp/pn.pn /tmp/file
我只找到9个匹配项(您可能会发现或多或少的情况,我使用的是Vim版本8.0,补丁版本高达
<buffer>
)。在9项匹配中,有7项在文档中,只有2项是实际来源。您应该在$ VIMRUNTIME / syntax / dircolors.vim中找到它们:BufRead event → set 'filetype' option → load filetype plugins
我不知道它是否会引起问题,但它们不在内部augroup,这意味着每次重新加载文件类型为
b:undo_ftplugin
的缓冲区(如果您编辑名为:h undo_ftplugin
,b:undo_ftplugin
或路径以~/.vim/after/ftplugin/awk.vim
结尾的文件时都会发生),语法插件将添加一个新的本地缓冲区autocmd。 > 您可以像这样检查它:
setlocal list
最后一条命令应该显示以下内容: br />现在,重新加载缓冲区,然后再次询问当前缓冲区的本地缓冲区autocmds是什么: />
augroup my_potion
au! * <buffer>
au BufWinEnter <buffer> setlocal list
augroup END
每次重新加载文件后,每次触发事件
<buffer>
,134
,dircolors
,.dircolors
之一时,都会再次调用.dir_colors
和/etc/DIR_COLORS
。 /> 这可能不是什么大问题,因为即使重新加载了q4312079 q文件几次,我没有看到Vim的明显速度下降或意外行为。 ,如果要防止autocmds重复,则可以使用文件
s:reset_colors()
为s:preview_color('.')
文件创建自己的语法插件。在其中,您将导入原始语法插件的内容:exe 'au! my_markdown * <buffer>'
然后,在后者中,您只需将autocmd包装在要清除的augroup中。因此,您可以将这些行替换为:
snippet undo "undo ftplugin settings" bm
" teardown {{{1
let b:undo_ftplugin = get(b:, 'undo_ftplugin', '')
\ .(empty(get(b:, 'undo_ftplugin', '')) ? '' : '|')
\ ."${1:
\ setl ${2:option}<}${3:
\ | exe '${4:n}unmap <buffer> ${5:lhs}'}${6:
\ | exe 'au! ${7:group_name} * <buffer>'}${8:
\ | unlet! b:${9:variable}}${10:
\ | delcommand ${11:Cmd}}
\ "
let b:undo_ftplugin = get(b:, 'undo_ftplugin', '')
\ .(empty(get(b:, 'undo_ftplugin', '')) ? '' : '|')
\ ."
\ setl cms< cocu< cole< fdm< fdt< tw<
\| exe 'nunmap <buffer> K'
\| exe 'au! my_awk * <buffer>'
\| exe 'au! my_awk_format * <buffer>'
\ "
endsnippet
...,替换为:
:vim /au\%[tocmd!].\{-}<buffer>/ $VIMRUNTIME/**/*
请注意,如果您使用文件
CursorHold
创建了CursorHoldI
语法插件,则它将无法正常工作,因为默认语法插件将在之前获得。通过使用CursorMoved
,您的语法插件将在默认插件之前获取,并且将设置局部缓冲区变量CursorMovedI
,这将阻止源默认语法插件,因为它包含以下防护:autocmd CursorMoved,CursorMovedI <buffer> call s:preview_color('.')
autocmd CursorHold,CursorHoldI <buffer> call s:reset_colors()
一般规则似乎是:使用
dircolors
和dircolors
目录创建自定义文件类型/语法插件,并防止在运行时路径中获取下一个插件(对于相同文件类型)(包括默认的)。并使用~/.vim/syntax/dircolors.vim
,dircolors
,不是要阻止其他插件的来源,而只是要对某些设置的值有最后的认识。评论
我希望我能更努力地投票。
–丰富
17年11月22日在11:31
@Rich我为您争取了更大的努力。我唯一的抱怨是缺少摘要“ tl; dr”。文本细节的页面无论对理解至关重要,都使我衰老的灵魂难以磨灭。更换autocmd!用autocmd! augroup块中的CursorHold
– Cecil咖喱
18年2月7日在7:00
评论
我很确定如果您擦除缓冲区,所有本地缓冲区autocmds也会被擦除。确实是@ Tumbler41。它确实在帮助中说了几段。
并非完全符合您的要求,但up(自动更新:的缩写)比autocmd中的w更好(避免不必要的写入)。
@mMontu尼斯。它甚至解决了我的autocmd为我从git历史记录中检查的文件激活时遇到的问题。缓冲区是只读的,并且w失败。反复。 :up在这种情况下不执行任何操作。 :)
很高兴您喜欢:)顺便说一句,您还可以找到'autowrite'选项很有用(根据您的动机,可以删除autocmds)。