" Handle a buffer created for a new file; anchor its filename to be absolute " if it's relative and the directory path doesn't yet exist; this stops Vim " trying to save in the wrong place if the user changes directory before " writing the buffer function! write_mkpath#New(path) abort " We don't have fnameescape(); this old Vim < v7.1.299 is likely too buggy " to handle the buffer renaming for paths safely, so better not to mess with " it and instead to stick with suboptimal but consistent behaviour if !exists('*fnameescape') return endif " Path exists, or is absolute; we don't need to do anything if isdirectory(fnamemodify(a:path, ':h')) \ || s:Absolute(a:path) return endif " Set filename to absolute path using :file {name}; do it silently so that " the nice name remains displayed to the user. Record the name of the " alternate buffer first, so we can put it back after :file messes with it. let alt = @# execute 'silent file '.fnameescape(getcwd().'/'.a:path) " That :file command will have set the alternate buffer to an unlisted " buffer of the same name, which we don't want. Wipe it, and restore the " previous alternative buffer. bwipe # let @# = alt endfunction " Handle a :write operation; prompt for directory creation if needed with " 'confirm', force it with :write! function! write_mkpath#Write(path) abort " Get all directory elements leading up to directory let dir = fnamemodify(a:path, ':h') " Directory exists, we don't need to do anything if isdirectory(dir) return endif " If :write! was issued, we'll try to create the missing path; failing that, " if 'confirm' is enabled, and the user responds affirmatively to the " prompt, that will do, too. Otherwise, we will allow the write to fail. if v:cmdbang let mkpath = 1 elseif &confirm let mkpath = confirm('Create path '.dir.'?', "&Yes\n&No") == 1 else let mkpath = 0 endif " If we decided to attempt a path creation, do so if mkpath call mkdir(dir, 'p') endif endfunction " Clumsy and probably wrong helper function to check if a path is absolute function! s:Absolute(path) abort if has('unix') return a:path =~# '^/' " Leading slash on Unix elseif has('win32') || has('win64') return a:path =~# '^\u:' " e.g. C: -- I'm not sure this is right else echoerr 'Unrecognised operating system' endif endfunction