From 7b1d7bbb9ed83ebde5d3578e8ea68e223c767f31 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 24 May 2014 13:44:58 +0400 Subject: [PATCH] Use scripts/powerline-config to source tmux configuration Ref #872 --- powerline/bindings/config.py | 107 ++++++++++++++++++ powerline/bindings/tmux/powerline.conf | 18 +-- ...mon.conf => powerline_tmux_1.8_minus.conf} | 0 scripts/powerline-config | 33 ++++++ setup.py | 1 + 5 files changed, 142 insertions(+), 17 deletions(-) create mode 100644 powerline/bindings/config.py rename powerline/bindings/tmux/{powerline_tmux_legacy_common.conf => powerline_tmux_1.8_minus.conf} (100%) create mode 100755 scripts/powerline-config diff --git a/powerline/bindings/config.py b/powerline/bindings/config.py new file mode 100644 index 00000000..83bab203 --- /dev/null +++ b/powerline/bindings/config.py @@ -0,0 +1,107 @@ +# vim:fileencoding=utf-8:noet + +from __future__ import absolute_import, unicode_literals, print_function + +from collections import namedtuple +import os +import subprocess +import re + + +TmuxVersionInfo = namedtuple('TmuxVersionInfo', ('major', 'minor', 'suffix')) + + +def get_tmux_executable_name(): + '''Returns tmux executable name + + It should be defined in POWERLINE_TMUX_EXE environment variable, otherwise + it is simply “tmux”. + ''' + + return os.environ.get('POWERLINE_TMUX_EXE', 'tmux') + + +def _run_tmux(runner, args): + return runner([get_tmux_executable_name()] + list(args)) + + +def run_tmux_command(*args): + '''Run tmux command, ignoring the output''' + _run_tmux(subprocess.check_call, args) + + +def get_tmux_output(*args): + '''Run tmux command and return its output''' + return _run_tmux(subprocess.check_output, args) + + +NON_DIGITS = re.compile('[^0-9]+') +DIGITS = re.compile('[0-9]+') +NON_LETTERS = re.compile('[^a-z]+') + + +def get_tmux_version(): + version_string = get_tmux_output('-V') + _, version_string = version_string.split(' ') + version_string = version_string.strip() + major, minor = version_string.split('.') + suffix = DIGITS.subn('', minor)[0] or None + minor = NON_DIGITS.subn('', minor)[0] + return TmuxVersionInfo(int(major), int(minor), suffix) + + +CONFIG_FILE_NAME = re.compile(r'powerline_tmux_(?P\d+)\.(?P\d+)(?P[a-z]+)?(?:_(?Pplus|minus))?\.conf') +CONFIG_MATCHERS = { + None: (lambda a, b: a.major == b.major and a.minor == b.minor), + 'plus': (lambda a, b: a[:2] <= b[:2]), + 'minus': (lambda a, b: a[:2] >= b[:2]), +} +CONFIG_PRIORITY = { + None: 3, + 'plus': 2, + 'minus': 1, +} + + +def list_all_tmux_configs(): + '''List all version-specific tmux configuration files''' + directory = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'tmux') + for root, dirs, files in os.walk(directory): + dirs[:] = () + for fname in files: + match = CONFIG_FILE_NAME.match(fname) + if match: + assert match.group('suffix') is None + yield ( + os.path.join(root, fname), + CONFIG_MATCHERS[match.group('mod')], + CONFIG_PRIORITY[match.group('mod')], + TmuxVersionInfo( + int(match.group('major')), + int(match.group('minor')), + match.group('suffix'), + ), + ) + + +def get_tmux_configs(version): + '''Get tmux configuration suffix given parsed tmux version + + :param TmuxVersionInfo version: Parsed tmux version. + ''' + for fname, matcher, priority, file_version in list_all_tmux_configs(): + if matcher(file_version, version): + yield (fname, priority + file_version.minor * 10 + file_version.major * 10000) + + +def source_tmux_files(): + '''Source relevant version-specific tmux configuration files + + Files are sourced in the following order: + * First relevant files with older versions are sourced. + * If files for same versions are to be sourced then first _minus files are + sourced, then _plus files and then files without _minus or _plus suffixes. + ''' + version = get_tmux_version() + for fname, priority in sorted(get_tmux_configs(version), key=(lambda v: v[1])): + run_tmux_command('source', fname) diff --git a/powerline/bindings/tmux/powerline.conf b/powerline/bindings/tmux/powerline.conf index 55437d21..6735081e 100644 --- a/powerline/bindings/tmux/powerline.conf +++ b/powerline/bindings/tmux/powerline.conf @@ -1,6 +1,4 @@ if-shell 'test -z "$POWERLINE_COMMAND"' 'if-shell "which powerline-client" "set-environment -g POWERLINE_COMMAND powerline-client" "set-environment -g POWERLINE_COMMAND powerline"' -run-shell "tmux set-environment -g TMUX_VERSION_MAJOR $(tmux -V | cut -d' ' -f2 | cut -d'.' -f1 | sed 's/[^0-9]*//g')" -run-shell "tmux set-environment -g TMUX_VERSION_MINOR $(tmux -V | cut -d' ' -f2 | cut -d'.' -f2 | sed 's/[^0-9]*//g')" # Don't version-check for this core functionality -- anything too old to # support these options likely won't work well with powerline @@ -19,19 +17,5 @@ set -g status-left '#[fg=colour16,bg=colour254,bold] #S #[fg=colour254,bg=colour # Simplify tmux version checking by using multiple config files. Source these # config files based on the version in which tmux features were added and/or # deprecated. By splitting these configuration options into separate files, -# less 'if-shell' commands are necessary and reading/editing of config files is -# much easier. - -# tmux Version 1.9 adds foo-style options -if-shell '[ $TMUX_VERSION_MAJOR -gt 1 -o \( $TMUX_VERSION_MAJOR -eq 1 -a $TMUX_VERSION_MINOR -ge 9 \) ]' \ - "source "$POWERLINE_BINDINGS_DIR/tmux/powerline_tmux_1.9_plus.conf"" -# tmux Version 1.8 adds the 'client_prefix' format variable -if-shell '[ $TMUX_VERSION_MAJOR -gt 1 -o \( $TMUX_VERSION_MAJOR -eq 1 -a $TMUX_VERSION_MINOR -ge 8 \) ]' \ - "source "$POWERLINE_BINDINGS_DIR/tmux/powerline_tmux_1.8_plus.conf"" -# tmux Version 1.8 adds a legacy window-status-last-{attr,bg,fg} option -if-shell '[ $TMUX_VERSION_MAJOR -eq 1 -a $TMUX_VERSION_MINOR -eq 8 ]' \ - "source "$POWERLINE_BINDINGS_DIR/tmux/powerline_tmux_1.8.conf"" -# tmux Versions 1.8 and earlier use the legacy foo-{attr,bg,fg} options -if-shell '[ $TMUX_VERSION_MAJOR -eq 1 -a $TMUX_VERSION_MINOR -le 8 ]' \ - "source "$POWERLINE_BINDINGS_DIR/tmux/powerline_tmux_legacy_common.conf"" +run-shell "powerline-config tmux source" # vim: ft=tmux diff --git a/powerline/bindings/tmux/powerline_tmux_legacy_common.conf b/powerline/bindings/tmux/powerline_tmux_1.8_minus.conf similarity index 100% rename from powerline/bindings/tmux/powerline_tmux_legacy_common.conf rename to powerline/bindings/tmux/powerline_tmux_1.8_minus.conf diff --git a/scripts/powerline-config b/scripts/powerline-config new file mode 100755 index 00000000..151dc1d5 --- /dev/null +++ b/scripts/powerline-config @@ -0,0 +1,33 @@ +#!/usr/bin/env python +# vim:fileencoding=utf-8:noet +'''Script used to obtain powerline configuration''' + +import argparse + +try: + import powerline.bindings.config as config +except ImportError: + sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(os.path.realpath(__file__))))) + import powerline.bindings.config as config # NOQA + + +TMUX_ACTIONS = { + 'source': (lambda args: config.source_tmux_files()), +} + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description=__doc__) + subparsers = parser.add_subparsers() + tmux_parser = subparsers.add_parser('tmux', help='Tmux-specific commands') + tmux_parser.add_argument( + 'function', + choices=tuple(TMUX_ACTIONS.values()), + metavar='action', + type=(lambda v: TMUX_ACTIONS.get(v)), + help='If action is "source" then version-specific tmux configuration files are sourced.' + ) + + args = parser.parse_args() + + args.function(args) diff --git a/setup.py b/setup.py index 0b449011..e341ceec 100755 --- a/setup.py +++ b/setup.py @@ -26,6 +26,7 @@ setup( scripts=[ 'scripts/powerline', 'scripts/powerline-lint', + 'scripts/powerline-config', ], keywords='', packages=find_packages(exclude=('tests', 'tests.*')),