如果我调用 vim foo/bar/somefile但 foo/bar不存在,Vim 拒绝保存。
vim foo/bar/somefile
foo/bar
我知道我可以从 Vim 切换到 shell 或者执行 :!mkdir foo/bar,但是我很懒:) 有没有一种方法可以让 Vim 在保存缓冲区时自动做到这一点?
:!mkdir foo/bar
基于对我的问题的建议,以下是我的结论:
function WriteCreatingDirs() execute ':silent !mkdir -p %:h' write endfunction command W call WriteCreatingDirs()
这定义了 :W命令。理想情况下,我希望所有的 :w!,:wq,:wq!,:wall等工作相同,但我不知道是否有可能,如果没有基本上重新实现他们所有的自定义函数。
:W
:w!
:wq
:wq!
:wall
augroup BWCCreateDir autocmd! autocmd BufWritePre * if expand("<afile>")!~#'^\w\+:/' && !isdirectory(expand("%:h")) | execute "silent! !mkdir -p ".shellescape(expand('%:h'), 1) | redraw! | endif augroup END
注意条件: expand("<afile>")!~#'^\w\+:/'将阻止 vim 为诸如 ftp://*之类的文件创建目录,而 !isdirectory将阻止昂贵的 mkdir 调用。
expand("<afile>")!~#'^\w\+:/'
ftp://*
!isdirectory
更新 : 稍微好一点的解决方案,它也检查非空 buftype 并使用 mkdir():
mkdir()
function s:MkNonExDir(file, buf) if empty(getbufvar(a:buf, '&buftype')) && a:file!~#'\v^\w+\:\/' let dir=fnamemodify(a:file, ':h') if !isdirectory(dir) call mkdir(dir, 'p') endif endif endfunction augroup BWCCreateDir autocmd! autocmd BufWritePre * :call s:MkNonExDir(expand('<afile>'), +expand('<abuf>')) augroup END
我把这个添加到我的 ~/. vimrc
cnoremap mk. !mkdir -p <c-r>=expand("%:h")<cr>/
如果我需要创建我所在的目录,我输入 :mk.,它会用“ !Mkdir-p/path/to/my/file/”,并允许我在调用命令之前查看该命令。
:mk.
我让 :saveas!创建缺少的目录: https://github.com/henrik/dotfiles/commit/54cc9474b345332cf54cf25b51ddb8a9bd00a0bb
:saveas!
我想我成功地用三句话做到了这一点,结合了其他人对这个答案的看法。
这似乎奏效了:
if has("autocmd") autocmd BufWritePre * :silent !mkdir -p %:p:h end
它尝试在保存缓冲区时自动创建文件夹。如果有任何不好的事情发生(比如权限问题) ,它就会关闭,让文件写失败。
如果有人看到任何明显的缺陷,请发表评论。我不是很精通 Vimscript。
编辑: 感谢 ZyX 的笔记
这段代码 将提示您使用 :w创建目录,或者只使用 :w!:
:w
augroup vimrc-auto-mkdir autocmd! autocmd BufWritePre * call s:auto_mkdir(expand('<afile>:p:h'), v:cmdbang) function! s:auto_mkdir(dir, force) if !isdirectory(a:dir) \ && (a:force \ || input("'" . a:dir . "' does not exist. Create? [y/N]") =~? '^y\%[es]$') call mkdir(iconv(a:dir, &encoding, &termencoding), 'p') endif endfunction augroup END