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 - New features
- Extensions: - Extensions:
- [Defx](https://github.com/Shougo/defx.nvim) support - [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 ## [0.10] - 2018-12-15
- New features - New features

View File

@ -180,7 +180,8 @@ function! s:invoke_funcrefs(context, funcrefs)
if err == 1 if err == 1
let a:context.line = builder.build() let a:context.line = builder.build()
let s:contexts[a:context.winnr] = a:context 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 endif
endfunction endfunction
@ -190,7 +191,6 @@ function! airline#statusline(winnr)
if has_key(s:contexts, a:winnr) if has_key(s:contexts, a:winnr)
return '%{airline#check_mode('.a:winnr.')}'.s:contexts[a:winnr].line return '%{airline#check_mode('.a:winnr.')}'.s:contexts[a:winnr].line
endif endif
" in rare circumstances this happens...see #276 " in rare circumstances this happens...see #276
return '' return ''
endfunction endfunction

View File

@ -88,7 +88,8 @@ function! s:update_git_branch()
let s:vcs_config['git'].branch = exists("*FugitiveHead") ? let s:vcs_config['git'].branch = exists("*FugitiveHead") ?
\ FugitiveHead(s:sha1size) : fugitive#head(s:sha1size) \ 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 " Shorten default a bit
let s:vcs_config['git'].branch='mas' let s:vcs_config['git'].branch='mas'
endif endif

View File

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

View File

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

View File

@ -19,7 +19,7 @@ function! airline#extensions#nrrwrgn#apply(...)
let dict=nrrwrgn#NrrwRgnStatus() let dict=nrrwrgn#NrrwRgnStatus()
let vmode = { 'v': 'Char ', 'V': 'Line ', '': 'Block '} let vmode = { 'v': 'Char ', 'V': 'Line ', '': 'Block '}
let mode = dict.visual ? vmode[dict.visual] : vmode['V'] let mode = dict.visual ? vmode[dict.visual] : vmode['V']
let winwidth = winwidth(0) let winwidth = airline#util#winwidth()
if winwidth < 80 if winwidth < 80
let mode = mode[0] let mode = mode[0]
endif 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' ? '…' : '.'). ']' let b:airline_po_stats = b:airline_po_stats[0:(w:displayed_po_limit - 2)].(&encoding==?'utf-8' ? '…' : '.'). ']'
endif endif
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 fuzzy = ''
let untranslated = '' let untranslated = ''
let messages = '' let messages = ''
@ -35,8 +35,8 @@ endfunction
function! airline#extensions#po#on_winenter() function! airline#extensions#po#on_winenter()
" only reset cache, if the window size changed " only reset cache, if the window size changed
if get(b:, 'airline_winwidth', 0) != winwidth(0) if get(b:, 'airline_winwidth', 0) != airline#util#winwidth()
let b:airline_winwidth = winwidth(0) let b:airline_winwidth = airline#util#winwidth()
" needs re-formatting " needs re-formatting
unlet! b:airline_po_stats unlet! b:airline_po_stats
endif endif

View File

@ -33,6 +33,11 @@ function! s:toggle_off()
endfunction endfunction
function! s:toggle_on() 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#autoshow#on()
call airline#extensions#tabline#tabs#on() call airline#extensions#tabline#tabs#on()
call airline#extensions#tabline#buffers#on() call airline#extensions#tabline#buffers#on()
@ -58,12 +63,25 @@ function! s:update_tabline()
return return
endif endif
call airline#util#doautocmd('BufMRUChange') 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 " sometimes, the tabline is not correctly updated see #1580
" so force redraw here " so force redraw here
if exists(":redrawtabline") == 2 if exists(":redrawtabline") == 2
redrawtabline redrawtabline
else 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 endif
endfunction endfunction

View File

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

View File

@ -24,7 +24,7 @@ else
endif endif
function! airline#extensions#wordcount#formatters#default#to_string(wordcount) function! airline#extensions#wordcount#formatters#default#to_string(wordcount)
if winwidth(0) >= 80 if airline#util#winwidth() >= 80
if a:wordcount > 999 if a:wordcount > 999
" Format number according to locale, e.g. German: 1.245 or English: 1,245 " 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') 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']) let g:airline_section_y = airline#section#create_right(['ffenc'])
endif endif
if !exists('g:airline_section_z') 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']) let g:airline_section_z = airline#section#create(['windowswap', 'obsession', '%3p%%'.spc, 'linenr', 'maxlinenr', spc.':%3v'])
else else
let g:airline_section_z = airline#section#create(['%3p%%'.spc, 'linenr', ':%3v']) let g:airline_section_z = airline#section#create(['%3p%%'.spc, 'linenr', ':%3v'])

View File

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

View File

@ -1,17 +1,26 @@
" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. " MIT License. Copyright (c) 2013-2018 Bailey Ling et al.
" vim: et ts=2 sts=2 sw=2 " 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 scriptencoding utf-8
call airline#init#bootstrap() call airline#init#bootstrap()
let s:spc = g:airline_symbols.space let s:spc = g:airline_symbols.space
let s:nomodeline = (v:version > 703 || (v:version == 703 && has("patch438"))) ? '<nomodeline>' : '' 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, ...) 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) if get(a:000, 0, 0)
" shorten from tail " shorten from tail
return '…'.matchstr(a:text, '.\{'.a:minwidth.'}$') return '…'.matchstr(a:text, '.\{'.a:minwidth.'}$')
@ -25,14 +34,14 @@ function! airline#util#shorten(text, winwidth, minwidth, ...)
endfunction endfunction
function! airline#util#wrap(text, minwidth) function! airline#util#wrap(text, minwidth)
if a:minwidth > 0 && winwidth(0) < a:minwidth if a:minwidth > 0 && airline#util#winwidth() < a:minwidth
return '' return ''
endif endif
return a:text return a:text
endfunction endfunction
function! airline#util#append(text, minwidth) function! airline#util#append(text, minwidth)
if a:minwidth > 0 && winwidth(0) < a:minwidth if a:minwidth > 0 && airline#util#winwidth() < a:minwidth
return '' return ''
endif endif
let prefix = s:spc == "\ua0" ? s:spc : s:spc.s:spc let prefix = s:spc == "\ua0" ? s:spc : s:spc.s:spc
@ -46,7 +55,7 @@ function! airline#util#warning(msg)
endfunction endfunction
function! airline#util#prepend(text, minwidth) function! airline#util#prepend(text, minwidth)
if a:minwidth > 0 && winwidth(0) < a:minwidth if a:minwidth > 0 && airline#util#winwidth() < a:minwidth
return '' return ''
endif endif
return empty(a:text) ? '' : a:text.s:spc.g:airline_right_alt_sep.s:spc 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 * configure the fileformat output
By default, it will display something like 'utf-8[unix]', however, you can 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, skip displaying it, if the output matches a configured string. To do so, set >
set >
let g:airline#parts#ffenc#skip_expected_string='utf-8[unix]' 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* COMMANDS *airline-commands*

View File

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