Make vim example work with split and inactive windows

This commit introduces a bunch of changes. Most importantly, it ensures
that split windows and inactive windows work as expected. This is
accomplished with some clever workarounds for vim's statusline
limitations.

Vim statuslines evaluated using the %! statusline item are always
evaluated in the buffer context and not in the statusline's owner
window's context, and this made the previous implementation show the
same statusline for all windows. The only way to ensure that the correct
statusline is rendered to the correct window is to walk through all
windows, and setting the statuslines with a reference to the current
window number every time the current window is changed. This is
accomplished by a set of BufEnter, BufLeave, etc. autocommands.

The Syntastic segment has been temporarily removed due to errors when
referencing the statusline function before Syntastic has been loaded.
This commit is contained in:
Kim Silkebækken 2012-11-20 21:16:12 +01:00
parent a532da4834
commit 6c5316a058
2 changed files with 101 additions and 75 deletions

View File

@ -70,16 +70,24 @@ vim_funcs = {
'col': get_vim_func('col', rettype=int), 'col': get_vim_func('col', rettype=int),
'expand': get_vim_func('expand'), 'expand': get_vim_func('expand'),
'tbcurtag': get_vim_func('tagbar#currenttag'), 'tbcurtag': get_vim_func('tagbar#currenttag'),
'sstlflag': get_vim_func('SyntasticStatuslineFlag'),
'hlexists': get_vim_func('hlexists', rettype=int), 'hlexists': get_vim_func('hlexists', rettype=int),
} }
getwinvar = get_vim_func('getwinvar')
setwinvar = get_vim_func('setwinvar')
def statusline():
winwidth = vim_funcs['winwidth'](0)
# Prepare segment contents def statusline(winnr):
mode = modes[vim_funcs['mode']()] winwidth = vim_funcs['winwidth'](winnr)
current = getwinvar(winnr, 'current')
windata = getwinvar(winnr, 'powerline')
if current:
# Recreate segment data for each redraw if we're in the current window
line_current = vim_funcs['line']('.')
line_end = vim_funcs['line']('$')
line_percent = line_current * 100 // line_end
try: try:
branch = vim_funcs['fghead'](5) branch = vim_funcs['fghead'](5)
@ -91,10 +99,6 @@ def statusline():
if branch: if branch:
branch = '' + branch branch = '' + branch
line_current = vim_funcs['line']('.')
line_end = vim_funcs['line']('$')
line_percent = line_current * 100 // line_end
# Fun gradient colored percent segment # Fun gradient colored percent segment
line_percent_gradient = [160, 166, 172, 178, 184, 190] line_percent_gradient = [160, 166, 172, 178, 184, 190]
line_percent_color = line_percent_gradient[int((len(line_percent_gradient) - 1) * line_percent / 100)] line_percent_color = line_percent_gradient[int((len(line_percent_gradient) - 1) * line_percent / 100)]
@ -121,36 +125,48 @@ def statusline():
except TypeError: except TypeError:
currenttag = '' currenttag = ''
# The Syntastic segment is center aligned (filler segment on each side) to show off how the filler segments work windata = {
# Not necessarily how it's going to look in the final theme 'paste': vim.eval('&paste ? "PASTE" : ""'),
set_global_var('syntastic_stl_format', '%E{ ERRORS (%e) ⭡ %fe }%W{ WARNINGS (%w) ⭡ %fw } ⮁') 'branch': branch,
try: 'readonly': readonly,
syntastic = vim_funcs['sstlflag']() 'filepath': filepath,
except vim.error: 'filename': filename,
vim_funcs['sstlflag'] = None 'filename_color': filename_color,
syntastic = '' 'modified': modified,
except TypeError: 'currenttag': currenttag,
syntastic = '' 'fileformat': vim.eval('&ff'),
'fileencoding': vim.eval('&fenc'),
'filetype': vim.eval('&ft'),
'line_percent': str(line_percent).rjust(3) + '%',
'line_percent_color': line_percent_color,
'linecurrent': str(line_current).rjust(3),
'colcurrent': ':' + str(col_current).ljust(2),
}
setwinvar(winnr, 'powerline', windata)
mode = modes[vim_funcs['mode']()]
if not current:
mode = None
powerline = Powerline([ powerline = Powerline([
Segment(mode, 22, 148, attr=Segment.ATTR_BOLD), Segment(mode, 22, 148, attr=Segment.ATTR_BOLD),
Segment(vim.eval('&paste ? "PASTE" : ""'), 231, 166, attr=Segment.ATTR_BOLD), Segment(windata['paste'], 231, 166, attr=Segment.ATTR_BOLD),
Segment(branch, 250, 240, priority=10), Segment(windata['branch'], 250, 240, priority=10),
Segment(readonly, 196, 240, draw_divider=False), Segment(windata['readonly'], 196, 240, draw_divider=False),
Segment(filepath, 250, 240, draw_divider=False, priority=5), Segment(windata['filepath'], 250, 240, draw_divider=False, priority=5),
Segment(filename, filename_color, 240, attr=Segment.ATTR_BOLD, draw_divider=not len(modified)), Segment(windata['filename'], windata['filename_color'], 240, attr=Segment.ATTR_BOLD, draw_divider=not len(windata['modified'])),
Segment(modified, 220, 240, attr=Segment.ATTR_BOLD), Segment(windata['modified'], 220, 240, attr=Segment.ATTR_BOLD),
Segment(currenttag, 246, 236, draw_divider=False, priority=100), Segment(windata['currenttag'], 246, 236, draw_divider=False, priority=100),
Segment(filler=True, fg=236, bg=236), Segment(filler=True, fg=236, bg=236),
Segment(syntastic, 214, 236, attr=Segment.ATTR_BOLD, draw_divider=False, priority=100), Segment(windata['fileformat'], 247, 236, side='r', priority=50),
Segment(filler=True, fg=236, bg=236), Segment(windata['fileencoding'], 247, 236, side='r', priority=50),
Segment(vim.eval('&ff'), 247, 236, side='r', priority=50), Segment(windata['filetype'], 247, 236, side='r', priority=50),
Segment(vim.eval('&fenc'), 247, 236, side='r', priority=50), Segment(windata['line_percent'], windata['line_percent_color'], 240, side='r', priority=30),
Segment(vim.eval('&ft'), 247, 236, side='r', priority=50),
Segment(str(line_percent).rjust(3) + '%', line_percent_color, 240, side='r', priority=30),
Segment('', 239, 252, side='r'), Segment('', 239, 252, side='r'),
Segment(str(line_current).rjust(3), 235, 252, attr=Segment.ATTR_BOLD, side='r', draw_divider=False), Segment(windata['linecurrent'], 235, 252, attr=Segment.ATTR_BOLD, side='r', draw_divider=False),
Segment(':' + str(col_current).ljust(2), 244, 252, side='r', priority=30, draw_divider=False), Segment(windata['colcurrent'], 244, 252, side='r', priority=30, draw_divider=False),
]) ])
renderer = VimSegmentRenderer() renderer = VimSegmentRenderer()
@ -176,6 +192,4 @@ def statusline():
return stl return stl
statusline()
# vim: ft=python ts=4 sts=4 sw=4 noet # vim: ft=python ts=4 sts=4 sw=4 noet

View File

@ -14,8 +14,20 @@ else
endfunction endfunction
endif endif
function! DynStl() function! Powerline(winnr)
return s:pyeval('statusline()') return s:pyeval('statusline('. a:winnr .')')
endfunction endfunction
set stl=%!DynStl() function! s:WinDoPowerline()
if ! exists('w:powerline')
let w:powerline = {}
endif
let &l:stl = '%!Powerline('. winnr() .')'
endfunction
augroup Powerline
autocmd!
autocmd BufEnter,BufWinEnter,WinEnter * let w:current = 1 | let currwin = winnr() | windo call s:WinDoPowerline() | exec currwin . 'wincmd w'
autocmd BufLeave,BufWinLeave,WinLeave * let w:current = 0
augroup END