util.vim 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. " MIT License. Copyright (c) 2013-2021 Bailey Ling Christian Brabandt et al.
  2. " vim: et ts=2 sts=2 sw=2
  3. scriptencoding utf-8
  4. call airline#init#bootstrap()
  5. " couple of static variables. Those should not change within a session, thus
  6. " can be initialized here as "static"
  7. let s:spc = g:airline_symbols.space
  8. let s:nomodeline = (v:version > 703 || (v:version == 703 && has("patch438"))) ? '<nomodeline>' : ''
  9. let s:has_strchars = exists('*strchars')
  10. let s:has_strcharpart = exists('*strcharpart')
  11. let s:focusgained_ignore_time = 0
  12. " TODO: Try to cache winwidth(0) function
  13. " e.g. store winwidth per window and access that, only update it, if the size
  14. " actually changed.
  15. function! airline#util#winwidth(...) abort
  16. let nr = get(a:000, 0, 0)
  17. " When statusline is on top, or using global statusline for Neovim
  18. " always return the number of columns
  19. if get(g:, 'airline_statusline_ontop', 0) || &laststatus > 2
  20. return &columns
  21. else
  22. return winwidth(nr)
  23. endif
  24. endfunction
  25. function! airline#util#shorten(text, winwidth, minwidth, ...)
  26. if airline#util#winwidth() < a:winwidth && len(split(a:text, '\zs')) > a:minwidth
  27. if get(a:000, 0, 0)
  28. " shorten from tail
  29. return '…'.matchstr(a:text, '.\{'.a:minwidth.'}$')
  30. else
  31. " shorten from beginning of string
  32. return matchstr(a:text, '^.\{'.a:minwidth.'}').'…'
  33. endif
  34. else
  35. return a:text
  36. endif
  37. endfunction
  38. function! airline#util#wrap(text, minwidth)
  39. if a:minwidth > 0 && airline#util#winwidth() < a:minwidth
  40. return ''
  41. endif
  42. return a:text
  43. endfunction
  44. function! airline#util#append(text, minwidth)
  45. if a:minwidth > 0 && airline#util#winwidth() < a:minwidth
  46. return ''
  47. endif
  48. let prefix = s:spc == "\ua0" ? s:spc : s:spc.s:spc
  49. return empty(a:text) ? '' : prefix.g:airline_left_alt_sep.s:spc.a:text
  50. endfunction
  51. function! airline#util#warning(msg)
  52. echohl WarningMsg
  53. echomsg "airline: ".a:msg
  54. echohl Normal
  55. endfunction
  56. function! airline#util#prepend(text, minwidth)
  57. if a:minwidth > 0 && airline#util#winwidth() < a:minwidth
  58. return ''
  59. endif
  60. return empty(a:text) ? '' : a:text.s:spc.g:airline_right_alt_sep.s:spc
  61. endfunction
  62. if v:version >= 704
  63. function! airline#util#getbufvar(bufnr, key, def)
  64. return getbufvar(a:bufnr, a:key, a:def)
  65. endfunction
  66. else
  67. function! airline#util#getbufvar(bufnr, key, def)
  68. let bufvals = getbufvar(a:bufnr, '')
  69. return get(bufvals, a:key, a:def)
  70. endfunction
  71. endif
  72. if v:version >= 704
  73. function! airline#util#getwinvar(winnr, key, def)
  74. return getwinvar(a:winnr, a:key, a:def)
  75. endfunction
  76. else
  77. function! airline#util#getwinvar(winnr, key, def)
  78. let winvals = getwinvar(a:winnr, '')
  79. return get(winvals, a:key, a:def)
  80. endfunction
  81. endif
  82. if v:version >= 704
  83. function! airline#util#exec_funcrefs(list, ...)
  84. for Fn in a:list
  85. let code = call(Fn, a:000)
  86. if code != 0
  87. return code
  88. endif
  89. endfor
  90. return 0
  91. endfunction
  92. else
  93. function! airline#util#exec_funcrefs(list, ...)
  94. " for 7.2; we cannot iterate the list, hence why we use range()
  95. " for 7.3-[97, 328]; we cannot reuse the variable, hence the {}
  96. for i in range(0, len(a:list) - 1)
  97. let Fn{i} = a:list[i]
  98. let code = call(Fn{i}, a:000)
  99. if code != 0
  100. return code
  101. endif
  102. endfor
  103. return 0
  104. endfunction
  105. endif
  106. " Compatibility wrapper for strchars, in case this vim version does not
  107. " have it natively
  108. function! airline#util#strchars(str)
  109. if s:has_strchars
  110. return strchars(a:str)
  111. else
  112. return strlen(substitute(a:str, '.', 'a', 'g'))
  113. endif
  114. endfunction
  115. function! airline#util#strcharpart(...)
  116. if s:has_strcharpart
  117. return call('strcharpart', a:000)
  118. else
  119. " does not handle multibyte chars :(
  120. return a:1[(a:2):(a:3)]
  121. endif
  122. endfunction
  123. function! airline#util#ignore_buf(name)
  124. let pat = '\c\v'. get(g:, 'airline#ignore_bufadd_pat', '').
  125. \ get(g:, 'airline#extensions#tabline#ignore_bufadd_pat',
  126. \ '!|defx|gundo|nerd_tree|startify|tagbar|term://|undotree|vimfiler')
  127. return match(a:name, pat) > -1
  128. endfunction
  129. function! airline#util#has_fugitive()
  130. if !exists("s:has_fugitive")
  131. let s:has_fugitive = exists('*FugitiveHead')
  132. endif
  133. return s:has_fugitive
  134. endfunction
  135. function! airline#util#has_gina()
  136. if !exists("s:has_gina")
  137. let s:has_gina = (exists(':Gina') && v:version >= 800)
  138. endif
  139. return s:has_gina
  140. endfunction
  141. function! airline#util#has_lawrencium()
  142. if !exists("s:has_lawrencium")
  143. let s:has_lawrencium = exists('*lawrencium#statusline')
  144. endif
  145. return s:has_lawrencium
  146. endfunction
  147. function! airline#util#has_vcscommand()
  148. if !exists("s:has_vcscommand")
  149. let s:has_vcscommand = exists('*VCSCommandGetStatusLine')
  150. endif
  151. return get(g:, 'airline#extensions#branch#use_vcscommand', 0) && s:has_vcscommand
  152. endfunction
  153. function! airline#util#has_custom_scm()
  154. return !empty(get(g:, 'airline#extensions#branch#custom_head', ''))
  155. endfunction
  156. function! airline#util#doautocmd(event)
  157. if !exists('#airline') && a:event !=? 'AirlineToggledOff'
  158. " airline disabled
  159. return
  160. endif
  161. try
  162. exe printf("silent doautocmd %s User %s", s:nomodeline, a:event)
  163. catch /^Vim\%((\a\+)\)\=:E48:/
  164. " Catch: Sandbox mode
  165. " no-op
  166. endtry
  167. endfunction
  168. function! airline#util#themes(match)
  169. let files = split(globpath(&rtp, 'autoload/airline/themes/'.a:match.'*.vim', 1), "\n")
  170. return sort(map(files, 'fnamemodify(v:val, ":t:r")') + ('random' =~ a:match ? ['random'] : []))
  171. endfunction
  172. function! airline#util#stl_disabled(winnr)
  173. " setting the statusline is disabled,
  174. " either globally, per window, or per buffer
  175. " w:airline_disabled is deprecated!
  176. return get(g:, 'airline_disable_statusline', 0) ||
  177. \ airline#util#getwinvar(a:winnr, 'airline_disable_statusline', 0) ||
  178. \ airline#util#getwinvar(a:winnr, 'airline_disabled', 0) ||
  179. \ airline#util#getbufvar(winbufnr(a:winnr), 'airline_disable_statusline', 0)
  180. endfunction
  181. function! airline#util#ignore_next_focusgain()
  182. if has('win32')
  183. " Setup an ignore for platforms that trigger FocusLost on calls to
  184. " system(). macvim (gui and terminal) and Linux terminal vim do not.
  185. let s:focusgained_ignore_time = localtime()
  186. endif
  187. endfunction
  188. function! airline#util#is_popup_window(winnr)
  189. " Keep the statusline active if it's a popup window
  190. if exists('*win_gettype')
  191. return win_gettype(a:winnr) ==# 'popup' || win_gettype(a:winnr) ==# 'autocmd'
  192. else
  193. return airline#util#getwinvar(a:winnr, '&buftype', '') ==# 'popup'
  194. endif
  195. endfunction
  196. function! airline#util#try_focusgained()
  197. " Ignore lasts for at most one second and is cleared on the first
  198. " focusgained. We use ignore to prevent system() calls from triggering
  199. " FocusGained (which occurs 100% on win32 and seem to sometimes occur under
  200. " tmux).
  201. let dt = localtime() - s:focusgained_ignore_time
  202. let s:focusgained_ignore_time = 0
  203. return dt >= 1
  204. endfunction
  205. function! airline#util#has_vim9_script()
  206. " Returns true, if Vim is new enough to understand vim9 script
  207. return (exists(":def") &&
  208. \ exists("v:versionlong") &&
  209. \ v:versionlong >= 8022844 &&
  210. \ get(g:, "airline_experimental", 0))
  211. endfunction