Move some functions from VimL to python code

Should be faster with new interfaces, but that is not the case

Should remove zero that can be viewed temporary in place of statusline in new 
windows

Target: ressurect setup function like source_plugin (but in place of sourcing 
something code is moved to python) to make it possible to do the following 
sequence:

1. Install powerline via pip
2. Add a line to the vimrc like

        py from powerline.vim import setup as setup_powerline; setup_powerline(); del setup_powerline

3. See new fancy statusline

Currently there are no convenient options to use powerline installed by pip in 
vim. powerline/bindings/vim/plugin/powerline.vim will do what it does: check for 
appropriate python versions available, fix sys.path and so on, but it won’t 
create autocommands, set options or define PowerlinePyeval function.

Note: may be rebased on top of the develop.
This commit is contained in:
ZyX 2013-05-14 09:01:04 +04:00
parent e3ed3aba6c
commit 9f20fb1f3f
3 changed files with 60 additions and 32 deletions

View File

@ -41,39 +41,14 @@ finally
endtry
if !get(g:, 'powerline_debugging_pyeval') && exists('*'. s:powerline_pyeval)
let s:pyeval = function(s:powerline_pyeval)
let PowerlinePyeval = function(s:powerline_pyeval)
else
exec s:powerline_pycmd 'import json, vim'
exec "function! s:pyeval(e)\n".
exec "function! PowerlinePyeval(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
@ -91,5 +66,4 @@ 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()
set statusline=%!PowerlinePyeval('powerline.new_window()')

View File

@ -68,17 +68,18 @@ 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,
}
segment_info['buffer'] = segment_info['window'].buffer
segment_info['bufnr'] = segment_info['buffer'].number

View File

@ -7,9 +7,12 @@ 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)
vim_getwinvar = vim_get_func('getwinvar')
vim_setwinvar = vim_get_func('setwinvar')
def _override_from(config, override_varname):
@ -23,9 +26,13 @@ def _override_from(config, override_varname):
return config
WINDOW_STASUSLINE = '%!PowerlinePyeval(\'powerline.statusline({0})\')'
class VimPowerline(Powerline):
def __init__(self):
super(VimPowerline, self).__init__('vim')
self.last_window_id = 1
def add_local_theme(self, key, config):
'''Add local themes at runtime (during vim session).
@ -93,3 +100,49 @@ 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 = WINDOW_STASUSLINE.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:
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')
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)
statusline = WINDOW_STASUSLINE.format(curwindow_id)
if vim_getwinvar(winnr, '&statusline') != statusline:
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)