diff --git a/powerline/bindings/vim/__init__.py b/powerline/bindings/vim/__init__.py index 3d7f0c08..46ae29a5 100644 --- a/powerline/bindings/vim/__init__.py +++ b/powerline/bindings/vim/__init__.py @@ -7,13 +7,7 @@ try: except ImportError: vim = {} -try: - _vim_globals = vim.bindeval('g:') - - def vim_set_global_var(var, val): - '''Set a global var in vim using bindeval().''' - _vim_globals[var] = val - +if hasattr(vim, 'bindeval'): def vim_get_func(f, rettype=None): '''Return a vim function binding.''' try: @@ -23,16 +17,9 @@ try: return func except vim.error: return None -except AttributeError: +else: import json - def vim_set_global_var(var, val): # NOQA - '''Set a global var in vim using vim.command(). - - This is a fallback function for older vim versions. - ''' - vim.command('let g:{0}={1}'.format(var, json.dumps(val))) - class VimFunc(object): '''Evaluate a vim function using vim.eval(). @@ -52,6 +39,36 @@ except AttributeError: vim_get_func = VimFunc + +if hasattr(vim, 'vars'): + def vim_getvar(varname): + return vim.vars[bytes(varname)] +elif hasattr(vim, 'bindeval'): + _vim_globals = vim.bindeval('g:') + + def vim_getvar(varname): # NOQA + try: + return _vim_globals[bytes(varname)] + except (KeyError, IndexError): + raise KeyError(varname) +else: + _vim_exists = vim_get_func('exists', rettype=int) + + def vim_getvar(varname): # NOQA + varname = 'g:' + varname + if _vim_exists(varname): + return vim.eval(varname) + else: + raise KeyError(varname) + +if hasattr(vim, 'options'): + def vim_getbufoption(info, option): + return info['buffer'].options[option] +else: + def vim_getbufoption(info, option): # NOQA + return getbufvar(info['bufnr'], '&' + option) + + if sys.version_info < (3,) or not hasattr(vim, 'bindeval'): getbufvar = vim_get_func('getbufvar') else: diff --git a/powerline/matchers/vim.py b/powerline/matchers/vim.py index 9d8eec37..1a16fb49 100644 --- a/powerline/matchers/vim.py +++ b/powerline/matchers/vim.py @@ -3,11 +3,11 @@ from __future__ import absolute_import import os -from powerline.bindings.vim import getbufvar +from powerline.bindings.vim import vim_getbufoption def help(matcher_info): - return str(getbufvar(matcher_info['bufnr'], '&buftype')) == 'help' + return str(vim_getbufoption(matcher_info, 'buftype')) == 'help' def cmdwin(matcher_info): @@ -16,4 +16,4 @@ def cmdwin(matcher_info): def quickfix(matcher_info): - return str(getbufvar(matcher_info['bufnr'], '&buftype')) == 'quickfix' + return str(vim_getbufoption(matcher_info, 'buftype')) == 'quickfix' diff --git a/powerline/segments/vim.py b/powerline/segments/vim.py index 2bd92bd6..5ba63588 100644 --- a/powerline/segments/vim.py +++ b/powerline/segments/vim.py @@ -8,7 +8,7 @@ try: except ImportError: vim = {} # NOQA -from powerline.bindings.vim import vim_get_func, getbufvar +from powerline.bindings.vim import vim_get_func, getbufvar, vim_getbufoption from powerline.theme import requires_segment_info from powerline.lib import add_divider_highlight_group from powerline.lib.vcs import guess, tree_status @@ -94,7 +94,7 @@ def modified_indicator(pl, segment_info, text='+'): :param string text: text to display if the current buffer is modified ''' - return text if int(getbufvar(segment_info['bufnr'], '&modified')) else None + return text if int(vim_getbufoption(segment_info, 'modified')) else None @requires_segment_info @@ -114,7 +114,7 @@ def readonly_indicator(pl, segment_info, text=''): :param string text: text to display if the current buffer is read-only ''' - return text if int(getbufvar(segment_info['bufnr'], '&readonly')) else None + return text if int(vim_getbufoption(segment_info, 'readonly')) else None @requires_segment_info @@ -189,7 +189,7 @@ def file_format(pl, segment_info): Divider highlight group used: ``background:divider``. ''' - return getbufvar(segment_info['bufnr'], '&fileformat') or None + return vim_getbufoption(segment_info, 'fileformat') or None @requires_segment_info @@ -201,7 +201,7 @@ def file_encoding(pl, segment_info): Divider highlight group used: ``background:divider``. ''' - return getbufvar(segment_info['bufnr'], '&fileencoding') or None + return vim_getbufoption(segment_info, 'fileencoding') or None @requires_segment_info @@ -213,7 +213,7 @@ def file_type(pl, segment_info): Divider highlight group used: ``background:divider``. ''' - return getbufvar(segment_info['bufnr'], '&filetype') or None + return vim_getbufoption(segment_info, 'filetype') or None @requires_segment_info @@ -295,7 +295,7 @@ def branch(pl, segment_info, status_colors=False): Divider highlight group used: ``branch:divider``. ''' name = segment_info['buffer'].name - skip = not (name and (not getbufvar(segment_info['bufnr'], '&buftype'))) + skip = not (name and (not vim_getbufoption(segment_info, 'buftype'))) if not skip: repo = guess(path=name) if repo is not None: @@ -317,7 +317,7 @@ def file_vcs_status(pl, segment_info): Highlight groups used: ``file_vcs_status``. ''' name = segment_info['buffer'].name - skip = not (name and (not getbufvar(segment_info['bufnr'], '&buftype'))) + skip = not (name and (not vim_getbufoption(segment_info, 'buftype'))) if not skip: repo = guess(path=name) if repo is not None: diff --git a/powerline/vim.py b/powerline/vim.py index a15854af..b658b8df 100644 --- a/powerline/vim.py +++ b/powerline/vim.py @@ -2,7 +2,7 @@ from __future__ import absolute_import -from powerline.bindings.vim import vim_get_func +from powerline.bindings.vim import vim_get_func, vim_getvar from powerline import Powerline from powerline.lib import mergedicts from powerline.matcher import gen_matcher_getter @@ -13,19 +13,12 @@ if not hasattr(vim, 'bindeval'): import json -vim_exists = vim_get_func('exists', rettype=int) -vim_getwinvar = vim_get_func('getwinvar') -vim_setwinvar = vim_get_func('setwinvar') - - def _override_from(config, override_varname): - if vim_exists(override_varname): - # FIXME vim.eval has problem with numeric types, vim.bindeval may be - # absent (and requires converting values to python built-in types), - # vim.eval with typed call like the one I implemented in frawor is slow. - # Maybe eval(vime.eval('string({0})'.format(override_varname)))? - overrides = vim.eval(override_varname) - mergedicts(config, overrides) + try: + overrides = vim_getvar(override_varname) + except KeyError: + return config + mergedicts(config, overrides) return config @@ -64,14 +57,14 @@ class VimPowerline(Powerline): return True def load_main_config(self): - return _override_from(super(VimPowerline, self).load_main_config(), 'g:powerline_config_overrides') + return _override_from(super(VimPowerline, self).load_main_config(), 'powerline_config_overrides') def load_theme_config(self, name): # Note: themes with non-[a-zA-Z0-9_] names are impossible to override # (though as far as I know exists() won’t throw). Won’t fix, use proper # theme names. return _override_from(super(VimPowerline, self).load_theme_config(name), - 'g:powerline_theme_overrides__' + name) + 'powerline_theme_overrides__' + name) def get_local_themes(self, local_themes): if not local_themes: @@ -82,9 +75,9 @@ class VimPowerline(Powerline): for key, val in local_themes.items())) def get_config_paths(self): - if vim_exists('g:powerline_config_path'): - return [vim.eval('g:powerline_config_path')] - else: + try: + return [vim_getvar('powerline_config_path')] + except KeyError: return super(VimPowerline, self).get_config_paths() @staticmethod @@ -120,19 +113,22 @@ class VimPowerline(Powerline): r = (window, curwindow_id, window.number) return r else: + _vim_getwinvar = staticmethod(vim_get_func('getwinvar')) + _vim_setwinvar = staticmethod(vim_get_func('setwinvar')) + def win_idx(self, window_id): # NOQA r = None for winnr, window in zip(count(1), vim.windows): - curwindow_id = vim_getwinvar(winnr, 'powerline_window_id') + curwindow_id = self._vim_getwinvar(winnr, 'powerline_window_id') if curwindow_id: curwindow_id = int(curwindow_id) else: curwindow_id = self.last_window_id self.last_window_id += 1 - vim_setwinvar(winnr, 'powerline_window_id', curwindow_id) + self._vim_setwinvar(winnr, 'powerline_window_id', curwindow_id) statusline = self.window_statusline.format(curwindow_id) - if vim_getwinvar(winnr, '&statusline') != statusline: - vim_setwinvar(winnr, '&statusline', statusline) + if self._vim_getwinvar(winnr, '&statusline') != statusline: + self._vim_setwinvar(winnr, '&statusline', statusline) if curwindow_id == window_id if window_id else window is vim.current.window: assert r is None, "Non-unique window ID" r = (window, curwindow_id, winnr)