aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Ryder <tom@sanctum.geek.nz>2019-05-31 23:16:51 +1200
committerTom Ryder <tom@sanctum.geek.nz>2019-05-31 23:16:51 +1200
commite9ef1eb2832c73e4130da1b4bd1f0de73609c10c (patch)
tree0a2397aba7214c4e65d9d29d8185362cf5868621
parentMerge branch 'release/v0.4.0' (diff)
parentBump VERSION (diff)
downloadvim-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--VERSION2
-rw-r--r--autoload/write_mkpath.vim63
-rw-r--r--doc/write_mkpath.txt11
-rw-r--r--plugin/write_mkpath.vim4
4 files changed, 66 insertions, 14 deletions
diff --git a/VERSION b/VERSION
index 1d0ba9e..3eefcb9 100644
--- a/VERSION
+++ b/VERSION
@@ -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