From 708306c6bae453dcdd2cd68e4facd2d404a00381 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 17 Nov 2012 13:58:28 +0359 Subject: [PATCH] Avoid invoking vim parser as much as possible in case vim is recent enough --- examples/vim/powerline.py | 102 ++++++++++++++++++++++++++++++------- examples/vim/powerline.vim | 2 +- 2 files changed, 85 insertions(+), 19 deletions(-) diff --git a/examples/vim/powerline.py b/examples/vim/powerline.py index d267a5ef..76044b17 100644 --- a/examples/vim/powerline.py +++ b/examples/vim/powerline.py @@ -28,28 +28,78 @@ modes = { '!': 'SHELL', } +if hasattr(vim, 'bindeval'): + # This branch is used to avoid invoking vim parser as much as possible + + def get_vim_func(f, rettype=None): + try: + return vim.bindeval('function("'+f+'")') + except vim.error: + return None + + vim_globals = vim.bindeval('g:') + + def set_global_var(var, val): + vim_globals[var] = val +else: + import json + class VimFunc(object): + __slots__ = ('f','rettype') + def __init__(self, f, rettype=None): + self.f = f + self.rettype = rettype + + def __call__(self, *args): + r = vim.eval(self.f+'('+json.dumps(args)[1:-1]+')') + if self.rettype: + return self.rettype(r) + return r + + def get_vim_func(f): + return VimFunc(f) + + def set_global_var(var, val): + vim.command('let g:{0}={1}'.format(var, json.dumps(val))) + +vim_funcs = { + 'winwidth' : get_vim_func('winwidth', rettype=int), + 'mode' : get_vim_func('mode'), + 'fghead' : get_vim_func('fugitive#head'), + 'line' : get_vim_func('line', rettype=int), + 'col' : get_vim_func('col', rettype=int), + 'expand' : get_vim_func('expand'), + 'tbcurtag' : get_vim_func('tagbar#currenttag'), + 'sstlflag' : get_vim_func('SyntasticStatuslineFlag'), + 'hlexists' : get_vim_func('hlexists', rettype=int), +} def statusline(): - winwidth = int(vim.bindeval('winwidth(0)')) + winwidth = vim_funcs['winwidth'](0) # Prepare segment contents - mode = modes[vim.bindeval('mode()')] + mode = modes[vim_funcs['mode']()] - branch = vim.bindeval('fugitive#head(5)') + try: + branch = vim_funcs['fghead'](5) + except vim.error: + vim_funcs['fghead'] = None + branch = '' + except TypeError: + branch = '' if branch: branch = '⭠ ' + branch - line_current = int(vim.bindeval('line(".")')) - line_end = int(vim.bindeval('line("$")')) - line_percent = int(float(line_current) / float(line_end) * 100) + line_current = vim_funcs['line']('.') + line_end = vim_funcs['line']('$') + line_percent = line_current * 100 // line_end # Fun gradient colored percent segment line_percent_gradient = [160, 166, 172, 178, 184, 190] line_percent_color = line_percent_gradient[int((len(line_percent_gradient) - 1) * line_percent / 100)] - col_current = vim.bindeval('col(".")') + col_current = vim_funcs['col']('.') - filepath, filename = os.path.split(vim.bindeval('expand("%:~:.")')) + filepath, filename = os.path.split(vim_funcs['expand']('%:~:.')) filename_color = 231 if filepath: filepath += os.sep @@ -58,19 +108,31 @@ def statusline(): filename = '[No Name]' filename_color = 250 - readonly = vim.bindeval('&ro ? "⭤ " : ""') - modified = vim.bindeval('&mod ? " +" : ""') + readonly = vim.eval('&ro ? "⭤ " : ""') + modified = vim.eval('&mod ? " +" : ""') - currenttag = vim.bindeval('tagbar#currenttag("%s", "")') + try: + currenttag = vim_funcs['tbcurtag']('%s', '') + except vim.error: + vim_funcs['tbcurtag'] = None + currenttag = '' + except TypeError: + currenttag = '' # The Syntastic segment is center aligned (filler segment on each side) to show off how the filler segments work # Not necessarily how it's going to look in the final theme - vim.command('let g:syntastic_stl_format = "⮃ %E{ ERRORS (%e) ⭡ %fe }%W{ WARNINGS (%w) ⭡ %fw } ⮁"') - syntastic = vim.bindeval('SyntasticStatuslineFlag()') + set_global_var('syntastic_stl_format', '⮃ %E{ ERRORS (%e) ⭡ %fe }%W{ WARNINGS (%w) ⭡ %fw } ⮁') + try: + syntastic = vim_funcs['sstlflag']() + except vim.error: + vim_funcs['sstlflag'] = None + syntastic = '' + except TypeError: + syntastic = '' powerline = Powerline([ Segment(mode, 22, 148, attr=Segment.ATTR_BOLD), - Segment(vim.bindeval('&paste ? "PASTE" : ""'), 231, 166, attr=Segment.ATTR_BOLD), + Segment(vim.eval('&paste ? "PASTE" : ""'), 231, 166, attr=Segment.ATTR_BOLD), Segment(branch, 250, 240, priority=10), Segment(readonly, 196, 240, draw_divider=False), Segment(filepath, 250, 240, draw_divider=False, priority=5), @@ -80,9 +142,9 @@ def statusline(): Segment(filler=True, fg=236, bg=236), Segment(syntastic, 214, 236, attr=Segment.ATTR_BOLD, draw_divider=False, priority=100), Segment(filler=True, fg=236, bg=236), - Segment(vim.bindeval('&ff'), 247, 236, side='r', priority=50), - Segment(vim.bindeval('&fenc'), 247, 236, side='r', priority=50), - Segment(vim.bindeval('&ft'), 247, 236, side='r', priority=50), + Segment(vim.eval('&ff'), 247, 236, side='r', priority=50), + Segment(vim.eval('&fenc'), 247, 236, side='r', priority=50), + 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(str(line_current).rjust(3), 235, 252, attr=Segment.ATTR_BOLD, side='r', draw_divider=False), @@ -97,7 +159,7 @@ def statusline(): # Create highlighting groups for group, hl in renderer.hl_groups.items(): - if int(vim.bindeval('hlexists("{0}")'.format(group))): + if vim_funcs['hlexists'](group): # Only create hl group if it doesn't already exist continue @@ -111,3 +173,7 @@ def statusline(): )) return stl + +statusline() + +# vim: ft=python ts=4 sts=4 sw=4 noet diff --git a/examples/vim/powerline.vim b/examples/vim/powerline.vim index d3b86b12..84cdefd5 100644 --- a/examples/vim/powerline.vim +++ b/examples/vim/powerline.vim @@ -9,7 +9,7 @@ if exists('*pyeval') let s:pyeval=function('pyeval') else python import json - function s:pyeval(e) + function! s:pyeval(e) python vim.command('return ' + json.dumps(eval(vim.eval('a:e')))) endfunction endif