aboutsummaryrefslogtreecommitdiff
path: root/autoload/write_mkpath.vim
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 /autoload/write_mkpath.vim
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
Diffstat (limited to 'autoload/write_mkpath.vim')
-rw-r--r--autoload/write_mkpath.vim63
1 files changed, 52 insertions, 11 deletions
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