如何阻止Vim编写文件而不会引发错误?


10

我正在尝试从此答案中改进代码,以在创建缺少的目录之前要求确认,这就是我写的内容:

function! CreateDirectoryAskConfirmation(path)
    if !isdirectory(a:path)
        echohl Question
        echo "Create directory " . a:path . "?"
        echohl None

        let response = nr2char(getchar())
        if response ==? "y"
            call mkdir(a:path, "p")
        endif
    endif
endfunction

autocmd BufWritePre * call CreateDirectoryAskConfirmation(expand("<afile>:p:h"))

有一件事我错过了:我不要按y在提示我想让Vim中止写,所以我没有得到错误E212: Can't open file for writing,我也不需要打另一个键,使该错误信息消失。有办法实现吗?

Answers:


9

除了使用BufWritePreautocmd,还可以使用BufWriteCmd 来自:help BufWriteCmd以下位置的autocmd :

应该写入文件,如果成功,则将其重置为“ modified”,除非“ cpo”中包含“ +”并写入另一个文件cpo- +。

我们可以:write从autocmd 调用。这将照顾设置modified

因此,逻辑将被修改为:write在目录已经存在时调用,并:write在创建目录后调用(如果尚不存在)。如果您按n,我们什么都不做。这将使缓冲区保持原样,并且不会重置modified,因此:q仍然会给您一个E37: No write since last change错误。

function! CreateDirectoryAskConfirmation(path, dir)
    silent doautocmd BufWritePre

    " Directory exists, :write and return
    if isdirectory(a:dir)
        execute 'write ' . a:path
        silent doautocmd BufWritePost
        return
    endif

    " Ask for confirmation to create this directory
    echohl Question
    echo "Create directory `" . a:dir . "' [y/N]?"
    echohl None

    let response = nr2char(getchar())
    " mkdir() and :write if we want to make a directory
    if response ==? "y"
        call mkdir(a:dir, "p")
        execute 'write ' . a:path
        silent doautocmd BufWritePost
    endif
endfunction

autocmd BufWriteCmd * call CreateDirectoryAskConfirmation(expand("<amatch>:p"), expand("<amatch>:p:h"))

2
在VimScript文件中,:命令永远不需要引号。
tommcdo

@tommcdo谢谢。由于某些原因,我的大脑有时会忘记这个> _ <
Martin Tournoij 2015年

2
@ toro2k谢谢。我不知道 我编辑了答案,并添加了内容,silent因此,如果您不使用this,则不会收到任何消息autogroup。我还修复了我注意到的另一个问题::w another_name无效(无效)。
马丁·图尔诺伊

2
@ toro2k因为否则write将仅写入当前文件名(就像您键入时一样:write),并且:write another_filename将不起作用(它将仍然使用原始文件名)。
马丁·图尔诺伊

1
@whitesiroi您可以使用该bufype设置获取缓冲区类型。随时编辑带有修复的帖子(或者,如果您不喜欢,我将在下周发布)。
马丁·图尔诺伊
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.