如果我调用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
事件似乎在这里不起作用。