/autoload/vital/__latest__/system/filepath.vim

https://bitbucket.org/deris0126/vital.vim · Vim Script · 173 lines · 119 code · 26 blank · 28 comment · 26 complexity · 238633ee702697d5e527176b464dd2b6 MD5 · raw file

  1. " You should check the following related builtin functions.
  2. " fnamemodify()
  3. " resolve()
  4. " simplify()
  5. let s:save_cpo = &cpo
  6. set cpo&vim
  7. let s:path_sep_pattern = (exists('+shellslash') ? '[\\/]' : '/') . '\+'
  8. let s:is_windows = has('win16') || has('win32') || has('win64')
  9. let s:is_cygwin = has('win32unix')
  10. let s:is_mac = !s:is_windows && !s:is_cygwin
  11. \ && (has('mac') || has('macunix') || has('gui_macvim') ||
  12. \ (!isdirectory('/proc') && executable('sw_vers')))
  13. " Get the directory separator.
  14. function! s:separator()
  15. return fnamemodify('.', ':p')[-1 :]
  16. endfunction
  17. " Get the path separator.
  18. let s:path_separator = s:is_windows ? ';' : ':'
  19. function! s:path_separator()
  20. return s:path_separator
  21. endfunction
  22. " Get the path extensions
  23. function! s:path_extensions()
  24. if !exists('s:path_extensions')
  25. if s:is_windows
  26. if exists('$PATHEXT')
  27. let pathext = $PATHEXT
  28. else
  29. " get default PATHEXT
  30. let pathext = matchstr(system('set pathext'), '^pathext=\zs.*\ze\n', 'i')
  31. endif
  32. let s:path_extensions = map(split(pathext, s:path_separator), 'tolower(v:val)')
  33. elseif s:is_cygwin
  34. " cygwin is not use $PATHEXT
  35. let s:path_extensions = ['', '.exe']
  36. else
  37. let s:path_extensions = ['']
  38. endif
  39. endif
  40. return s:path_extensions
  41. endfunction
  42. " Convert all directory separators to "/".
  43. function! s:unify_separator(path)
  44. return substitute(a:path, s:path_sep_pattern, '/', 'g')
  45. endfunction
  46. " Get the full path of command.
  47. function! s:which(command, ...)
  48. let pathlist = a:command =~# s:path_sep_pattern ? [''] :
  49. \ !a:0 ? split($PATH, s:path_separator) :
  50. \ type(a:1) == type([]) ? copy(a:1) :
  51. \ split(a:1, s:path_separator)
  52. let pathext = s:path_extensions()
  53. if index(pathext, '.' . tolower(fnamemodify(a:command, ':e'))) != -1
  54. let pathext = ['']
  55. endif
  56. let dirsep = s:separator()
  57. for dir in pathlist
  58. let head = dir ==# '' ? '' : dir . dirsep
  59. for ext in pathext
  60. let full = fnamemodify(head . a:command . ext, ':p')
  61. if filereadable(full)
  62. if s:is_case_tolerant()
  63. let full = glob(substitute(
  64. \ toupper(full), '\u:\@!', '[\0\L\0]', 'g'), 1)
  65. endif
  66. if full != ''
  67. return full
  68. endif
  69. endif
  70. endfor
  71. endfor
  72. return ''
  73. endfunction
  74. " Split the path with directory separator.
  75. " Note that this includes the drive letter of MS Windows.
  76. function! s:split(path)
  77. return split(a:path, s:path_sep_pattern)
  78. endfunction
  79. " Join the paths.
  80. " join('foo', 'bar') => 'foo/bar'
  81. " join('foo/', 'bar') => 'foo/bar'
  82. " join('/foo/', ['bar', 'buz/']) => '/foo/bar/buz/'
  83. function! s:join(...)
  84. let sep = s:separator()
  85. let path = ''
  86. for part in a:000
  87. let path .= sep .
  88. \ (type(part) is type([]) ? call('s:join', part) :
  89. \ part)
  90. unlet part
  91. endfor
  92. return substitute(path[1 :], s:path_sep_pattern, sep, 'g')
  93. endfunction
  94. " Check if the path is absolute path.
  95. if s:is_windows
  96. function! s:is_absolute(path)
  97. return a:path =~? '^[a-z]:[/\]'
  98. endfunction
  99. else
  100. function! s:is_absolute(path)
  101. return a:path[0] ==# '/'
  102. endfunction
  103. endif
  104. function! s:is_relative(path)
  105. return !s:is_absolute(a:path)
  106. endfunction
  107. " Return the parent directory of the path.
  108. " NOTE: fnamemodify(path, ':h') does not return the parent directory
  109. " when path[-1] is the separator.
  110. function! s:dirname(path)
  111. let path = a:path
  112. let orig = a:path
  113. let path = s:remove_last_separator(path)
  114. if path == ''
  115. return orig " root directory
  116. endif
  117. let path = fnamemodify(path, ':h')
  118. return path
  119. endfunction
  120. " Return the basename of the path.
  121. " NOTE: fnamemodify(path, ':h') does not return basename
  122. " when path[-1] is the separator.
  123. function! s:basename(path)
  124. let path = a:path
  125. let orig = a:path
  126. let path = s:remove_last_separator(path)
  127. if path == ''
  128. return orig " root directory
  129. endif
  130. let path = fnamemodify(path, ':t')
  131. return path
  132. endfunction
  133. " Remove the separator at the end of a:path.
  134. function! s:remove_last_separator(path)
  135. let sep = s:separator()
  136. let pat = (sep == '\' ? '\\' : '/') . '\+$'
  137. return substitute(a:path, pat, '', '')
  138. endfunction
  139. " Return true if filesystem ignores alphabetic case of a filename.
  140. " Return false otherwise.
  141. let s:is_case_tolerant = filereadable(expand('<sfile>:r') . '.VIM')
  142. function! s:is_case_tolerant()
  143. return s:is_case_tolerant
  144. endfunction
  145. let &cpo = s:save_cpo
  146. unlet s:save_cpo
  147. " vim:set et ts=2 sts=2 sw=2 tw=0: