0
0
.dotfiles/powerline-bin/powerline/bindings/zsh/__init__.py

229 lines
5.4 KiB
Python
Raw Normal View History

2024-09-07 11:49:53 -04:00
# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)
import atexit
from weakref import WeakValueDictionary, ref
import zsh
from powerline.shell import ShellPowerline
from powerline.lib.overrides import parsedotval, parse_override_var
from powerline.lib.unicode import unicode, u
from powerline.lib.encoding import (get_preferred_output_encoding,
get_preferred_environment_encoding)
from powerline.lib.dict import mergeargs
used_powerlines = WeakValueDictionary()
def shutdown():
for powerline in tuple(used_powerlines.values()):
powerline.shutdown()
def get_var_config(var):
try:
val = zsh.getvalue(var)
if isinstance(val, dict):
return mergeargs([parsedotval((u(k), u(v))) for k, v in val.items()])
elif isinstance(val, (unicode, str, bytes)):
return mergeargs(parse_override_var(u(val)))
else:
return None
except:
return None
class Args(object):
__slots__ = ('last_pipe_status', 'last_exit_code')
ext = ['shell']
renderer_module = '.zsh'
@property
def config_override(self):
return get_var_config('POWERLINE_CONFIG_OVERRIDES')
@property
def theme_override(self):
return get_var_config('POWERLINE_THEME_OVERRIDES')
@property
def config_path(self):
try:
ret = zsh.getvalue('POWERLINE_CONFIG_PATHS')
except IndexError:
return None
else:
if isinstance(ret, (unicode, str, bytes)):
return [
path
for path in ret.split((b':' if isinstance(ret, bytes) else ':'))
if path
]
else:
return ret
@property
def jobnum(self):
return zsh.getvalue('_POWERLINE_JOBNUM')
def string(s):
if type(s) is bytes:
return s.decode(get_preferred_environment_encoding(), 'replace')
else:
return str(s)
class Environment(object):
@staticmethod
def __getitem__(key):
try:
return string(zsh.getvalue(key))
except IndexError as e:
raise KeyError(*e.args)
@staticmethod
def get(key, default=None):
try:
return string(zsh.getvalue(key))
except IndexError:
return default
@staticmethod
def __contains__(key):
try:
zsh.getvalue(key)
return True
except IndexError:
return False
if hasattr(getattr(zsh, 'environ', None), '__contains__'):
environ = zsh.environ
else:
environ = Environment()
if hasattr(zsh, 'expand') and zsh.expand('${:-}') == '':
zsh_expand = zsh.expand
else:
def zsh_expand(s):
zsh.eval('local _POWERLINE_REPLY="' + s + '"')
ret = zsh.getvalue('_POWERLINE_REPLY')
zsh.setvalue('_POWERLINE_REPLY', None)
return ret
class ZshPowerline(ShellPowerline):
def init(self, **kwargs):
super(ZshPowerline, self).init(Args(), **kwargs)
def precmd(self):
self.args.last_pipe_status = zsh.pipestatus()
self.args.last_exit_code = zsh.last_exit_code()
def do_setup(self, zsh_globals):
set_prompt(self, 'PS1', 'left', None, above=True)
set_prompt(self, 'RPS1', 'right', None)
set_prompt(self, 'PS2', 'left', 'continuation')
set_prompt(self, 'RPS2', 'right', 'continuation')
set_prompt(self, 'PS3', 'left', 'select')
used_powerlines[id(self)] = self
zsh_globals['_powerline'] = self
class Prompt(object):
__slots__ = ('powerline', 'side', 'savedpsvar', 'savedps', 'args', 'theme', 'above', '__weakref__')
def __init__(self, powerline, side, theme, savedpsvar=None, savedps=None, above=False):
self.powerline = powerline
self.side = side
self.above = above
self.savedpsvar = savedpsvar
self.savedps = savedps
self.args = powerline.args
self.theme = theme
def __str__(self):
parser_state = u(zsh_expand('${(%):-%_}'))
shortened_path = u(zsh_expand('${(%):-%~}'))
try:
mode = u(zsh.getvalue('_POWERLINE_MODE'))
except IndexError:
mode = None
try:
default_mode = u(zsh.getvalue('_POWERLINE_DEFAULT_MODE'))
except IndexError:
default_mode = None
segment_info = {
'args': self.args,
'environ': environ,
'client_id': 1,
'local_theme': self.theme,
'parser_state': parser_state,
'shortened_path': shortened_path,
'mode': mode,
'default_mode': default_mode,
}
try:
zle_rprompt_indent = zsh.getvalue('ZLE_RPROMPT_INDENT')
except IndexError:
zle_rprompt_indent = 1
r = ''
if self.above:
for line in self.powerline.render_above_lines(
width=zsh.columns() - zle_rprompt_indent,
segment_info=segment_info,
):
if line:
r += line + '\n'
r += self.powerline.render(
width=zsh.columns(),
side=self.side,
segment_info=segment_info,
mode=mode,
)
if type(r) is not str:
if type(r) is bytes:
return r.decode(get_preferred_output_encoding(), 'replace')
else:
return r.encode(get_preferred_output_encoding(), 'replace')
return r
def __del__(self):
if self.savedps:
zsh.setvalue(self.savedpsvar, self.savedps)
self.powerline.shutdown()
def set_prompt(powerline, psvar, side, theme, above=False):
try:
savedps = zsh.getvalue(psvar)
except IndexError:
savedps = None
zpyvar = 'ZPYTHON_POWERLINE_' + psvar
prompt = Prompt(powerline, side, theme, psvar, savedps, above)
zsh.setvalue(zpyvar, None)
zsh.set_special_string(zpyvar, prompt)
zsh.setvalue(psvar, '${' + zpyvar + '}')
return ref(prompt)
def reload():
for powerline in tuple(used_powerlines.values()):
powerline.reload()
def reload_config():
for powerline in used_powerlines.values():
powerline.create_renderer(load_main=True, load_colors=True, load_colorscheme=True, load_theme=True)
def setup(zsh_globals):
powerline = ZshPowerline()
powerline.setup(zsh_globals)
atexit.register(shutdown)