How to Create Parent Directories. A parent directory is a directory that is above another directory in the directory tree. To create parent directories, use the -p option. When the -p option is used, the command creates the directory only if it doesn't exist.
As we all know. Every Unix directories contains special directories- current(.) & parent(..).
You can change the working directory with :cd path/to/new/directory . Or you can enter the full path to the location where you want to save the file with the write command, e.g., :w /var/www/filename .
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
    Based on the suggestions to my question, here's what I ended up with:
function WriteCreatingDirs()
    execute ':silent !mkdir -p %:h'
    write
endfunction
command W call WriteCreatingDirs()
This defines the :W command. Ideally, I'd like to have all of :w!, :wq, :wq!, :wall etc work the same, but I'm not sure if it's possible without basically reimplementing them all with custom functions.
I added this to my ~/.vimrc
cnoremap mk. !mkdir -p <c-r>=expand("%:h")<cr>/
If I need to create the directory I'm in I type :mk. and it replaces that with "!mkdir -p /path/to/my/file/" and allows me to review the command before I invoke it.
This code will prompt you to create the directory with :w, or just do it with :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
    I made :saveas! create the directory if missing: https://github.com/henrik/dotfiles/commit/54cc9474b345332cf54cf25b51ddb8a9bd00a0bb
I think I managed to do this in three lines, combining what others are saying on this answer.
This seems to do the trick:
if has("autocmd")
  autocmd BufWritePre * :silent !mkdir -p %:p:h
end
It attempts to create the folder automatically when saving a buffer. If anything bad happens (i.e. permission issues) it will just shut up and let the file write fail.
If anyone sees any obvious flaws, please post a comment. I'm not very versed in vimscript.
EDIT: Notes thanks to ZyX
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With