allow to show the statusline on top

This is an experimental feature that allows to display the statusline in
the tabline. It might still be a bit rough, but seems to work so far.

Remaining problem:
- Mode changes are not immediately detected, only after moving the
  cursor

fixes #1388
closes #1867
This commit is contained in:
Christian Brabandt 2019-02-03 17:30:55 +01:00
parent 58bbc512f9
commit fd5bde1a3a
No known key found for this signature in database
GPG Key ID: F3F92DA383FDDE09
15 changed files with 94 additions and 33 deletions

View File

@ -6,6 +6,9 @@ This is the Changelog for the vim-airline project.
- New features
- Extensions:
- [Defx](https://github.com/Shougo/defx.nvim) support
- Improvements
- The statusline can be configured to be shown on top (in the tabline)
Set the `g:airline_statusline_ontop` to enable this experimental feature.
## [0.10] - 2018-12-15
- New features

View File

@ -180,7 +180,8 @@ function! s:invoke_funcrefs(context, funcrefs)
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.')')
let option = get(g:, 'airline_statusline_ontop', 0) ? '&tabline' : '&statusline'
call setwinvar(a:context.winnr, option, '%!airline#statusline('.a:context.winnr.')')
endif
endfunction
@ -190,7 +191,6 @@ 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

View File

@ -88,7 +88,8 @@ function! s:update_git_branch()
let s:vcs_config['git'].branch = exists("*FugitiveHead") ?
\ FugitiveHead(s:sha1size) : fugitive#head(s:sha1size)
if s:vcs_config['git'].branch is# 'master' && winwidth(0) < 81
if s:vcs_config['git'].branch is# 'master' &&
\ airline#util#winwidth() < 81
" Shorten default a bit
let s:vcs_config['git'].branch='mas'
endif

View File

