如果我调用vim foo/bar/somefile但foo/bar尚不存在,Vim拒绝保存。
我知道我可以切换到shell或:!mkdir foo/bar从Vim进行操作,但是我很懒:)有没有办法让Vim在保存缓冲区时自动执行此操作?
write,并调用系统mkdir -p上dirname,否则,它映射到W...我懒得搜索语法并把它张贴作为答案...对不起
:w,mkdir -p %:h然后再进行构建:write
如果我调用vim foo/bar/somefile但foo/bar尚不存在,Vim拒绝保存。
我知道我可以切换到shell或:!mkdir foo/bar从Vim进行操作,但是我很懒:)有没有办法让Vim在保存缓冲区时自动执行此操作?
write,并调用系统mkdir -p上dirname,否则,它映射到W...我懒得搜索语法并把它张贴作为答案...对不起
:w,mkdir -p %:h然后再进行构建:write
Answers:
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
call mkdir(expand('%:h'), 'p')可能更便携。
根据对我的问题的建议,以下是我得出的结论:
function WriteCreatingDirs()
execute ':silent !mkdir -p %:h'
write
endfunction
command W call WriteCreatingDirs()
这定义了:W命令。理想情况下,我想有所有的:w!,:wq,:wq!,:wall等工作相同,但我不知道是否有可能基本上没有重新实现他们所有的自定义功能。
:W,屏幕几乎都变成空白。我将尝试删除以前的选项并提供反馈。
我将此添加到我的〜/ .vimrc
cnoremap mk. !mkdir -p <c-r>=expand("%:h")<cr>/
如果需要创建目录,请输入,:mk.并将其替换为“!mkdir -p / path / to / my / file /”,并允许我在调用该命令之前先对其进行检查。
:saveas!如果丢失,我创建了目录:https : //github.com/henrik/dotfiles/commit/54cc9474b345332cf54cf25b51ddb8a9bd00a0bb
此代码将提示您使用创建目录: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
我认为我成功地做到了三行,结合了其他人对此答案的看法。
这似乎可以解决问题:
if has("autocmd")
autocmd BufWritePre * :silent !mkdir -p %:p:h
end
保存缓冲区时,它将尝试自动创建文件夹。如果发生任何不良情况(即权限问题),它将关闭并让文件写入失败。
如果有人发现任何明显的缺陷,请发表评论。我对vimscript不太了解。
编辑:感谢ZyX
%在此类脚本中使用。VIM是不会逃避任何特殊符号:例如,如果您正在编辑一个文件名为/mnt/windows/Documents and Settings/User/_vimrc你最终将有四个新的目录:/mnt/windows/Documents,./and,./Settings和./Settings/User。而且,顺便说一句,您不需要:execute在这里。
system()功能可用于完全无声的shell调用,但是您并不需要:execute和%:p:h:都:silent !mkdir -p %:p:h完全按照您编写的内容工作(尽管:redraw!最后可能需要,在这种情况下:execute很方便),但最好使用call system('mkdir -p '.shellescape(expand('%:p:h')))。:execute '!command' shellescape(arg, 1)如果必须使用bang而不是,请使用(带有shellescape的第二个参数)system()。如果转义参数包含换行符,请使用刘海。
:source ~/.vimrc)(这是augroup和autocmd!是),发射后壳报废视图命令(这是什么redraw!),在使用伪文件的情况下创建垃圾目录(在第一个代码片段中,仅通过将文件名与模式匹配来进行检查,但在第二个代码中,我也进行了检查&buftype),并且在情况目录下无用的shell调用存在(isdirectory()条件)。
%扩展有太多问题,无法建议任何人使用它。伪文件用于大量插件(例如,逃犯或我的金光闪闪)中,因此值得关注。对vimrc进行资源配置也是一种常见的做法。您可以在vimrc中拥有任何想要的东西,只是不要建议它作为答案。使用:silent! call mkdir(expand('%:p:h'), 'p')variant解决了我提到的两点,我没有提到的三点:!mkdir在Windows上不起作用。
mkdir -p %:h更好,因为它适用于嵌套的不存在的路径,当路径已经存在时不会引发错误,并且%:h是当前文件的完整路径。但是,我不知道如何自动调用它。通常,这是通过automcommands完成的,但是该BufWritePre事件似乎在这里不起作用。