Vim:保存时创build父目录

如果我调用vim foo/bar/somefile但是foo/bar不存在,Vim拒绝保存。

我知道我可以切换到一个shell或做:!mkdir foo/bar Vim的:!mkdir foo/bar ,但我很懒:)有没有办法让Vim自动保存缓冲区?

 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等文件创build目录,从而避免昂贵的mkdir调用。

更新 :sligtly更好的解决scheme,也检查非空buftype和使用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 

基于对我的问题的build议,以下是我最终的结果:

 function WriteCreatingDirs() execute ':silent !mkdir -p %:h' write endfunction command W call WriteCreatingDirs() 

这定义了:W命令。 理想情况下,我想拥有所有的:w!:wq:wq!:wall等工作是一样的,但我不知道是否有可能没有基本上用自定义函数重新实现它们。

我把这个添加到我的〜/ .vimrc中

cnoremap mk. !mkdir -p <cr>=expand("%:h")<cr>/

如果我需要创build目录我在我input:mk. 并用“!mkdir -p / path / to / my / file /”replace它,并允许我在调用之前查看该命令。

我做了:saveas! 如果缺less创build目录: https : //github.com/henrik/dotfiles/commit/54cc9474b345332cf54cf25b51ddb8a9bd00a0bb

我想我设法做到了三行,结合了其他人对这个答案的看法。

这似乎是诀窍:

 if has("autocmd") autocmd BufWritePre * :silent !mkdir -p %:p:h end 

它试图在保存缓冲区时自动创build文件夹。 如果有什么不好的情况发生(比如许可问题),它会closures,让文件写入失败。

如果有人发现任何明显的缺陷,请发表评论。 我对vimscript不是很熟悉。

编辑:注意感谢ZyX

  • 这不会工作,如果你的文件夹上有空格(显然他们没有正确逃脱或什么的)
  • 或者如果你正在做伪文件。
  • 或者如果你正在采购你的vimrc。
  • 但是,儿子,这是短暂的。

这段代码会提示你使用:w来创build目录,或者直接使用: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