From b8049fab87769fea6bb156d27c5755e982393553 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 10 Aug 2014 16:01:57 +0400 Subject: [PATCH] Add ext.*.components configuration support Also fixes various problems in shell bindings. Closes #969 --- docs/source/configuration/local.rst | 12 ++++----- docs/source/configuration/reference.rst | 22 ++++++++++++++++ powerline/__init__.py | 20 ++++++++++++++- powerline/bindings/bash/powerline.sh | 24 +++++++++-------- powerline/bindings/config.py | 27 ++++++++++++++++++-- powerline/bindings/fish/powerline-setup.fish | 20 +++++++++------ powerline/bindings/shell/powerline.sh | 23 +++++++++-------- powerline/bindings/tcsh/powerline.tcsh | 17 +++++++----- powerline/bindings/zsh/powerline.zsh | 20 +++++++++------ powerline/lint/__init__.py | 3 +++ powerline/vim.py | 19 ++++++++++---- scripts/powerline-config | 15 ++++++++++- 12 files changed, 163 insertions(+), 59 deletions(-) diff --git a/docs/source/configuration/local.rst b/docs/source/configuration/local.rst index 527f9650..13902514 100644 --- a/docs/source/configuration/local.rst +++ b/docs/source/configuration/local.rst @@ -115,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:: @@ -150,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 9a828d2f..8f043e43 100644 --- a/docs/source/configuration/reference.rst +++ b/docs/source/configuration/reference.rst @@ -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 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/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/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/lint/__init__.py b/powerline/lint/__init__.py index afb39dc1..7d894049 100644 --- a/powerline/lint/__init__.py +++ b/powerline/lint/__init__.py @@ -525,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(), @@ -556,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( @@ -570,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(), diff --git a/powerline/vim.py b/powerline/vim.py index 8afae555..81b0b9ba 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): @@ -159,6 +160,18 @@ class VimPowerline(Powerline): 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 @@ -192,6 +205,7 @@ def setup(pyeval=None, pycmd=None, can_replace_pyeval=True): 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()