在没有文件,不存在的文件或空白文件的情况下启动Vim时如何运行autocmd(但从现有文件开始时则不能)?


11

当我启动Vim时,我想在以下情况下运行一个autocmd:

  • 没有指定文件名。
  • 文件为新文件时。
  • 文件存在但完全空白时。

在以上三种情况下,我都想运行一个autocmd;具体而言,我想自动启动插入模式在上述情况(而不是当我打开一个已经存在和不为空的文件)。


更新:

我试过将以下内容放入我的_vimrc,但是运气不好(另外,我不确定在vim中是否有一个函数在打开文件之前先计算文件中字符的数量(看是否为零):

if @% == "" || filereadable(@%)
  autocmd BufRead,BufNewFile * startinsert
endif

不,这不是重复的。我希望vi仅针对我提到的三个场景以插入模式启动。
John Sonderson

3
好的,很抱歉,但确实看起来像是重复的。;-)我已对您的问题进行了一些编辑,以使差异更加清楚。
马丁·图尔诺伊


2
@JohnSonderson,第一个链接告诉您如何查找是否未提供文件名,第二个链接可以通过使用normal代替进行修改exec
muru

1
vimrc文件只读一次:Vim启动时。autocmd的内容在每次触发时运行。因此,该if语句不应位于autocmd 周围,而应位于 autocmd 内部,因此它将在每次触发autocmd时运行。
马丁·图尔诺伊

Answers:


10

这对您的所有3种情况都适用:

function InsertIfEmpty()
    if @% == ""
        " No filename for current buffer
        startinsert
    elseif filereadable(@%) == 0
        " File doesn't exist yet
        startinsert
    elseif line('$') == 1 && col('$') == 1
        " File is empty
        startinsert
    endif
endfunction

au VimEnter * call InsertIfEmpty()

这些可能会被压缩为文件是否为空的最后检查,因为通常没有文件名或不存在的文件作为空缓冲区开始。但是,在前两种情况之一(例如某些模板插件)中,其他某些插件可能会预先填充一些内容,因此最好检查所有这三种情况。

您已经进行的第一个测试。

第二个测试需要检查filereadable零值(不存在)以确定它是否是新值(与您所拥有的相反)。

最后一个测试检查文件中最后一行的编号是否为1(这也是第一行,也就是只有一行),以及行尾的列号(其中的最后一个字符后的列)该行)为1,表示有0个字符。如果只有1行包含0个字符,则文件必须为空。

最后一点:问题中的陈述方式可能会导致一些令人惊讶的结果。即,您正在设置BufRead并且BufNewFile仅在启动时满足条件的情况下使用,但是在其余的会话中都存在那些自动命令。因此,如果要从设置这些命令的空文件开始,则随后打开的每个文件(无论是否新建,为空)都将以插入模式启动。

自动命令VimEnter在Vim启动结束时运行,并且在整个会话中仅运行一次。这样,您的测试仅在启动Vim时运行,而不在其他时间运行。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.