diff options
Diffstat (limited to 'powerline/commands')
-rw-r--r-- | powerline/commands/__init__.py | 0 | ||||
-rw-r--r-- | powerline/commands/config.py | 109 | ||||
-rw-r--r-- | powerline/commands/daemon.py | 24 | ||||
-rw-r--r-- | powerline/commands/lemonbar.py | 35 | ||||
-rwxr-xr-x | powerline/commands/lint.py | 21 | ||||
-rw-r--r-- | powerline/commands/main.py | 190 |
6 files changed, 379 insertions, 0 deletions
diff --git a/powerline/commands/__init__.py b/powerline/commands/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/powerline/commands/__init__.py diff --git a/powerline/commands/config.py b/powerline/commands/config.py new file mode 100644 index 0000000..e9ca5f9 --- /dev/null +++ b/powerline/commands/config.py @@ -0,0 +1,109 @@ +# vim:fileencoding=utf-8:noet +from __future__ import (division, absolute_import, print_function) + +import argparse + +import powerline.bindings.config as config + + +class StrFunction(object): + def __init__(self, function, name=None): + self.name = name or function.__name__ + self.function = function + + def __call__(self, *args, **kwargs): + self.function(*args, **kwargs) + + def __str__(self): + return self.name + + +TMUX_ACTIONS = { + 'source': StrFunction(config.source_tmux_files, 'source'), + 'setenv': StrFunction(config.init_tmux_environment, 'setenv'), + 'setup': StrFunction(config.tmux_setup, 'setup'), +} + + +SHELL_ACTIONS = { + 'command': StrFunction(config.shell_command, 'command'), + 'uses': StrFunction(config.uses), +} + + +class ConfigArgParser(argparse.ArgumentParser): + def parse_args(self, *args, **kwargs): + ret = super(ConfigArgParser, self).parse_args(*args, **kwargs) + if not hasattr(ret, 'function'): + # In Python-3* `powerline-config` (without arguments) raises + # AttributeError. I have not found any standard way to display same + # error message as in Python-2*. + self.error('too few arguments') + return ret + + +def get_argparser(ArgumentParser=ConfigArgParser): + parser = ArgumentParser(description='Script used to obtain powerline configuration.') + parser.add_argument( + '-p', '--config-path', action='append', metavar='PATH', + help='Path to configuration directory. If it is present ' + 'then configuration files will only be sought in the provided path. ' + 'May be provided multiple times to search in a list of directories.' + ) + 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, if it is `setenv\' then special ' + '(prefixed with `_POWERLINE\') tmux global environment variables ' + 'are filled with data from powerline configuration. ' + 'Action `setup\' is just doing `setenv\' then `source\'.' + ) + tpg = tmux_parser.add_mutually_exclusive_group() + tpg.add_argument( + '-s', '--source', action='store_true', default=None, + help='When using `setup\': always use configuration file sourcing. ' + 'By default this is determined automatically based on tmux ' + 'version: this is the default for tmux 1.8 and below.', + ) + tpg.add_argument( + '-n', '--no-source', action='store_false', dest='source', default=None, + help='When using `setup\': in place of sourcing directly execute ' + 'configuration files. That is, read each needed ' + 'powerline-specific configuration file, substitute ' + '`$_POWERLINE_…\' variables with appropriate values and run ' + '`tmux config line\'. This is the default behaviour for ' + 'tmux 1.9 and above.' + ) + + shell_parser = subparsers.add_parser('shell', help='Shell-specific commands') + shell_parser.add_argument( + 'function', + choices=tuple(SHELL_ACTIONS.values()), + type=(lambda v: SHELL_ACTIONS.get(v)), + 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', + help='Only applicable for `uses\' subcommand: makes `powerline-config\' ' + 'exit with 0 if specific component is enabled and with 1 otherwise. ' + '`tmux\' component stands for tmux bindings ' + '(e.g. those that notify tmux about current directory changes), ' + '`prompt\' component stands for shell prompt.' + ) + shell_parser.add_argument( + '-s', '--shell', + metavar='SHELL', + help='Shell for which query is run', + ) + return parser diff --git a/powerline/commands/daemon.py b/powerline/commands/daemon.py new file mode 100644 index 0000000..7e8c8ab --- /dev/null +++ b/powerline/commands/daemon.py @@ -0,0 +1,24 @@ +# vim:fileencoding=utf-8:noet +from __future__ import (division, absolute_import, print_function) + +import argparse + + +def get_argparser(ArgumentParser=argparse.ArgumentParser): + parser = ArgumentParser(description='Daemon that improves powerline performance.') + parser.add_argument( + '--quiet', '-q', action='store_true', + help='Without other options: do not complain about already running ' + 'powerline-daemon instance. ' + 'Will still exit with 1. ' + 'With `--kill\' and `--replace\': do not show any messages. ' + 'With `--foreground\': ignored. ' + 'Does not silence exceptions in any case.' + ) + parser.add_argument('--socket', '-s', help='Specify socket which will be used for connecting to daemon.') + exclusive_group = parser.add_mutually_exclusive_group() + exclusive_group.add_argument('--kill', '-k', action='store_true', help='Kill an already running instance.') + replace_group = exclusive_group.add_argument_group() + replace_group.add_argument('--foreground', '-f', action='store_true', help='Run in the foreground (don’t daemonize).') + replace_group.add_argument('--replace', '-r', action='store_true', help='Replace an already running instance.') + return parser diff --git a/powerline/commands/lemonbar.py b/powerline/commands/lemonbar.py new file mode 100644 index 0000000..547c52c --- /dev/null +++ b/powerline/commands/lemonbar.py @@ -0,0 +1,35 @@ +# vim:fileencoding=utf-8:noet +# WARNING: using unicode_literals causes errors in argparse +from __future__ import (division, absolute_import, print_function) + +import argparse + + +def get_argparser(ArgumentParser=argparse.ArgumentParser): + parser = ArgumentParser( + description='Powerline BAR bindings.' + ) + parser.add_argument( + '--i3', action='store_true', + help='Subscribe for i3 events.' + ) + parser.add_argument( + '--height', default='', + metavar='PIXELS', help='Bar height.' + ) + parser.add_argument( + '--interval', '-i', + type=float, default=0.5, + metavar='SECONDS', help='Refresh interval.' + ) + parser.add_argument( + '--bar-command', '-C', + default='lemonbar', + metavar='CMD', help='Name of the lemonbar executable to use.' + ) + parser.add_argument( + 'args', nargs=argparse.REMAINDER, + help='Extra arguments for lemonbar. Should be preceded with ``--`` ' + 'argument in order not to be confused with script own arguments.' + ) + return parser diff --git a/powerline/commands/lint.py b/powerline/commands/lint.py new file mode 100755 index 0000000..8961a65 --- /dev/null +++ b/powerline/commands/lint.py @@ -0,0 +1,21 @@ +# vim:fileencoding=utf-8:noet +from __future__ import (division, absolute_import, print_function) + +import argparse + + +def get_argparser(ArgumentParser=argparse.ArgumentParser): + parser = ArgumentParser(description='Powerline configuration checker.') + parser.add_argument( + '-p', '--config-path', action='append', metavar='PATH', + help='Paths where configuration should be checked, in order. You must ' + 'supply all paths necessary for powerline to work, ' + 'checking partial (e.g. only user overrides) configuration ' + 'is not supported.' + ) + parser.add_argument( + '-d', '--debug', action='store_const', const=True, + help='Display additional information. Used for debugging ' + '`powerline-lint\' itself, not for debugging configuration.' + ) + return parser diff --git a/powerline/commands/main.py b/powerline/commands/main.py new file mode 100644 index 0000000..373225f --- /dev/null +++ b/powerline/commands/main.py @@ -0,0 +1,190 @@ +# vim:fileencoding=utf-8:noet +# WARNING: using unicode_literals causes errors in argparse +from __future__ import (division, absolute_import, print_function) + +import argparse +import sys + +from itertools import chain + +from powerline.lib.overrides import parsedotval, parse_override_var +from powerline.lib.dict import mergeargs +from powerline.lib.encoding import get_preferred_arguments_encoding +from powerline.lib.unicode import u, unicode +from powerline.bindings.wm import wm_threads + + +if sys.version_info < (3,): + encoding = get_preferred_arguments_encoding() + + def arg_to_unicode(s): + return unicode(s, encoding, 'replace') if not isinstance(s, unicode) else s # NOQA +else: + def arg_to_unicode(s): + return s + + +def finish_args(parser, environ, args, is_daemon=False): + '''Do some final transformations + + Transforms ``*_override`` arguments into dictionaries, adding overrides from + environment variables. Transforms ``renderer_arg`` argument into dictionary + as well, but only if it is true. + + :param dict environ: + Environment from which additional overrides should be taken from. + :param args: + Arguments object returned by + :py:meth:`argparse.ArgumentParser.parse_args`. Will be modified + in-place. + + :return: Object received as second (``args``) argument. + ''' + args.config_override = mergeargs(chain( + parse_override_var(environ.get('POWERLINE_CONFIG_OVERRIDES', '')), + (parsedotval(v) for v in args.config_override or ()), + )) + args.theme_override = mergeargs(chain( + parse_override_var(environ.get('POWERLINE_THEME_OVERRIDES', '')), + (parsedotval(v) for v in args.theme_override or ()), + )) + if args.renderer_arg: + args.renderer_arg = mergeargs((parsedotval(v) for v in args.renderer_arg), remove=True) + if 'pane_id' in args.renderer_arg: + if isinstance(args.renderer_arg['pane_id'], (bytes, unicode)): + try: + args.renderer_arg['pane_id'] = int(args.renderer_arg['pane_id'].lstrip(' %')) + except ValueError: + pass + if 'client_id' not in args.renderer_arg: + args.renderer_arg['client_id'] = args.renderer_arg['pane_id'] + args.config_path = ( + [path for path in environ.get('POWERLINE_CONFIG_PATHS', '').split(':') if path] + + (args.config_path or []) + ) + if args.ext[0].startswith('wm.'): + if not is_daemon: + parser.error('WM bindings must be used with daemon only') + elif args.ext[0][3:] not in wm_threads: + parser.error('WM binding not found') + elif not args.side: + parser.error('expected one argument') + return args + + +def int_or_sig(s): + if s.startswith('sig'): + return u(s) + else: + return int(s) + + +def get_argparser(ArgumentParser=argparse.ArgumentParser): + parser = ArgumentParser(description='Powerline prompt and statusline script.') + parser.add_argument( + 'ext', nargs=1, + help='Extension: application for which powerline command is launched ' + '(usually `shell\' or `tmux\'). Also supports `wm.\' extensions: ' + + ', '.join(('`wm.' + key + '\'' for key in wm_threads.keys())) + '.' + ) + parser.add_argument( + 'side', nargs='?', choices=('left', 'right', 'above', 'aboveleft'), + help='Side: `left\' and `right\' represent left and right side ' + 'respectively, `above\' emits lines that are supposed to be printed ' + 'just above the prompt and `aboveleft\' is like concatenating ' + '`above\' with `left\' with the exception that only one Python ' + 'instance is used in this case. May be omitted for `wm.*\' extensions.' + ) + parser.add_argument( + '-r', '--renderer-module', metavar='MODULE', type=str, + help='Renderer module. Usually something like `.bash\' or `.zsh\' ' + '(with leading dot) which is `powerline.renderers.{ext}{MODULE}\', ' + 'may also be full module name (must contain at least one dot or ' + 'end with a dot in case it is top-level module) or ' + '`powerline.renderers\' submodule (in case there are no dots).' + ) + parser.add_argument( + '-w', '--width', type=int, + help='Maximum prompt with. Triggers truncation of some segments.' + ) + parser.add_argument( + '--last-exit-code', metavar='INT', type=int_or_sig, + help='Last exit code.' + ) + parser.add_argument( + '--last-pipe-status', metavar='LIST', default='', + type=lambda s: [int_or_sig(status) for status in s.split()], + help='Like above, but is supposed to contain space-separated array ' + 'of statuses, representing exit statuses of commands in one pipe.' + ) + parser.add_argument( + '--jobnum', metavar='INT', type=int, + help='Number of jobs.' + ) + parser.add_argument( + '-c', '--config-override', metavar='KEY.KEY=VALUE', type=arg_to_unicode, + action='append', + help='Configuration overrides for `config.json\'. Is translated to a ' + 'dictionary and merged with the dictionary obtained from actual ' + 'JSON configuration: KEY.KEY=VALUE is translated to ' + '`{"KEY": {"KEY": VALUE}}\' and then merged recursively. ' + 'VALUE may be any JSON value, values that are not ' + '`null\', `true\', `false\', start with digit, `{\', `[\' ' + 'are treated like strings. If VALUE is omitted ' + 'then corresponding key is removed.' + ) + parser.add_argument( + '-t', '--theme-override', metavar='THEME.KEY.KEY=VALUE', type=arg_to_unicode, + action='append', + help='Like above, but theme-specific. THEME should point to ' + 'an existing and used theme to have any effect, but it is fine ' + 'to use any theme here.' + ) + parser.add_argument( + '-R', '--renderer-arg', + metavar='KEY=VAL', type=arg_to_unicode, action='append', + help='Like above, but provides argument for renderer. Is supposed ' + 'to be used only by shell bindings to provide various data like ' + 'last-exit-code or last-pipe-status (they are not using ' + '`--renderer-arg\' for historical reasons: `--renderer-arg\' ' + 'was added later).' + ) + parser.add_argument( + '-p', '--config-path', action='append', metavar='PATH', + help='Path to configuration directory. If it is present then ' + 'configuration files will only be sought in the provided path. ' + 'May be provided multiple times to search in a list of directories.' + ) + parser.add_argument( + '--socket', metavar='ADDRESS', type=str, + help='Socket address to use in daemon clients. Is always UNIX domain ' + 'socket on linux and file socket on Mac OS X. Not used here, ' + 'present only for compatibility with other powerline clients. ' + 'This argument must always be the first one and be in a form ' + '`--socket ADDRESS\': no `=\' or short form allowed ' + '(in other powerline clients, not here).' + ) + return parser + + +def write_output(args, powerline, segment_info, write): + if args.renderer_arg: + segment_info.update(args.renderer_arg) + if args.side.startswith('above'): + for line in powerline.render_above_lines( + width=args.width, + segment_info=segment_info, + mode=segment_info.get('mode', None), + ): + if line: + write(line + '\n') + args.side = args.side[len('above'):] + + if args.side: + rendered = powerline.render( + width=args.width, + side=args.side, + segment_info=segment_info, + mode=segment_info.get('mode', None), + ) + write(rendered) |