airline.vim 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. " MIT License. Copyright (c) 2013-2021 Bailey Ling, Christian Brabandt et al.
  2. " vim: et ts=2 sts=2 sw=2
  3. let s:save_cpo = &cpo
  4. set cpo&vim
  5. scriptencoding utf-8
  6. if &cp || v:version < 702 || (exists('g:loaded_airline') && g:loaded_airline)
  7. finish
  8. endif
  9. let g:loaded_airline = 1
  10. let s:airline_initialized = 0
  11. function! s:init()
  12. if s:airline_initialized
  13. return
  14. endif
  15. let s:airline_initialized = 1
  16. call airline#extensions#load()
  17. call airline#init#sections()
  18. let s:theme_in_vimrc = exists('g:airline_theme')
  19. if s:theme_in_vimrc
  20. try
  21. if g:airline_theme is# 'random'
  22. let g:airline_theme=s:random_theme()
  23. endif
  24. let palette = g:airline#themes#{g:airline_theme}#palette
  25. catch
  26. call airline#util#warning(printf('Could not resolve airline theme "%s". Themes have been migrated to github.com/vim-airline/vim-airline-themes.', g:airline_theme))
  27. let g:airline_theme = 'dark'
  28. endtry
  29. try
  30. silent call airline#switch_theme(g:airline_theme)
  31. catch
  32. call airline#util#warning(printf('Could not find airline theme "%s".', g:airline_theme))
  33. let g:airline_theme = 'dark'
  34. silent call airline#switch_theme(g:airline_theme)
  35. endtry
  36. else
  37. let g:airline_theme = 'dark'
  38. silent call s:on_colorscheme_changed()
  39. endif
  40. call airline#util#doautocmd('AirlineAfterInit')
  41. endfunction
  42. let s:active_winnr = -1
  43. function! s:on_window_changed(event)
  44. " don't trigger for Vim popup windows
  45. if &buftype is# 'popup'
  46. return
  47. endif
  48. if pumvisible() && (!&previewwindow || g:airline_exclude_preview)
  49. " do not trigger for previewwindows
  50. return
  51. endif
  52. let s:active_winnr = winnr()
  53. " Handle each window only once, since we might come here several times for
  54. " different autocommands.
  55. let l:key = [bufnr('%'), s:active_winnr, winnr('$'), tabpagenr(), &ft]
  56. if get(g:, 'airline_last_window_changed', []) == l:key
  57. \ && &stl is# '%!airline#statusline('.s:active_winnr.')'
  58. \ && &ft !~? 'gitcommit'
  59. " fugitive is special, it changes names and filetypes several times,
  60. " make sure the caching does not get into its way
  61. if a:event ==# 'BufUnload'
  62. " in the BufUnload event, make sure the cacheing does not prevent
  63. " removing stale entries
  64. call airline#highlighter#remove_separators_for_bufnr(expand('<abuf>'))
  65. endif
  66. return
  67. endif
  68. let g:airline_last_window_changed = l:key
  69. call s:init()
  70. call airline#update_statusline()
  71. if a:event ==# 'BufUnload'
  72. call airline#highlighter#remove_separators_for_bufnr(expand('<abuf>'))
  73. endif
  74. endfunction
  75. function! s:on_focus_gained()
  76. if &eventignore =~? 'focusgained'
  77. return
  78. endif
  79. if airline#util#try_focusgained()
  80. unlet! w:airline_lastmode | :call <sid>airline_refresh(1)
  81. endif
  82. endfunction
  83. function! s:on_cursor_moved()
  84. if winnr() != s:active_winnr || !exists('w:airline_active')
  85. call s:on_window_changed('CursorMoved')
  86. endif
  87. call airline#update_tabline()
  88. endfunction
  89. function! s:on_colorscheme_changed()
  90. call s:init()
  91. unlet! g:airline#highlighter#normal_fg_hi
  92. call airline#highlighter#reset_hlcache()
  93. if !s:theme_in_vimrc
  94. call airline#switch_matching_theme()
  95. endif
  96. " couldn't find a match, or theme was defined, just refresh
  97. call airline#load_theme()
  98. endfunction
  99. function! airline#cmdwinenter(...)
  100. call airline#extensions#apply_left_override('Command Line', '')
  101. endfunction
  102. function! s:airline_toggle()
  103. if exists("#airline")
  104. augroup airline
  105. au!
  106. augroup END
  107. augroup! airline
  108. if exists("s:stl")
  109. let &stl = s:stl
  110. endif
  111. if exists("s:tal")
  112. let [&tal, &showtabline] = s:tal
  113. endif
  114. call airline#highlighter#reset_hlcache()
  115. call airline#util#doautocmd('AirlineToggledOff')
  116. else
  117. let s:stl = &statusline
  118. let s:tal = [&tabline, &showtabline]
  119. augroup airline
  120. autocmd!
  121. autocmd CmdwinEnter *
  122. \ call airline#add_statusline_func('airline#cmdwinenter')
  123. \ | call <sid>on_window_changed('CmdwinEnter')
  124. autocmd CmdwinLeave * call airline#remove_statusline_func('airline#cmdwinenter')
  125. autocmd ColorScheme * call <sid>on_colorscheme_changed()
  126. " Set all statuslines to inactive
  127. autocmd FocusLost * call airline#update_statusline_focuslost()
  128. " Refresh airline for :syntax off
  129. autocmd SourcePre */syntax/syntax.vim
  130. \ call airline#extensions#tabline#buffers#invalidate()
  131. autocmd VimEnter * call <sid>on_window_changed('VimEnter')
  132. autocmd WinEnter * call <sid>on_window_changed('WinEnter')
  133. autocmd FileType * call <sid>on_window_changed('FileType')
  134. autocmd BufWinEnter * call <sid>on_window_changed('BufWinEnter')
  135. autocmd BufUnload * call <sid>on_window_changed('BufUnload')
  136. if exists('##CompleteDone')
  137. autocmd CompleteDone * call <sid>on_window_changed('CompleteDone')
  138. endif
  139. " non-trivial number of external plugins use eventignore=all, so we need to account for that
  140. autocmd CursorMoved * call <sid>on_cursor_moved()
  141. autocmd VimResized * call <sid>on_focus_gained()
  142. if exists('*timer_start') && exists('*funcref') && &eventignore !~? 'focusgained'
  143. " do not trigger FocusGained on startup, it might erase the intro screen (see #1817)
  144. " needs funcref() (needs 7.4.2137) and timers (7.4.1578)
  145. let Handler=funcref('<sid>FocusGainedHandler')
  146. let s:timer=timer_start(5000, Handler)
  147. else
  148. autocmd FocusGained * call <sid>on_focus_gained()
  149. endif
  150. if exists("##TerminalOpen")
  151. " Using the same function with the TermOpen autocommand
  152. " breaks for Neovim see #1828, looks like a neovim bug.
  153. autocmd TerminalOpen * :call airline#load_theme() " reload current theme for Terminal, forces the terminal extension to be loaded
  154. endif
  155. autocmd TabEnter * :unlet! w:airline_lastmode | let w:airline_active=1
  156. autocmd BufWritePost */autoload/airline/themes/*.vim
  157. \ exec 'source '.split(globpath(&rtp, 'autoload/airline/themes/'.g:airline_theme.'.vim', 1), "\n")[0]
  158. \ | call airline#load_theme()
  159. autocmd User AirlineModeChanged nested call airline#mode_changed()
  160. if get(g:, 'airline_statusline_ontop', 0)
  161. " Force update of tabline more often
  162. autocmd InsertEnter,InsertLeave,CursorMovedI * :call airline#update_tabline()
  163. endif
  164. if exists("##ModeChanged")
  165. autocmd ModeChanged * :call airline#update_tabline()
  166. endif
  167. augroup END
  168. if !airline#util#stl_disabled(winnr())
  169. if &laststatus < 2
  170. let _scroll=&scroll
  171. if !get(g:, 'airline_statusline_ontop', 0)
  172. set laststatus=2
  173. endif
  174. if &scroll != _scroll
  175. let &scroll = _scroll
  176. endif
  177. endif
  178. endif
  179. if s:airline_initialized
  180. call s:on_window_changed('Init')
  181. endif
  182. call airline#util#doautocmd('AirlineToggledOn')
  183. endif
  184. endfunction
  185. function! s:get_airline_themes(a, l, p)
  186. return airline#util#themes(a:a)
  187. endfunction
  188. function! s:airline_theme(...)
  189. if a:0
  190. try
  191. let theme = a:1
  192. if theme is# 'random'
  193. let theme = s:random_theme()
  194. endif
  195. call airline#switch_theme(theme)
  196. catch " discard error
  197. endtry
  198. if a:1 is# 'random'
  199. echo g:airline_theme
  200. endif
  201. else
  202. echo g:airline_theme
  203. endif
  204. endfunction
  205. function! s:airline_refresh(...)
  206. " a:1, fast refresh, do not reload the theme
  207. let fast=!empty(get(a:000, 0, 0))
  208. if !exists("#airline")
  209. " disabled
  210. return
  211. endif
  212. call airline#util#doautocmd('AirlineBeforeRefresh')
  213. call airline#highlighter#reset_hlcache()
  214. if !fast
  215. call airline#load_theme()
  216. endif
  217. call airline#update_statusline()
  218. call airline#update_tabline()
  219. endfunction
  220. function! s:FocusGainedHandler(timer)
  221. if exists("s:timer") && a:timer == s:timer && exists('#airline') && &eventignore !~? 'focusgained'
  222. augroup airline
  223. au FocusGained * call s:on_focus_gained()
  224. augroup END
  225. endif
  226. endfu
  227. function! s:airline_extensions()
  228. let loaded = airline#extensions#get_loaded_extensions()
  229. let files = split(globpath(&rtp, 'autoload/airline/extensions/*.vim', 1), "\n")
  230. call map(files, 'fnamemodify(v:val, ":t:r")')
  231. if empty(files)
  232. echo "No extensions loaded"
  233. return
  234. endif
  235. echohl Title
  236. echo printf("%-15s\t%s\t%s", "Extension", "Extern", "Status")
  237. echohl Normal
  238. let set=[]
  239. for ext in sort(files)
  240. if index(set, ext) > -1
  241. continue
  242. endif
  243. let indx=match(loaded, '^'.ext.'\*\?$')
  244. let external = (indx > -1 && loaded[indx] =~ '\*$')
  245. echo printf("%-15s\t%s\t%sloaded", ext, external, indx == -1 ? 'not ' : '')
  246. call add(set, ext)
  247. endfor
  248. endfunction
  249. function! s:rand(max) abort
  250. if exists("*rand")
  251. " Needs Vim 8.1.2342
  252. let number=rand()
  253. elseif has("reltime")
  254. let timerstr=reltimestr(reltime())
  255. let number=split(timerstr, '\.')[1]+0
  256. elseif has("win32") && &shell =~ 'cmd'
  257. let number=system("echo %random%")+0
  258. else
  259. " best effort, bash and zsh provide $RANDOM
  260. " cmd.exe on windows provides %random%, but expand()
  261. " does not seem to be able to expand this correctly.
  262. " In the worst case, this always returns zero
  263. let number=expand("$RANDOM")+0
  264. endif
  265. return number % a:max
  266. endfunction
  267. function! s:random_theme() abort
  268. let themes=airline#util#themes('')
  269. return themes[s:rand(len(themes))]
  270. endfunction
  271. command! -bar -nargs=? -complete=customlist,<sid>get_airline_themes AirlineTheme call <sid>airline_theme(<f-args>)
  272. command! -bar AirlineToggleWhitespace call airline#extensions#whitespace#toggle()
  273. command! -bar AirlineToggle call s:airline_toggle()
  274. command! -bar -bang AirlineRefresh call s:airline_refresh(<q-bang>)
  275. command! AirlineExtensions call s:airline_extensions()
  276. call airline#init#bootstrap()
  277. call s:airline_toggle()
  278. if exists("v:vim_did_enter") && v:vim_did_enter
  279. call <sid>on_window_changed('VimEnter')
  280. endif
  281. let &cpo = s:save_cpo
  282. unlet s:save_cpo