mirror of
https://github.com/powerline/powerline.git
synced 2025-04-08 19:25:04 +02:00
Merge remote-tracking branch 'zyx-i/less-viml' into develop
This commit is contained in:
commit
5710b7b37f
@ -91,8 +91,19 @@ Usage
|
||||
Vim statusline
|
||||
--------------
|
||||
|
||||
Add the following line to your :file:`vimrc`, where ``{repository_root}`` is the
|
||||
absolute path to your Powerline installation directory:
|
||||
If installed using pip just use
|
||||
|
||||
.. code-block:: vim
|
||||
|
||||
python from powerline.vim import setup as powerline_setup
|
||||
python powerline_setup()
|
||||
python del powerline_setup
|
||||
|
||||
(replace ``python`` with ``python3`` if appropriate).
|
||||
|
||||
If you just cloned the repository add the following line to your :file:`vimrc`,
|
||||
where ``{repository_root}`` is the absolute path to your Powerline installation
|
||||
directory:
|
||||
|
||||
.. code-block:: vim
|
||||
|
||||
@ -109,6 +120,9 @@ hand: ``powerline`` is installed and run just like any other plugin using
|
||||
|
||||
call vam#ActivateAddons(['powerline'])
|
||||
|
||||
Note: when using Gentoo ebuild you need to specify ``USE=vim`` to enable
|
||||
powerline.
|
||||
|
||||
Shell prompts
|
||||
-------------
|
||||
|
||||
|
@ -376,7 +376,10 @@ class Powerline(object):
|
||||
current application.
|
||||
'''
|
||||
self.shutdown_event.set()
|
||||
self.renderer.shutdown()
|
||||
try:
|
||||
self.renderer.shutdown()
|
||||
except AttributeError:
|
||||
pass
|
||||
functions = (
|
||||
self.on_main_change,
|
||||
self.on_colors_change,
|
||||
|
@ -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[str(varname)]
|
||||
elif hasattr(vim, 'bindeval'):
|
||||
_vim_globals = vim.bindeval('g:')
|
||||
|
||||
def vim_getvar(varname): # NOQA
|
||||
try:
|
||||
return _vim_globals[str(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:
|
||||
@ -62,3 +79,21 @@ else:
|
||||
if type(r) is bytes:
|
||||
return r.decode('utf-8')
|
||||
return r
|
||||
|
||||
|
||||
class VimEnviron(object):
|
||||
@staticmethod
|
||||
def __getitem__(key):
|
||||
return vim.eval('$' + key)
|
||||
|
||||
@staticmethod
|
||||
def get(key, default=None):
|
||||
return vim.eval('$' + key) or default
|
||||
|
||||
@staticmethod
|
||||
def __setitem__(key, value):
|
||||
return vim.command('let $' + key + '="'
|
||||
+ value.replace('"', '\\"').replace('\\', '\\\\').replace('\n', '\\n').replace('\0', '')
|
||||
+ '"')
|
||||
|
||||
environ = VimEnviron()
|
||||
|
@ -15,18 +15,18 @@ if ! has('python') && ! has('python3')
|
||||
finish
|
||||
endif
|
||||
|
||||
let s:powerline_pycmd = substitute(get(g:, 'powerline_pycmd', has('python') ? 'py' : 'py3'),
|
||||
let s:pycmd = substitute(get(g:, 'powerline_pycmd', has('python') ? 'py' : 'py3'),
|
||||
\'\v^(py)%[thon](3?)$', '\1\2', '')
|
||||
let s:powerline_pyeval = get(g:, 'powerline_pyeval', s:powerline_pycmd.'eval')
|
||||
let s:pyeval = get(g:, 'powerline_pyeval', s:pycmd.'eval')
|
||||
|
||||
let s:import_cmd = 'from powerline.vim import VimPowerline'
|
||||
let s:import_cmd = 'from powerline.vim import setup as powerline_setup'
|
||||
try
|
||||
exec s:powerline_pycmd "try:\n"
|
||||
\ ." ".s:import_cmd."\n"
|
||||
\ ."except ImportError:\n"
|
||||
\ ." import sys, vim\n"
|
||||
\ ." sys.path.append(vim.eval('expand(\"<sfile>:h:h:h:h:h\")'))\n"
|
||||
\ ." ".s:import_cmd
|
||||
execute s:pycmd "try:\n"
|
||||
\ ." ".s:import_cmd."\n"
|
||||
\ ."except ImportError:\n"
|
||||
\ ." import sys, vim\n"
|
||||
\ ." sys.path.append(vim.eval('expand(\"<sfile>:h:h:h:h:h\")'))\n"
|
||||
\ ." ".s:import_cmd
|
||||
let s:launched = 1
|
||||
finally
|
||||
if !exists('s:launched')
|
||||
@ -40,56 +40,5 @@ finally
|
||||
endif
|
||||
endtry
|
||||
|
||||
if !get(g:, 'powerline_debugging_pyeval') && exists('*'. s:powerline_pyeval)
|
||||
let s:pyeval = function(s:powerline_pyeval)
|
||||
else
|
||||
exec s:powerline_pycmd 'import json, vim'
|
||||
exec "function! s:pyeval(e)\n".
|
||||
\ s:powerline_pycmd." vim.command('return ' + json.dumps(eval(vim.eval('a:e'))))\n".
|
||||
\"endfunction"
|
||||
endif
|
||||
|
||||
let s:last_window_id = 0
|
||||
function! s:GetWinID(winnr)
|
||||
let r = getwinvar(a:winnr, 'window_id')
|
||||
if empty(r)
|
||||
let r = s:last_window_id
|
||||
let s:last_window_id += 1
|
||||
call setwinvar(a:winnr, 'window_id', r)
|
||||
endif
|
||||
" Without this condition it triggers unneeded statusline redraw
|
||||
if getwinvar(a:winnr, '&statusline') isnot# '%!Powerline('.r.')'
|
||||
call setwinvar(a:winnr, '&statusline', '%!Powerline('.r.')')
|
||||
endif
|
||||
return r
|
||||
endfunction
|
||||
|
||||
function! Powerline(window_id)
|
||||
let winidx = index(map(range(1, winnr('$')), 's:GetWinID(v:val)'), a:window_id)
|
||||
let current = w:window_id is# a:window_id
|
||||
return s:pyeval('powerline.render('. a:window_id .', '. winidx .', '. current .')')
|
||||
endfunction
|
||||
|
||||
function! PowerlineNew()
|
||||
call map(range(1, winnr('$')), 's:GetWinID(v:val)')
|
||||
endfunction
|
||||
|
||||
function! PowerlineRegisterCachePurgerEvent(event)
|
||||
exec s:powerline_pycmd 'from powerline.segments.vim import launchevent as powerline_launchevent'
|
||||
augroup Powerline
|
||||
exec 'autocmd' a:event '*' s:powerline_pycmd.' powerline_launchevent("'.a:event.'")'
|
||||
augroup END
|
||||
endfunction
|
||||
|
||||
augroup Powerline
|
||||
autocmd! ColorScheme * :exec s:powerline_pycmd 'powerline.reset_highlight()'
|
||||
autocmd! VimEnter * :redrawstatus!
|
||||
autocmd! VimLeavePre * :exec s:powerline_pycmd 'powerline.shutdown()'
|
||||
augroup END
|
||||
|
||||
exec s:powerline_pycmd 'powerline = VimPowerline()'
|
||||
exec s:powerline_pycmd 'del VimPowerline'
|
||||
" Is immediately changed when PowerlineNew() function is run. Good for global
|
||||
" value.
|
||||
set statusline=%!PowerlineNew()
|
||||
call PowerlineNew()
|
||||
execute s:pycmd 'powerline_setup(pyeval=vim.eval("s:pyeval"), pycmd=vim.eval("s:pycmd"))'
|
||||
execute s:pycmd 'del powerline_setup'
|
||||
|
@ -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'
|
||||
|
@ -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, environ
|
||||
from powerline.renderer import Renderer
|
||||
from powerline.colorscheme import ATTR_BOLD, ATTR_ITALIC, ATTR_UNDERLINE
|
||||
from powerline.theme import Theme
|
||||
@ -68,17 +68,19 @@ class VimRenderer(Renderer):
|
||||
def get_segment_info(self, segment_info):
|
||||
return segment_info or self.segment_info
|
||||
|
||||
def render(self, window_id, winidx, current):
|
||||
def render(self, window, window_id, winnr):
|
||||
'''Render all segments.'''
|
||||
if current:
|
||||
if window is vim.current.window:
|
||||
mode = vim_mode(1)
|
||||
mode = mode_translations.get(mode, mode)
|
||||
else:
|
||||
mode = 'nc'
|
||||
segment_info = {
|
||||
'window': vim.windows[winidx],
|
||||
'window': window,
|
||||
'mode': mode,
|
||||
'window_id': window_id,
|
||||
'winnr': winnr,
|
||||
'environ': environ,
|
||||
}
|
||||
segment_info['buffer'] = segment_info['window'].buffer
|
||||
segment_info['bufnr'] = segment_info['buffer'].number
|
||||
|
@ -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
|
||||
@ -51,29 +51,6 @@ bufeventfuncs = defaultdict(lambda: [])
|
||||
defined_events = set()
|
||||
|
||||
|
||||
def purgeonevents_reg(func, events, is_buffer_event=False):
|
||||
if is_buffer_event:
|
||||
cureventfuncs = bufeventfuncs
|
||||
else:
|
||||
cureventfuncs = eventfuncs
|
||||
for event in events:
|
||||
if event not in defined_events:
|
||||
vim.eval('PowerlineRegisterCachePurgerEvent("' + event + '")')
|
||||
defined_events.add(event)
|
||||
cureventfuncs[event].append(func)
|
||||
|
||||
|
||||
def launchevent(event):
|
||||
global eventfuncs
|
||||
global bufeventfuncs
|
||||
for func in eventfuncs[event]:
|
||||
func()
|
||||
if bufeventfuncs[event]:
|
||||
buffer = vim.buffers[int(vim_funcs['expand']('<abuf>')) - 1]
|
||||
for func in bufeventfuncs[event]:
|
||||
func(buffer)
|
||||
|
||||
|
||||
# TODO Remove cache when needed
|
||||
def window_cached(func):
|
||||
cache = {}
|
||||
@ -117,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
|
||||
@ -137,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
|
||||
@ -212,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
|
||||
@ -224,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
|
||||
@ -236,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
|
||||
@ -318,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:
|
||||
@ -340,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:
|
||||
|
@ -28,7 +28,7 @@ class ShellPowerline(Powerline):
|
||||
|
||||
def load_theme_config(self, name):
|
||||
r = super(ShellPowerline, self).load_theme_config(name)
|
||||
if name in self.theme_option:
|
||||
if self.theme_option and name in self.theme_option:
|
||||
mergedicts(r, self.theme_option[name])
|
||||
return r
|
||||
|
||||
|
127
powerline/vim.py
127
powerline/vim.py
@ -2,30 +2,31 @@
|
||||
|
||||
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
|
||||
import vim
|
||||
from itertools import count
|
||||
|
||||
|
||||
vim_exists = vim_get_func('exists', rettype=int)
|
||||
if not hasattr(vim, 'bindeval'):
|
||||
import json
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
class VimPowerline(Powerline):
|
||||
def __init__(self):
|
||||
def __init__(self, pyeval='PowerlinePyeval'):
|
||||
super(VimPowerline, self).__init__('vim')
|
||||
self.last_window_id = 1
|
||||
self.window_statusline = '%!' + pyeval + '(\'powerline.statusline({0})\')'
|
||||
|
||||
def add_local_theme(self, key, config):
|
||||
'''Add local themes at runtime (during vim session).
|
||||
@ -56,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:
|
||||
@ -74,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
|
||||
@ -93,3 +94,97 @@ class VimPowerline(Powerline):
|
||||
# fine to ignore it: no renderer == no colors to reset == no need to
|
||||
# do anything.
|
||||
pass
|
||||
|
||||
if all((hasattr(vim.current.window, attr) for attr in ('options', 'vars', 'number'))):
|
||||
def win_idx(self, window_id):
|
||||
r = None
|
||||
for window in vim.windows:
|
||||
try:
|
||||
curwindow_id = window.vars['powerline_window_id']
|
||||
except KeyError:
|
||||
curwindow_id = self.last_window_id
|
||||
self.last_window_id += 1
|
||||
window.vars['powerline_window_id'] = curwindow_id
|
||||
statusline = self.window_statusline.format(curwindow_id)
|
||||
if window.options['statusline'] != statusline:
|
||||
window.options['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, 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 = 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
|
||||
self._vim_setwinvar(winnr, 'powerline_window_id', curwindow_id)
|
||||
statusline = self.window_statusline.format(curwindow_id)
|
||||
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)
|
||||
return r
|
||||
|
||||
def statusline(self, window_id):
|
||||
window, window_id, winnr = self.win_idx(window_id) or (None, None, None)
|
||||
if not window:
|
||||
return 'No window {0}'.format(window_id)
|
||||
return self.render(window, window_id, winnr)
|
||||
|
||||
def new_window(self):
|
||||
window, window_id, winnr = self.win_idx(None)
|
||||
return self.render(window, window_id, winnr)
|
||||
|
||||
if not hasattr(vim, 'bindeval'):
|
||||
# Method for PowerlinePyeval function. Is here to reduce the number of
|
||||
# requirements to __main__ globals to just one powerline object
|
||||
# (previously it required as well vim and json)
|
||||
@staticmethod
|
||||
def pyeval():
|
||||
import __main__
|
||||
vim.command('return ' + json.dumps(eval(vim.eval('a:e'),
|
||||
__main__.__dict__)))
|
||||
|
||||
|
||||
def setup(pyeval=None, pycmd=None):
|
||||
import sys
|
||||
import __main__
|
||||
if not pyeval:
|
||||
pyeval = 'pyeval' if sys.version_info < (3,) else 'py3eval'
|
||||
if not pycmd:
|
||||
pycmd = 'python' if sys.version_info < (3,) else 'python3'
|
||||
|
||||
# pyeval() and vim.bindeval were both introduced in one patch
|
||||
if not hasattr(vim, 'bindeval'):
|
||||
vim.command(('''
|
||||
function! PowerlinePyeval(e)
|
||||
{pycmd} powerline.pyeval()
|
||||
endfunction
|
||||
''').format(pycmd=pycmd))
|
||||
pyeval = 'PowerlinePyeval'
|
||||
|
||||
powerline = VimPowerline(pyeval)
|
||||
__main__.powerline = powerline
|
||||
|
||||
# Cannot have this in one line due to weird newline handling (in :execute
|
||||
# context newline is considered part of the command in just the same cases
|
||||
# when bar is considered part of the command (unless defining function
|
||||
# inside :execute)). vim.command is :execute equivalent regarding this case.
|
||||
vim.command('augroup Powerline')
|
||||
vim.command(' autocmd! ColorScheme * :{pycmd} powerline.reset_highlight()'.format(pycmd=pycmd))
|
||||
vim.command(' autocmd! VimEnter * :redrawstatus!')
|
||||
vim.command(' autocmd! VimLeavePre * :{pycmd} powerline.shutdown()'.format(pycmd=pycmd))
|
||||
vim.command('augroup END')
|
||||
|
||||
# Is immediately changed after new_window function is run. Good for global
|
||||
# value.
|
||||
vim.command('set statusline=%!{pyeval}(\'powerline.new_window()\')'.format(pyeval=pyeval))
|
||||
|
@ -19,36 +19,42 @@ class TestConfig(TestCase):
|
||||
def test_vim(self):
|
||||
from powerline.vim import VimPowerline
|
||||
cfg_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'powerline', 'config_files')
|
||||
buffers = ((('bufoptions',), {'buftype': 'help'}), (('buffer', '[Command Line]'), {}), (('bufoptions',), {'buftype': 'quickfix'}))
|
||||
buffers = ((('bufoptions',), {'buftype': 'help'}), (('bufname', '[Command Line]'), {}), (('bufoptions',), {'buftype': 'quickfix'}))
|
||||
with open(os.path.join(cfg_path, 'config.json'), 'r') as f:
|
||||
self.assertEqual(len(buffers), len(json.load(f)['ext']['vim']['local_themes']))
|
||||
outputs = {}
|
||||
i = 0
|
||||
mode = None
|
||||
|
||||
with VimPowerline() as powerline:
|
||||
def check_output(*args):
|
||||
out = powerline.render(*args + (0 if mode == 'nc' else 1,))
|
||||
if out in outputs:
|
||||
self.fail('Duplicate in set #{0} for mode {1!r} (previously defined in set #{2} for mode {3!r})'.format(i, mode, *outputs[out]))
|
||||
outputs[out] = (i, mode)
|
||||
with vim_module._with('split'):
|
||||
with VimPowerline() as powerline:
|
||||
def check_output(mode, args, kwargs):
|
||||
if mode == 'nc':
|
||||
window = vim_module.windows[0]
|
||||
window_id = 2
|
||||
else:
|
||||
vim_module._start_mode(mode)
|
||||
window = vim_module.current.window
|
||||
window_id = 1
|
||||
winnr = window.number
|
||||
out = powerline.render(window, window_id, winnr)
|
||||
if out in outputs:
|
||||
self.fail('Duplicate in set #{0} ({1}) for mode {2!r} (previously defined in set #{3} ({4!r}) for mode {5!r})'.format(i, (args, kwargs), mode, *outputs[out]))
|
||||
outputs[out] = (i, (args, kwargs), mode)
|
||||
|
||||
with vim_module._with('buffer', 'foo.txt'):
|
||||
with vim_module._with('globals', powerline_config_path=cfg_path):
|
||||
exclude = set(('no', 'v', 'V', VBLOCK, 's', 'S', SBLOCK, 'R', 'Rv', 'c', 'cv', 'ce', 'r', 'rm', 'r?', '!'))
|
||||
try:
|
||||
for mode in ['n', 'nc', 'no', 'v', 'V', VBLOCK, 's', 'S', SBLOCK, 'i', 'R', 'Rv', 'c', 'cv', 'ce', 'r', 'rm', 'r?', '!']:
|
||||
if mode != 'nc':
|
||||
vim_module._start_mode(mode)
|
||||
check_output(1, 0)
|
||||
for args, kwargs in buffers:
|
||||
i += 1
|
||||
if mode in exclude:
|
||||
continue
|
||||
with vim_module._with(*args, **kwargs):
|
||||
check_output(1, 0)
|
||||
finally:
|
||||
vim_module._start_mode('n')
|
||||
with vim_module._with('bufname', '/tmp/foo.txt'):
|
||||
with vim_module._with('globals', powerline_config_path=cfg_path):
|
||||
exclude = set(('no', 'v', 'V', VBLOCK, 's', 'S', SBLOCK, 'R', 'Rv', 'c', 'cv', 'ce', 'r', 'rm', 'r?', '!'))
|
||||
try:
|
||||
for mode in ['n', 'nc', 'no', 'v', 'V', VBLOCK, 's', 'S', SBLOCK, 'i', 'R', 'Rv', 'c', 'cv', 'ce', 'r', 'rm', 'r?', '!']:
|
||||
check_output(mode, None, None)
|
||||
for args, kwargs in buffers:
|
||||
i += 1
|
||||
if mode in exclude:
|
||||
continue
|
||||
with vim_module._with(*args, **kwargs):
|
||||
check_output(mode, args, kwargs)
|
||||
finally:
|
||||
vim_module._start_mode('n')
|
||||
|
||||
def test_tmux(self):
|
||||
from powerline.segments import common
|
||||
|
100
tests/vim.py
100
tests/vim.py
@ -1,10 +1,10 @@
|
||||
# vim:fileencoding=utf-8:noet
|
||||
_log = []
|
||||
_g = {}
|
||||
vars = {}
|
||||
_window = 0
|
||||
_mode = 'n'
|
||||
_buf_purge_events = set()
|
||||
_options = {
|
||||
options = {
|
||||
'paste': 0,
|
||||
'ambiwidth': 'single',
|
||||
}
|
||||
@ -151,7 +151,7 @@ def command(cmd):
|
||||
if cmd.startswith('let g:'):
|
||||
import re
|
||||
varname, value = re.compile(r'^let g:(\w+)\s*=\s*(.*)').match(cmd).groups()
|
||||
_g[varname] = value
|
||||
vars[varname] = value
|
||||
elif cmd.startswith('hi '):
|
||||
sp = cmd.split()
|
||||
_highlights[sp[1]] = sp[2:]
|
||||
@ -162,9 +162,9 @@ def command(cmd):
|
||||
@_vim
|
||||
def eval(expr):
|
||||
if expr.startswith('g:'):
|
||||
return _g[expr[2:]]
|
||||
return vars[expr[2:]]
|
||||
elif expr.startswith('&'):
|
||||
return _options[expr[1:]]
|
||||
return options[expr[1:]]
|
||||
elif expr.startswith('PowerlineRegisterCachePurgerEvent'):
|
||||
_buf_purge_events.add(expr[expr.find('"') + 1:expr.rfind('"') - 1])
|
||||
return "0"
|
||||
@ -174,7 +174,7 @@ def eval(expr):
|
||||
@_vim
|
||||
def bindeval(expr):
|
||||
if expr == 'g:':
|
||||
return _g
|
||||
return vars
|
||||
import re
|
||||
match = re.compile(r'^function\("([^"\\]+)"\)$').match(expr)
|
||||
if match:
|
||||
@ -201,10 +201,10 @@ def _emul_getbufvar(bufnr, varname):
|
||||
if bufnr not in buffers:
|
||||
return ''
|
||||
try:
|
||||
return _buf_options[bufnr][varname[1:]]
|
||||
return buffers[bufnr].options[varname[1:]]
|
||||
except KeyError:
|
||||
try:
|
||||
return _options[varname[1:]]
|
||||
return options[varname[1:]]
|
||||
except KeyError:
|
||||
return ''
|
||||
raise NotImplementedError
|
||||
@ -213,12 +213,12 @@ def _emul_getbufvar(bufnr, varname):
|
||||
@_vim
|
||||
@_str_func
|
||||
def _emul_getwinvar(winnr, varname):
|
||||
return _win_scopes[winnr][varname]
|
||||
return windows[winnr].vars[varname]
|
||||
|
||||
|
||||
@_vim
|
||||
def _emul_setwinvar(winnr, varname, value):
|
||||
_win_scopes[winnr][varname] = value
|
||||
windows[winnr].vars[varname] = value
|
||||
|
||||
|
||||
@_vim
|
||||
@ -262,7 +262,7 @@ def _emul_bufnr(expr):
|
||||
@_vim
|
||||
def _emul_exists(varname):
|
||||
if varname.startswith('g:'):
|
||||
return varname[2:] in _g
|
||||
return varname[2:] in vars
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
@ -273,10 +273,9 @@ def _emul_line2byte(line):
|
||||
return sum((len(s) for s in buflines)) + 1
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
_window_ids = [None]
|
||||
_window_id = 0
|
||||
_win_scopes = [None]
|
||||
_win_options = [None]
|
||||
|
||||
|
||||
class _Window(object):
|
||||
@ -284,6 +283,7 @@ class _Window(object):
|
||||
global _window_id
|
||||
self.cursor = cursor
|
||||
self.width = width
|
||||
self.number = len(windows) + 1
|
||||
if buffer:
|
||||
if type(buffer) is _Buffer:
|
||||
self.buffer = buffer
|
||||
@ -294,15 +294,13 @@ class _Window(object):
|
||||
windows.append(self)
|
||||
_window_id += 1
|
||||
_window_ids.append(_window_id)
|
||||
_win_scopes.append({})
|
||||
_win_options.append({})
|
||||
self.options = {}
|
||||
self.vars = {}
|
||||
|
||||
def __repr__(self):
|
||||
return '<window ' + str(windows.index(self)) + '>'
|
||||
|
||||
|
||||
_buf_scopes = {}
|
||||
_buf_options = {}
|
||||
_buf_lines = {}
|
||||
_undostate = {}
|
||||
_undo_written = {}
|
||||
@ -316,8 +314,8 @@ class _Buffer(object):
|
||||
bufnr = _last_bufnr
|
||||
self.number = bufnr
|
||||
self.name = os.path.abspath(name) if name else None
|
||||
_buf_scopes[bufnr] = {}
|
||||
_buf_options[bufnr] = {
|
||||
self.vars = {}
|
||||
self.options = {
|
||||
'modified': 0,
|
||||
'readonly': 0,
|
||||
'fileformat': 'unix',
|
||||
@ -336,13 +334,13 @@ class _Buffer(object):
|
||||
return _buf_lines[self.number][line]
|
||||
|
||||
def __setitem__(self, line, value):
|
||||
_buf_options[self.number]['modified'] = 1
|
||||
self.options['modified'] = 1
|
||||
_buf_lines[self.number][line] = value
|
||||
from copy import copy
|
||||
_undostate[self.number].append(copy(_buf_lines[self.number]))
|
||||
|
||||
def __setslice__(self, *args):
|
||||
_buf_options[self.number]['modified'] = 1
|
||||
self.options['modified'] = 1
|
||||
_buf_lines[self.number].__setslice__(*args)
|
||||
from copy import copy
|
||||
_undostate[self.number].append(copy(_buf_lines[self.number]))
|
||||
@ -358,12 +356,12 @@ class _Buffer(object):
|
||||
|
||||
def __del__(self):
|
||||
bufnr = self.number
|
||||
if _buf_options:
|
||||
_buf_options.pop(bufnr)
|
||||
if _buf_lines:
|
||||
_buf_lines.pop(bufnr)
|
||||
if _undostate:
|
||||
_undostate.pop(bufnr)
|
||||
if _undo_written:
|
||||
_undo_written.pop(bufnr)
|
||||
_buf_scopes.pop(bufnr)
|
||||
|
||||
|
||||
class _Current(object):
|
||||
@ -371,6 +369,10 @@ class _Current(object):
|
||||
def buffer(self):
|
||||
return buffers[_buffer()]
|
||||
|
||||
@property
|
||||
def window(self):
|
||||
return windows[_window - 1]
|
||||
|
||||
|
||||
current = _Current()
|
||||
|
||||
@ -431,8 +433,9 @@ def _undo():
|
||||
return
|
||||
_undostate[_buffer()].pop(-1)
|
||||
_buf_lines[_buffer()] = _undostate[_buffer()][-1]
|
||||
buf = current.buffer
|
||||
if _undo_written[_buffer()] == len(_undostate[_buffer()]):
|
||||
_buf_options[_buffer()]['modified'] = 0
|
||||
buf.options['modified'] = 0
|
||||
|
||||
|
||||
@_vim
|
||||
@ -453,11 +456,16 @@ def _new(name=None):
|
||||
_window = len(windows)
|
||||
|
||||
|
||||
@_vim
|
||||
def _split():
|
||||
global _window
|
||||
_Window(buffer=buffers[_buffer()])
|
||||
_window = len(windows)
|
||||
|
||||
|
||||
@_vim
|
||||
def _del_window(winnr):
|
||||
win = windows.pop(winnr - 1)
|
||||
_win_scopes.pop(winnr)
|
||||
_win_options.pop(winnr)
|
||||
_window_ids.pop(winnr)
|
||||
return win
|
||||
|
||||
@ -513,7 +521,7 @@ def _get_buffer():
|
||||
|
||||
@_vim
|
||||
def _set_bufoption(option, value, bufnr=None):
|
||||
_buf_options[bufnr or _buffer()][option] = value
|
||||
buffers[bufnr or _buffer()].options[option] = value
|
||||
if option == 'filetype':
|
||||
_launch_event('FileType')
|
||||
|
||||
@ -553,11 +561,11 @@ class _WithBufOption(object):
|
||||
self.new = new
|
||||
|
||||
def __enter__(self):
|
||||
self.bufnr = _buffer()
|
||||
self.old = _set_dict(_buf_options[self.bufnr], self.new, _set_bufoption)[0]
|
||||
self.buffer = buffers[_buffer()]
|
||||
self.old = _set_dict(self.buffer.options, self.new, _set_bufoption)[0]
|
||||
|
||||
def __exit__(self, *args):
|
||||
_buf_options[self.bufnr].update(self.old)
|
||||
self.buffer.options.update(self.old)
|
||||
|
||||
|
||||
class _WithMode(object):
|
||||
@ -587,15 +595,41 @@ class _WithDict(object):
|
||||
self.d.pop(k)
|
||||
|
||||
|
||||
class _WithSplit(object):
|
||||
def __enter__(self):
|
||||
_split()
|
||||
|
||||
def __exit__(self, *args):
|
||||
_close(2, wipe=False)
|
||||
|
||||
|
||||
class _WithBufName(object):
|
||||
def __init__(self, new):
|
||||
self.new = new
|
||||
|
||||
def __enter__(self):
|
||||
buffer = buffers[_buffer()]
|
||||
self.buffer = buffer
|
||||
self.old = buffer.name
|
||||
buffer.name = self.new
|
||||
|
||||
def __exit__(self, *args):
|
||||
self.buffer.name = self.old
|
||||
|
||||
|
||||
@_vim
|
||||
def _with(key, *args, **kwargs):
|
||||
if key == 'buffer':
|
||||
return _WithNewBuffer(_edit, *args, **kwargs)
|
||||
elif key == 'bufname':
|
||||
return _WithBufName(*args, **kwargs)
|
||||
elif key == 'mode':
|
||||
return _WithMode(*args, **kwargs)
|
||||
elif key == 'bufoptions':
|
||||
return _WithBufOption(**kwargs)
|
||||
elif key == 'options':
|
||||
return _WithDict(_options, **kwargs)
|
||||
return _WithDict(options, **kwargs)
|
||||
elif key == 'globals':
|
||||
return _WithDict(_g, **kwargs)
|
||||
return _WithDict(vars, **kwargs)
|
||||
elif key == 'split':
|
||||
return _WithSplit()
|
||||
|
Loading…
x
Reference in New Issue
Block a user