Prelude.vim 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. " ___vital___
  2. " NOTE: lines between '" ___vital___' is generated by :Vitalize.
  3. " Do not mofidify the code nor insert new lines before '" ___vital___'
  4. if v:version > 703 || v:version == 703 && has('patch1170')
  5. function! vital#_neocomplete#Prelude#import() abort
  6. return map({'escape_pattern': '', 'is_funcref': '', 'path2directory': '', 'wcswidth': '', 'is_string': '', 'input_helper': '', 'is_number': '', 'is_cygwin': '', 'path2project_directory': '', 'strwidthpart_reverse': '', 'input_safe': '', 'is_list': '', 'truncate_skipping': '', 'glob': '', 'truncate': '', 'is_dict': '', 'set_default': '', 'is_numeric': '', 'getchar_safe': '', 'substitute_path_separator': '', 'is_mac': '', 'strwidthpart': '', 'getchar': '', 'is_unix': '', 'is_windows': '', 'globpath': '', 'escape_file_searching': '', 'is_float': '', 'smart_execute_command': ''}, 'function("s:" . v:key)')
  7. endfunction
  8. else
  9. function! s:_SID() abort
  10. return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
  11. endfunction
  12. execute join(['function! vital#_neocomplete#Prelude#import() abort', printf("return map({'escape_pattern': '', 'is_funcref': '', 'path2directory': '', 'wcswidth': '', 'is_string': '', 'input_helper': '', 'is_number': '', 'is_cygwin': '', 'path2project_directory': '', 'strwidthpart_reverse': '', 'input_safe': '', 'is_list': '', 'truncate_skipping': '', 'glob': '', 'truncate': '', 'is_dict': '', 'set_default': '', 'is_numeric': '', 'getchar_safe': '', 'substitute_path_separator': '', 'is_mac': '', 'strwidthpart': '', 'getchar': '', 'is_unix': '', 'is_windows': '', 'globpath': '', 'escape_file_searching': '', 'is_float': '', 'smart_execute_command': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
  13. delfunction s:_SID
  14. endif
  15. " ___vital___
  16. let s:save_cpo = &cpo
  17. set cpo&vim
  18. if v:version > 703 ||
  19. \ (v:version == 703 && has('patch465'))
  20. function! s:glob(expr) abort
  21. return glob(a:expr, 1, 1)
  22. endfunction
  23. else
  24. function! s:glob(expr) abort
  25. return split(glob(a:expr, 1), '\n')
  26. endfunction
  27. endif
  28. if v:version > 704 ||
  29. \ (v:version == 704 && has('patch279'))
  30. function! s:globpath(path, expr) abort
  31. return globpath(a:path, a:expr, 1, 1)
  32. endfunction
  33. else
  34. function! s:globpath(path, expr) abort
  35. return split(globpath(a:path, a:expr, 1), '\n')
  36. endfunction
  37. endif
  38. " Wrapper functions for type().
  39. " NOTE: __TYPE_FLOAT = -1 when -float.
  40. " this doesn't match to anything.
  41. if has('patch-7.4.2071')
  42. let [
  43. \ s:__TYPE_NUMBER,
  44. \ s:__TYPE_STRING,
  45. \ s:__TYPE_FUNCREF,
  46. \ s:__TYPE_LIST,
  47. \ s:__TYPE_DICT,
  48. \ s:__TYPE_FLOAT] = [
  49. \ v:t_number,
  50. \ v:t_string,
  51. \ v:t_func,
  52. \ v:t_list,
  53. \ v:t_dict,
  54. \ v:t_float]
  55. else
  56. let [
  57. \ s:__TYPE_NUMBER,
  58. \ s:__TYPE_STRING,
  59. \ s:__TYPE_FUNCREF,
  60. \ s:__TYPE_LIST,
  61. \ s:__TYPE_DICT,
  62. \ s:__TYPE_FLOAT] = [
  63. \ type(3),
  64. \ type(''),
  65. \ type(function('tr')),
  66. \ type([]),
  67. \ type({}),
  68. \ has('float') ? type(str2float('0')) : -1]
  69. endif
  70. " Number or Float
  71. function! s:is_numeric(Value) abort
  72. let _ = type(a:Value)
  73. return _ ==# s:__TYPE_NUMBER
  74. \ || _ ==# s:__TYPE_FLOAT
  75. endfunction
  76. " Number
  77. function! s:is_number(Value) abort
  78. return type(a:Value) ==# s:__TYPE_NUMBER
  79. endfunction
  80. " String
  81. function! s:is_string(Value) abort
  82. return type(a:Value) ==# s:__TYPE_STRING
  83. endfunction
  84. " Funcref
  85. function! s:is_funcref(Value) abort
  86. return type(a:Value) ==# s:__TYPE_FUNCREF
  87. endfunction
  88. " List
  89. function! s:is_list(Value) abort
  90. return type(a:Value) ==# s:__TYPE_LIST
  91. endfunction
  92. " Dictionary
  93. function! s:is_dict(Value) abort
  94. return type(a:Value) ==# s:__TYPE_DICT
  95. endfunction
  96. " Float
  97. function! s:is_float(Value) abort
  98. return type(a:Value) ==# s:__TYPE_FLOAT
  99. endfunction
  100. function! s:truncate_skipping(str, max, footer_width, separator) abort
  101. call s:_warn_deprecated('truncate_skipping', 'Data.String.truncate_skipping')
  102. let width = s:wcswidth(a:str)
  103. if width <= a:max
  104. let ret = a:str
  105. else
  106. let header_width = a:max - s:wcswidth(a:separator) - a:footer_width
  107. let ret = s:strwidthpart(a:str, header_width) . a:separator
  108. \ . s:strwidthpart_reverse(a:str, a:footer_width)
  109. endif
  110. return s:truncate(ret, a:max)
  111. endfunction
  112. function! s:truncate(str, width) abort
  113. " Original function is from mattn.
  114. " http://github.com/mattn/googlereader-vim/tree/master
  115. call s:_warn_deprecated('truncate', 'Data.String.truncate')
  116. if a:str =~# '^[\x00-\x7f]*$'
  117. return len(a:str) < a:width ?
  118. \ printf('%-'.a:width.'s', a:str) : strpart(a:str, 0, a:width)
  119. endif
  120. let ret = a:str
  121. let width = s:wcswidth(a:str)
  122. if width > a:width
  123. let ret = s:strwidthpart(ret, a:width)
  124. let width = s:wcswidth(ret)
  125. endif
  126. if width < a:width
  127. let ret .= repeat(' ', a:width - width)
  128. endif
  129. return ret
  130. endfunction
  131. function! s:strwidthpart(str, width) abort
  132. call s:_warn_deprecated('strwidthpart', 'Data.String.strwidthpart')
  133. if a:width <= 0
  134. return ''
  135. endif
  136. let ret = a:str
  137. let width = s:wcswidth(a:str)
  138. while width > a:width
  139. let char = matchstr(ret, '.$')
  140. let ret = ret[: -1 - len(char)]
  141. let width -= s:wcswidth(char)
  142. endwhile
  143. return ret
  144. endfunction
  145. function! s:strwidthpart_reverse(str, width) abort
  146. call s:_warn_deprecated('strwidthpart_reverse', 'Data.String.strwidthpart_reverse')
  147. if a:width <= 0
  148. return ''
  149. endif
  150. let ret = a:str
  151. let width = s:wcswidth(a:str)
  152. while width > a:width
  153. let char = matchstr(ret, '^.')
  154. let ret = ret[len(char) :]
  155. let width -= s:wcswidth(char)
  156. endwhile
  157. return ret
  158. endfunction
  159. if v:version >= 703
  160. " Use builtin function.
  161. function! s:wcswidth(str) abort
  162. call s:_warn_deprecated('wcswidth', 'Data.String.wcswidth')
  163. return strwidth(a:str)
  164. endfunction
  165. else
  166. function! s:wcswidth(str) abort
  167. call s:_warn_deprecated('wcswidth', 'Data.String.wcswidth')
  168. if a:str =~# '^[\x00-\x7f]*$'
  169. return strlen(a:str)
  170. end
  171. let mx_first = '^\(.\)'
  172. let str = a:str
  173. let width = 0
  174. while 1
  175. let ucs = char2nr(substitute(str, mx_first, '\1', ''))
  176. if ucs == 0
  177. break
  178. endif
  179. let width += s:_wcwidth(ucs)
  180. let str = substitute(str, mx_first, '', '')
  181. endwhile
  182. return width
  183. endfunction
  184. " UTF-8 only.
  185. function! s:_wcwidth(ucs) abort
  186. let ucs = a:ucs
  187. if (ucs >= 0x1100
  188. \ && (ucs <= 0x115f
  189. \ || ucs == 0x2329
  190. \ || ucs == 0x232a
  191. \ || (ucs >= 0x2e80 && ucs <= 0xa4cf
  192. \ && ucs != 0x303f)
  193. \ || (ucs >= 0xac00 && ucs <= 0xd7a3)
  194. \ || (ucs >= 0xf900 && ucs <= 0xfaff)
  195. \ || (ucs >= 0xfe30 && ucs <= 0xfe6f)
  196. \ || (ucs >= 0xff00 && ucs <= 0xff60)
  197. \ || (ucs >= 0xffe0 && ucs <= 0xffe6)
  198. \ || (ucs >= 0x20000 && ucs <= 0x2fffd)
  199. \ || (ucs >= 0x30000 && ucs <= 0x3fffd)
  200. \ ))
  201. return 2
  202. endif
  203. return 1
  204. endfunction
  205. endif
  206. let s:is_windows = has('win16') || has('win32') || has('win64') || has('win95')
  207. let s:is_cygwin = has('win32unix')
  208. let s:is_mac = !s:is_windows && !s:is_cygwin
  209. \ && (has('mac') || has('macunix') || has('gui_macvim') ||
  210. \ (!isdirectory('/proc') && executable('sw_vers')))
  211. let s:is_unix = has('unix')
  212. function! s:is_windows() abort
  213. return s:is_windows
  214. endfunction
  215. function! s:is_cygwin() abort
  216. return s:is_cygwin
  217. endfunction
  218. function! s:is_mac() abort
  219. return s:is_mac
  220. endfunction
  221. function! s:is_unix() abort
  222. return s:is_unix
  223. endfunction
  224. function! s:_warn_deprecated(name, alternative) abort
  225. try
  226. echohl Error
  227. echomsg 'Prelude.' . a:name . ' is deprecated! Please use ' . a:alternative . ' instead.'
  228. finally
  229. echohl None
  230. endtry
  231. endfunction
  232. function! s:smart_execute_command(action, word) abort
  233. execute a:action . ' ' . (a:word ==# '' ? '' : '`=a:word`')
  234. endfunction
  235. function! s:escape_file_searching(buffer_name) abort
  236. return escape(a:buffer_name, '*[]?{}, ')
  237. endfunction
  238. function! s:escape_pattern(str) abort
  239. call s:_warn_deprecated(
  240. \ 'escape_pattern',
  241. \ 'Data.String.escape_pattern',
  242. \)
  243. return escape(a:str, '~"\.^$[]*')
  244. endfunction
  245. function! s:getchar(...) abort
  246. let c = call('getchar', a:000)
  247. return type(c) == type(0) ? nr2char(c) : c
  248. endfunction
  249. function! s:getchar_safe(...) abort
  250. let c = s:input_helper('getchar', a:000)
  251. return type(c) == type('') ? c : nr2char(c)
  252. endfunction
  253. function! s:input_safe(...) abort
  254. return s:input_helper('input', a:000)
  255. endfunction
  256. function! s:input_helper(funcname, args) abort
  257. let success = 0
  258. if inputsave() !=# success
  259. throw 'vital: Prelude: inputsave() failed'
  260. endif
  261. try
  262. return call(a:funcname, a:args)
  263. finally
  264. if inputrestore() !=# success
  265. throw 'vital: Prelude: inputrestore() failed'
  266. endif
  267. endtry
  268. endfunction
  269. function! s:set_default(var, val) abort
  270. if !exists(a:var) || type({a:var}) != type(a:val)
  271. let {a:var} = a:val
  272. endif
  273. endfunction
  274. function! s:substitute_path_separator(path) abort
  275. return s:is_windows ? substitute(a:path, '\\', '/', 'g') : a:path
  276. endfunction
  277. function! s:path2directory(path) abort
  278. return s:substitute_path_separator(isdirectory(a:path) ? a:path : fnamemodify(a:path, ':p:h'))
  279. endfunction
  280. function! s:_path2project_directory_git(path) abort
  281. let parent = a:path
  282. while 1
  283. let path = parent . '/.git'
  284. if isdirectory(path) || filereadable(path)
  285. return parent
  286. endif
  287. let next = fnamemodify(parent, ':h')
  288. if next == parent
  289. return ''
  290. endif
  291. let parent = next
  292. endwhile
  293. endfunction
  294. function! s:_path2project_directory_svn(path) abort
  295. let search_directory = a:path
  296. let directory = ''
  297. let find_directory = s:escape_file_searching(search_directory)
  298. let d = finddir('.svn', find_directory . ';')
  299. if d ==# ''
  300. return ''
  301. endif
  302. let directory = fnamemodify(d, ':p:h:h')
  303. " Search parent directories.
  304. let parent_directory = s:path2directory(
  305. \ fnamemodify(directory, ':h'))
  306. if parent_directory !=# ''
  307. let d = finddir('.svn', parent_directory . ';')
  308. if d !=# ''
  309. let directory = s:_path2project_directory_svn(parent_directory)
  310. endif
  311. endif
  312. return directory
  313. endfunction
  314. function! s:_path2project_directory_others(vcs, path) abort
  315. let vcs = a:vcs
  316. let search_directory = a:path
  317. let find_directory = s:escape_file_searching(search_directory)
  318. let d = finddir(vcs, find_directory . ';')
  319. if d ==# ''
  320. return ''
  321. endif
  322. return fnamemodify(d, ':p:h:h')
  323. endfunction
  324. function! s:path2project_directory(path, ...) abort
  325. let is_allow_empty = get(a:000, 0, 0)
  326. let search_directory = s:path2directory(a:path)
  327. let directory = ''
  328. " Search VCS directory.
  329. for vcs in ['.git', '.bzr', '.hg', '.svn']
  330. if vcs ==# '.git'
  331. let directory = s:_path2project_directory_git(search_directory)
  332. elseif vcs ==# '.svn'
  333. let directory = s:_path2project_directory_svn(search_directory)
  334. else
  335. let directory = s:_path2project_directory_others(vcs, search_directory)
  336. endif
  337. if directory !=# ''
  338. break
  339. endif
  340. endfor
  341. " Search project file.
  342. if directory ==# ''
  343. for d in ['build.xml', 'prj.el', '.project', 'pom.xml', 'package.json',
  344. \ 'Makefile', 'configure', 'Rakefile', 'NAnt.build',
  345. \ 'P4CONFIG', 'tags', 'gtags']
  346. let d = findfile(d, s:escape_file_searching(search_directory) . ';')
  347. if d !=# ''
  348. let directory = fnamemodify(d, ':p:h')
  349. break
  350. endif
  351. endfor
  352. endif
  353. if directory ==# ''
  354. " Search /src/ directory.
  355. let base = s:substitute_path_separator(search_directory)
  356. if base =~# '/src/'
  357. let directory = base[: strridx(base, '/src/') + 3]
  358. endif
  359. endif
  360. if directory ==# '' && !is_allow_empty
  361. " Use original path.
  362. let directory = search_directory
  363. endif
  364. return s:substitute_path_separator(directory)
  365. endfunction
  366. let &cpo = s:save_cpo
  367. unlet s:save_cpo
  368. " vim:set et ts=2 sts=2 sw=2 tw=0: