diff --git a/client/powerline.c b/client/powerline.c index 0800f701..44819ffe 100644 --- a/client/powerline.c +++ b/client/powerline.c @@ -106,8 +106,10 @@ int main(int argc, char *argv[]) { wd = getcwd(NULL, 0); if (wd != NULL) { do_write(sd, wd, strlen(wd)); - free(wd); wd = NULL; + free(wd); + wd = NULL; } + do_write(sd, eof, 1); for(envp=environ; *envp; envp++) { do_write(sd, *envp, strlen(*envp)); diff --git a/docs/source/configuration/local.rst b/docs/source/configuration/local.rst index d8d55e84..13902514 100644 --- a/docs/source/configuration/local.rst +++ b/docs/source/configuration/local.rst @@ -81,12 +81,13 @@ are taken from zsh variables. but only subdictionaries for ``THEME_NAME`` key are merged with theme configuration when theme with given name is requested. -``POWERLINE_CONFIG_PATH`` - Sets directory where configuration should be read from. If present, no +``POWERLINE_CONFIG_PATHS`` + Sets directories where configuration should be read from. If present, no default locations are searched for configuration. No expansions are performed by powerline script itself, but zsh usually performs them on its - own if you set variable without quotes: ``POWERLINE_CONFIG_PATH=~/example``. - Expansion depends on zsh configuration. + own if you set variable without quotes: ``POWERLINE_CONFIG_PATHS=( ~/example + )``. You should use array parameter or the usual colon-separated + ``POWERLINE_CONFIG_PATHS=$HOME/path1:$HOME/path2``. Ipython overrides ================= @@ -104,8 +105,8 @@ use ``c.Powerline.KEY``. Supported ``KEY`` strings or keyword argument names: a dictionary where keys are theme names and values are dictionaries which will be recursively merged with the contents of the given theme. -``path`` - Sets directory where configuration should be read from. If present, no +``paths`` + Sets directories where configuration should be read from. If present, no default locations are searched for configuration. No expansions are performed thus you cannot use paths starting with ``~/``. @@ -114,9 +115,9 @@ Prompt command In addition to the above configuration options you can use ``$POWERLINE_COMMAND`` environment variable to tell shell or tmux to use -specific powerline implementation. This is mostly useful for putting powerline -into different directory or replacing ``powerline`` script with -``powerline-client`` for performance reasons. +specific powerline implementation and ``$POWERLINE_CONFIG`` to tell zsh or tmux +where ``powerline-config`` script is located. This is mostly useful for putting +powerline into different directory. .. note:: @@ -149,6 +150,6 @@ fish in order to support multiline prompt you should set .. note:: - Most supported shells’ configuration scripts check for additional - configuration variables being empty. But tcsh configuration script checks - for variables being *defined*, not empty. + Most supported shells’ configuration scripts check for ``$POWERLINE_CONFIG`` + and ``$POWERLINE_COMMAND`` configuration variables being empty. But tcsh + configuration script checks for variables being *defined*, not empty. diff --git a/docs/source/configuration/reference.rst b/docs/source/configuration/reference.rst index f8e7f148..8f043e43 100644 --- a/docs/source/configuration/reference.rst +++ b/docs/source/configuration/reference.rst @@ -101,20 +101,20 @@ Common configuration is a subdictionary that is a value of ``ext`` key in ``colorscheme`` Defines the colorscheme used for this extension. -``theme`` - .. _config-ext-theme: +.. _config-ext-theme: +``theme`` Defines the theme used for this extension. -``top_theme`` - .. _config-ext-top_theme: +.. _config-ext-top_theme: +``top_theme`` Defines the top-level theme used for this extension. See `Themes`_ section for more details. -``local_themes`` - .. _config-ext-local_themes: +.. _config-ext-local_themes: +``local_themes`` Defines themes used when certain conditions are met, e.g. for buffer-specific statuslines in vim. Value depends on extension used. For vim it is a dictionary ``{matcher_name : theme_name}``, where ``matcher_name`` @@ -123,6 +123,28 @@ Common configuration is a subdictionary that is a value of ``ext`` key in ``module_attribute`` should point to a function that returns boolean value indicating that current buffer has (not) matched conditions. +``components`` + Determines which extension components should be enabled. This key is highly + extension-specific, here is the table of extensions and corresponding + components: + + +---------+----------+-----------------------------------------------------+ + |Extension|Component |Description | + +---------+----------+-----------------------------------------------------+ + |vim |statusline|Makes Vim use powerline statusline. | + | +----------+-----------------------------------------------------+ + | |tabline |Makes Vim use powerline tabline. | + +---------+----------+-----------------------------------------------------+ + |shell |prompt |Makes shell display powerline prompt. | + | +----------+-----------------------------------------------------+ + | |tmux |Makes shell report its current working directory | + | | |and screen width to tmux for tmux powerline | + | | |bindings. | + | | |  | + +---------+----------+-----------------------------------------------------+ + + All components are enabled by default. + .. _config-colors: Color definitions @@ -324,54 +346,54 @@ ascii Theme without any unicode characters at all ` and :ref:`args ` options. - ``module`` - .. _config-themes-seg-module: + .. _config-themes-seg-module: + ``module`` Function module, only required for function segments. Defaults to ``powerline.segments.{extension}``. Default is overriden by :ref:`default_module theme option `. - ``name`` - .. _config-themes-seg-name: + .. _config-themes-seg-name: + ``name`` Function name, only required for function and list segments. - ``highlight_group`` - .. _config-themes-seg-highlight_group: + .. _config-themes-seg-highlight_group: - Highlighting group for this segment. Consists of a prioritized list - of highlighting groups, where the first highlighting group that is + ``highlight_group`` + Highlighting group for this segment. Consists of a prioritized list of + highlighting groups, where the first highlighting group that is available in the colorscheme is used. Ignored for segments that have ``function`` type. - ``before`` - .. _config-themes-seg-before: + .. _config-themes-seg-before: + ``before`` A string which will be prepended to the segment contents. - ``after`` - .. _config-themes-seg-after: + .. _config-themes-seg-after: + ``after`` A string which will be appended to the segment contents. - ``contents`` - .. _config-themes-seg-contents: + .. _config-themes-seg-contents: + ``contents`` Segment contents, only required for ``string`` segments. - ``args`` - .. _config-themes-seg-args: + .. _config-themes-seg-args: + ``args`` A dict of arguments to be passed to a ``function`` segment. ``align`` Aligns the segments contents to the left (``l``), center (``c``) or right (``r``). - ``width`` - .. _config-themes-seg-width: + .. _config-themes-seg-width: + ``width`` Enforces a specific width for this segment. This segment will work as a spacer if the width is set to ``auto``. @@ -412,13 +434,13 @@ ascii Theme without any unicode characters at all A list of modes where this segment will be included: The segment is *not* included in any modes, *except* for the modes in this list. - ``display`` - .. _config-themes-seg-display: + .. _config-themes-seg-display: + ``display`` Boolean. If false disables displaying of the segment. Defaults to ``True``. - ``segments`` - .. _config-themes-seg-segments: + .. _config-themes-seg-segments: + ``segments`` A list of subsegments. diff --git a/powerline/__init__.py b/powerline/__init__.py index 08446057..ff568cf1 100644 --- a/powerline/__init__.py +++ b/powerline/__init__.py @@ -394,7 +394,15 @@ class Powerline(object): self.ext_config = config['ext'][self.ext] if self.ext_config != self.prev_ext_config: ext_config_differs = True - if not self.prev_ext_config or self.ext_config.get('local_themes') != self.prev_ext_config.get('local_themes'): + if ( + not self.prev_ext_config + or self.ext_config.get('components') != self.prev_ext_config.get('components') + ): + self.setup_components(self.ext_config.get('components')) + if ( + not self.prev_ext_config + or self.ext_config.get('local_themes') != self.prev_ext_config.get('local_themes') + ): self.renderer_options['local_themes'] = self.get_local_themes(self.ext_config.get('local_themes')) load_colorscheme = (load_colorscheme or not self.prev_ext_config @@ -439,6 +447,16 @@ class Powerline(object): else: self.renderer = renderer + def setup_components(self, components): + '''Run component-specific setup + + :param set components: + Set of the enabled componets or None. + + Should be overridden by subclasses. + ''' + pass + @staticmethod def get_config_paths(): '''Get configuration paths. diff --git a/powerline/bindings/bash/powerline.sh b/powerline/bindings/bash/powerline.sh index 501b48aa..eb705a7c 100644 --- a/powerline/bindings/bash/powerline.sh +++ b/powerline/bindings/bash/powerline.sh @@ -35,7 +35,7 @@ _powerline_init_tmux_support() { _powerline_tmux_set_columns test "x$PROMPT_COMMAND" != "x${PROMPT_COMMAND/_powerline_tmux_set_pwd}" || - export PROMPT_COMMAND="${PROMPT_COMMAND}"$'\n_powerline_tmux_set_pwd' + PROMPT_COMMAND="${PROMPT_COMMAND}"$'\n_powerline_tmux_set_pwd' fi } @@ -54,21 +54,23 @@ _powerline_set_prompt() { _powerline_setup_prompt() { VIRTUAL_ENV_DISABLE_PROMPT=1 if test -z "${POWERLINE_COMMAND}" ; then - if which powerline-config &>/dev/null ; then - export POWERLINE_COMMAND="$(powerline-config shell command)" - else - # `$0` is set to `-bash` when using SSH so that won't work - local powerline_dir="$(dirname "$BASH_SOURCE")/../../.." - export POWERLINE_COMMAND="$($powerline_dir/scripts/powerline-config shell command)" - fi + POWERLINE_COMMAND="$("$POWERLINE_CONFIG" shell command)" fi test "x$PROMPT_COMMAND" != "x${PROMPT_COMMAND%_powerline_set_prompt*}" || - export PROMPT_COMMAND=$'_powerline_set_prompt\n'"${PROMPT_COMMAND}" + PROMPT_COMMAND=$'_powerline_set_prompt\n'"${PROMPT_COMMAND}" } -if test -z "$POWERLINE_NO_BASH_PROMPT$POWERLINE_NO_SHELL_PROMPT" ; then +if test -z "${POWERLINE_CONFIG}" ; then + if which powerline-config >/dev/null ; then + POWERLINE_CONFIG=powerline-config + else + POWERLINE_CONFIG="$(dirname "$BASH_SOURCE")/../../../scripts/powerline-config" + fi +fi + +if "${POWERLINE_CONFIG}" shell --shell=bash uses prompt ; then _powerline_setup_prompt fi -if test -z "$POWERLINE_NO_BASH_TMUX_SUPPORT$POWERLINE_NO_SHELL_TMUX_SUPPORT" ; then +if "${POWERLINE_CONFIG}" shell --shell=bash uses tmux ; then _powerline_init_tmux_support fi diff --git a/powerline/bindings/config.py b/powerline/bindings/config.py index e63a6c00..fac81ae0 100644 --- a/powerline/bindings/config.py +++ b/powerline/bindings/config.py @@ -118,10 +118,14 @@ def source_tmux_files(pl, args): run_tmux_command('refresh-client') -def create_powerline_logger(args): +def get_main_config(args): find_config_files = generate_config_finder() config_loader = ConfigLoader(run_once=True) - config = load_config('config', find_config_files, config_loader) + return load_config('config', find_config_files, config_loader) + + +def create_powerline_logger(args): + config = get_main_config(args) common_config = finish_common_config(config['common']) logger = create_logger(common_config) return PowerlineLogger(use_daemon_threads=True, logger=logger, ext='config') @@ -166,3 +170,22 @@ def shell_command(pl, args): print(cmd) else: sys.exit(1) + + +def uses(pl, args): + component = args.component + if not component: + raise ValueError('Must specify component') + shell = args.shell + template = 'POWERLINE_NO_{shell}_{component}' + for sh in (shell, 'shell') if shell else ('shell'): + varname = template.format(shell=sh.upper(), component=component.upper()) + if os.environ.get(varname): + print ('HERE') + sys.exit(1) + config = get_main_config(args) + if component in config.get('ext', {}).get('shell', {}).get('components', ('tmux', 'prompt')): + sys.exit(0) + else: + print ('THERE') + sys.exit(1) diff --git a/powerline/bindings/fish/powerline-setup.fish b/powerline/bindings/fish/powerline-setup.fish index 89fe9778..56f6d52e 100644 --- a/powerline/bindings/fish/powerline-setup.fish +++ b/powerline/bindings/fish/powerline-setup.fish @@ -18,14 +18,17 @@ function powerline-setup end end - if test -z "$POWERLINE_NO_FISH_PROMPT$POWERLINE_NO_SHELL_PROMPT" + if test -z "$POWERLINE_CONFIG" + if which powerline-config >/dev/null + set -g POWERLINE_CONFIG powerline-config + else + set -g POWERLINE_CONFIG (dirname (status -f))/../../../scripts/powerline-config + end + end + + if eval $POWERLINE_CONFIG shell --shell=fish uses prompt if test -z "$POWERLINE_COMMAND" - if false ;and which powerline-config >/dev/null - set -g -x POWERLINE_COMMAND (powerline-config shell command) - else - set -l powerline_dir (dirname (status -f))/../../.. - set -g -x POWERLINE_COMMAND (eval $powerline_dir/scripts/powerline-config shell command) - end + set -g POWERLINE_COMMAND (eval $POWERLINE_CONFIG shell command) end function --on-variable POWERLINE_COMMAND _powerline_update set -l addargs "--last_exit_code=\$status" @@ -60,7 +63,7 @@ function powerline-setup end _powerline_update end - if test -z "$POWERLINE_NO_FISH_TMUX_SUPPORT$POWERLINE_NO_SHELL_TMUX_SUPPORT" + if eval $POWERLINE_CONFIG shell --shell=fish uses tmux if test -n "$TMUX" if tmux refresh -S ^/dev/null function _powerline_tmux_setenv @@ -79,3 +82,4 @@ function powerline-setup end end end +# vim: ft=fish diff --git a/powerline/bindings/ipython/post_0_11.py b/powerline/bindings/ipython/post_0_11.py index dc6c8112..92f0887c 100644 --- a/powerline/bindings/ipython/post_0_11.py +++ b/powerline/bindings/ipython/post_0_11.py @@ -47,7 +47,7 @@ class ConfigurableIpythonPowerline(IpythonPowerline): config = ip.config.Powerline self.config_overrides = config.get('config_overrides') self.theme_overrides = config.get('theme_overrides', {}) - self.path = config.get('path') + self.paths = config.get('paths') super(ConfigurableIpythonPowerline, self).__init__(is_prompt) diff --git a/powerline/bindings/ipython/pre_0_11.py b/powerline/bindings/ipython/pre_0_11.py index 8d7f0503..a007cdb0 100644 --- a/powerline/bindings/ipython/pre_0_11.py +++ b/powerline/bindings/ipython/pre_0_11.py @@ -82,10 +82,10 @@ class PowerlinePrompt2(PowerlinePromptOut): class ConfigurableIpythonPowerline(IpythonPowerline): - def __init__(self, is_prompt, config_overrides=None, theme_overrides={}, path=None): + def __init__(self, is_prompt, config_overrides=None, theme_overrides={}, paths=None): self.config_overrides = config_overrides self.theme_overrides = theme_overrides - self.path = path + self.paths = paths super(ConfigurableIpythonPowerline, self).__init__(is_prompt) diff --git a/powerline/bindings/shell/powerline.sh b/powerline/bindings/shell/powerline.sh index ae5c035f..e78e3625 100644 --- a/powerline/bindings/shell/powerline.sh +++ b/powerline/bindings/shell/powerline.sh @@ -98,12 +98,7 @@ _powerline_set_set_jobs() { _powerline_set_command() { if test -z "${POWERLINE_COMMAND}" ; then - if which powerline-config &>/dev/null ; then - export POWERLINE_COMMAND="$(powerline-config shell command)" - else - local powerline_dir="$(dirname "$POWERLINE_SOURCED")/../../.." - export POWERLINE_COMMAND="$($powerline_dir/scripts/powerline-config shell command)" - fi + POWERLINE_COMMAND="$("$POWERLINE_CONFIG" shell command)" fi } @@ -167,14 +162,22 @@ _powerline_init_tmux_support() { fi } +if test -z "${POWERLINE_CONFIG}" ; then + if which powerline-config >/dev/null ; then + POWERLINE_CONFIG=powerline-config + else + POWERLINE_CONFIG="$(dirname "$_POWERLINE_SOURCED")/../../../scripts/powerline-config" + fi +fi + # Strips the leading `-`: it may be present when shell is a login shell _POWERLINE_USED_SHELL=${0#-} _POWERLINE_USED_SHELL=${_POWERLINE_USED_SHELL#/usr} _POWERLINE_USED_SHELL=${_POWERLINE_USED_SHELL#/bin/} -if test -z "$POWERLINE_NO_BB_PROMPT$POWERLINE_NO_SHELL_PROMPT" ; then - _powerline_setup_prompt $_POWERLINE_USED_SHELL -fi -if test -z "$POWERLINE_NO_BB_TMUX_SUPPORT$POWERLINE_NO_SHELL_TMUX_SUPPORT" ; then +if "${POWERLINE_CONFIG}" shell uses tmux ; then _powerline_init_tmux_support $_POWERLINE_USED_SHELL fi +if "${POWERLINE_CONFIG}" shell --shell=bash uses prompt ; then + _powerline_setup_prompt $_POWERLINE_USED_SHELL +fi diff --git a/powerline/bindings/tcsh/powerline.tcsh b/powerline/bindings/tcsh/powerline.tcsh index 69f34a2e..5ac0cf33 100644 --- a/powerline/bindings/tcsh/powerline.tcsh +++ b/powerline/bindings/tcsh/powerline.tcsh @@ -5,17 +5,20 @@ # Guess this relies on `$_` being set as to last argument to previous command # which must be `.` or `source` in this case set POWERLINE_SOURCED=($_) -if ! ( $?POWERLINE_NO_TCSH_TMUX_SUPPORT || $?POWERLINE_NO_SHELL_TMUX_SUPPORT ) then +if ! $?POWERLINE_CONFIG then + if ( { which powerline-config > /dev/null } ) then + set POWERLINE_CONFIG="powerline-config" + else + set POWERLINE_CONFIG="$POWERLINE_SOURCED[2]:h:h:h:h/scripts/powerline-config" + endif +endif +if ( { $POWERLINE_CONFIG shell --shell=tcsh uses tmux } ) then alias _powerline_tmux_set_pwd 'if ( $?TMUX && { tmux refresh -S >&/dev/null } ) tmux setenv -g TMUX_PWD_`tmux display -p "#D" | tr -d %` $PWD:q ; if ( $?TMUX ) tmux refresh -S >&/dev/null' alias cwdcmd "`alias cwdcmd` ; _powerline_tmux_set_pwd" endif -if ! ( $?POWERLINE_NO_TCSH_PROMPT || $?POWERLINE_NO_SHELL_PROMPT ) then +if ( { $POWERLINE_CONFIG shell --shell=tcsh uses prompt } ) then if ! $?POWERLINE_COMMAND then - if ( { which powerline-config > /dev/null } ) then - setenv POWERLINE_COMMAND "`powerline-config shell command`" - else - setenv POWERLINE_COMMAND "`$POWERLINE_SOURCED[2]:h:h:h:h:q/scripts/powerline-config shell command`" - endif + set POWERLINE_COMMAND="`$POWERLINE_CONFIG:q shell command`" endif if ( $?POWERLINE_NO_TCSH_ABOVE || $?POWERLINE_NO_SHELL_ABOVE ) then diff --git a/powerline/bindings/vim/__init__.py b/powerline/bindings/vim/__init__.py index 76c40ffe..d030bd43 100644 --- a/powerline/bindings/vim/__init__.py +++ b/powerline/bindings/vim/__init__.py @@ -99,10 +99,23 @@ else: if hasattr(vim, 'options'): def vim_getbufoption(info, option): return info['buffer'].options[str(option)] + + def vim_getoption(option): + return vim.options[str(option)] + + def vim_setoption(option, value): + vim.options[str(option)] = value else: def vim_getbufoption(info, option): # NOQA return getbufvar(info['bufnr'], '&' + option) + def vim_getoption(option): # NOQA + return vim.eval('&g:' + option) + + def vim_setoption(option, value): # NOQA + vim.command('let &g:{option} = {value}'.format( + option=option, value=json.encode(value))) + if hasattr(vim, 'tabpages'): current_tabpage = lambda: vim.current.tabpage diff --git a/powerline/bindings/zsh/__init__.py b/powerline/bindings/zsh/__init__.py index 2bbf3184..444490b5 100644 --- a/powerline/bindings/zsh/__init__.py +++ b/powerline/bindings/zsh/__init__.py @@ -5,6 +5,7 @@ import zsh import atexit from powerline.shell import ShellPowerline from powerline.lib import parsedotval +from powerline.lib.unicode import unicode used_powerlines = [] @@ -44,9 +45,14 @@ class Args(object): @property def config_path(self): try: - return zsh.getvalue('POWERLINE_CONFIG_PATH') + ret = zsh.getvalue('POWERLINE_CONFIG_PATHS') except IndexError: return None + else: + if isinstance(ret, (unicode, str, bytes)): + return ret.split(type(ret)(':')) + else: + return ret @property def jobnum(self): diff --git a/powerline/bindings/zsh/powerline.zsh b/powerline/bindings/zsh/powerline.zsh index 5439167a..626ee58c 100644 --- a/powerline/bindings/zsh/powerline.zsh +++ b/powerline/bindings/zsh/powerline.zsh @@ -126,12 +126,7 @@ _powerline_setup_prompt() { zpython 'del _powerline_setup' else if test -z "${POWERLINE_COMMAND}" ; then - if which powerline-config &>/dev/null ; then - export POWERLINE_COMMAND="$(powerline-config shell command)" - else - local powerline_dir="$POWERLINE_SOURCED:h:h:h:h" - export POWERLINE_COMMAND="$($powerline_dir/scripts/powerline-config shell command)" - fi + POWERLINE_COMMAND=( "$($POWERLINE_CONFIG shell command)" ) fi local add_args='--last_exit_code=$?' @@ -176,12 +171,21 @@ _powerline_add_widget() { fi } +if test -z "${POWERLINE_CONFIG}" ; then + if which powerline-config >/dev/null ; then + export POWERLINE_CONFIG=powerline-config + else + export POWERLINE_CONFIG="$_POWERLINE_SOURCED:h:h:h:h/scripts/powerline-config" + fi +fi + setopt promptpercent setopt promptsubst -if test -z "$POWERLINE_NO_ZSH_PROMPT$POWERLINE_NO_SHELL_PROMPT" ; then + +if ${POWERLINE_CONFIG} shell --shell=zsh uses prompt ; then _powerline_setup_prompt _powerline_init_modes_support fi -if test -z "$POWERLINE_NO_ZSH_TMUX_SUPPORT$POWERLINE_NO_SHELL_TMUX_SUPPORT" ; then +if ${POWERLINE_CONFIG} shell --shell=zsh uses tmux ; then _powerline_init_tmux_support fi diff --git a/powerline/ipython.py b/powerline/ipython.py index 6716e075..80327e72 100644 --- a/powerline/ipython.py +++ b/powerline/ipython.py @@ -31,8 +31,8 @@ class IpythonPowerline(Powerline): ) def get_config_paths(self): - if self.path: - return [self.path] + if self.paths: + return self.paths else: return super(IpythonPowerline, self).get_config_paths() diff --git a/powerline/lint/__init__.py b/powerline/lint/__init__.py index 721d1a5a..7d894049 100644 --- a/powerline/lint/__init__.py +++ b/powerline/lint/__init__.py @@ -8,6 +8,7 @@ from powerline.segments.vim import vim_modes from powerline.lint.inspect import getconfigargspec from powerline.lib.threaded import ThreadedSegment from powerline.lib import mergedicts_copy +from powerline.lib.unicode import unicode import itertools import sys import os @@ -17,12 +18,6 @@ from copy import copy import logging -try: - from __builtin__ import unicode -except ImportError: - unicode = str - - def open_file(path): return open(path, 'rb') @@ -530,6 +525,7 @@ ext_spec = Spec( theme=ext_theme_spec(), top_theme=top_theme_spec().optional(), ).copy +gen_components_spec = (lambda *components: Spec().list(Spec().type(unicode).oneof(set(components)))) main_spec = (Spec( common=Spec( default_top_theme=top_theme_spec().optional(), @@ -561,6 +557,7 @@ main_spec = (Spec( ).context_message('Error while loading common configuration (key {key})'), ext=Spec( vim=ext_spec().update( + components=gen_components_spec('statusline', 'tabline').optional(), local_themes=Spec( __tabline__=ext_theme_spec(), ).unknown_spec( @@ -575,6 +572,7 @@ main_spec = (Spec( ), ).optional(), shell=ext_spec().update( + components=gen_components_spec('tmux', 'prompt').optional(), local_themes=Spec( continuation=ext_theme_spec(), select=ext_theme_spec(), @@ -1078,8 +1076,8 @@ def list_themes(data, context): is_main_theme = (data['theme'] == main_theme_name) if theme_type == 'top': return list(itertools.chain(*[ - [(ext, theme) for theme in theme_configs.values()] - for ext, theme_configs in data['theme_configs'].items() + [(theme_ext, theme) for theme in theme_configs.values()] + for theme_ext, theme_configs in data['theme_configs'].items() ])) elif theme_type == 'main' or is_main_theme: return [(ext, theme) for theme in data['ext_theme_configs'].values()] diff --git a/powerline/shell.py b/powerline/shell.py index baf0973c..513a6974 100644 --- a/powerline/shell.py +++ b/powerline/shell.py @@ -1,7 +1,5 @@ # vim:fileencoding=utf-8:noet -import os - from powerline import Powerline from powerline.lib import mergedicts, parsedotval @@ -82,7 +80,7 @@ def write_output(args, powerline, segment_info, write): for line in powerline.render_above_lines( width=args.width, segment_info=segment_info, - mode=os.environ.get('_POWERLINE_MODE'), + mode=segment_info['environ'].get('_POWERLINE_MODE'), ): write(line) write('\n') @@ -93,6 +91,6 @@ def write_output(args, powerline, segment_info, write): width=args.width, side=args.side, segment_info=segment_info, - mode=os.environ.get('_POWERLINE_MODE'), + mode=segment_info['environ'].get('_POWERLINE_MODE'), ) write(rendered) diff --git a/powerline/vim.py b/powerline/vim.py index 8afae555..c60ee20c 100644 --- a/powerline/vim.py +++ b/powerline/vim.py @@ -27,6 +27,7 @@ class VimPowerline(Powerline): def __init__(self, pyeval='PowerlinePyeval', **kwargs): super(VimPowerline, self).__init__('vim', **kwargs) self.last_window_id = 1 + self.pyeval = pyeval self.window_statusline = '%!' + pyeval + '(\'powerline.statusline({0})\')' def add_local_theme(self, key, config): @@ -154,11 +155,23 @@ class VimPowerline(Powerline): # requirements to __main__ globals to just one powerline object # (previously it required as well vim and json) @staticmethod - def pyeval(): + def do_pyeval(): import __main__ vim.command('return ' + json.dumps(eval(vim.eval('a:e'), __main__.__dict__))) + def setup_components(self, components): + if components is None: + components = ('statusline', 'tabline') + if 'statusline' in components: + # Is immediately changed after new_window function is run. Good for + # global value. + vim.command('set statusline=%!{pyeval}(\'powerline.new_window()\')'.format( + pyeval=self.pyeval)) + if 'tabline' in components: + vim.command('set tabline=%!{pyeval}(\'powerline.tabline()\')'.format( + pyeval=self.pyeval)) + pycmd = None @@ -186,12 +199,13 @@ def setup(pyeval=None, pycmd=None, can_replace_pyeval=True): if not hasattr(vim, 'bindeval') and can_replace_pyeval: vim.command((''' function! PowerlinePyeval(e) - {pycmd} powerline.pyeval() + {pycmd} powerline.do_pyeval() endfunction ''').format(pycmd=pycmd)) pyeval = 'PowerlinePyeval' powerline = VimPowerline(pyeval) + powerline.update_renderer() __main__.powerline = powerline # Cannot have this in one line due to weird newline handling (in :execute @@ -202,8 +216,3 @@ def setup(pyeval=None, pycmd=None, can_replace_pyeval=True): vim.command(' autocmd! ColorScheme * :{pycmd} powerline.reset_highlight()'.format(pycmd=pycmd)) 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)) - vim.command('set tabline=%!{pyeval}(\'powerline.tabline()\')'.format(pyeval=pyeval)) diff --git a/scripts/powerline-config b/scripts/powerline-config index 2e636437..0d82eba5 100755 --- a/scripts/powerline-config +++ b/scripts/powerline-config @@ -20,6 +20,7 @@ TMUX_ACTIONS = { SHELL_ACTIONS = { 'command': config.shell_command, + 'uses': config.uses, } @@ -40,7 +41,19 @@ if __name__ == '__main__': 'function', choices=tuple(SHELL_ACTIONS.values()), type=(lambda v: SHELL_ACTIONS.get(v)), - help='If action is "command" then preferred powerline command is output', + metavar='action', + help='If action is "command" then preferred powerline command is output, if it is “uses” then powerline-config script will exit with 1 if specified component is disabled and 0 otherwise.', + ) + shell_parser.add_argument( + 'component', + nargs='?', + choices=('tmux', 'prompt'), + metavar='component', + ) + shell_parser.add_argument( + '-s', '--shell', + nargs='?', + help='Shell for which query is run', ) args = parser.parse_args() diff --git a/tests/test_provided_config_files.py b/tests/test_provided_config_files.py index 90dc3d4e..e738301f 100644 --- a/tests/test_provided_config_files.py +++ b/tests/test_provided_config_files.py @@ -112,7 +112,7 @@ class TestConfig(TestCase): from powerline.ipython import IpythonPowerline class IpyPowerline(IpythonPowerline): - path = None + paths = None config_overrides = None theme_overrides = {} diff --git a/tests/test_shells/input.fish b/tests/test_shells/input.fish index f8da144e..d256c6fa 100644 --- a/tests/test_shells/input.fish +++ b/tests/test_shells/input.fish @@ -1,4 +1,4 @@ -set fish_function_path $fish_function_path "$PWD/powerline/bindings/fish" +set fish_function_path "$PWD/powerline/bindings/fish" $fish_function_path powerline-setup set POWERLINE_COMMAND "$POWERLINE_COMMAND -p $PWD/powerline/config_files" set POWERLINE_COMMAND "$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.args.only_if_ssh=false" diff --git a/tests/test_shells/input.tcsh b/tests/test_shells/input.tcsh index 0bc6b78a..3b5b1eb0 100644 --- a/tests/test_shells/input.tcsh +++ b/tests/test_shells/input.tcsh @@ -1,10 +1,10 @@ source powerline/bindings/tcsh/powerline.tcsh -setenv POWERLINE_COMMAND "$POWERLINE_COMMAND -p "$PWD:q/powerline/config_files" -t default_leftonly.segment_data.hostname.args.only_if_ssh=false -c ext.shell.theme=default_leftonly" +set POWERLINE_COMMAND=$POWERLINE_COMMAND:q" -p "$PWD:q/powerline/config_files" -t default_leftonly.segment_data.hostname.args.only_if_ssh=false -c ext.shell.theme=default_leftonly" unsetenv VIRTUAL_ENV cd tests/shell/3rd cd .git cd .. -setenv VIRTUAL_ENV $HOME:q"/.virtenvs/some-virtual-environment" +setenv VIRTUAL_ENV "/home/foo/.virtenvs/some-virtual-environment" unsetenv VIRTUAL_ENV bash -c 'echo $$>pid ; while true ; do sleep 0.1s ; done' & false # Warning: currently tcsh bindings do not support job count diff --git a/tests/test_shells/ipython_home/profile_default/ipython_config.py b/tests/test_shells/ipython_home/profile_default/ipython_config.py index 658334f1..9f6bb567 100644 --- a/tests/test_shells/ipython_home/profile_default/ipython_config.py +++ b/tests/test_shells/ipython_home/profile_default/ipython_config.py @@ -1,6 +1,8 @@ +import os c = get_config() c.InteractiveShellApp.extensions = ['powerline.bindings.ipython.post_0_11'] c.TerminalInteractiveShell.autocall = 1 +c.Powerline.paths = [os.path.abspath('powerline/config_files')] c.Powerline.theme_overrides = { 'in': { 'segment_data': { diff --git a/tests/test_shells/test.sh b/tests/test_shells/test.sh index 3977d77f..4aff414e 100755 --- a/tests/test_shells/test.sh +++ b/tests/test_shells/test.sh @@ -17,6 +17,25 @@ check_screen_log() { fi } +run() { + local local_path="$PWD/tests/shell/path:$PWD/scripts" + if test "x$SH" = "xfish" ; then + local_path="${local_path}:/usr/bin:/bin" + fi + env -i \ + PATH="$local_path" \ + TERM="${TERM}" \ + COLUMNS="${COLUMNS}" \ + LINES="${LINES}" \ + TEST_TYPE="${TEST_TYPE}" \ + SH="${SH}" \ + DIR1="${DIR1}" \ + DIR2="${DIR2}" \ + XDG_CONFIG_HOME="$PWD/tests/shell/fish_home" \ + IPYTHONDIR="$PWD/tests/shell/ipython_home" \ + "$@" +} + run_test() { TEST_TYPE="$1" shift @@ -41,7 +60,7 @@ run_test() { export TEST_TYPE export SH - screen -L -c tests/test_shells/screenrc -d -m -S "$SESNAME" \ + run screen -L -c tests/test_shells/screenrc -d -m -S "$SESNAME" \ env LANG=en_US.UTF-8 BINDFILE="$BINDFILE" "${ARGS[@]}" screen -S "$SESNAME" -X readreg a tests/test_shells/input.$SH # Wait for screen to initialize @@ -121,12 +140,45 @@ mkdir tests/shell/3rd/'`echo`' mkdir tests/shell/fish_home cp -r tests/test_shells/ipython_home tests/shell -export XDG_CONFIG_HOME="$PWD/tests/shell/fish_home" -export IPYTHONDIR="$PWD/tests/shell/ipython_home" + +mkdir tests/shell/path +ln -s "$(which "${PYTHON:-python}")" tests/shell/path/python +ln -s "$(which screen)" tests/shell/path +ln -s "$(which env)" tests/shell/path +ln -s "$(which sleep)" tests/shell/path +ln -s "$(which cat)" tests/shell/path +ln -s "$(which false)" tests/shell/path +ln -s "$(which true)" tests/shell/path +ln -s "$(which kill)" tests/shell/path +ln -s "$(which echo)" tests/shell/path +ln -s "$(which which)" tests/shell/path +ln -s "$(which dirname)" tests/shell/path +ln -s "$(which wc)" tests/shell/path +ln -s "$(which stty)" tests/shell/path +ln -s "$(which cut)" tests/shell/path +ln -s "$(which bc)" tests/shell/path +ln -s "$(which expr)" tests/shell/path +ln -s "$(which mktemp)" tests/shell/path +for pexe in powerline powerline-config ; do + if test -e scripts/$pexe ; then + ln -s "$PWD/scripts/$pexe" tests/shell/path + elif which $pexe ; then + ln -s "$(which $pexe)" tests/shell/path + else + echo "Executable $pexe was not found" + exit 1 + fi +done + +for exe in bash zsh bb busybox fish tcsh mksh dash ipython ; do + if which $exe >/dev/null ; then + ln -s "$(which $exe)" tests/shell/path + fi +done unset ENV -if test "x${ONLY_SHELL%sh}" != "x${ONLY_SHELL}" || test "x${ONLY_SHELL}" = xbb ; then +if test -z "${ONLY_SHELL}" || test "x${ONLY_SHELL%sh}" != "x${ONLY_SHELL}" || test "x${ONLY_SHELL}" = xbb ; then powerline-daemon -k || true sleep 1s @@ -183,5 +235,5 @@ if ! run_test ipython ipython ; then FAILED=1 fi -test "x$ONLY_SHELL" = "x" && rm -r tests/shell +test $FAILED -eq 0 && rm -r tests/shell exit $FAILED diff --git a/tests/test_shells/zsh.daemon.ok b/tests/test_shells/zsh.daemon.ok index 7469e23b..3582bc70 100644 Binary files a/tests/test_shells/zsh.daemon.ok and b/tests/test_shells/zsh.daemon.ok differ diff --git a/tests/vim.py b/tests/vim.py index 7867f563..29da4415 100644 --- a/tests/vim.py +++ b/tests/vim.py @@ -211,8 +211,15 @@ def command(cmd): if not aucmd.startswith(':python3 '): raise NotImplementedError _on_wipeout.append(aucmd.partition(' ')[2]) + elif cmd.startswith('set '): + if cmd.startswith('set statusline='): + options['statusline'] = cmd[len('set statusline='):] + elif cmd.startswith('set tabline='): + options['tabline'] = cmd[len('set tabline='):] + else: + raise NotImplementedError(cmd) else: - raise NotImplementedError + raise NotImplementedError(cmd) @_vim @@ -481,6 +488,7 @@ class _Tabpage(object): return win def _close(self): + global _tabpage while self.windows: self._close_window(1, False) tabpages._pop(self.number) @@ -532,7 +540,7 @@ class _Buffer(object): import os if type(name) is not bytes: name = name.encode('utf-8') - if b':/' in name: + if b':/' in name: self._name = name else: self._name = os.path.abspath(name) @@ -680,6 +688,7 @@ def _edit(name=None): @_vim def _tabnew(name=None): global windows + global _tabpage tabpage = tabpages._new() windows = tabpage.windows _tabpage = len(tabpages)