Support zsh “modes” (different keymaps like when using vicmd/viins pair)
Fixes #508
This commit is contained in:
parent
417884a3ed
commit
becc8ee59c
|
@ -59,6 +59,47 @@ _powerline_setup_prompt() {
|
|||
fi
|
||||
}
|
||||
|
||||
_powerline_add_widget() {
|
||||
local widget="$1"
|
||||
local function="$2"
|
||||
local old_widget_command="$(zle -l -L $widget)"
|
||||
if [[ "$old_widget_command" = "zle -N $widget $function" ]] ; then
|
||||
return 0
|
||||
elif [[ -z "$old_widget_command" ]] ; then
|
||||
zle -N $widget $function
|
||||
else
|
||||
local save_widget="powerline_save_$widget"
|
||||
local -i i=0
|
||||
while ! test -z "$(zle -l -L $save_widget)" ; do
|
||||
save_widget="${save_widget}_$i"
|
||||
(( i++ ))
|
||||
done
|
||||
eval "${old_widget_command/$widget/$save_widget}"
|
||||
zle -N $widget $function
|
||||
export POWERLINE_SAVE_WIDGET="$save_widget"
|
||||
fi
|
||||
}
|
||||
|
||||
_powerline_zle_keymap_select() {
|
||||
export POWERLINE_MODE="${KEYMAP}"
|
||||
zle reset-prompt
|
||||
test -z "$POWERLINE_SAVE_WIDGET" || zle $POWERLINE_SAVE_WIDGET
|
||||
}
|
||||
|
||||
_powerline_set_mode() {
|
||||
local keymap
|
||||
if test -z "$(bindkey -lL main)" ; then
|
||||
keymap=".safe"
|
||||
else
|
||||
keymap="main"
|
||||
fi
|
||||
export POWERLINE_MODE="${keymap}"
|
||||
}
|
||||
|
||||
_powerline_set_mode
|
||||
|
||||
_powerline_add_widget zle-keymap-select _powerline_zle_keymap_select
|
||||
|
||||
trap "_powerline_tmux_set_columns" SIGWINCH
|
||||
_powerline_tmux_set_columns
|
||||
_powerline_tmux_set_pwd
|
||||
|
|
|
@ -14,6 +14,14 @@
|
|||
"hostname": { "fg": "brightyellow", "bg": "mediumorange" },
|
||||
"exit_fail": { "fg": "white", "bg": "darkestred" },
|
||||
"exit_success": { "fg": "white", "bg": "darkestgreen" },
|
||||
"environment": { "fg": "white", "bg": "darkestgreen" }
|
||||
"environment": { "fg": "white", "bg": "darkestgreen" },
|
||||
"mode": { "fg": "darkestgreen", "bg": "brightgreen", "attr": ["bold"] }
|
||||
},
|
||||
"mode_translations": {
|
||||
"vicmd": {
|
||||
"groups": {
|
||||
"mode": {"fg": "darkestcyan", "bg": "white", "attr": ["bold"]}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,14 @@
|
|||
"hostname": { "fg": "oldlace", "bg": "darkgreencopper" },
|
||||
"exit_fail": { "fg": "oldlace", "bg": "red" },
|
||||
"exit_success": { "fg": "oldlace", "bg": "green" },
|
||||
"environment": { "fg": "oldlace", "bg": "green" }
|
||||
"environment": { "fg": "oldlace", "bg": "green" },
|
||||
"mode": { "fg": "oldlace", "bg": "green", "attr": ["bold"] }
|
||||
},
|
||||
"mode_translations": {
|
||||
"vicmd": {
|
||||
"groups": {
|
||||
"mode": { "fg": "oldlace", "bg": "blue", "attr": ["bold"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,10 @@
|
|||
},
|
||||
"segments": {
|
||||
"left": [
|
||||
{
|
||||
"module": "powerline.segments.shell",
|
||||
"name": "mode"
|
||||
},
|
||||
{
|
||||
"name": "hostname"
|
||||
},
|
||||
|
|
|
@ -535,15 +535,15 @@ group_name_spec = Spec().re('^\w+(?::\w+)?$').copy
|
|||
groups_spec = Spec().unknown_spec(
|
||||
group_name_spec(),
|
||||
group_spec(),
|
||||
).copy
|
||||
).context_message('Error while loading groups (key {key})').copy
|
||||
colorscheme_spec = (Spec(
|
||||
name=name_spec(),
|
||||
groups=groups_spec().context_message('Error while loading groups (key {key})'),
|
||||
groups=groups_spec(),
|
||||
).context_message('Error while loading coloscheme'))
|
||||
vim_mode_spec = Spec().oneof(set(list(vim_modes) + ['nc'])).copy
|
||||
vim_colorscheme_spec = (Spec(
|
||||
name=name_spec(),
|
||||
groups=groups_spec().context_message('Error while loading groups (key {key})'),
|
||||
groups=groups_spec(),
|
||||
mode_translations=Spec().unknown_spec(
|
||||
vim_mode_spec(),
|
||||
Spec(
|
||||
|
@ -558,6 +558,24 @@ vim_colorscheme_spec = (Spec(
|
|||
),
|
||||
).context_message('Error while loading mode translations (key {key})'),
|
||||
).context_message('Error while loading vim colorscheme'))
|
||||
shell_mode_spec = Spec().re('^(?:[\w\-]+|\.safe)$').copy
|
||||
shell_colorscheme_spec = (Spec(
|
||||
name=name_spec(),
|
||||
groups=groups_spec(),
|
||||
mode_translations=Spec().unknown_spec(
|
||||
shell_mode_spec(),
|
||||
Spec(
|
||||
colors=Spec().unknown_spec(
|
||||
color_spec(),
|
||||
color_spec(),
|
||||
).optional(),
|
||||
groups=Spec().unknown_spec(
|
||||
group_name_spec().func(check_translated_group_name),
|
||||
group_spec(),
|
||||
).optional(),
|
||||
),
|
||||
).context_message('Error while loading mode translations (key {key})'),
|
||||
).context_message('Error while loading shell colorscheme'))
|
||||
|
||||
|
||||
generic_keys = set(('exclude_modes', 'include_modes', 'width', 'align', 'name', 'draw_soft_divider', 'draw_hard_divider', 'priority', 'after', 'before'))
|
||||
|
@ -1106,6 +1124,8 @@ def check(path=None, debug=False):
|
|||
colorscheme_configs[ext][colorscheme] = config
|
||||
if ext == 'vim':
|
||||
spec = vim_colorscheme_spec
|
||||
elif ext == 'shell':
|
||||
spec = shell_colorscheme_spec
|
||||
else:
|
||||
spec = colorscheme_spec
|
||||
if spec.match(config, context=(('', config),), data=data, echoerr=ee)[1]:
|
||||
|
|
|
@ -150,7 +150,7 @@ class Renderer(object):
|
|||
segment['divider_highlight'] = None
|
||||
return segment
|
||||
|
||||
def get_segment_info(self, segment_info):
|
||||
def get_segment_info(self, segment_info, mode):
|
||||
'''Get segment information.
|
||||
|
||||
Must return a dictionary containing at least ``home``, ``environ`` and
|
||||
|
@ -167,6 +167,7 @@ class Renderer(object):
|
|||
:return: dict with segment information.
|
||||
'''
|
||||
r = self.segment_info.copy()
|
||||
r['mode'] = mode
|
||||
if segment_info:
|
||||
r.update(segment_info)
|
||||
if 'PWD' in r['environ']:
|
||||
|
@ -201,7 +202,7 @@ class Renderer(object):
|
|||
Matcher information. Is processed in ``.get_theme()`` method.
|
||||
'''
|
||||
theme = self.get_theme(matcher_info)
|
||||
segments = theme.get_segments(side, self.get_segment_info(segment_info))
|
||||
segments = theme.get_segments(side, self.get_segment_info(segment_info, mode))
|
||||
|
||||
# Handle excluded/included segments for the current mode
|
||||
segments = [self._get_highlighting(segment, mode) for segment in segments
|
||||
|
|
|
@ -9,7 +9,7 @@ class IpythonRenderer(ShellRenderer):
|
|||
escape_hl_start = '\x01'
|
||||
escape_hl_end = '\x02'
|
||||
|
||||
def get_segment_info(self, segment_info):
|
||||
def get_segment_info(self, segment_info, mode):
|
||||
r = self.segment_info.copy()
|
||||
r['ipython'] = segment_info
|
||||
return r
|
||||
|
|
|
@ -46,7 +46,7 @@ class TmuxRenderer(Renderer):
|
|||
tmux_attr += ['nounderscore']
|
||||
return '#[' + ','.join(tmux_attr) + ']'
|
||||
|
||||
def get_segment_info(self, segment_info):
|
||||
def get_segment_info(self, segment_info, mode):
|
||||
r = self.segment_info.copy()
|
||||
if segment_info:
|
||||
r.update(segment_info)
|
||||
|
@ -54,6 +54,7 @@ class TmuxRenderer(Renderer):
|
|||
varname = 'TMUX_PWD_' + r['pane_id'].lstrip('%')
|
||||
if varname in r['environ']:
|
||||
r['getcwd'] = lambda: r['environ'][varname]
|
||||
r['mode'] = mode
|
||||
return r
|
||||
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ class VimRenderer(Renderer):
|
|||
def strwidth(string):
|
||||
return vim.strwidth(string)
|
||||
|
||||
def get_segment_info(self, segment_info):
|
||||
def get_segment_info(self, segment_info, mode):
|
||||
return segment_info or self.segment_info
|
||||
|
||||
def render(self, window, window_id, winnr):
|
||||
|
|
|
@ -41,3 +41,31 @@ def last_pipe_status(pl, segment_info):
|
|||
for status in last_pipe_status]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
@requires_segment_info
|
||||
def mode(pl, segment_info, override={'vicmd': 'COMMND', 'viins': 'INSERT'}, default='main'):
|
||||
'''Return the current mode.
|
||||
|
||||
:param dict override:
|
||||
dict for overriding mode strings.
|
||||
:param str default:
|
||||
If current mode is equal to this string then this segment will not get
|
||||
displayed.
|
||||
'''
|
||||
mode = segment_info['mode']
|
||||
if not mode:
|
||||
pl.warn('No or empty POWERLINE_MODE variable')
|
||||
return None
|
||||
if mode == default:
|
||||
return None
|
||||
try:
|
||||
return override[mode]
|
||||
except KeyError:
|
||||
# Note: with zsh line editor you can emulate as much modes as you wish.
|
||||
# Thus having unknown mode is not an error: maybe just some developer
|
||||
# added support for his own zle widgets. As there is no built-in mode()
|
||||
# function like in VimL and POWERLINE_MODE is likely be defined by our
|
||||
# code or by somebody knowing what he is doing there is absolutely no
|
||||
# need in keeping translations dictionary.
|
||||
return mode.upper()
|
||||
|
|
|
@ -22,6 +22,7 @@ if __name__ == '__main__':
|
|||
width=args.width,
|
||||
side=args.side,
|
||||
segment_info=segment_info,
|
||||
mode=os.environ.get('POWERLINE_MODE'),
|
||||
)
|
||||
try:
|
||||
sys.stdout.write(rendered)
|
||||
|
|
Loading…
Reference in New Issue