如果我调用vim foo/bar/somefile
但foo/bar
不存在,Vim 拒绝保存。
我知道我可以切换到 shell 或:!mkdir foo/bar
从 Vim 执行,但我很懒 :) 有没有办法让 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
阻止昂贵的 mkdir 调用。
更新:更好的解决方案,它还检查非空 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
根据对我的问题的建议,这就是我最终得到的结果:
function WriteCreatingDirs()
execute ':silent !mkdir -p %:h'
write
endfunction
command W call WriteCreatingDirs()
这定义了:W
命令。理想情况下,我希望所有 , :w!
, :wq
,:wq!
等都:wall
一样工作,但我不确定如果不使用自定义函数基本上重新实现它们是否有可能。
我将此添加到我的 ~/.vimrc
cnoremap mk. !mkdir -p <c-r>=expand("%:h")<cr>/
如果我需要创建我所在的目录,我输入:mk.
并将其替换为“!mkdir -p /path/to/my/file/”,并允许我在调用它之前查看命令。
此代码将提示您使用创建目录: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
:saveas!
如果丢失,我创建了目录: https ://github.com/henrik/dotfiles/commit/54cc9474b345332cf54cf25b51ddb8a9bd00a0bb
我想我设法在三行中做到了这一点,结合了其他人对这个答案的看法。
这似乎可以解决问题:
if has("autocmd")
autocmd BufWritePre * :silent !mkdir -p %:p:h
end
它会在保存缓冲区时尝试自动创建文件夹。如果发生任何不好的事情(即权限问题),它将关闭并让文件写入失败。
如果有人看到任何明显的缺陷,请发表评论。我不是很精通vimscript。
编辑:感谢 ZyX 的注释