From a122e73b9b64a16a929330bd21cf1bcf9e206546 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kim=20Silkeb=C3=A6kken?= Date: Wed, 31 Jul 2013 22:15:35 +0200 Subject: [PATCH 01/22] Add files from @kovidgoyal's powerline-daemon repo Minor changes have been applied: - Removed copyright info and GPL 3 license since Powerline is MIT (needs confirmation from kovidgoyal before merge) - The `powerline-client` script is renamed to `powerline`, and calls the daemon or `powerline-render` (the previous `powerline`) to render a statusline - Minor coding style corrections to match the rest of the project - Python 3 support is removed for now due to setuptools failing with binary scripts Todo: - Automatically attempt to launch powerline-daemon the first time powerline is run if the daemon isn't already running? - pip install -e fails with binary files (it appears that pip recodes the powerline binary to ASCII, the compiled powerline script must be copied manually to ~/.local/bin after pip install -e has been run) --- client/powerline | Bin 0 -> 10732 bytes client/powerline.c | 115 +++++++ client/powerline.py | 77 +++++ scripts/.gitignore | 1 + scripts/powerline-daemon | 395 ++++++++++++++++++++++++ scripts/{powerline => powerline-render} | 0 setup.py | 36 ++- 7 files changed, 620 insertions(+), 4 deletions(-) create mode 100755 client/powerline create mode 100644 client/powerline.c create mode 100755 client/powerline.py create mode 100644 scripts/.gitignore create mode 100755 scripts/powerline-daemon rename scripts/{powerline => powerline-render} (100%) diff --git a/client/powerline b/client/powerline new file mode 100755 index 0000000000000000000000000000000000000000..fd6de02466fadefde0a29997f5b142205dd85172 GIT binary patch literal 10732 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 LQ1P3LRsVkg?!G}> literal 0 HcmV?d00001 diff --git a/client/powerline.c b/client/powerline.c new file mode 100644 index 00000000..cef562ec --- /dev/null +++ b/client/powerline.c @@ -0,0 +1,115 @@ +/* vim:fileencoding=utf-8:noet */ + +#include +#include +#include +#include +#include +#include +#include + +#define handle_error(msg) \ + do { perror(msg); exit(EXIT_FAILURE); } while (0) + +#ifndef TEMP_FAILURE_RETRY +#define TEMP_FAILURE_RETRY(expression) \ + ( \ + ({ long int __result; \ + do __result = (long int) (expression); \ + while (__result == -1L && errno == EINTR); \ + __result; })) +#endif + +extern char **environ; + +void do_write(int sd, const char *raw, int len) { + int written = 0, n = -1; + + while (written < len) { + n = TEMP_FAILURE_RETRY(write(sd, raw+written, len-written)); + if (n == -1) { + close(sd); + handle_error("write() failed"); + } + written += n; + } +} + +int main(int argc, char *argv[]) { + int sd = -1, i; + struct sockaddr_un server; + char address[50] = {}; + const char eof[2] = "\0\0"; + char buf[4096] = {}; + char *newargv[200] = {}; + char *wd = NULL; + char **envp; + + if (argc < 2) { printf("Must provide at least one argument.\n"); return EXIT_FAILURE; } + +#ifdef __APPLE__ + snprintf(address, 50, "/tmp/powerline-ipc-%d", getuid()); +#else + snprintf(address, 50, "powerline-ipc-%d", getuid()); +#endif + + sd = socket(AF_UNIX, SOCK_STREAM, 0); + if (sd == -1) handle_error("socket() failed"); + + memset(&server, 0, sizeof(struct sockaddr_un)); // Clear + server.sun_family = AF_UNIX; +#ifdef __APPLE__ + strncpy(server.sun_path, address, strlen(address)); +#else + strncpy(server.sun_path+1, address, strlen(address)); +#endif + +#ifdef __APPLE__ + if (connect(sd, (struct sockaddr *) &server, sizeof(server.sun_family) + strlen(address)) < 0) { +#else + if (connect(sd, (struct sockaddr *) &server, sizeof(server.sun_family) + strlen(address)+1) < 0) { +#endif + close(sd); + // We failed to connect to the daemon, execute powerline instead + argc = (argc < 199) ? argc : 199; + for (i=1; i < argc; i++) newargv[i] = argv[i]; + newargv[0] = "powerline-render"; + newargv[argc] = NULL; + execvp("powerline-render", newargv); + } + + for (i = 1; i < argc; i++) { + do_write(sd, argv[i], strlen(argv[i])); + do_write(sd, eof, 1); + } + + for(envp=environ; *envp; envp++) { + do_write(sd, "--env=", 6); + do_write(sd, *envp, strlen(*envp)); + do_write(sd, eof, 1); + } + + wd = getcwd(NULL, 0); + if (wd != NULL) { + do_write(sd, "--cwd=", 6); + do_write(sd, wd, strlen(wd)); + free(wd); wd = NULL; + } + + do_write(sd, eof, 2); + + i = -1; + while (i != 0) { + i = TEMP_FAILURE_RETRY(read(sd, buf, 4096)); + if (i == -1) { + close(sd); + handle_error("read() failed"); + } + if (i > 0) + write(STDOUT_FILENO, buf, i) || 0; + } + + close(sd); + + return 0; +} diff --git a/client/powerline.py b/client/powerline.py new file mode 100755 index 00000000..bbcfffbe --- /dev/null +++ b/client/powerline.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python +# vim:fileencoding=utf-8:noet + +from __future__ import (unicode_literals, division, absolute_import, print_function) + +import sys +import socket +import os +import errno + +if len(sys.argv) < 2: + print('Must provide at least one argument.', file=sys.stderr) + raise SystemExit(1) + +platform = sys.platform.lower() +use_filesystem = 'darwin' in platform +# use_filesystem = True +del platform + +address = ('/tmp/powerline-ipc-%d' if use_filesystem else '\0powerline-ipc-%d')%os.getuid() + +sock = socket.socket(family=socket.AF_UNIX) + + +def eintr_retry_call(func, *args, **kwargs): + while True: + try: + return func(*args, **kwargs) + except EnvironmentError as e: + if getattr(e, 'errno', None) == errno.EINTR: + continue + raise + +try: + eintr_retry_call(sock.connect, address) +except Exception: + # Run the powerline renderer + args = ['powerline-render'] + sys.argv[1:] + os.execvp('powerline-render', args) + +fenc = sys.getfilesystemencoding() or 'utf-8' +if fenc == 'ascii': + fenc = 'utf-8' + +args = [x.encode(fenc) if isinstance(x, type('')) else x for x in sys.argv[1:]] + +try: + cwd = os.getcwd() +except EnvironmentError: + pass +else: + if isinstance(cwd, type('')): + cwd = cwd.encode(fenc) + args.append(b'--cwd=' + cwd) + + +env = (k + '=' + v for k, v in os.environ.items()) +env = (x if isinstance(x, bytes) else x.encode(fenc, 'replace') for x in env) +args.extend((b'--env=' + x for x in env)) + +EOF = b'\0\0' + +for a in args: + eintr_retry_call(sock.sendall, a + EOF[0]) + +eintr_retry_call(sock.sendall, EOF) + +received = [] +while True: + r = sock.recv(4096) + if not r: + break + received.append(r) + +sock.close() + +print (b''.join(received)) diff --git a/scripts/.gitignore b/scripts/.gitignore new file mode 100644 index 00000000..f2ffc12a --- /dev/null +++ b/scripts/.gitignore @@ -0,0 +1 @@ +powerline diff --git a/scripts/powerline-daemon b/scripts/powerline-daemon new file mode 100755 index 00000000..b7627cc4 --- /dev/null +++ b/scripts/powerline-daemon @@ -0,0 +1,395 @@ +#!/usr/bin/env python +# vim:fileencoding=utf-8:noet +from __future__ import (unicode_literals, division, absolute_import, print_function) + +import socket +import os +import errno +import sys +from argparse import ArgumentParser +from select import select +from signal import signal, SIGTERM +from time import sleep +from functools import partial +from locale import getpreferredencoding + +from powerline.shell import get_argparser, finish_args, ShellPowerline +from powerline.lib.monotonic import monotonic + +is_daemon = False +platform = sys.platform.lower() +use_filesystem = 'darwin' in platform +# use_filesystem = True +del platform + +if use_filesystem: + address = '/tmp/powerline-ipc-%d' + pidfile = address + '.pid' +else: + # Use the abstract namespace for sockets rather than the filesystem + # (Available only in linux) + address = '\0powerline-ipc-%d' +address = address % os.getuid() + + +class NonInteractiveArgParser(ArgumentParser): + def print_usage(self, file=None): + raise Exception(self.format_usage()) + + def print_help(self, file=None): + raise Exception(self.format_help()) + + def exit(self, status=0, message=None): + pass + + def error(self, message): + raise Exception(self.format_usage()) + + +parser = get_argparser(parser=NonInteractiveArgParser, description='powerline daemon') +parser.add_argument('--cwd', metavar='PATH') +parser.add_argument('--env', action='append') + +EOF = b'EOF\0\0' + +powerlines = {} +logger = None +config_loader = None +home = os.path.expanduser('~') + + +class PowerlineDaemon(ShellPowerline): + def get_log_handler(self): + if not is_daemon: + import logging + return logging.StreamHandler() + return super(PowerlineDaemon, self).get_log_handler() + + +def render(args): + global logger + global config_loader + environ = dict(((k, v) for k, v in (x.partition('=')[0::2] for x in args.env))) + cwd = environ.get('PWD', args.cwd or '/') + segment_info = { + 'getcwd': lambda: cwd, + 'home': environ.get('HOME', home), + 'environ': environ, + 'args': args, + } + key = (args.ext[0], args.renderer_module, + tuple(args.config) if args.config else None, + tuple(args.theme_option) if args.theme_option else None,) + if args.renderer_arg: + segment_info.update(args.renderer_arg) + finish_args(args) + pl = None + try: + pl = powerlines[key] + except KeyError: + try: + pl = powerlines[key] = PowerlineDaemon( + args, + logger=logger, + config_loader=config_loader + ) + except SystemExit: + # Somebody thought raising system exit was a good idea, + return '' + except Exception as e: + if pl: + pl.pl.exception('Failed to render {0}: {1}', str(key), str(e)) + else: + return 'Failed to render {0}: {1}'.format(str(key), str(e)) + if logger is None: + logger = pl.logger + if config_loader is None: + config_loader = pl.config_loader + return pl.render(width=args.width, side=args.side, segment_info=segment_info) + + +def eintr_retry_call(func, *args, **kwargs): + while True: + try: + return func(*args, **kwargs) + except EnvironmentError as e: + if getattr(e, 'errno', None) == errno.EINTR: + continue + raise + + +def do_read(conn, timeout=2.0): + ''' Read data from the client. If the client fails to send data within + timeout seconds, abort. ''' + read = [] + end_time = monotonic() + timeout + while not read or not read[-1].endswith(b'\0\0'): + r, w, e = select((conn,), (), (conn,), timeout) + if e: + return + if monotonic() > end_time: + return + if not r: + continue + x = eintr_retry_call(conn.recv, 4096) + if x: + read.append(x) + else: + break + return b''.join(read) + + +def do_write(conn, result): + try: + eintr_retry_call(conn.sendall, result + b'\0') + except Exception: + pass + + +encoding = getpreferredencoding() or 'UTF-8' +if encoding.lower() == 'ascii': + encoding = 'UTF-8' + + +def safe_bytes(o, encoding=encoding): + '''Return bytes instance without ever throwing an exception.''' + try: + try: + # We are assuming that o is a unicode object + return o.encode(encoding, 'replace') + except Exception: + # Object may have defined __bytes__ (python 3) or __str__ method + # (python 2) + # This also catches problem with non_ascii_bytes.encode('utf-8') + # that first tries to decode to UTF-8 using ascii codec (and fails + # in this case) and then encode to given encoding: errors= argument + # is not used in the first stage. + return bytes(o) + except Exception as e: + return safe_bytes(str(e), encoding) + + +def do_render(req): + try: + args = [x.decode(encoding) for x in req.split(b'\0') if x] + args = parser.parse_args(args) + return safe_bytes(render(args)) + except Exception as e: + return safe_bytes(str(e)) + + +def do_one(sock, read_sockets, write_sockets, result_map): + r, w, e = select( + tuple(read_sockets) + (sock,), + tuple(write_sockets), + tuple(read_sockets) + tuple(write_sockets) + (sock,), + 60.0 + ) + + if sock in e: + # We cannot accept any more connections, so we exit + raise SystemExit(1) + + for s in e: + # Discard all broken connections to clients + s.close() + read_sockets.discard(s) + write_sockets.discard(s) + + for s in r: + if s == sock: + # A client wants to connect + conn, _ = eintr_retry_call(sock.accept) + read_sockets.add(conn) + else: + # A client has sent some data + read_sockets.discard(s) + req = do_read(s) + if req == EOF: + raise SystemExit(0) + elif req: + ans = do_render(req) + result_map[s] = ans + write_sockets.add(s) + else: + s.close() + + for s in w: + # A client is ready to receive the result + write_sockets.discard(s) + result = result_map.pop(s) + try: + do_write(s, result) + finally: + s.close() + + +def main_loop(sock): + sock.listen(1) + sock.setblocking(0) + + read_sockets, write_sockets = set(), set() + result_map = {} + try: + while True: + do_one(sock, read_sockets, write_sockets, result_map) + except KeyboardInterrupt: + raise SystemExit(0) + return 0 + + +def daemonize(stdin=os.devnull, stdout=os.devnull, stderr=os.devnull): + try: + pid = os.fork() + if pid > 0: + # exit first parent + sys.exit(0) + except OSError as e: + print ("fork #1 failed: %d (%s)" % (e.errno, e.strerror), file=sys.stderr) + sys.exit(1) + + # decouple from parent environment + os.chdir("/") + os.setsid() + os.umask(0) + + # do second fork + try: + pid = os.fork() + if pid > 0: + # exit from second parent + sys.exit(0) + except OSError as e: + print ("fork #2 failed: %d (%s)" % (e.errno, e.strerror), file=sys.stderr) + sys.exit(1) + + # Redirect standard file descriptors. + si = file(stdin, 'r') + so = file(stdout, 'a+') + se = file(stderr, 'a+', 0) + os.dup2(si.fileno(), sys.stdin.fileno()) + os.dup2(so.fileno(), sys.stdout.fileno()) + os.dup2(se.fileno(), sys.stderr.fileno()) + global is_daemon + is_daemon = True + + +def check_existing(): + if use_filesystem: + # We cannot bind if the socket file already exists so remove it, we + # already have a lock on pidfile, so this should be safe. + try: + os.unlink(address) + except EnvironmentError: + pass + + sock = socket.socket(family=socket.AF_UNIX) + try: + sock.bind(address) + except socket.error as e: + if getattr(e, 'errno', None) == errno.EADDRINUSE: + return None + raise + return sock + + +def test_connect(): + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + try: + try: + eintr_retry_call(sock.connect, address) + except socket.error: + return False + else: + eintr_retry_call(sock.sendall, EOF) + finally: + sock.close() + return True + + +def cleanup_lockfile(fd, *args): + try: + # Remove the directory entry for the lock file + os.unlink(pidfile) + # Close the file descriptor + os.close(fd) + except EnvironmentError: + pass + if args: + # Called in signal handler + raise SystemExit(1) + + +def lockpidfile(): + import fcntl + import atexit + import stat + fd = os.open(pidfile, os.O_WRONLY|os.O_CREAT, + stat.S_IRUSR|stat.S_IWUSR|stat.S_IRGRP|stat.S_IROTH) + try: + fcntl.lockf(fd, fcntl.LOCK_EX | fcntl.LOCK_NB) + except EnvironmentError: + os.close(fd) + return None + os.lseek(fd, 0, os.SEEK_SET) + os.ftruncate(fd, 0) + os.write(fd, ('%d' % os.getpid()).encode('ascii')) + os.fsync(fd) + cleanup = partial(cleanup_lockfile, fd) + signal(SIGTERM, cleanup) + atexit.register(cleanup) + return fd + + +def main(): + p = ArgumentParser(description= + 'Daemon to improve the performance of powerline') + a = p.add_mutually_exclusive_group().add_argument + a('--kill', '-k', action='store_true', help='Kill an already running instance') + a('--foreground', '-f', action='store_true', help='Run in the foreground (dont daemonize)') + a('--replace', '-r', action='store_true', help='Replace an already running instance') + args = p.parse_args() + + if args.kill: + if test_connect(): + print ('Kill command sent to daemon, if it does not die in a couple of seconds use kill to kill it') + else: + print ('No running daemon found') + return + + if args.replace: + while test_connect(): + print ('Kill command sent to daemon, waiting for daemon to exit, press Ctrl-C to terminate wait and exit') + sleep(2) + + if use_filesystem and not args.foreground: + # We must daemonize before creating the locked pidfile, unfortunately, + # this means further print statements are discarded + daemonize() + + if use_filesystem: + # Create a locked pid file containing the daemon's PID + if lockpidfile() is None: + print ('The daemon is already running. Use %s -k to kill it.' % os.path.basename(sys.argv[0]), + file=sys.stderr) + raise SystemExit(1) + + # Bind to address or bail if we cannot bind + sock = check_existing() + if sock is None: + print ('The daemon is already running. Use %s -k to kill it.' % os.path.basename(sys.argv[0]), + file=sys.stderr) + raise SystemExit(1) + + if args.foreground: + return main_loop(sock) + + if not use_filesystem: + # We daemonize on linux + daemonize() + + main_loop(sock) + + +if __name__ == '__main__': + main() diff --git a/scripts/powerline b/scripts/powerline-render similarity index 100% rename from scripts/powerline rename to scripts/powerline-render diff --git a/setup.py b/setup.py index e341ceec..770a927e 100755 --- a/setup.py +++ b/setup.py @@ -3,16 +3,42 @@ from __future__ import unicode_literals import os import sys +import subprocess from setuptools import setup, find_packages -here = os.path.abspath(os.path.dirname(__file__)) +CURRENT_DIR = os.path.abspath(os.path.dirname(__file__)) try: - README = open(os.path.join(here, 'README.rst'), 'rb').read().decode('utf-8') + README = open(os.path.join(CURRENT_DIR, 'README.rst'), 'rb').read().decode('utf-8') except IOError: README = '' -old_python = sys.version_info < (2, 7) +OLD_PYTHON = sys.version_info < (2, 7) + + +def compile_client(): + '''Compile the C powerline-client script.''' + + if hasattr(sys, 'getwindowsversion'): + raise NotImplementedError() + if sys.version_info >= (3, 0): + # FIXME Python 3 doesn't allow compiled C files to be included in the + # scripts list below. This is because Python 3 distutils tries to + # decode the file to ASCII, and fails when powerline-client is + # a binary. + raise NotImplementedError() + else: + from distutils.ccompiler import new_compiler + compiler = new_compiler().compiler + subprocess.check_call(compiler + ['-O3', 'client/powerline.c', '-o', 'scripts/powerline']) + +try: + compile_client() +except Exception: + # FIXME Catch more specific exceptions + import shutil + print('Compiling C version of powerline-client failed, using Python version instead') + shutil.copyfile('client/powerline.py', 'scripts/powerline') setup( name='Powerline', @@ -26,6 +52,8 @@ setup( scripts=[ 'scripts/powerline', 'scripts/powerline-lint', + 'scripts/powerline-daemon', + 'scripts/powerline-render', 'scripts/powerline-config', ], keywords='', @@ -38,5 +66,5 @@ setup( 'Sphinx', ], }, - test_suite='tests' if not old_python else None, + test_suite='tests' if not OLD_PYTHON else None, ) From c1d290b5708537faaff8239cb7d51a19eeb21f83 Mon Sep 17 00:00:00 2001 From: ZyX Date: Wed, 20 Nov 2013 23:30:35 +0400 Subject: [PATCH 02/22] Use data_files on python-3 --- setup.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/setup.py b/setup.py index 770a927e..6dd474bd 100755 --- a/setup.py +++ b/setup.py @@ -14,6 +14,7 @@ except IOError: README = '' OLD_PYTHON = sys.version_info < (2, 7) +PYTHON_3 = sys.version_info > (2,) def compile_client(): @@ -21,12 +22,6 @@ def compile_client(): if hasattr(sys, 'getwindowsversion'): raise NotImplementedError() - if sys.version_info >= (3, 0): - # FIXME Python 3 doesn't allow compiled C files to be included in the - # scripts list below. This is because Python 3 distutils tries to - # decode the file to ASCII, and fails when powerline-client is - # a binary. - raise NotImplementedError() else: from distutils.ccompiler import new_compiler compiler = new_compiler().compiler @@ -49,13 +44,16 @@ setup( author='Kim Silkebaekken', author_email='kim.silkebaekken+vim@gmail.com', url='https://github.com/Lokaltog/powerline', + # FIXME Python 3 doesn't allow compiled C files to be included in the + # scripts list below. This is because Python 3 distutils tries to decode the + # file to ASCII, and fails when powerline-client is a binary. scripts=[ - 'scripts/powerline', 'scripts/powerline-lint', 'scripts/powerline-daemon', 'scripts/powerline-render', 'scripts/powerline-config', - ], + ] + ([] if PYTHON_3 else ['scripts/powerline']), + data_files=([('bin', ['scripts/powerline'])] if PYTHON_3 else None), keywords='', packages=find_packages(exclude=('tests', 'tests.*')), include_package_data=True, From 75536825ba9077df12c21f2adb50d412dc984761 Mon Sep 17 00:00:00 2001 From: ZyX Date: Wed, 20 Nov 2013 23:34:15 +0400 Subject: [PATCH 03/22] Use powerline/powerline-render pair in place of powerline-client/powerline --- powerline/bindings/bash/powerline.sh | 9 +++++---- powerline/bindings/fish/powerline-setup.fish | 6 +++--- powerline/bindings/tcsh/powerline.tcsh | 6 +++--- powerline/bindings/tmux/powerline.conf | 2 +- powerline/bindings/zsh/powerline.zsh | 6 +++--- 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/powerline/bindings/bash/powerline.sh b/powerline/bindings/bash/powerline.sh index dabacfa9..8e3782d6 100644 --- a/powerline/bindings/bash/powerline.sh +++ b/powerline/bindings/bash/powerline.sh @@ -54,13 +54,14 @@ _powerline_set_prompt() { _powerline_setup_prompt() { VIRTUAL_ENV_DISABLE_PROMPT=1 if test -z "${POWERLINE_COMMAND}" ; then - if which powerline-client &>/dev/null ; then - export POWERLINE_COMMAND=powerline-client - elif which powerline &>/dev/null ; then + if which powerline &>/dev/null ; then export POWERLINE_COMMAND=powerline + elif which powerline-render &>/dev/null ; then + export POWERLINE_COMMAND=powerline-render else # `$0` is set to `-bash` when using SSH so that won't work - export POWERLINE_COMMAND="$(dirname "$BASH_SOURCE")/../../../scripts/powerline" + local powerline_dir="$(dirname "$BASH_SOURCE")/../../.." + export POWERLINE_COMMAND="$powerline_dir/scripts/powerline" fi fi test "x$PROMPT_COMMAND" != "x${PROMPT_COMMAND%_powerline_set_prompt*}" || diff --git a/powerline/bindings/fish/powerline-setup.fish b/powerline/bindings/fish/powerline-setup.fish index 35ec5763..32f50131 100644 --- a/powerline/bindings/fish/powerline-setup.fish +++ b/powerline/bindings/fish/powerline-setup.fish @@ -20,10 +20,10 @@ function powerline-setup if test -z "$POWERLINE_NO_FISH_PROMPT$POWERLINE_NO_SHELL_PROMPT" if test -z "$POWERLINE_COMMAND" - if which powerline-client >/dev/null - set -g -x POWERLINE_COMMAND powerline-client - else if which powerline >/dev/null + if which powerline >/dev/null set -g -x POWERLINE_COMMAND powerline + else if which powerline-render >/dev/null + set -g -x POWERLINE_COMMAND powerline-render else set -g -x POWERLINE_COMMAND (dirname (status -f))/../../../scripts/powerline end diff --git a/powerline/bindings/tcsh/powerline.tcsh b/powerline/bindings/tcsh/powerline.tcsh index 931b9ab0..1ff61cb2 100644 --- a/powerline/bindings/tcsh/powerline.tcsh +++ b/powerline/bindings/tcsh/powerline.tcsh @@ -11,10 +11,10 @@ if ! ( $?POWERLINE_NO_TCSH_TMUX_SUPPORT || $?POWERLINE_NO_SHELL_TMUX_SUPPORT ) t endif if ! ( $?POWERLINE_NO_TCSH_PROMPT || $?POWERLINE_NO_SHELL_PROMPT ) then if ! $?POWERLINE_COMMAND then - if ( { which powerline-client > /dev/null } ) then - setenv POWERLINE_COMMAND powerline-client - else if ( { which powerline > /dev/null } ) then + if ( { which powerline > /dev/null } ) then setenv POWERLINE_COMMAND powerline + else if ( { which powerline-render > /dev/null } ) then + setenv POWERLINE_COMMAND powerline-render else setenv POWERLINE_COMMAND $POWERLINE_SOURCED:h:h:h:h:q/scripts/powerline endif diff --git a/powerline/bindings/tmux/powerline.conf b/powerline/bindings/tmux/powerline.conf index a55b4856..31f7be40 100644 --- a/powerline/bindings/tmux/powerline.conf +++ b/powerline/bindings/tmux/powerline.conf @@ -1,4 +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"' +if-shell 'test -z "$POWERLINE_COMMAND"' 'if-shell "which powerline" "set-environment -g POWERLINE_COMMAND powerline" "set-environment -g POWERLINE_COMMAND powerline-render"' if-shell 'test -z "$POWERLINE_CONFIG_COMMAND"' 'set-environment -g POWERLINE_CONFIG_COMMAND powerline-config' # Don't version-check for this core functionality -- anything too old to diff --git a/powerline/bindings/zsh/powerline.zsh b/powerline/bindings/zsh/powerline.zsh index 096d0ff4..a9717749 100644 --- a/powerline/bindings/zsh/powerline.zsh +++ b/powerline/bindings/zsh/powerline.zsh @@ -124,10 +124,10 @@ _powerline_setup_prompt() { zpython 'del _powerline_setup' else if test -z "${POWERLINE_COMMAND}" ; then - if which powerline-client &>/dev/null ; then - export POWERLINE_COMMAND=powerline-client - elif which powerline &>/dev/null ; then + if which powerline &>/dev/null ; then export POWERLINE_COMMAND=powerline + elif which powerline-render &>/dev/null ; then + export POWERLINE_COMMAND=powerline-render else export POWERLINE_COMMAND="$0:A:h:h:h:h/scripts/powerline" fi From 21ee641a0288eaaffbf18db86e0153f668e3f85f Mon Sep 17 00:00:00 2001 From: ZyX Date: Fri, 22 Nov 2013 20:23:56 +0400 Subject: [PATCH 04/22] Do not use scripts=[] to install powerline at all. --- setup.py | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/setup.py b/setup.py index 6dd474bd..9e7013ae 100755 --- a/setup.py +++ b/setup.py @@ -14,7 +14,6 @@ except IOError: README = '' OLD_PYTHON = sys.version_info < (2, 7) -PYTHON_3 = sys.version_info > (2,) def compile_client(): @@ -44,16 +43,31 @@ setup( author='Kim Silkebaekken', author_email='kim.silkebaekken+vim@gmail.com', url='https://github.com/Lokaltog/powerline', - # FIXME Python 3 doesn't allow compiled C files to be included in the - # scripts list below. This is because Python 3 distutils tries to decode the - # file to ASCII, and fails when powerline-client is a binary. + # XXX Python 3 doesn't allow compiled C files to be included in the scripts + # list below. This is because Python 3 distutils tries to decode the file to + # ASCII, and fails when powerline-client is a binary. + # + # XXX Python 2 fucks up script contents*. Not using it to install scripts + # any longer. + # * Consider the following input: + # % alias hex1=$'hexdump -e \'"" 1/1 "%02X\n"\'' + # % diff <(hex1 ./scripts/powerline) <(hex1 ~/.local/bin/powerline) + # This will show output like + # 375c375 + # < 0D + # --- + # > 0A + # (repeated, with diff segment header numbers growing up). + # + # FIXME Current solution does not work with `pip install -e`. Still better + # then solution that is not working at all. scripts=[ 'scripts/powerline-lint', 'scripts/powerline-daemon', 'scripts/powerline-render', 'scripts/powerline-config', - ] + ([] if PYTHON_3 else ['scripts/powerline']), - data_files=([('bin', ['scripts/powerline'])] if PYTHON_3 else None), + ], + data_files=[('bin', ['scripts/powerline'])], keywords='', packages=find_packages(exclude=('tests', 'tests.*')), include_package_data=True, From a27f90df62beb25289cbd2b989b7734eb6fc304e Mon Sep 17 00:00:00 2001 From: ZyX Date: Fri, 22 Nov 2013 20:31:04 +0400 Subject: [PATCH 05/22] Add a note about not fully working --editable to linux.rst --- docs/source/installation/linux.rst | 5 +++++ docs/source/installation/osx.rst | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/docs/source/installation/linux.rst b/docs/source/installation/linux.rst index 74e6f74f..e8ff6d72 100644 --- a/docs/source/installation/linux.rst +++ b/docs/source/installation/linux.rst @@ -30,6 +30,11 @@ Plugin installation project is currently unavailable on the PyPI due to a naming conflict with an unrelated project. +.. note:: If you are powerline developer you should be aware that ``pip install + --editable`` does not currently fully work. If you + install powerline this way you will be missing ``powerline`` executable and + need to symlink it. It will be located in ``scripts/powerline``. + Font installation ================= diff --git a/docs/source/installation/osx.rst b/docs/source/installation/osx.rst index aa029f11..c991eac7 100644 --- a/docs/source/installation/osx.rst +++ b/docs/source/installation/osx.rst @@ -26,6 +26,11 @@ Python package project is currently unavailable on the PyPI due to a naming conflict with an unrelated project. +.. note:: If you are powerline developer you should be aware that ``pip install + --editable`` does not currently fully work. If you + install powerline this way you will be missing ``powerline`` executable and + need to symlink it. It will be located in ``scripts/powerline``. + Vim installation ---------------- From 7db428667cb0fdc890c5f9c62ad2e29b97284d3c Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 23 Nov 2013 13:20:05 +0400 Subject: [PATCH 06/22] Get rid of modeline E518 error --- client/powerline.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/powerline.c b/client/powerline.c index cef562ec..a60743a7 100644 --- a/client/powerline.c +++ b/client/powerline.c @@ -1,4 +1,5 @@ -/* vim:fileencoding=utf-8:noet */ +/* vim:fileencoding=utf-8:noet + */ #include #include From e613beb8df449f18d7d066ff98164674b39c8485 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 23 Nov 2013 13:54:23 +0400 Subject: [PATCH 07/22] Add shell version of powerline-client MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Note: this shell script is still faster then client/powerline.py. `time` reports 0.00, 0.01, 0.02÷0.03 for powerline, powerline.sh and powerline.py respectively (run with `./client/powerline* tmux right`). Note: does not work in busybox as env there does not support -0 argument. Requires sed, id (for dash as $UID is not available there), env, printf and socat. Is not currently handled by setup.py. --- client/powerline.sh | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100755 client/powerline.sh diff --git a/client/powerline.sh b/client/powerline.sh new file mode 100755 index 00000000..d1657738 --- /dev/null +++ b/client/powerline.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +ADDRESS="powerline-ipc-${UID:-`id -u`}" + +# Warning: env -0 does not work in busybox. Consider switching to parsing +# `set` output in this case +( + for argv in "$@" ; do + printf '%s\0' "$argv" + done + env -0 | sed 's/\(\x00\)\([^\x00]\)\|^/\1--env=\2/g' + printf -- '--cwd=%s\0' "$PWD" +) | socat -t 10 - abstract-client:"$ADDRESS" From e37b13cc4411b5fe63404b029676df79814cff1c Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 2 Aug 2014 18:56:44 +0400 Subject: [PATCH 08/22] Remove compiled binary from repository --- .gitignore | 2 ++ client/powerline | Bin 10732 -> 0 bytes 2 files changed, 2 insertions(+) delete mode 100755 client/powerline diff --git a/.gitignore b/.gitignore index 7468a1a5..dbae1ed8 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,5 @@ dist build message.fail + +client/powerline diff --git a/client/powerline b/client/powerline deleted file mode 100755 index fd6de02466fadefde0a29997f5b142205dd85172..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10732 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 LQ1P3LRsVkg?!G}> From 3b060562e29264f0b51a6a1325a724ef980105e0 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 2 Aug 2014 19:46:04 +0400 Subject: [PATCH 09/22] Fix UnicodeDecodeError in Python version of powerline client --- client/powerline.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/powerline.py b/client/powerline.py index bbcfffbe..a00c38cd 100755 --- a/client/powerline.py +++ b/client/powerline.py @@ -54,7 +54,7 @@ else: args.append(b'--cwd=' + cwd) -env = (k + '=' + v for k, v in os.environ.items()) +env = (k + b'=' + v for k, v in os.environ.items()) env = (x if isinstance(x, bytes) else x.encode(fenc, 'replace') for x in env) args.extend((b'--env=' + x for x in env)) From 95dcef8bf8b42bbd5118bccf37bb14f3e88f0cd1 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 2 Aug 2014 19:47:03 +0400 Subject: [PATCH 10/22] Some style fixes --- client/powerline.py | 2 +- scripts/powerline-daemon | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/powerline.py b/client/powerline.py index a00c38cd..89e56f8e 100755 --- a/client/powerline.py +++ b/client/powerline.py @@ -17,7 +17,7 @@ use_filesystem = 'darwin' in platform # use_filesystem = True del platform -address = ('/tmp/powerline-ipc-%d' if use_filesystem else '\0powerline-ipc-%d')%os.getuid() +address = ('/tmp/powerline-ipc-%d' if use_filesystem else '\0powerline-ipc-%d') % os.getuid() sock = socket.socket(family=socket.AF_UNIX) diff --git a/scripts/powerline-daemon b/scripts/powerline-daemon index b7627cc4..e110625f 100755 --- a/scripts/powerline-daemon +++ b/scripts/powerline-daemon @@ -324,8 +324,8 @@ def lockpidfile(): import fcntl import atexit import stat - fd = os.open(pidfile, os.O_WRONLY|os.O_CREAT, - stat.S_IRUSR|stat.S_IWUSR|stat.S_IRGRP|stat.S_IROTH) + fd = os.open(pidfile, os.O_WRONLY | os.O_CREAT, + stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH) try: fcntl.lockf(fd, fcntl.LOCK_EX | fcntl.LOCK_NB) except EnvironmentError: From 925d3eb0e44e41880eb5c66c0d58094e4b8d6c6e Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 2 Aug 2014 19:48:07 +0400 Subject: [PATCH 11/22] Show exception in setup.py and try to fall back to powerline.sh --- setup.py | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/setup.py b/setup.py index 9e7013ae..16561d85 100755 --- a/setup.py +++ b/setup.py @@ -4,6 +4,7 @@ from __future__ import unicode_literals import os import sys import subprocess +import logging from setuptools import setup, find_packages @@ -28,11 +29,26 @@ def compile_client(): try: compile_client() -except Exception: +except Exception as e: + print('Compiling C version of powerline-client failed') + logging.exception(e) # FIXME Catch more specific exceptions import shutil - print('Compiling C version of powerline-client failed, using Python version instead') - shutil.copyfile('client/powerline.py', 'scripts/powerline') + if hasattr(shutil, 'which'): + which = shutil.which + else: + sys.path.append(CURRENT_DIR) + from powerline.lib import which + if which('socat') and which('sed') and which('sh'): + print('Using powerline.sh script instead of C version (requires socat, sed and sh)') + shutil.copyfile('client/powerline.sh', 'scripts/powerline') + can_use_scripts = True + else: + print('Using powerline.py script instead of C version') + shutil.copyfile('client/powerline.py', 'scripts/powerline') + can_use_scripts = True +else: + can_use_scripts = False setup( name='Powerline', @@ -66,8 +82,8 @@ setup( 'scripts/powerline-daemon', 'scripts/powerline-render', 'scripts/powerline-config', - ], - data_files=[('bin', ['scripts/powerline'])], + ] + (['scripts/powerline'] if can_use_scripts else []), + data_files=(None if can_use_scripts else (('bin', ['scripts/powerline']),)), keywords='', packages=find_packages(exclude=('tests', 'tests.*')), include_package_data=True, From 05384e31e446bb36d0ce914bf7d8682e98310afc Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 2 Aug 2014 20:07:55 +0400 Subject: [PATCH 12/22] Add `powerline-config shell command` and use it in all shell bindings --- powerline/bindings/bash/powerline.sh | 8 +-- powerline/bindings/config.py | 37 ++++++++++- powerline/bindings/fish/powerline-setup.fish | 9 ++- powerline/bindings/shell/powerline.sh | 11 ++-- powerline/bindings/tcsh/powerline.tcsh | 8 +-- powerline/bindings/zsh/powerline.zsh | 11 ++-- powerline/config.py | 3 +- powerline/lib/shell.py | 69 ++++++++++++++++++++ scripts/powerline-config | 13 ++++ 9 files changed, 140 insertions(+), 29 deletions(-) diff --git a/powerline/bindings/bash/powerline.sh b/powerline/bindings/bash/powerline.sh index 8e3782d6..501b48aa 100644 --- a/powerline/bindings/bash/powerline.sh +++ b/powerline/bindings/bash/powerline.sh @@ -54,14 +54,12 @@ _powerline_set_prompt() { _powerline_setup_prompt() { VIRTUAL_ENV_DISABLE_PROMPT=1 if test -z "${POWERLINE_COMMAND}" ; then - if which powerline &>/dev/null ; then - export POWERLINE_COMMAND=powerline - elif which powerline-render &>/dev/null ; then - export POWERLINE_COMMAND=powerline-render + 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" + export POWERLINE_COMMAND="$($powerline_dir/scripts/powerline-config shell command)" fi fi test "x$PROMPT_COMMAND" != "x${PROMPT_COMMAND%_powerline_set_prompt*}" || diff --git a/powerline/bindings/config.py b/powerline/bindings/config.py index 3591903a..846c66f0 100644 --- a/powerline/bindings/config.py +++ b/powerline/bindings/config.py @@ -6,11 +6,12 @@ from collections import namedtuple import os import subprocess import re +import sys -from powerline.config import TMUX_CONFIG_DIRECTORY +from powerline.config import POWERLINE_ROOT, TMUX_CONFIG_DIRECTORY from powerline.lib.config import ConfigLoader from powerline import generate_config_finder, load_config, create_logger, PowerlineLogger, finish_common_config -from powerline.lib.shell import run_cmd +from powerline.lib.shell import run_cmd, which TmuxVersionInfo = namedtuple('TmuxVersionInfo', ('major', 'minor', 'suffix')) @@ -119,3 +120,35 @@ def create_powerline_logger(args): common_config = finish_common_config(config['common']) logger = create_logger(common_config) return PowerlineLogger(use_daemon_threads=True, logger=logger, ext='config') + + +def check_command(cmd): + if which(cmd): + print(cmd) + sys.exit(0) + + +def shell_command(pl, args): + '''Deduce which command to use for ``powerline`` + + Candidates: + + * ``powerline``. Present only when installed system-wide. + * ``{powerline_root}/scripts/powerline``. Present after ``pip install -e`` + was run and C client was compiled (in this case ``pip`` does not install + binary file). + * ``{powerline_root}/client/powerline.sh``. Useful when ``sh``, ``sed`` and + ``socat`` are present, but ``pip`` or ``setup.py`` was not run. + * ``{powerline_root}/client/powerline.py``. Like above, but when one of + ``sh``, ``sed`` and ``socat`` was not present. + * ``powerline-render``. Should not really ever be used. + * ``{powerline_root}/scripts/powerline-render``. Same. + ''' + check_command('powerline') + check_command(os.path.join(POWERLINE_ROOT, 'scripts', 'powerline')) + if which('sh') and which('sed') and which('socat'): + check_command(os.path.join(POWERLINE_ROOT, 'client', 'powerline.sh')) + check_command(os.path.join(POWERLINE_ROOT, 'client', 'powerline.py')) + check_command('powerline-render') + check_command(os.path.join(POWERLINE_ROOT, 'scripts', 'powerline-render')) + sys.exit(1) diff --git a/powerline/bindings/fish/powerline-setup.fish b/powerline/bindings/fish/powerline-setup.fish index 32f50131..89fe9778 100644 --- a/powerline/bindings/fish/powerline-setup.fish +++ b/powerline/bindings/fish/powerline-setup.fish @@ -20,12 +20,11 @@ function powerline-setup if test -z "$POWERLINE_NO_FISH_PROMPT$POWERLINE_NO_SHELL_PROMPT" if test -z "$POWERLINE_COMMAND" - if which powerline >/dev/null - set -g -x POWERLINE_COMMAND powerline - else if which powerline-render >/dev/null - set -g -x POWERLINE_COMMAND powerline-render + if false ;and which powerline-config >/dev/null + set -g -x POWERLINE_COMMAND (powerline-config shell command) else - set -g -x POWERLINE_COMMAND (dirname (status -f))/../../../scripts/powerline + set -l powerline_dir (dirname (status -f))/../../.. + set -g -x POWERLINE_COMMAND (eval $powerline_dir/scripts/powerline-config shell command) end end function --on-variable POWERLINE_COMMAND _powerline_update diff --git a/powerline/bindings/shell/powerline.sh b/powerline/bindings/shell/powerline.sh index 6f45ffde..ae5c035f 100644 --- a/powerline/bindings/shell/powerline.sh +++ b/powerline/bindings/shell/powerline.sh @@ -1,3 +1,4 @@ +_POWERLINE_SOURCED="$_" _powerline_columns_fallback() { if which stty >/dev/null ; then # Ksh does not have “local” built-in @@ -97,13 +98,11 @@ _powerline_set_set_jobs() { _powerline_set_command() { if test -z "${POWERLINE_COMMAND}" ; then - if which powerline-client >/dev/null ; then - export POWERLINE_COMMAND=powerline-client - elif which powerline >/dev/null ; then - export POWERLINE_COMMAND=powerline + 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 - export POWERLINE_COMMAND="$(dirname "$BASH_SOURCE")/../../../scripts/powerline" + local powerline_dir="$(dirname "$POWERLINE_SOURCED")/../../.." + export POWERLINE_COMMAND="$($powerline_dir/scripts/powerline-config shell command)" fi fi } diff --git a/powerline/bindings/tcsh/powerline.tcsh b/powerline/bindings/tcsh/powerline.tcsh index 1ff61cb2..69f34a2e 100644 --- a/powerline/bindings/tcsh/powerline.tcsh +++ b/powerline/bindings/tcsh/powerline.tcsh @@ -11,12 +11,10 @@ if ! ( $?POWERLINE_NO_TCSH_TMUX_SUPPORT || $?POWERLINE_NO_SHELL_TMUX_SUPPORT ) t endif if ! ( $?POWERLINE_NO_TCSH_PROMPT || $?POWERLINE_NO_SHELL_PROMPT ) then if ! $?POWERLINE_COMMAND then - if ( { which powerline > /dev/null } ) then - setenv POWERLINE_COMMAND powerline - else if ( { which powerline-render > /dev/null } ) then - setenv POWERLINE_COMMAND powerline-render + if ( { which powerline-config > /dev/null } ) then + setenv POWERLINE_COMMAND "`powerline-config shell command`" else - setenv POWERLINE_COMMAND $POWERLINE_SOURCED:h:h:h:h:q/scripts/powerline + setenv POWERLINE_COMMAND "`$POWERLINE_SOURCED[2]:h:h:h:h:q/scripts/powerline-config shell command`" endif endif diff --git a/powerline/bindings/zsh/powerline.zsh b/powerline/bindings/zsh/powerline.zsh index a9717749..5439167a 100644 --- a/powerline/bindings/zsh/powerline.zsh +++ b/powerline/bindings/zsh/powerline.zsh @@ -1,3 +1,5 @@ +_POWERLINE_SOURCED="$0:A" + _powerline_columns_fallback() { if which stty &>/dev/null ; then local cols="$(stty size 2>/dev/null)" @@ -124,12 +126,11 @@ _powerline_setup_prompt() { zpython 'del _powerline_setup' else if test -z "${POWERLINE_COMMAND}" ; then - if which powerline &>/dev/null ; then - export POWERLINE_COMMAND=powerline - elif which powerline-render &>/dev/null ; then - export POWERLINE_COMMAND=powerline-render + if which powerline-config &>/dev/null ; then + export POWERLINE_COMMAND="$(powerline-config shell command)" else - export POWERLINE_COMMAND="$0:A:h:h:h:h/scripts/powerline" + local powerline_dir="$POWERLINE_SOURCED:h:h:h:h" + export POWERLINE_COMMAND="$($powerline_dir/scripts/powerline-config shell command)" fi fi diff --git a/powerline/config.py b/powerline/config.py index 53e530f4..c895da5e 100644 --- a/powerline/config.py +++ b/powerline/config.py @@ -3,6 +3,7 @@ from __future__ import absolute_import, unicode_literals, print_function import os -BINDINGS_DIRECTORY = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'bindings') +POWERLINE_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +BINDINGS_DIRECTORY = os.path.join(POWERLINE_ROOT, 'powerline', 'bindings') TMUX_CONFIG_DIRECTORY = os.path.join(BINDINGS_DIRECTORY, 'tmux') DEFAULT_SYSTEM_CONFIG_DIR = None diff --git a/powerline/lib/shell.py b/powerline/lib/shell.py index ea777770..4418c3d9 100644 --- a/powerline/lib/shell.py +++ b/powerline/lib/shell.py @@ -6,6 +6,7 @@ from subprocess import Popen, PIPE from locale import getlocale, getdefaultlocale, LC_MESSAGES from functools import partial import sys +import os if sys.platform.startswith('win32'): @@ -60,3 +61,71 @@ def readlines(cmd, cwd): with p.stdout: for line in p.stdout: yield line[:-1].decode(encoding) + + +try: + from shutil import which +except ImportError: + # shutil.which was added in python-3.3. Here is what was added: + # Lib/shutil.py, commit 5abe28a9c8fe701ba19b1db5190863384e96c798 + def which(cmd, mode=os.F_OK | os.X_OK, path=None): # NOQA + """Given a command, mode, and a PATH string, return the path which + conforms to the given mode on the PATH, or None if there is no such + file. + + `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result + of os.environ.get("PATH"), or can be overridden with a custom search + path. + + """ + # Check that a given file can be accessed with the correct mode. + # Additionally check that `file` is not a directory, as on Windows + # directories pass the os.access check. + def _access_check(fn, mode): + return (os.path.exists(fn) and os.access(fn, mode) + and not os.path.isdir(fn)) + + # If we're given a path with a directory part, look it up directly rather + # than referring to PATH directories. This includes checking relative to the + # current directory, e.g. ./script + if os.path.dirname(cmd): + if _access_check(cmd, mode): + return cmd + return None + + if path is None: + path = os.environ.get("PATH", os.defpath) + if not path: + return None + path = path.split(os.pathsep) + + if sys.platform == "win32": + # The current directory takes precedence on Windows. + if not os.curdir in path: + path.insert(0, os.curdir) + + # PATHEXT is necessary to check on Windows. + pathext = os.environ.get("PATHEXT", "").split(os.pathsep) + # See if the given file matches any of the expected path extensions. + # This will allow us to short circuit when given "python.exe". + # If it does match, only test that one, otherwise we have to try + # others. + if any(cmd.lower().endswith(ext.lower()) for ext in pathext): + files = [cmd] + else: + files = [cmd + ext for ext in pathext] + else: + # On other platforms you don't have things like PATHEXT to tell you + # what file suffixes are executable, so just pass on cmd as-is. + files = [cmd] + + seen = set() + for dir in path: + normdir = os.path.normcase(dir) + if not normdir in seen: + seen.add(normdir) + for thefile in files: + name = os.path.join(dir, thefile) + if _access_check(name, mode): + return name + return None diff --git a/scripts/powerline-config b/scripts/powerline-config index bcece7e6..2e636437 100755 --- a/scripts/powerline-config +++ b/scripts/powerline-config @@ -18,6 +18,11 @@ TMUX_ACTIONS = { } +SHELL_ACTIONS = { + 'command': config.shell_command, +} + + if __name__ == '__main__': parser = argparse.ArgumentParser(description=__doc__) subparsers = parser.add_subparsers() @@ -30,6 +35,14 @@ if __name__ == '__main__': help='If action is "source" then version-specific tmux configuration files are sourced.' ) + 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)), + help='If action is "command" then preferred powerline command is output', + ) + args = parser.parse_args() pl = config.create_powerline_logger(args) From 8374a66ca7ac9f2b41683aadd59d3d5541ed02fc Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 2 Aug 2014 20:16:38 +0400 Subject: [PATCH 13/22] Also use the same code for tmux --- powerline/bindings/config.py | 35 ++++++++++++++++++-------- powerline/bindings/tmux/powerline.conf | 1 - 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/powerline/bindings/config.py b/powerline/bindings/config.py index 846c66f0..5899e740 100644 --- a/powerline/bindings/config.py +++ b/powerline/bindings/config.py @@ -111,6 +111,10 @@ def source_tmux_files(pl, args): version = get_tmux_version(pl) for fname, priority in sorted(get_tmux_configs(version), key=(lambda v: v[1])): run_tmux_command('source', fname) + cmd = deduce_command() + if cmd: + run_tmux_command('set-environment', '-g', 'POWERLINE_COMMAND', deduce_command()) + run_tmux_command('refresh-client') def create_powerline_logger(args): @@ -124,11 +128,10 @@ def create_powerline_logger(args): def check_command(cmd): if which(cmd): - print(cmd) - sys.exit(0) + return cmd -def shell_command(pl, args): +def deduce_command(): '''Deduce which command to use for ``powerline`` Candidates: @@ -144,11 +147,21 @@ def shell_command(pl, args): * ``powerline-render``. Should not really ever be used. * ``{powerline_root}/scripts/powerline-render``. Same. ''' - check_command('powerline') - check_command(os.path.join(POWERLINE_ROOT, 'scripts', 'powerline')) - if which('sh') and which('sed') and which('socat'): - check_command(os.path.join(POWERLINE_ROOT, 'client', 'powerline.sh')) - check_command(os.path.join(POWERLINE_ROOT, 'client', 'powerline.py')) - check_command('powerline-render') - check_command(os.path.join(POWERLINE_ROOT, 'scripts', 'powerline-render')) - sys.exit(1) + return ( + None + or check_command('powerline') + or check_command(os.path.join(POWERLINE_ROOT, 'scripts', 'powerline')) + or ((which('sh') and which('sed') and which('socat')) + and check_command(os.path.join(POWERLINE_ROOT, 'client', 'powerline.sh'))) + or check_command(os.path.join(POWERLINE_ROOT, 'client', 'powerline.py')) + or check_command('powerline-render') + or check_command(os.path.join(POWERLINE_ROOT, 'scripts', 'powerline-render')) + ) + + +def shell_command(pl, args): + cmd = deduce_command() + if cmd: + print(cmd) + else: + sys.exit(1) diff --git a/powerline/bindings/tmux/powerline.conf b/powerline/bindings/tmux/powerline.conf index 31f7be40..81928706 100644 --- a/powerline/bindings/tmux/powerline.conf +++ b/powerline/bindings/tmux/powerline.conf @@ -1,4 +1,3 @@ -if-shell 'test -z "$POWERLINE_COMMAND"' 'if-shell "which powerline" "set-environment -g POWERLINE_COMMAND powerline" "set-environment -g POWERLINE_COMMAND powerline-render"' if-shell 'test -z "$POWERLINE_CONFIG_COMMAND"' 'set-environment -g POWERLINE_CONFIG_COMMAND powerline-config' # Don't version-check for this core functionality -- anything too old to From 9290c2a23bcbae8e756b676645e1fd32f8f452ab Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 2 Aug 2014 20:35:23 +0400 Subject: [PATCH 14/22] Make daemon work with aboveleft shell key --- powerline/shell.py | 25 ++++++++++++++++++++++++ scripts/powerline-daemon | 41 +++++++++++++++++++++++----------------- scripts/powerline-render | 27 +++++--------------------- 3 files changed, 54 insertions(+), 39 deletions(-) diff --git a/powerline/shell.py b/powerline/shell.py index bffa1df8..8cfb2de6 100644 --- a/powerline/shell.py +++ b/powerline/shell.py @@ -1,5 +1,7 @@ # vim:fileencoding=utf-8:noet +import os + from powerline import Powerline from powerline.lib import mergedicts, parsedotval @@ -73,3 +75,26 @@ def finish_args(args): args.theme_option = {} if args.renderer_arg: args.renderer_arg = mergeargs((parsedotval(v) for v in args.renderer_arg)) + + +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=os.environ.get('_POWERLINE_MODE'), + ): + write(line) + write('\n') + args.side = args.side[len('above'):] + + if args.side: + rendered = powerline.render( + width=args.width, + side=args.side, + segment_info=segment_info, + mode=os.environ.get('_POWERLINE_MODE'), + ) + write(rendered) diff --git a/scripts/powerline-daemon b/scripts/powerline-daemon index e110625f..7ffcdb2f 100755 --- a/scripts/powerline-daemon +++ b/scripts/powerline-daemon @@ -12,8 +12,9 @@ from signal import signal, SIGTERM from time import sleep from functools import partial from locale import getpreferredencoding +from io import StringIO -from powerline.shell import get_argparser, finish_args, ShellPowerline +from powerline.shell import get_argparser, finish_args, ShellPowerline, write_output from powerline.lib.monotonic import monotonic is_daemon = False @@ -77,35 +78,41 @@ def render(args): 'environ': environ, 'args': args, } - key = (args.ext[0], args.renderer_module, - tuple(args.config) if args.config else None, - tuple(args.theme_option) if args.theme_option else None,) - if args.renderer_arg: - segment_info.update(args.renderer_arg) + key = ( + args.ext[0], + args.renderer_module, + tuple(args.config) if args.config else None, + tuple(args.theme_option) if args.theme_option else None, + tuple(args.renderer_arg) if args.renderer_arg else None, + ) finish_args(args) - pl = None + powerline = None try: - pl = powerlines[key] + powerline = powerlines[key] except KeyError: try: - pl = powerlines[key] = PowerlineDaemon( + powerline = powerlines[key] = PowerlineDaemon( args, logger=logger, - config_loader=config_loader + config_loader=config_loader, + run_once=False, ) + if logger is None: + logger = powerline.logger + if config_loader is None: + config_loader = powerline.config_loader except SystemExit: # Somebody thought raising system exit was a good idea, return '' except Exception as e: - if pl: - pl.pl.exception('Failed to render {0}: {1}', str(key), str(e)) + if powerline: + powerline.pl.exception('Failed to render {0}: {1}', str(key), str(e)) else: return 'Failed to render {0}: {1}'.format(str(key), str(e)) - if logger is None: - logger = pl.logger - if config_loader is None: - config_loader = pl.config_loader - return pl.render(width=args.width, side=args.side, segment_info=segment_info) + s = StringIO() + write_output(args, powerline, segment_info, s.write) + s.seek(0) + return s.read() def eintr_retry_call(func, *args, **kwargs): diff --git a/scripts/powerline-render b/scripts/powerline-render index 8b125217..bdedb1b7 100755 --- a/scripts/powerline-render +++ b/scripts/powerline-render @@ -5,10 +5,11 @@ import sys import os try: - from powerline.shell import ShellPowerline, get_argparser, finish_args + from powerline.shell import ShellPowerline, get_argparser, finish_args, write_output except ImportError: sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(os.path.realpath(__file__))))) - from powerline.shell import ShellPowerline, get_argparser, finish_args # NOQA + from powerline.shell import ShellPowerline, get_argparser, finish_args, write_output # NOQA + def write(output): try: @@ -16,28 +17,10 @@ def write(output): except UnicodeEncodeError: sys.stdout.write(output.encode('utf-8')) + if __name__ == '__main__': args = get_argparser(description=__doc__).parse_args() finish_args(args) powerline = ShellPowerline(args, run_once=True) segment_info = {'args': args, 'environ': os.environ} - 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=os.environ.get('_POWERLINE_MODE'), - ): - write(line) - sys.stdout.write('\n') - args.side = args.side[len('above'):] - - if args.side: - rendered = powerline.render( - width=args.width, - side=args.side, - segment_info=segment_info, - mode=os.environ.get('_POWERLINE_MODE'), - ) - write(rendered) + write_output(args, powerline, segment_info, write) From fed43e8af50a428ee2d2058d9a682974918df578 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 2 Aug 2014 21:02:26 +0400 Subject: [PATCH 15/22] Run shell tests with and without daemon --- tests/test_shells/postproc.py | 7 +-- tests/test_shells/screenrc | 2 +- tests/test_shells/test.sh | 92 +++++++++++++++++++------------- tests/test_shells/zsh.daemon.ok | Bin 0 -> 11672 bytes 4 files changed, 61 insertions(+), 40 deletions(-) create mode 100644 tests/test_shells/zsh.daemon.ok diff --git a/tests/test_shells/postproc.py b/tests/test_shells/postproc.py index ce68c9d5..f34fa81c 100755 --- a/tests/test_shells/postproc.py +++ b/tests/test_shells/postproc.py @@ -8,9 +8,10 @@ import sys import codecs -shell = sys.argv[1] -fname = os.path.join('tests', 'shell', shell + '.full.log') -new_fname = os.path.join('tests', 'shell', shell + '.log') +test_type = sys.argv[1] +shell = sys.argv[2] +fname = os.path.join('tests', 'shell', shell + '.' + test_type + '.full.log') +new_fname = os.path.join('tests', 'shell', shell + '.' + test_type + '.log') pid_fname = os.path.join('tests', 'shell', '3rd', 'pid') diff --git a/tests/test_shells/screenrc b/tests/test_shells/screenrc index d998652a..7c9674e5 100644 --- a/tests/test_shells/screenrc +++ b/tests/test_shells/screenrc @@ -1,3 +1,3 @@ width 1024 height 1 -logfile "tests/shell/${SH}.full.log" +logfile "tests/shell/${SH}.${TEST_TYPE}.full.log" diff --git a/tests/test_shells/test.sh b/tests/test_shells/test.sh index b0f30fed..656f2f71 100755 --- a/tests/test_shells/test.sh +++ b/tests/test_shells/test.sh @@ -3,17 +3,23 @@ FAILED=0 ONLY_SHELL="$1" check_screen_log() { - SH="$1" - if test -e tests/test_shells/${SH}.ok ; then - diff -u tests/test_shells/${SH}.ok tests/shell/${SH}.log + TEST_TYPE="$1" + SH="$2" + if test -e tests/test_shells/${SH}.${TEST_TYPE}.ok ; then + diff -a -u tests/test_shells/${SH}.${TEST_TYPE}.ok tests/shell/${SH}.${TEST_TYPE}.log + return $? + elif test -e tests/test_shells/${SH}.ok ; then + diff -a -u tests/test_shells/${SH}.ok tests/shell/${SH}.${TEST_TYPE}.log return $? else - cat tests/shell/${SH}.log + cat tests/shell/${SH}.${TEST_TYPE}.log return 1 fi } run_test() { + TEST_TYPE="$1" + shift SH="$1" SESNAME="powerline-shell-test-${SH}-$$" ARGS=( "$@" ) @@ -32,6 +38,7 @@ run_test() { fi fi + export TEST_TYPE export SH screen -L -c tests/test_shells/screenrc -d -m -S "$SESNAME" \ @@ -59,21 +66,21 @@ run_test() { while screen -S "$SESNAME" -X blankerprg "" > /dev/null ; do sleep 0.1s done - ./tests/test_shells/postproc.py ${SH} - if ! check_screen_log ${SH} ; then + ./tests/test_shells/postproc.py ${TEST_TYPE} ${SH} + if ! check_screen_log ${TEST_TYPE} ${SH} ; then echo '____________________________________________________________' # Repeat the diff to make it better viewable in travis output echo "Diff (cat -v):" echo '============================================================' - check_screen_log ${SH} | cat -v + check_screen_log ${TEST_TYPE} ${SH} | cat -v echo '____________________________________________________________' echo "Failed ${SH}. Full output:" echo '============================================================' - cat tests/shell/${SH}.full.log + cat tests/shell/${SH}.${TEST_TYPE}.full.log echo '____________________________________________________________' echo "Full output (cat -v):" echo '============================================================' - cat -v tests/shell/${SH}.full.log + cat -v tests/shell/${SH}.${TEST_TYPE}.full.log echo '____________________________________________________________' case ${SH} in *ksh) @@ -112,39 +119,52 @@ mkdir tests/shell/3rd/'(echo)' mkdir tests/shell/3rd/'$(echo)' mkdir tests/shell/3rd/'`echo`' -if ! run_test bash --norc --noprofile -i ; then - FAILED=1 -fi - -if ! run_test zsh -f -i ; then - FAILED=1 -fi - mkdir tests/shell/fish_home export XDG_CONFIG_HOME="$PWD/tests/shell/fish_home" -if ! run_test fish -i ; then - FAILED=1 -fi - -if ! run_test tcsh -f -i ; then - FAILED=1 -fi - -if ! run_test bb -i ; then - FAILED=1 -fi unset ENV -if ! run_test mksh -i ; then - FAILED=1 -fi +powerline-daemon -k || true +sleep 1s -if ! run_test dash -i ; then - # dash tests are not stable, see #931 - # FAILED=1 - true -fi +for TEST_TYPE in "daemon" "nodaemon" ; do + if test $TEST_TYPE == daemon ; then + sh -c 'echo $$ > tests/shell/daemon_pid; ./scripts/powerline-daemon -f &>tests/shell/daemon_log' & + fi + if ! run_test $TEST_TYPE bash --norc --noprofile -i ; then + FAILED=1 + fi + + if ! run_test $TEST_TYPE zsh -f -i ; then + FAILED=1 + fi + + if ! run_test $TEST_TYPE fish -i ; then + FAILED=1 + fi + + if ! run_test $TEST_TYPE tcsh -f -i ; then + FAILED=1 + fi + + if ! run_test $TEST_TYPE bb -i ; then + FAILED=1 + fi + + if ! run_test $TEST_TYPE mksh -i ; then + FAILED=1 + fi + + if ! run_test $TEST_TYPE dash -i ; then + # dash tests are not stable, see #931 + # FAILED=1 + true + fi + if test $TEST_TYPE == daemon ; then + ./scripts/powerline-daemon -k + wait $(cat tests/shell/daemon_pid) + fi +done test "x$ONLY_SHELL" = "x" && rm -r tests/shell exit $FAILED diff --git a/tests/test_shells/zsh.daemon.ok b/tests/test_shells/zsh.daemon.ok new file mode 100644 index 0000000000000000000000000000000000000000..3e4000aed992ae14f684fbc9e44e4f914e4d5377 GIT binary patch literal 11672 zcmeHNTW;Dw6zw-#$j?=3N>Izg50X|Wm1u$#ssIsr^uwXS;7M`uBeET;D9TTM``Io4 zbpvg;z*4e+tf4cuNe2=fQ&qts0}|jF-!U`i-ZN+JOkzpS8%wevk`D=gyvGGa@pZ9K z6oh;qQOq4bfJ|Oz~j6q5Eh&>!^_Zq`3(OAaS~>0M3fS$m=lnlNf|M z%@}+HnF#o08G0UNOhqrg;dfAJ?CqDfkIJ=!^<{3WUM=Ucea&`}*>`e|WuOeXI#u)x zF41huG?3{o#{us(i6)YO>qlI?CK*@Xz7H|oPU{2Z*0?2~e;I+}>9R1!0F&f#o4{!g zii2OUX_$zfSy5~&P8TvANTE*G0*-roqNz}XFI`PX;M%7MU#J#1IzlIq&+?9UZK4#s zNXUE>b}E|;{6{kh1akNe0;R<=PjRFtk0+$tv7$SOp}y#-6KBD6GJR205DeN?2=z>O zii332aY1Q!Kr=x_$MC7E!RMYH<~`#ShG%lG5i+Mg{QG8^NY-eRy;H4)=my}I&;A&v zh3Qe-MoMoXdZSt;cIKDE`9J!hr|CMhI*JQeY__nV^wlNrc#0BUf{ScJGZh!90RJpdnOi*?fij^Q zaB6Uw+pIMBSmYbxysn&2cJQMtivmumhl(ST-_7Pc90i7>ucD{s3Fn04*lxrf0@ued zbtoS;Q;bf->2y925@;d?Vk((r5XLeJlgVfRK9}2;uChQ3_DW;Mr2#t8pj;u#?KF$W zSjM9dPBb7nh9uc^7@c2;Sxg4#M1!(LVzR|zGL|vvgA)ZvCR4*@YJ5*5?9@M$8{3sy z`DmkFt(Iz=>np(BDwO$GQWLmy?)-LDp?Q%z($TSNnfloUq;Y1ct(j^Mok6A_3&$7{ z<=7cB`n=Wx9`uUC0k5Yx?#$uo`GO9zS(oZF9*kiFKc|8BHZjQ_<~{qE54NfF6lupl G9P$SVyM#di literal 0 HcmV?d00001 From f3d972849ebedf0993d42b5f85e2fe6ce16245f4 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 2 Aug 2014 21:10:15 +0400 Subject: [PATCH 16/22] Fall back to powerline-render when using powerline.sh --- client/powerline.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/client/powerline.sh b/client/powerline.sh index d1657738..a56bc296 100755 --- a/client/powerline.sh +++ b/client/powerline.sh @@ -10,4 +10,8 @@ ADDRESS="powerline-ipc-${UID:-`id -u`}" done env -0 | sed 's/\(\x00\)\([^\x00]\)\|^/\1--env=\2/g' printf -- '--cwd=%s\0' "$PWD" -) | socat -t 10 - abstract-client:"$ADDRESS" +) | socat -lf/dev/null -t 10 - abstract-client:"$ADDRESS" + +if test $? -ne 0 ; then + powerline-render "$@" +fi From 9da3e04bc2519f173d6c594539102aef68734ac5 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 2 Aug 2014 21:27:31 +0400 Subject: [PATCH 17/22] Do not hardcode scripts/powerline in input.* --- tests/test_shells/input.bash | 7 ++++--- tests/test_shells/input.bb | 5 +++-- tests/test_shells/input.dash | 5 +++-- tests/test_shells/input.fish | 7 ++++--- tests/test_shells/input.mksh | 5 +++-- tests/test_shells/input.tcsh | 5 +++-- tests/test_shells/input.zsh | 9 +++++---- tests/test_shells/test.sh | 2 ++ 8 files changed, 27 insertions(+), 18 deletions(-) diff --git a/tests/test_shells/input.bash b/tests/test_shells/input.bash index 748e78fa..ff7ad797 100644 --- a/tests/test_shells/input.bash +++ b/tests/test_shells/input.bash @@ -1,8 +1,9 @@ -POWERLINE_COMMAND="$PWD/scripts/powerline -p $PWD/powerline/config_files" +export VIRTUAL_ENV= +source powerline/bindings/bash/powerline.sh +POWERLINE_COMMAND="$POWERLINE_COMMAND -p $PWD/powerline/config_files" POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.args.only_if_ssh=false" POWERLINE_COMMAND="$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly" -export VIRTUAL_ENV= -source powerline/bindings/bash/powerline.sh ; cd tests/shell/3rd +cd tests/shell/3rd cd .git cd .. VIRTUAL_ENV="$HOME/.virtenvs/some-virtual-environment" diff --git a/tests/test_shells/input.bb b/tests/test_shells/input.bb index d9ae1342..2d4fbc42 100644 --- a/tests/test_shells/input.bb +++ b/tests/test_shells/input.bb @@ -1,8 +1,9 @@ -POWERLINE_COMMAND="$PWD/scripts/powerline -p $PWD/powerline/config_files" +. powerline/bindings/shell/powerline.sh +POWERLINE_COMMAND="$POWERLINE_COMMAND -p $PWD/powerline/config_files" POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.args.only_if_ssh=false" POWERLINE_COMMAND="$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly" export VIRTUAL_ENV= -. powerline/bindings/shell/powerline.sh ; cd tests/shell/3rd +cd tests/shell/3rd cd .git cd .. VIRTUAL_ENV="$HOME/.virtenvs/some-virtual-environment" diff --git a/tests/test_shells/input.dash b/tests/test_shells/input.dash index d9ae1342..2d4fbc42 100644 --- a/tests/test_shells/input.dash +++ b/tests/test_shells/input.dash @@ -1,8 +1,9 @@ -POWERLINE_COMMAND="$PWD/scripts/powerline -p $PWD/powerline/config_files" +. powerline/bindings/shell/powerline.sh +POWERLINE_COMMAND="$POWERLINE_COMMAND -p $PWD/powerline/config_files" POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.args.only_if_ssh=false" POWERLINE_COMMAND="$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly" export VIRTUAL_ENV= -. powerline/bindings/shell/powerline.sh ; cd tests/shell/3rd +cd tests/shell/3rd cd .git cd .. VIRTUAL_ENV="$HOME/.virtenvs/some-virtual-environment" diff --git a/tests/test_shells/input.fish b/tests/test_shells/input.fish index 3e69ad5e..f8da144e 100644 --- a/tests/test_shells/input.fish +++ b/tests/test_shells/input.fish @@ -1,9 +1,10 @@ -set POWERLINE_COMMAND "$PWD/scripts/powerline -p $PWD/powerline/config_files" +set fish_function_path $fish_function_path "$PWD/powerline/bindings/fish" +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" set POWERLINE_COMMAND "$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly" setenv VIRTUAL_ENV -set fish_function_path $fish_function_path "$PWD/powerline/bindings/fish" -powerline-setup ; cd tests/shell/3rd +cd tests/shell/3rd cd .git cd .. setenv VIRTUAL_ENV "$HOME/.virtenvs/some-virtual-environment" diff --git a/tests/test_shells/input.mksh b/tests/test_shells/input.mksh index a4a5928a..a2f0a7dd 100644 --- a/tests/test_shells/input.mksh +++ b/tests/test_shells/input.mksh @@ -1,8 +1,9 @@ -POWERLINE_COMMAND="$PWD/scripts/powerline -p $PWD/powerline/config_files" +. powerline/bindings/shell/powerline.sh +POWERLINE_COMMAND="$POWERLINE_COMMAND -p $PWD/powerline/config_files" POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.args.only_if_ssh=false" POWERLINE_COMMAND="$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly" export VIRTUAL_ENV= -. powerline/bindings/shell/powerline.sh ; cd tests/shell/3rd +cd tests/shell/3rd cd .git cd .. VIRTUAL_ENV="$HOME/.virtenvs/some-virtual-environment" diff --git a/tests/test_shells/input.tcsh b/tests/test_shells/input.tcsh index 4d48a465..0bc6b78a 100644 --- a/tests/test_shells/input.tcsh +++ b/tests/test_shells/input.tcsh @@ -1,6 +1,7 @@ -setenv POWERLINE_COMMAND $PWD:q/scripts/powerline" -p "$PWD:q/powerline/config_files" -t default_leftonly.segment_data.hostname.args.only_if_ssh=false -c ext.shell.theme=default_leftonly" +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" unsetenv VIRTUAL_ENV -source powerline/bindings/tcsh/powerline.tcsh ; cd tests/shell/3rd +cd tests/shell/3rd cd .git cd .. setenv VIRTUAL_ENV $HOME:q"/.virtenvs/some-virtual-environment" diff --git a/tests/test_shells/input.zsh b/tests/test_shells/input.zsh index b40c3283..952ee756 100644 --- a/tests/test_shells/input.zsh +++ b/tests/test_shells/input.zsh @@ -1,14 +1,15 @@ unsetopt promptsp transientrprompt -POWERLINE_COMMAND=( $PWD/scripts/powerline -p $PWD/powerline/config_files ) -POWERLINE_COMMAND=( $POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.args.only_if_ssh=false ) -POWERLINE_COMMAND=( $POWERLINE_COMMAND -c ext.shell.theme=default_leftonly ) setopt interactivecomments # POWERLINE_CONFIG_PATH=$PWD/powerline/config_files # POWERLINE_THEME_CONFIG=( default_leftonly.segment_data.hostname.args.only_if_ssh=false ) # POWERLINE_CONFIG=( ext.shell.theme=default_leftonly ) POWERLINE_NO_ZSH_ZPYTHON=1 # TODO: make tests work with zsh/zpython +source powerline/bindings/zsh/powerline.zsh +POWERLINE_COMMAND=( $POWERLINE_COMMAND -p $PWD/powerline/config_files ) +POWERLINE_COMMAND=( $POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.args.only_if_ssh=false ) +POWERLINE_COMMAND=( $POWERLINE_COMMAND -c ext.shell.theme=default_leftonly ) export VIRTUAL_ENV= -source powerline/bindings/zsh/powerline.zsh ; cd tests/shell/3rd +cd tests/shell/3rd cd .git cd .. VIRTUAL_ENV="$HOME/.virtenvs/some-virtual-environment" diff --git a/tests/test_shells/test.sh b/tests/test_shells/test.sh index 656f2f71..433b7319 100755 --- a/tests/test_shells/test.sh +++ b/tests/test_shells/test.sh @@ -127,6 +127,8 @@ unset ENV powerline-daemon -k || true sleep 1s +scripts/powerline-config shell command + for TEST_TYPE in "daemon" "nodaemon" ; do if test $TEST_TYPE == daemon ; then sh -c 'echo $$ > tests/shell/daemon_pid; ./scripts/powerline-daemon -f &>tests/shell/daemon_log' & From 28aee92c517d5e8758a47dc7543ba19aeca6f6b8 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 2 Aug 2014 21:56:37 +0400 Subject: [PATCH 18/22] Fix zsh daemon tests: disable hostname and user before testing select Reason: hostname and user do not have stable width and select prompt width with daemon depends on previous prompt width. --- tests/test_shells/input.zsh | 16 ++++++++------ tests/test_shells/zsh.daemon.ok | Bin 11672 -> 11878 bytes tests/test_shells/{zsh.ok => zsh.nodaemon.ok} | 20 ++++++++++-------- 3 files changed, 20 insertions(+), 16 deletions(-) rename tests/test_shells/{zsh.ok => zsh.nodaemon.ok} (90%) diff --git a/tests/test_shells/input.zsh b/tests/test_shells/input.zsh index 952ee756..51095f5f 100644 --- a/tests/test_shells/input.zsh +++ b/tests/test_shells/input.zsh @@ -1,4 +1,4 @@ -unsetopt promptsp transientrprompt +unsetopt promptsp notransientrprompt setopt interactivecomments # POWERLINE_CONFIG_PATH=$PWD/powerline/config_files # POWERLINE_THEME_CONFIG=( default_leftonly.segment_data.hostname.args.only_if_ssh=false ) @@ -16,12 +16,6 @@ VIRTUAL_ENV="$HOME/.virtenvs/some-virtual-environment" VIRTUAL_ENV= bash -c 'echo $$>pid ; while true ; do sleep 0.1s ; done' & false -select abc in def ghi jkl -do - echo $abc - break -done -1 kill `cat pid` ; sleep 1s cd "$DIR1" cd ../"$DIR2" @@ -37,5 +31,13 @@ POWERLINE_COMMAND=( $POWERLINE_COMMAND[1,4] ${${POWERLINE_COMMAND[5]}/_leftonly} echo abc false +POWERLINE_COMMAND=( $POWERLINE_COMMAND -t default.segment_data.hostname.display=false ) +POWERLINE_COMMAND=( $POWERLINE_COMMAND -t default.segment_data.user.display=false ) +select abc in def ghi jkl +do + echo $abc + break +done +1 true is the last line exit diff --git a/tests/test_shells/zsh.daemon.ok b/tests/test_shells/zsh.daemon.ok index 3e4000aed992ae14f684fbc9e44e4f914e4d5377..7469e23b61ee6790cceceee1aa8a298fed046535 100644 GIT binary patch delta 203 zcmbOc{VZm~eBRAlg&#{!uI6r;yg>8Ifxv6<2@hOQV ziFz6N#U*)(xv6?7nZ*S;iIui#i8;lo3YwD-GRjP@7U5+&v|ux%HV-4n6kVLAloqEJ zVVDreFFWxLH_(8|2Q@EGp3j>4agI1L@IKpL|Ov8Lxb_Zag0OCfss5T$7FT YOg0~4lxLi*z}P)mpWAKoeBQ^B0Eapid ; while true ; do sleep 0.1s ; done' & [1] PID   HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  false -  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  1  select abc in def ghi jkl - select  do - select   echo $abc - select   break - select  done -1) def 2) ghi 3) jkl - Select variant  1 -def -  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  kill `cat pid` ; sleep 1s +  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  1  kill `cat pid` ; sleep 1s [1] + terminated bash -c 'echo $$>pid ; while true ; do sleep 0.1s ; done'   HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  cd "$DIR1"   HOSTNAME  USER   BRANCH  ⋯  shell  3rd  ^[[32m  cd ../"$DIR2" @@ -31,3 +23,13 @@ def  INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd  echo abc abc  INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd  false + INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd  POWERLINE_COMMAND=( $POWERLINE_COMMAND -t default.segment_data.hostname.display=false ) + INSERT  USER  ⋯  tests  shell  3rd  POWERLINE_COMMAND=( $POWERLINE_COMMAND -t default.segment_data.user.display=false ) + INSERT  ⋯  tests  shell  3rd  select abc in def ghi jkl + select  do + select   echo $abc + select   break + select  done +1) def 2) ghi 3) jkl + Select variant  1 +def From 44cca975666e5b8f6406310e323bc239fb80b1e5 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 2 Aug 2014 22:03:22 +0400 Subject: [PATCH 19/22] Check whether daemon log is as empty as it should --- tests/test_shells/test.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/test_shells/test.sh b/tests/test_shells/test.sh index 433b7319..f224e22f 100755 --- a/tests/test_shells/test.sh +++ b/tests/test_shells/test.sh @@ -165,6 +165,13 @@ for TEST_TYPE in "daemon" "nodaemon" ; do if test $TEST_TYPE == daemon ; then ./scripts/powerline-daemon -k wait $(cat tests/shell/daemon_pid) + if ! test -z "$(cat tests/shell/daemon_log)" ; then + echo '____________________________________________________________' + echo "Daemon log:" + echo '============================================================' + cat tests/shell/daemon_log + FAILED=1 + fi fi done From ea7f3b650134e639be4acd68f9d504ee42db5c49 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 2 Aug 2014 22:20:06 +0400 Subject: [PATCH 20/22] Add powerline-daemon --quiet --- scripts/powerline-daemon | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/scripts/powerline-daemon b/scripts/powerline-daemon index 7ffcdb2f..bc054680 100755 --- a/scripts/powerline-daemon +++ b/scripts/powerline-daemon @@ -300,7 +300,7 @@ def check_existing(): return sock -def test_connect(): +def kill_daemon(): sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) try: try: @@ -351,6 +351,7 @@ def lockpidfile(): def main(): p = ArgumentParser(description= 'Daemon to improve the performance of powerline') + p.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.') a = p.add_mutually_exclusive_group().add_argument a('--kill', '-k', action='store_true', help='Kill an already running instance') a('--foreground', '-f', action='store_true', help='Run in the foreground (dont daemonize)') @@ -358,15 +359,19 @@ def main(): args = p.parse_args() if args.kill: - if test_connect(): - print ('Kill command sent to daemon, if it does not die in a couple of seconds use kill to kill it') + if kill_daemon(): + if not args.quiet: + print ('Kill command sent to daemon, if it does not die in a couple of seconds use kill to kill it') + raise SystemExit(0) else: - print ('No running daemon found') - return + if not args.quiet: + print ('No running daemon found') + raise SystemExit(1) if args.replace: - while test_connect(): - print ('Kill command sent to daemon, waiting for daemon to exit, press Ctrl-C to terminate wait and exit') + while kill_daemon(): + if not args.quiet: + print ('Kill command sent to daemon, waiting for daemon to exit, press Ctrl-C to terminate wait and exit') sleep(2) if use_filesystem and not args.foreground: @@ -377,15 +382,17 @@ def main(): if use_filesystem: # Create a locked pid file containing the daemon's PID if lockpidfile() is None: - print ('The daemon is already running. Use %s -k to kill it.' % os.path.basename(sys.argv[0]), - file=sys.stderr) + if not args.quiet: + print ('The daemon is already running. Use %s -k to kill it.' % os.path.basename(sys.argv[0]), + file=sys.stderr) raise SystemExit(1) # Bind to address or bail if we cannot bind sock = check_existing() if sock is None: - print ('The daemon is already running. Use %s -k to kill it.' % os.path.basename(sys.argv[0]), - file=sys.stderr) + if not args.quiet: + print ('The daemon is already running. Use %s -k to kill it.' % os.path.basename(sys.argv[0]), + file=sys.stderr) raise SystemExit(1) if args.foreground: From 4ddac2a2f5452c57cf3ceea44771a3f69e3b51ed Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 2 Aug 2014 22:27:58 +0400 Subject: [PATCH 21/22] Do not run `set-environment` in tmux if POWERLINE_COMMAND is set --- powerline/bindings/config.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/powerline/bindings/config.py b/powerline/bindings/config.py index 5899e740..4dd79cc2 100644 --- a/powerline/bindings/config.py +++ b/powerline/bindings/config.py @@ -111,10 +111,11 @@ def source_tmux_files(pl, args): version = get_tmux_version(pl) for fname, priority in sorted(get_tmux_configs(version), key=(lambda v: v[1])): run_tmux_command('source', fname) - cmd = deduce_command() - if cmd: - run_tmux_command('set-environment', '-g', 'POWERLINE_COMMAND', deduce_command()) - run_tmux_command('refresh-client') + if not os.environ.get('POWERLINE_COMMAND'): + cmd = deduce_command() + if cmd: + run_tmux_command('set-environment', '-g', 'POWERLINE_COMMAND', deduce_command()) + run_tmux_command('refresh-client') def create_powerline_logger(args): From 8bc5bb3ff4368588334cd2b3ad8f362aaad10f87 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 2 Aug 2014 22:24:23 +0400 Subject: [PATCH 22/22] Update documentation --- .../installation/troubleshooting-common.rst | 7 +------ docs/source/overview.rst | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/docs/source/installation/troubleshooting-common.rst b/docs/source/installation/troubleshooting-common.rst index bb688d7e..55345394 100644 --- a/docs/source/installation/troubleshooting-common.rst +++ b/docs/source/installation/troubleshooting-common.rst @@ -124,12 +124,7 @@ I am suffering bad lags before displaying shell prompt To get rid of these lags there currently are two options: -* Take ``powerline-daemon`` script and one of ``powerline-client`` - implementations from ``feature/daemon`` branch (all ``powerline-client`` - implementations leave in ``client`` folder: you need to either compile - ``powerline.c`` or install ``socat`` and use ``powerline.sh`` - (``powerline.py`` is much slower)). Fortunately this branch will be merged in - the future. +* Run ``powerline-daemon``. Powerline does not automatically start it for you. * Compile and install ``libzpython`` module that lives in https://bitbucket.org/ZyX_I/zpython. This variant is zsh-specific. diff --git a/docs/source/overview.rst b/docs/source/overview.rst index 9ddc798a..f50940a6 100644 --- a/docs/source/overview.rst +++ b/docs/source/overview.rst @@ -149,6 +149,19 @@ hand: ``powerline`` is installed and run just like any other plugin using Shell prompts ------------- +.. note:: + It is advised that you run ``powerline-daemon`` before using any of the + below solutions. To do this add + + .. code-block:: bash + + powerline-daemon -q + + just before sourcing powerline bindings script or running + ``powerline-setup``. Use ``|| true`` or equivalent if you run your + configuration with ``set -e`` because ``powerline-daemon`` will exit with + ``1`` if daemon is already running. + Bash prompt ^^^^^^^^^^^ @@ -227,6 +240,14 @@ is the absolute path to your Powerline installation directory:: powerline support. You may specify location of this script via ``$POWERLINE_CONFIG_COMMAND`` environment variable. +.. note:: + It is advised that you run ``powerline-daemon`` before adding the above line + to tmux.conf. To do so add:: + + run-shell "powerline-daemon -q" + + to :file:`.tmux.conf`. + IPython prompt --------------