@ -19,7 +19,7 @@ let s:layout = get(g:, 'airline#extensions#default#layout', [
function! s:get_section(winnr, key, ...)
if has_key(s:section_truncate_width, a:key)
if winwidth(a:winnr) < s:section_truncate_width[a:key]
if airline#util#winwidth(a:winnr) < s:section_truncate_width[a:key]
return ''
endif
endif

View File

@ -66,7 +66,7 @@ function! airline#extensions#hunks#get_hunks()
" Cache values, so that it isn't called too often
if exists("b:airline_hunks") &&
\ get(b:, 'airline_changenr', 0) == b:changedtick &&
\ winwidth(0) == get(s:, 'airline_winwidth', 0) &&
\ airline#util#winwidth() == get(s:, 'airline_winwidth', 0) &&
\ get(b:, 'source_func', '') isnot# 's:get_hunks_signify' &&
\ get(b:, 'source_func', '') isnot# 's:get_hunks_gitgutter' &&
\ get(b:, 'source_func', '') isnot# 's:get_hunks_empty' &&
@ -77,14 +77,14 @@ function! airline#extensions#hunks#get_hunks()
let string = ''
if !empty(hunks)
for i in [0, 1, 2]
if (s:non_zero_only == 0 && winwidth(0) > 100) || hunks[i] > 0
if (s:non_zero_only == 0 && airline#util#winwidth() > 100) || hunks[i] > 0
let string .= printf('%s%s ', s:hunk_symbols[i], hunks[i])
endif
endfor
endif
let b:airline_hunks = string
let b:airline_changenr = b:changedtick
let s:airline_winwidth = winwidth(0)
let s:airline_winwidth = airline#util#winwidth()
return string
endfunction

View File

@ -19,7 +19,7 @@ function! airline#extensions#nrrwrgn#apply(...)
let dict=nrrwrgn#NrrwRgnStatus()
let vmode = { 'v': 'Char ', 'V': 'Line ', '': 'Block '}
let mode = dict.visual ? vmode[dict.visual] : vmode['V']
let winwidth = winwidth(0)
let winwidth = airline#util#winwidth()
if winwidth < 80
let mode = mode[0]
endif

View File

@ -13,7 +13,7 @@ function! airline#extensions#po#shorten()
let b:airline_po_stats = b:airline_po_stats[0:(w:displayed_po_limit - 2)].(&encoding==?'utf-8' ? '…' : '.'). ']'
endif
endif
if strlen(get(b:, 'airline_po_stats', '')) >= 30 && winwidth(0) < 150
if strlen(get(b:, 'airline_po_stats', '')) >= 30 && airline#util#winwidth() < 150
let fuzzy = ''
let untranslated = ''
let messages = ''
@ -35,8 +35,8 @@ endfunction
function! airline#extensions#po#on_winenter()
" only reset cache, if the window size changed
if get(b:, 'airline_winwidth', 0) != winwidth(0)
let b:airline_winwidth = winwidth(0)
if get(b:, 'airline_winwidth', 0) != airline#util#winwidth()
let b:airline_winwidth = airline#util#winwidth()
" needs re-formatting
unlet! b:airline_po_stats
endif

View File

@ -33,6 +33,11 @@ function! s:toggle_off()
endfunction
function! s:toggle_on()
if get(g:, 'airline_statusline_ontop', 0)
call airline#extensions#tabline#enable()
let &tabline='%!airline#statusline('.winnr().')'
return
endif
call airline#extensions#tabline#autoshow#on()
call airline#extensions#tabline#tabs#on()
call airline#extensions#tabline#buffers#on()
@ -58,12 +63,25 @@ function! s:update_tabline()
return
endif
call airline#util#doautocmd('BufMRUChange')
call airline#extensions#tabline#redraw()
endfunction
function! airline#extensions#tabline#redraw()
" sometimes, the tabline is not correctly updated see #1580
" so force redraw here
if exists(":redrawtabline") == 2
redrawtabline
else
let &tabline = &tabline
" Have to set a property equal to itself to get airline to re-eval.
" Setting `let &tabline=&tabline` destroys the cursor position so we
" need something less invasive.
let &ro = &ro
endif
endfunction
function! airline#extensions#tabline#enable()
if &lines > 3
set showtabline=2
endif
endfunction

View File

@ -24,9 +24,7 @@ function! airline#extensions#tabline#autoshow#on()
augroup airline_tabline_autoshow
autocmd!
if s:buf_min_count <= 0 && s:tab_min_count <= 1
if &lines > 3
set showtabline=2
endif
call airline#extensions#tabline#enable()
else
if s:show_buffers == 1
autocmd BufEnter * call <sid>show_tabline(s:buf_min_count, len(airline#extensions#tabline#buflist#list()))

View File

@ -24,7 +24,7 @@ else
endif
function! airline#extensions#wordcount#formatters#default#to_string(wordcount)
if winwidth(0) >= 80
if airline#util#winwidth() >= 80
if a:wordcount > 999
" Format number according to locale, e.g. German: 1.245 or English: 1,245
let wordcount = substitute(a:wordcount, '\d\@<=\(\(\d\{3\}\)\+\)$', s:decimal_group.'&', 'g')

View File

@ -194,7 +194,7 @@ function! airline#init#sections()
let g:airline_section_y = airline#section#create_right(['ffenc'])
endif
if !exists('g:airline_section_z')
if winwidth(0) > 80
if airline#util#winwidth() > 80
let g:airline_section_z = airline#section#create(['windowswap', 'obsession', '%3p%%'.spc, 'linenr', 'maxlinenr', spc.':%3v'])
else
let g:airline_section_z = airline#section#create(['%3p%%'.spc, 'linenr', ':%3v'])

View File

@ -67,9 +67,10 @@ endfunction
function! airline#parts#spell()
let spelllang = g:airline_detect_spelllang ? printf(" [%s]", toupper(substitute(&spelllang, ',', '/', 'g'))) : ''
if g:airline_detect_spell && &spell
if winwidth(0) >= 90
let winwidth = airline#util#winwidth()
if winwidth >= 90
return g:airline_symbols.spell . spelllang
elseif winwidth(0) >= 70
elseif winwidth >= 70
return g:airline_symbols.spell
else
return split(g:airline_symbols.spell, '\zs')[0]
@ -99,7 +100,9 @@ function! airline#parts#readonly()
endfunction
function! airline#parts#filetype()
return winwidth(0) < 90 && strlen(&filetype) > 3 ? matchstr(&filetype, '...'). (&encoding is? 'utf-8' ? '…' : '>') : &filetype
return (airline#util#winwidth() < 90 && strlen(&filetype) > 3)
\ ? matchstr(&filetype, '...'). (&encoding is? 'utf-8' ? '…' : '>')
\ : &filetype
endfunction
function! airline#parts#ffenc()

View File

@ -1,17 +1,26 @@
" MIT License. Copyright (c) 2013-2018 Bailey Ling et al.
" vim: et ts=2 sts=2 sw=2
" TODO: Try to cache winwidth(0) function
" e.g. store winwidth per window and access that, only update it, if the size
" actually changed.
scriptencoding utf-8
call airline#init#bootstrap()
let s:spc = g:airline_symbols.space
let s:nomodeline = (v:version > 703 || (v:version == 703 && has("patch438"))) ? '<nomodeline>' : ''
" TODO: Try to cache winwidth(0) function
" e.g. store winwidth per window and access that, only update it, if the size
" actually changed.
function! airline#util#winwidth(...)
let nr = get(a:000, 0, 0)
if get(g:, 'airline_statusline_ontop', 0)
return &columns
else
return winwidth(nr)
endif
endfunction
function! airline#util#shorten(text, winwidth, minwidth, ...)
if winwidth(0) < a:winwidth && len(split(a:text, '\zs')) > a:minwidth
if airline#util#winwidth() < a:winwidth && len(split(a:text, '\zs')) > a:minwidth
if get(a:000, 0, 0)
" shorten from tail
return '…'.matchstr(a:text, '.\{'.a:minwidth.'}$')
@ -25,14 +34,14 @@ function! airline#util#shorten(text, winwidth, minwidth, ...)
endfunction
function! airline#util#wrap(text, minwidth)
if a:minwidth > 0 && winwidth(0) < a:minwidth
if a:minwidth > 0 && airline#util#winwidth() < a:minwidth
return ''
endif
return a:text
endfunction
function! airline#util#append(text, minwidth)
if a:minwidth > 0 && winwidth(0) < a:minwidth
if a:minwidth > 0 && airline#util#winwidth() < a:minwidth
return ''
endif
let prefix = s:spc == "\ua0" ? s:spc : s:spc.s:spc
@ -46,7 +55,7 @@ function! airline#util#warning(msg)
endfunction
function! airline#util#prepend(text, minwidth)
if a:minwidth > 0 && winwidth(0) < a:minwidth
if a:minwidth > 0 && airline#util#winwidth() < a:minwidth
return ''
endif
return empty(a:text) ? '' : a:text.s:spc.g:airline_right_alt_sep.s:spc

View File

@ -228,10 +228,19 @@ values):
<
* configure the fileformat output
By default, it will display something like 'utf-8[unix]', however, you can
skip displaying it, if the output matches a configured string. To do so,
set >
skip displaying it, if the output matches a configured string. To do so, set >
let g:airline#parts#ffenc#skip_expected_string='utf-8[unix]'
<
* Display the statusline in the tabline (first top line): >
let g:airline_statusline_ontop = 1
<
Setting this option, allows to use the statusline option to be used by
a custom function or another plugin, since airline won't change it.
Note: This setting is experimental and works on a best effort approach.
Updating the statusline might not always happen as fast as needed, but that
is a limitation, that comes from Vim. airline tries to force an update if
needed, but it might not always work as expected.
==============================================================================
COMMANDS *airline-commands*

View File

@ -57,6 +57,19 @@ function! s:on_window_changed()
call airline#update_statusline()
endfunction
function! s:on_cursor_moved()
if winnr() != s:active_winnr
call <sid>on_window_changed()
endif
call <sid>update_tabline()
endfunction
function! s:update_tabline()
if get(g:, 'airline_statusline_ontop', 0)
call airline#extensions#tabline#redraw()
endif
endfunction
function! s:on_colorscheme_changed()
call s:init()
unlet! g:airline#highlighter#normal_fg_hi
@ -84,11 +97,15 @@ function! s:airline_toggle()
if exists("s:stl")
let &stl = s:stl
endif
if exists("s:tal")
let [&tal, &showtabline] = s:tal
endif
call airline#highlighter#reset_hlcache()
call airline#util#doautocmd('AirlineToggledOff')
else
let s:stl = &statusline
let s:tal = [&tabline, &showtabline]
augroup airline
autocmd!
@ -113,10 +130,7 @@ function! s:airline_toggle()
autocmd CompleteDone * call <sid>on_window_changed()
endif
" non-trivial number of external plugins use eventignore=all, so we need to account for that
autocmd CursorMoved *
\ if winnr() != s:active_winnr
\ | call <sid>on_window_changed()
\ | endif
autocmd CursorMoved * call <sid>on_cursor_moved()
autocmd VimResized * unlet! w:airline_lastmode | :call <sid>airline_refresh()
if exists('*timer_start') && exists('*funcref')
@ -137,6 +151,11 @@ function! s:airline_toggle()
autocmd BufWritePost */autoload/airline/themes/*.vim
\ exec 'source '.split(globpath(&rtp, 'autoload/airline/themes/'.g:airline_theme.'.vim', 1), "\n")[0]
\ | call airline#load_theme()
if get(g:, 'airline_statusline_ontop', 0)
" Force update of tabline more often
autocmd InsertEnter,InsertLeave,CursorMovedI * :call <sid>update_tabline()
endif
augroup END
if &laststatus < 2
@ -174,6 +193,7 @@ function! s:airline_refresh()
call airline#highlighter#reset_hlcache()
call airline#load_theme()
call airline#update_statusline()
call s:update_tabline()
endfunction
function! s:FocusGainedHandler(timer)