aboutsummaryrefslogtreecommitdiff
path: root/autoload/write_mkpath.vim
blob: 3bcd7868b453afad6021014275e6011c06c81fb9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
" 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.
  execute 'silent keepalt 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 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