mirror of
https://github.com/vim-airline/vim-airline.git
synced 2024-11-23 07:10:59 +08:00
f045452743
When switching away from Vim and your terminal supports the FocusLost autocommand, set the statusline to inactive, so it won't distract you too much when working with another application. In the gui, the FocusLost autocommand should always trigger. This is now the default, if people start complaining, that behaviour should probably be made configurable. closes #1807
221 lines
6.3 KiB
VimL
221 lines
6.3 KiB
VimL
" MIT License. Copyright (c) 2013-2018 Bailey Ling et al.
|
||
" vim: et ts=2 sts=2 sw=2
|
||
|
||
scriptencoding utf-8
|
||
|
||
let g:airline_statusline_funcrefs = get(g:, 'airline_statusline_funcrefs', [])
|
||
|
||
let s:sections = ['a','b','c','gutter','x','y','z', 'error', 'warning']
|
||
let s:inactive_funcrefs = []
|
||
|
||
function! airline#add_statusline_func(name)
|
||
call airline#add_statusline_funcref(function(a:name))
|
||
endfunction
|
||
|
||
function! airline#add_statusline_funcref(function)
|
||
if index(g:airline_statusline_funcrefs, a:function) >= 0
|
||
echohl WarningMsg
|
||
echo 'The airline statusline funcref '.string(a:function).' has already been added.'
|
||
echohl NONE
|
||
return
|
||
endif
|
||
call add(g:airline_statusline_funcrefs, a:function)
|
||
endfunction
|
||
|
||
function! airline#remove_statusline_func(name)
|
||
let i = index(g:airline_statusline_funcrefs, function(a:name))
|
||
if i > -1
|
||
call remove(g:airline_statusline_funcrefs, i)
|
||
endif
|
||
endfunction
|
||
|
||
function! airline#add_inactive_statusline_func(name)
|
||
call add(s:inactive_funcrefs, function(a:name))
|
||
endfunction
|
||
|
||
function! airline#load_theme()
|
||
let g:airline_theme = get(g:, 'airline_theme', 'dark')
|
||
if exists('*airline#themes#{g:airline_theme}#refresh')
|
||
call airline#themes#{g:airline_theme}#refresh()
|
||
endif
|
||
|
||
let palette = g:airline#themes#{g:airline_theme}#palette
|
||
call airline#themes#patch(palette)
|
||
|
||
if exists('g:airline_theme_patch_func')
|
||
let Fn = function(g:airline_theme_patch_func)
|
||
call Fn(palette)
|
||
endif
|
||
|
||
call airline#highlighter#load_theme()
|
||
call airline#extensions#load_theme()
|
||
call airline#update_statusline()
|
||
endfunction
|
||
|
||
function! airline#switch_theme(name)
|
||
try
|
||
let palette = g:airline#themes#{a:name}#palette "also lazy loads the theme
|
||
let g:airline_theme = a:name
|
||
catch
|
||
echohl WarningMsg | echo 'The specified theme cannot be found.' | echohl NONE
|
||
if exists('g:airline_theme')
|
||
return
|
||
else
|
||
let g:airline_theme = 'dark'
|
||
endif
|
||
endtry
|
||
|
||
let w:airline_lastmode = ''
|
||
call airline#load_theme()
|
||
|
||
call airline#util#doautocmd('AirlineAfterTheme')
|
||
|
||
" this is required to prevent clobbering the startup info message, i don't know why...
|
||
call airline#check_mode(winnr())
|
||
endfunction
|
||
|
||
function! airline#switch_matching_theme()
|
||
if exists('g:colors_name')
|
||
let existing = g:airline_theme
|
||
let theme = substitute(tolower(g:colors_name), '-', '_', 'g')
|
||
try
|
||
let palette = g:airline#themes#{theme}#palette
|
||
call airline#switch_theme(theme)
|
||
return 1
|
||
catch
|
||
for map in items(g:airline_theme_map)
|
||
if match(g:colors_name, map[0]) > -1
|
||
try
|
||
let palette = g:airline#themes#{map[1]}#palette
|
||
call airline#switch_theme(map[1])
|
||
catch
|
||
call airline#switch_theme(existing)
|
||
endtry
|
||
return 1
|
||
endif
|
||
endfor
|
||
endtry
|
||
endif
|
||
return 0
|
||
endfunction
|
||
|
||
function! airline#update_statusline()
|
||
if airline#util#getwinvar(winnr(), 'airline_disabled', 0)
|
||
return
|
||
endif
|
||
let range = filter(range(1, winnr('$')), 'v:val != winnr()')
|
||
" create inactive statusline
|
||
call airline#update_statusline_inactive(range)
|
||
|
||
unlet! w:airline_render_left w:airline_render_right
|
||
exe 'unlet! ' 'w:airline_section_'. join(s:sections, ' w:airline_section_')
|
||
|
||
let w:airline_active = 1
|
||
let context = { 'winnr': winnr(), 'active': 1, 'bufnr': winbufnr(winnr()) }
|
||
call s:invoke_funcrefs(context, g:airline_statusline_funcrefs)
|
||
endfunction
|
||
|
||
function! airline#update_statusline_inactive(range)
|
||
if airline#util#getwinvar(winnr(), 'airline_disabled', 0)
|
||
return
|
||
endif
|
||
for nr in a:range
|
||
if airline#util#getwinvar(nr, 'airline_disabled', 0)
|
||
continue
|
||
endif
|
||
call setwinvar(nr, 'airline_active', 0)
|
||
let context = { 'winnr': nr, 'active': 0, 'bufnr': winbufnr(nr) }
|
||
call s:invoke_funcrefs(context, s:inactive_funcrefs)
|
||
endfor
|
||
endfunction
|
||
|
||
let s:contexts = {}
|
||
let s:core_funcrefs = [
|
||
\ function('airline#extensions#apply'),
|
||
\ function('airline#extensions#default#apply') ]
|
||
function! s:invoke_funcrefs(context, funcrefs)
|
||
let builder = airline#builder#new(a:context)
|
||
let err = airline#util#exec_funcrefs(a:funcrefs + s:core_funcrefs, builder, a:context)
|
||
if err == 1
|
||
let a:context.line = builder.build()
|
||
let s:contexts[a:context.winnr] = a:context
|
||
call setwinvar(a:context.winnr, '&statusline', '%!airline#statusline('.a:context.winnr.')')
|
||
endif
|
||
endfunction
|
||
|
||
function! airline#statusline(winnr)
|
||
if has_key(s:contexts, a:winnr)
|
||
return '%{airline#check_mode('.a:winnr.')}'.s:contexts[a:winnr].line
|
||
endif
|
||
|
||
" in rare circumstances this happens...see #276
|
||
return ''
|
||
endfunction
|
||
|
||
function! airline#check_mode(winnr)
|
||
let context = s:contexts[a:winnr]
|
||
|
||
if get(w:, 'airline_active', 1)
|
||
let l:m = mode(1)
|
||
if l:m ==# "i"
|
||
let l:mode = ['insert']
|
||
elseif l:m[0] ==# "i"
|
||
let l:mode = ['insert']
|
||
elseif l:m ==# "Rv"
|
||
let l:mode =['replace']
|
||
elseif l:m[0] ==# "R"
|
||
let l:mode = ['replace']
|
||
elseif l:m[0] =~# '\v(v|V||s|S|)'
|
||
let l:mode = ['visual']
|
||
elseif l:m ==# "t"
|
||
let l:mode = ['terminal']
|
||
elseif l:m[0] ==# "c"
|
||
let l:mode = ['commandline']
|
||
elseif l:m ==# "no" " does not work, most likely, Vim does not refresh the statusline in OP mode
|
||
let l:mode = ['normal']
|
||
elseif l:m[0:1] ==# 'ni'
|
||
let l:mode = ['normal']
|
||
let l:m = 'ni'
|
||
else
|
||
let l:mode = ['normal']
|
||
endif
|
||
if index(['Rv', 'no', 'ni', 'ix', 'ic'], l:m) == -1
|
||
let l:m = l:m[0]
|
||
endif
|
||
let w:airline_current_mode = get(g:airline_mode_map, l:m, l:m)
|
||
else
|
||
let l:mode = ['inactive']
|
||
let w:airline_current_mode = get(g:airline_mode_map, '__')
|
||
endif
|
||
|
||
if g:airline_detect_modified && &modified
|
||
call add(l:mode, 'modified')
|
||
endif
|
||
|
||
if g:airline_detect_paste && &paste
|
||
call add(l:mode, 'paste')
|
||
endif
|
||
|
||
if g:airline_detect_crypt && exists("+key") && !empty(&key)
|
||
call add(l:mode, 'crypt')
|
||
endif
|
||
|
||
if g:airline_detect_spell && &spell
|
||
call add(l:mode, 'spell')
|
||
endif
|
||
|
||
if &readonly || ! &modifiable
|
||
call add(l:mode, 'readonly')
|
||
endif
|
||
|
||
let mode_string = join(l:mode)
|
||
if get(w:, 'airline_lastmode', '') != mode_string
|
||
call airline#highlighter#highlight_modified_inactive(context.bufnr)
|
||
call airline#highlighter#highlight(l:mode, context.bufnr)
|
||
call airline#util#doautocmd('AirlineModeChanged')
|
||
let w:airline_lastmode = mode_string
|
||
endif
|
||
|
||
return ''
|
||
endfunction
|