Search code examples
vimmkdir

Vim: Creating parent directories on save


If I invoke vim foo/bar/somefile but foo/bar don't already exist, Vim refuses to save.

I know I could switch to a shell or do :!mkdir foo/bar from Vim but I'm lazy :) Is there a way to make Vim do that automatically when it saves the buffer?


Solution

  • augroup BWCCreateDir
        autocmd!
        autocmd BufWritePre * if expand("<afile>")!~#'^\w\+:/' && !isdirectory(expand("%:h")) | execute "silent! !mkdir -p ".shellescape(expand('%:h'), 1) | redraw! | endif
    augroup END
    

    Note the conditions: expand("<afile>")!~#'^\w\+:/' will prevent vim from creating directories for files like ftp://* and !isdirectory will prevent expensive mkdir call.

    Update: sligtly better solution that also checks for non-empty buftype and uses 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