Vim:保存时创建父目录

问题描述 投票:0回答:8

如果我调用

vim foo/bar/somefile
foo/bar
尚不存在,Vim 会拒绝保存。

我知道我可以切换到 shell 或从 Vim 做

:!mkdir foo/bar
,但我很懒:) 有没有办法让 Vim 在保存缓冲区时自动执行此操作?

vim mkdir
8个回答
97
投票
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

24
投票

根据对我的问题的建议,这就是我的结论:

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

这定义了

:W
命令。理想情况下,我希望所有的
:w!
:wq
:wq!
:wall
等都能以相同的方式工作,但我不确定是否可以在不使用自定义函数基本上重新实现它们的情况下实现。


9
投票

此代码将提示您使用

: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

7
投票

我将其添加到我的 ~/.vimrc 中

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

如果我需要创建我所在的目录,我输入

:mk.
并将其替换为“!mkdir -p /path/to/my/file/”,并允许我在调用命令之前查看该命令。


4
投票

4
投票

我想我成功地用三行代码做到了这一点,结合了其他人对此答案的看法。

这似乎可以解决问题:

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

保存缓冲区时它会尝试自动创建文件夹。如果发生任何不好的事情(即权限问题),它就会关闭并让文件写入失败。

如果有人发现任何明显的缺陷,请发表评论。我不太精通 vimscript。

编辑:感谢 ZyX 的注释

  • 如果您的文件夹上有空格(显然它们没有正确转义或其他什么),这将不起作用
  • 或者如果你正在做伪文件。
  • 或者如果您正在获取 vimrc。
  • 但是儿子,它很短。

2
投票

我不明白为什么每个人都尝试复杂的功能。这足以创建父文件夹

:!mkdir -p %:p:h
  • mkdir -p
    是创建父文件夹的 shell 命令
  • %:p:h
    是文件夹路径
    • %
      : vim 启动时给出的路径:
      vim foo/bar/file.ext
    • :p
      :给出完整路径:
      /home/user/foo/bar/file.ext
    • :h
      :从最终字符串中删除文件名:
      /home/user/foo/bar
  • %:h
    也可以工作并给出相对路径:
    foo/bar

0
投票

您可以为此安装一个插件,例如https://github.com/DataWraith/auto_mkdir

要使用 vim 的内置插件管理,请像这样克隆它:

git clone https://github.com/DataWraith/auto_mkdir ~/.vim/pack/vendor/start/auto_mkdir

下次打开 vim 时它将处于活动状态。

© www.soinside.com 2019 - 2024. All rights reserved.