diff options
author | Tom Ryder <tom@sanctum.geek.nz> | 2019-05-31 23:16:51 +1200 |
---|---|---|
committer | Tom Ryder <tom@sanctum.geek.nz> | 2019-05-31 23:16:51 +1200 |
commit | e9ef1eb2832c73e4130da1b4bd1f0de73609c10c (patch) | |
tree | 0a2397aba7214c4e65d9d29d8185362cf5868621 | |
parent | Merge branch 'release/v0.4.0' (diff) | |
parent | Bump VERSION (diff) | |
download | vim-write-mkpath-e9ef1eb2832c73e4130da1b4bd1f0de73609c10c.tar.gz vim-write-mkpath-e9ef1eb2832c73e4130da1b4bd1f0de73609c10c.zip |
Merge branch 'release/v1.0.0'v1.0.0
* release/v1.0.0:
Document Vim < 7.2 caveat
Suppress potentially confusing :file output
Handle :cd then buffer write of non-existent path
Remove unneeded variable scoping
-rw-r--r-- | VERSION | 2 | ||||
-rw-r--r-- | autoload/write_mkpath.vim | 63 | ||||
-rw-r--r-- | doc/write_mkpath.txt | 11 | ||||
-rw-r--r-- | plugin/write_mkpath.vim | 4 |
4 files changed, 66 insertions, 14 deletions
@@ -1 +1 @@ -0.4.0 +1.0.0 diff --git a/autoload/write_mkpath.vim b/autoload/write_mkpath.vim index 94fe21a..bfe45bd 100644 --- a/autoload/write_mkpath.vim +++ b/autoload/write_mkpath.vim @@ -1,24 +1,65 @@ -function! write_mkpath#(path) abort +" 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 - " Path exists, we don't need to do anything - if isdirectory(a:path) + " 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 - " If :write! was issued, we'll try to create the 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. + " 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 + execute 'silent file '.fnameescape(getcwd().'/'.a:path) + +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 l:mkpath = 1 + let mkpath = 1 elseif &confirm - let l:mkpath = confirm('Create path '.a:path.'?', "&Yes\n&No") == 1 + let mkpath = confirm('Create path '.dir.'?', "&Yes\n&No") == 1 else - let l:mkpath = 0 + let mkpath = 0 endif " If we decided to attempt a path creation, do so - if l:mkpath - call mkdir(a:path, 'p') + 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 diff --git a/doc/write_mkpath.txt b/doc/write_mkpath.txt index 8ba3709..db490f7 100644 --- a/doc/write_mkpath.txt +++ b/doc/write_mkpath.txt @@ -1,4 +1,4 @@ -*write_mkpath.txt* For Vim version 7.0 Last change: 2019 May 28 +*write_mkpath.txt* For Vim version 7.0 Last change: 2019 May 31 DESCRIPTION *write_mkpath* @@ -18,6 +18,15 @@ REQUIREMENTS *write_mkpath-requirements* This plugin only loads if 'compatible' is not set. +CAVEATS *write_mkpath-caveats* + +In Vim 7.0 and 7.1, the path will be created relative to Vim's working +directory at the time of the write operation, which might not be the same as +the working directory when the buffer was first created, e.g. after a |:cd| +change. This is worked around safely in Vim 7.2 and newer by calculating an +absolute path for new buffers with nonexistent relative paths, but filename +escaping bugs in earlier versions preclude the same fix in older versions. + AUTHOR *write_mkpath-author* Written and maintained by Tom Ryder <tom@sanctum.geek.nz>. diff --git a/plugin/write_mkpath.vim b/plugin/write_mkpath.vim index 334f24e..c7c9543 100644 --- a/plugin/write_mkpath.vim +++ b/plugin/write_mkpath.vim @@ -12,6 +12,8 @@ endif " Check path to every file before it's saved augroup write_mkpath autocmd! + autocmd BufNewFile * + \ call write_mkpath#New(expand('<afile>')) autocmd BufWritePre * - \ call write_mkpath#(expand('<afile>:p:h')) + \ call write_mkpath#Write(expand('<afile>')) augroup END |