mirror of
https://github.com/powerline/powerline.git
synced 2025-07-24 06:15:41 +02:00
Merge pull request #944 from ZyX-I/feature/daemon
Add powerline-daemon Closes #827 Fixes #616 Closes #170
This commit is contained in:
commit
1d696d3d4c
2
.gitignore
vendored
2
.gitignore
vendored
@ -9,3 +9,5 @@ dist
|
|||||||
build
|
build
|
||||||
|
|
||||||
message.fail
|
message.fail
|
||||||
|
|
||||||
|
client/powerline
|
||||||
|
116
client/powerline.c
Normal file
116
client/powerline.c
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
/* vim:fileencoding=utf-8:noet
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
77
client/powerline.py
Executable file
77
client/powerline.py
Executable file
@ -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 + 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))
|
||||||
|
|
||||||
|
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))
|
17
client/powerline.sh
Executable file
17
client/powerline.sh
Executable file
@ -0,0 +1,17 @@
|
|||||||
|
#!/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 -lf/dev/null -t 10 - abstract-client:"$ADDRESS"
|
||||||
|
|
||||||
|
if test $? -ne 0 ; then
|
||||||
|
powerline-render "$@"
|
||||||
|
fi
|
@ -30,6 +30,11 @@ Plugin installation
|
|||||||
project is currently unavailable on the PyPI due to a naming conflict
|
project is currently unavailable on the PyPI due to a naming conflict
|
||||||
with an unrelated project.
|
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
|
Font installation
|
||||||
=================
|
=================
|
||||||
|
|
||||||
|
@ -26,6 +26,11 @@ Python package
|
|||||||
project is currently unavailable on the PyPI due to a naming conflict
|
project is currently unavailable on the PyPI due to a naming conflict
|
||||||
with an unrelated project.
|
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
|
Vim installation
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
@ -124,12 +124,7 @@ I am suffering bad lags before displaying shell prompt
|
|||||||
|
|
||||||
To get rid of these lags there currently are two options:
|
To get rid of these lags there currently are two options:
|
||||||
|
|
||||||
* Take ``powerline-daemon`` script and one of ``powerline-client``
|
* Run ``powerline-daemon``. Powerline does not automatically start it for you.
|
||||||
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.
|
|
||||||
* Compile and install ``libzpython`` module that lives in
|
* Compile and install ``libzpython`` module that lives in
|
||||||
https://bitbucket.org/ZyX_I/zpython. This variant is zsh-specific.
|
https://bitbucket.org/ZyX_I/zpython. This variant is zsh-specific.
|
||||||
|
|
||||||
|
@ -149,6 +149,19 @@ hand: ``powerline`` is installed and run just like any other plugin using
|
|||||||
Shell prompts
|
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
|
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 support. You may specify location of this script via
|
||||||
``$POWERLINE_CONFIG_COMMAND`` environment variable.
|
``$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
|
IPython prompt
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
@ -54,13 +54,12 @@ _powerline_set_prompt() {
|
|||||||
_powerline_setup_prompt() {
|
_powerline_setup_prompt() {
|
||||||
VIRTUAL_ENV_DISABLE_PROMPT=1
|
VIRTUAL_ENV_DISABLE_PROMPT=1
|
||||||
if test -z "${POWERLINE_COMMAND}" ; then
|
if test -z "${POWERLINE_COMMAND}" ; then
|
||||||
if which powerline-client &>/dev/null ; then
|
if which powerline-config &>/dev/null ; then
|
||||||
export POWERLINE_COMMAND=powerline-client
|
export POWERLINE_COMMAND="$(powerline-config shell command)"
|
||||||
elif which powerline &>/dev/null ; then
|
|
||||||
export POWERLINE_COMMAND=powerline
|
|
||||||
else
|
else
|
||||||
# `$0` is set to `-bash` when using SSH so that won't work
|
# `$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-config shell command)"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
test "x$PROMPT_COMMAND" != "x${PROMPT_COMMAND%_powerline_set_prompt*}" ||
|
test "x$PROMPT_COMMAND" != "x${PROMPT_COMMAND%_powerline_set_prompt*}" ||
|
||||||
|
@ -6,11 +6,12 @@ from collections import namedtuple
|
|||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import re
|
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.lib.config import ConfigLoader
|
||||||
from powerline import generate_config_finder, load_config, create_logger, PowerlineLogger, finish_common_config
|
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'))
|
TmuxVersionInfo = namedtuple('TmuxVersionInfo', ('major', 'minor', 'suffix'))
|
||||||
@ -110,6 +111,11 @@ def source_tmux_files(pl, args):
|
|||||||
version = get_tmux_version(pl)
|
version = get_tmux_version(pl)
|
||||||
for fname, priority in sorted(get_tmux_configs(version), key=(lambda v: v[1])):
|
for fname, priority in sorted(get_tmux_configs(version), key=(lambda v: v[1])):
|
||||||
run_tmux_command('source', fname)
|
run_tmux_command('source', fname)
|
||||||
|
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):
|
def create_powerline_logger(args):
|
||||||
@ -119,3 +125,44 @@ def create_powerline_logger(args):
|
|||||||
common_config = finish_common_config(config['common'])
|
common_config = finish_common_config(config['common'])
|
||||||
logger = create_logger(common_config)
|
logger = create_logger(common_config)
|
||||||
return PowerlineLogger(use_daemon_threads=True, logger=logger, ext='config')
|
return PowerlineLogger(use_daemon_threads=True, logger=logger, ext='config')
|
||||||
|
|
||||||
|
|
||||||
|
def check_command(cmd):
|
||||||
|
if which(cmd):
|
||||||
|
return cmd
|
||||||
|
|
||||||
|
|
||||||
|
def deduce_command():
|
||||||
|
'''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.
|
||||||
|
'''
|
||||||
|
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)
|
||||||
|
@ -20,12 +20,11 @@ function powerline-setup
|
|||||||
|
|
||||||
if test -z "$POWERLINE_NO_FISH_PROMPT$POWERLINE_NO_SHELL_PROMPT"
|
if test -z "$POWERLINE_NO_FISH_PROMPT$POWERLINE_NO_SHELL_PROMPT"
|
||||||
if test -z "$POWERLINE_COMMAND"
|
if test -z "$POWERLINE_COMMAND"
|
||||||
if which powerline-client >/dev/null
|
if false ;and which powerline-config >/dev/null
|
||||||
set -g -x POWERLINE_COMMAND powerline-client
|
set -g -x POWERLINE_COMMAND (powerline-config shell command)
|
||||||
else if which powerline >/dev/null
|
|
||||||
set -g -x POWERLINE_COMMAND powerline
|
|
||||||
else
|
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
|
||||||
end
|
end
|
||||||
function --on-variable POWERLINE_COMMAND _powerline_update
|
function --on-variable POWERLINE_COMMAND _powerline_update
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
_POWERLINE_SOURCED="$_"
|
||||||
_powerline_columns_fallback() {
|
_powerline_columns_fallback() {
|
||||||
if which stty >/dev/null ; then
|
if which stty >/dev/null ; then
|
||||||
# Ksh does not have “local” built-in
|
# Ksh does not have “local” built-in
|
||||||
@ -97,13 +98,11 @@ _powerline_set_set_jobs() {
|
|||||||
|
|
||||||
_powerline_set_command() {
|
_powerline_set_command() {
|
||||||
if test -z "${POWERLINE_COMMAND}" ; then
|
if test -z "${POWERLINE_COMMAND}" ; then
|
||||||
if which powerline-client >/dev/null ; then
|
if which powerline-config &>/dev/null ; then
|
||||||
export POWERLINE_COMMAND=powerline-client
|
export POWERLINE_COMMAND="$(powerline-config shell command)"
|
||||||
elif which powerline >/dev/null ; then
|
|
||||||
export POWERLINE_COMMAND=powerline
|
|
||||||
else
|
else
|
||||||
# `$0` is set to `-bash` when using SSH so that won't work
|
local powerline_dir="$(dirname "$POWERLINE_SOURCED")/../../.."
|
||||||
export POWERLINE_COMMAND="$(dirname "$BASH_SOURCE")/../../../scripts/powerline"
|
export POWERLINE_COMMAND="$($powerline_dir/scripts/powerline-config shell command)"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
@ -11,12 +11,10 @@ if ! ( $?POWERLINE_NO_TCSH_TMUX_SUPPORT || $?POWERLINE_NO_SHELL_TMUX_SUPPORT ) t
|
|||||||
endif
|
endif
|
||||||
if ! ( $?POWERLINE_NO_TCSH_PROMPT || $?POWERLINE_NO_SHELL_PROMPT ) then
|
if ! ( $?POWERLINE_NO_TCSH_PROMPT || $?POWERLINE_NO_SHELL_PROMPT ) then
|
||||||
if ! $?POWERLINE_COMMAND then
|
if ! $?POWERLINE_COMMAND then
|
||||||
if ( { which powerline-client > /dev/null } ) then
|
if ( { which powerline-config > /dev/null } ) then
|
||||||
setenv POWERLINE_COMMAND powerline-client
|
setenv POWERLINE_COMMAND "`powerline-config shell command`"
|
||||||
else if ( { which powerline > /dev/null } ) then
|
|
||||||
setenv POWERLINE_COMMAND powerline
|
|
||||||
else
|
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
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
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_CONFIG_COMMAND"' 'set-environment -g POWERLINE_CONFIG_COMMAND powerline-config'
|
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
|
# Don't version-check for this core functionality -- anything too old to
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
_POWERLINE_SOURCED="$0:A"
|
||||||
|
|
||||||
_powerline_columns_fallback() {
|
_powerline_columns_fallback() {
|
||||||
if which stty &>/dev/null ; then
|
if which stty &>/dev/null ; then
|
||||||
local cols="$(stty size 2>/dev/null)"
|
local cols="$(stty size 2>/dev/null)"
|
||||||
@ -124,12 +126,11 @@ _powerline_setup_prompt() {
|
|||||||
zpython 'del _powerline_setup'
|
zpython 'del _powerline_setup'
|
||||||
else
|
else
|
||||||
if test -z "${POWERLINE_COMMAND}" ; then
|
if test -z "${POWERLINE_COMMAND}" ; then
|
||||||
if which powerline-client &>/dev/null ; then
|
if which powerline-config &>/dev/null ; then
|
||||||
export POWERLINE_COMMAND=powerline-client
|
export POWERLINE_COMMAND="$(powerline-config shell command)"
|
||||||
elif which powerline &>/dev/null ; then
|
|
||||||
export POWERLINE_COMMAND=powerline
|
|
||||||
else
|
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
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
from __future__ import absolute_import, unicode_literals, print_function
|
from __future__ import absolute_import, unicode_literals, print_function
|
||||||
import os
|
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')
|
TMUX_CONFIG_DIRECTORY = os.path.join(BINDINGS_DIRECTORY, 'tmux')
|
||||||
DEFAULT_SYSTEM_CONFIG_DIR = None
|
DEFAULT_SYSTEM_CONFIG_DIR = None
|
||||||
|
@ -6,6 +6,7 @@ from subprocess import Popen, PIPE
|
|||||||
from locale import getlocale, getdefaultlocale, LC_MESSAGES
|
from locale import getlocale, getdefaultlocale, LC_MESSAGES
|
||||||
from functools import partial
|
from functools import partial
|
||||||
import sys
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
if sys.platform.startswith('win32'):
|
if sys.platform.startswith('win32'):
|
||||||
@ -60,3 +61,71 @@ def readlines(cmd, cwd):
|
|||||||
with p.stdout:
|
with p.stdout:
|
||||||
for line in p.stdout:
|
for line in p.stdout:
|
||||||
yield line[:-1].decode(encoding)
|
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
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
# vim:fileencoding=utf-8:noet
|
# vim:fileencoding=utf-8:noet
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
from powerline import Powerline
|
from powerline import Powerline
|
||||||
from powerline.lib import mergedicts, parsedotval
|
from powerline.lib import mergedicts, parsedotval
|
||||||
|
|
||||||
@ -73,3 +75,26 @@ def finish_args(args):
|
|||||||
args.theme_option = {}
|
args.theme_option = {}
|
||||||
if args.renderer_arg:
|
if args.renderer_arg:
|
||||||
args.renderer_arg = mergeargs((parsedotval(v) for v in 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)
|
||||||
|
1
scripts/.gitignore
vendored
Normal file
1
scripts/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
powerline
|
@ -18,6 +18,11 @@ TMUX_ACTIONS = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SHELL_ACTIONS = {
|
||||||
|
'command': config.shell_command,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
subparsers = parser.add_subparsers()
|
subparsers = parser.add_subparsers()
|
||||||
@ -30,6 +35,14 @@ if __name__ == '__main__':
|
|||||||
help='If action is "source" then version-specific tmux configuration files are sourced.'
|
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()
|
args = parser.parse_args()
|
||||||
|
|
||||||
pl = config.create_powerline_logger(args)
|
pl = config.create_powerline_logger(args)
|
||||||
|
409
scripts/powerline-daemon
Executable file
409
scripts/powerline-daemon
Executable file
@ -0,0 +1,409 @@
|
|||||||
|
#!/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 io import StringIO
|
||||||
|
|
||||||
|
from powerline.shell import get_argparser, finish_args, ShellPowerline, write_output
|
||||||
|
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,
|
||||||
|
tuple(args.renderer_arg) if args.renderer_arg else None,
|
||||||
|
)
|
||||||
|
finish_args(args)
|
||||||
|
powerline = None
|
||||||
|
try:
|
||||||
|
powerline = powerlines[key]
|
||||||
|
except KeyError:
|
||||||
|
try:
|
||||||
|
powerline = powerlines[key] = PowerlineDaemon(
|
||||||
|
args,
|
||||||
|
logger=logger,
|
||||||
|
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 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))
|
||||||
|
s = StringIO()
|
||||||
|
write_output(args, powerline, segment_info, s.write)
|
||||||
|
s.seek(0)
|
||||||
|
return s.read()
|
||||||
|
|
||||||
|
|
||||||
|
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 kill_daemon():
|
||||||
|
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')
|
||||||
|
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)')
|
||||||
|
a('--replace', '-r', action='store_true', help='Replace an already running instance')
|
||||||
|
args = p.parse_args()
|
||||||
|
|
||||||
|
if args.kill:
|
||||||
|
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:
|
||||||
|
if not args.quiet:
|
||||||
|
print ('No running daemon found')
|
||||||
|
raise SystemExit(1)
|
||||||
|
|
||||||
|
if args.replace:
|
||||||
|
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:
|
||||||
|
# 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:
|
||||||
|
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:
|
||||||
|
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:
|
||||||
|
return main_loop(sock)
|
||||||
|
|
||||||
|
if not use_filesystem:
|
||||||
|
# We daemonize on linux
|
||||||
|
daemonize()
|
||||||
|
|
||||||
|
main_loop(sock)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
@ -5,10 +5,11 @@ import sys
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from powerline.shell import ShellPowerline, get_argparser, finish_args
|
from powerline.shell import ShellPowerline, get_argparser, finish_args, write_output
|
||||||
except ImportError:
|
except ImportError:
|
||||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(os.path.realpath(__file__)))))
|
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):
|
def write(output):
|
||||||
try:
|
try:
|
||||||
@ -16,28 +17,10 @@ def write(output):
|
|||||||
except UnicodeEncodeError:
|
except UnicodeEncodeError:
|
||||||
sys.stdout.write(output.encode('utf-8'))
|
sys.stdout.write(output.encode('utf-8'))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
args = get_argparser(description=__doc__).parse_args()
|
args = get_argparser(description=__doc__).parse_args()
|
||||||
finish_args(args)
|
finish_args(args)
|
||||||
powerline = ShellPowerline(args, run_once=True)
|
powerline = ShellPowerline(args, run_once=True)
|
||||||
segment_info = {'args': args, 'environ': os.environ}
|
segment_info = {'args': args, 'environ': os.environ}
|
||||||
if args.renderer_arg:
|
write_output(args, powerline, segment_info, write)
|
||||||
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)
|
|
68
setup.py
68
setup.py
@ -3,16 +3,52 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import subprocess
|
||||||
|
import logging
|
||||||
|
|
||||||
from setuptools import setup, find_packages
|
from setuptools import setup, find_packages
|
||||||
|
|
||||||
here = os.path.abspath(os.path.dirname(__file__))
|
CURRENT_DIR = os.path.abspath(os.path.dirname(__file__))
|
||||||
try:
|
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:
|
except IOError:
|
||||||
README = ''
|
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()
|
||||||
|
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 as e:
|
||||||
|
print('Compiling C version of powerline-client failed')
|
||||||
|
logging.exception(e)
|
||||||
|
# FIXME Catch more specific exceptions
|
||||||
|
import shutil
|
||||||
|
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(
|
setup(
|
||||||
name='Powerline',
|
name='Powerline',
|
||||||
@ -23,11 +59,31 @@ setup(
|
|||||||
author='Kim Silkebaekken',
|
author='Kim Silkebaekken',
|
||||||
author_email='kim.silkebaekken+vim@gmail.com',
|
author_email='kim.silkebaekken+vim@gmail.com',
|
||||||
url='https://github.com/Lokaltog/powerline',
|
url='https://github.com/Lokaltog/powerline',
|
||||||
|
# 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=[
|
||||||
'scripts/powerline',
|
|
||||||
'scripts/powerline-lint',
|
'scripts/powerline-lint',
|
||||||
|
'scripts/powerline-daemon',
|
||||||
|
'scripts/powerline-render',
|
||||||
'scripts/powerline-config',
|
'scripts/powerline-config',
|
||||||
],
|
] + (['scripts/powerline'] if can_use_scripts else []),
|
||||||
|
data_files=(None if can_use_scripts else (('bin', ['scripts/powerline']),)),
|
||||||
keywords='',
|
keywords='',
|
||||||
packages=find_packages(exclude=('tests', 'tests.*')),
|
packages=find_packages(exclude=('tests', 'tests.*')),
|
||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
@ -38,5 +94,5 @@ setup(
|
|||||||
'Sphinx',
|
'Sphinx',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
test_suite='tests' if not old_python else None,
|
test_suite='tests' if not OLD_PYTHON else None,
|
||||||
)
|
)
|
||||||
|
@ -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 -t default_leftonly.segment_data.hostname.args.only_if_ssh=false"
|
||||||
POWERLINE_COMMAND="$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly"
|
POWERLINE_COMMAND="$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly"
|
||||||
export VIRTUAL_ENV=
|
cd tests/shell/3rd
|
||||||
source powerline/bindings/bash/powerline.sh ; cd tests/shell/3rd
|
|
||||||
cd .git
|
cd .git
|
||||||
cd ..
|
cd ..
|
||||||
VIRTUAL_ENV="$HOME/.virtenvs/some-virtual-environment"
|
VIRTUAL_ENV="$HOME/.virtenvs/some-virtual-environment"
|
||||||
|
@ -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 -t default_leftonly.segment_data.hostname.args.only_if_ssh=false"
|
||||||
POWERLINE_COMMAND="$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly"
|
POWERLINE_COMMAND="$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly"
|
||||||
export VIRTUAL_ENV=
|
export VIRTUAL_ENV=
|
||||||
. powerline/bindings/shell/powerline.sh ; cd tests/shell/3rd
|
cd tests/shell/3rd
|
||||||
cd .git
|
cd .git
|
||||||
cd ..
|
cd ..
|
||||||
VIRTUAL_ENV="$HOME/.virtenvs/some-virtual-environment"
|
VIRTUAL_ENV="$HOME/.virtenvs/some-virtual-environment"
|
||||||
|
@ -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 -t default_leftonly.segment_data.hostname.args.only_if_ssh=false"
|
||||||
POWERLINE_COMMAND="$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly"
|
POWERLINE_COMMAND="$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly"
|
||||||
export VIRTUAL_ENV=
|
export VIRTUAL_ENV=
|
||||||
. powerline/bindings/shell/powerline.sh ; cd tests/shell/3rd
|
cd tests/shell/3rd
|
||||||
cd .git
|
cd .git
|
||||||
cd ..
|
cd ..
|
||||||
VIRTUAL_ENV="$HOME/.virtenvs/some-virtual-environment"
|
VIRTUAL_ENV="$HOME/.virtenvs/some-virtual-environment"
|
||||||
|
@ -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 -t default_leftonly.segment_data.hostname.args.only_if_ssh=false"
|
||||||
set POWERLINE_COMMAND "$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly"
|
set POWERLINE_COMMAND "$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly"
|
||||||
setenv VIRTUAL_ENV
|
setenv VIRTUAL_ENV
|
||||||
set fish_function_path $fish_function_path "$PWD/powerline/bindings/fish"
|
cd tests/shell/3rd
|
||||||
powerline-setup ; cd tests/shell/3rd
|
|
||||||
cd .git
|
cd .git
|
||||||
cd ..
|
cd ..
|
||||||
setenv VIRTUAL_ENV "$HOME/.virtenvs/some-virtual-environment"
|
setenv VIRTUAL_ENV "$HOME/.virtenvs/some-virtual-environment"
|
||||||
|
@ -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 -t default_leftonly.segment_data.hostname.args.only_if_ssh=false"
|
||||||
POWERLINE_COMMAND="$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly"
|
POWERLINE_COMMAND="$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly"
|
||||||
export VIRTUAL_ENV=
|
export VIRTUAL_ENV=
|
||||||
. powerline/bindings/shell/powerline.sh ; cd tests/shell/3rd
|
cd tests/shell/3rd
|
||||||
cd .git
|
cd .git
|
||||||
cd ..
|
cd ..
|
||||||
VIRTUAL_ENV="$HOME/.virtenvs/some-virtual-environment"
|
VIRTUAL_ENV="$HOME/.virtenvs/some-virtual-environment"
|
||||||
|
@ -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
|
unsetenv VIRTUAL_ENV
|
||||||
source powerline/bindings/tcsh/powerline.tcsh ; cd tests/shell/3rd
|
cd tests/shell/3rd
|
||||||
cd .git
|
cd .git
|
||||||
cd ..
|
cd ..
|
||||||
setenv VIRTUAL_ENV $HOME:q"/.virtenvs/some-virtual-environment"
|
setenv VIRTUAL_ENV $HOME:q"/.virtenvs/some-virtual-environment"
|
||||||
|
@ -1,26 +1,21 @@
|
|||||||
unsetopt promptsp transientrprompt
|
unsetopt promptsp notransientrprompt
|
||||||
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
|
setopt interactivecomments
|
||||||
# POWERLINE_CONFIG_PATH=$PWD/powerline/config_files
|
# POWERLINE_CONFIG_PATH=$PWD/powerline/config_files
|
||||||
# POWERLINE_THEME_CONFIG=( default_leftonly.segment_data.hostname.args.only_if_ssh=false )
|
# POWERLINE_THEME_CONFIG=( default_leftonly.segment_data.hostname.args.only_if_ssh=false )
|
||||||
# POWERLINE_CONFIG=( ext.shell.theme=default_leftonly )
|
# POWERLINE_CONFIG=( ext.shell.theme=default_leftonly )
|
||||||
POWERLINE_NO_ZSH_ZPYTHON=1 # TODO: make tests work with zsh/zpython
|
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=
|
export VIRTUAL_ENV=
|
||||||
source powerline/bindings/zsh/powerline.zsh ; cd tests/shell/3rd
|
cd tests/shell/3rd
|
||||||
cd .git
|
cd .git
|
||||||
cd ..
|
cd ..
|
||||||
VIRTUAL_ENV="$HOME/.virtenvs/some-virtual-environment"
|
VIRTUAL_ENV="$HOME/.virtenvs/some-virtual-environment"
|
||||||
VIRTUAL_ENV=
|
VIRTUAL_ENV=
|
||||||
bash -c 'echo $$>pid ; while true ; do sleep 0.1s ; done' &
|
bash -c 'echo $$>pid ; while true ; do sleep 0.1s ; done' &
|
||||||
false
|
false
|
||||||
select abc in def ghi jkl
|
|
||||||
do
|
|
||||||
echo $abc
|
|
||||||
break
|
|
||||||
done
|
|
||||||
1
|
|
||||||
kill `cat pid` ; sleep 1s
|
kill `cat pid` ; sleep 1s
|
||||||
cd "$DIR1"
|
cd "$DIR1"
|
||||||
cd ../"$DIR2"
|
cd ../"$DIR2"
|
||||||
@ -36,5 +31,13 @@ POWERLINE_COMMAND=( $POWERLINE_COMMAND[1,4] ${${POWERLINE_COMMAND[5]}/_leftonly}
|
|||||||
|
|
||||||
echo abc
|
echo abc
|
||||||
false
|
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
|
true is the last line
|
||||||
exit
|
exit
|
||||||
|
@ -8,9 +8,10 @@ import sys
|
|||||||
import codecs
|
import codecs
|
||||||
|
|
||||||
|
|
||||||
shell = sys.argv[1]
|
test_type = sys.argv[1]
|
||||||
fname = os.path.join('tests', 'shell', shell + '.full.log')
|
shell = sys.argv[2]
|
||||||
new_fname = os.path.join('tests', 'shell', shell + '.log')
|
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')
|
pid_fname = os.path.join('tests', 'shell', '3rd', 'pid')
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
width 1024
|
width 1024
|
||||||
height 1
|
height 1
|
||||||
logfile "tests/shell/${SH}.full.log"
|
logfile "tests/shell/${SH}.${TEST_TYPE}.full.log"
|
||||||
|
@ -3,17 +3,23 @@ FAILED=0
|
|||||||
ONLY_SHELL="$1"
|
ONLY_SHELL="$1"
|
||||||
|
|
||||||
check_screen_log() {
|
check_screen_log() {
|
||||||
SH="$1"
|
TEST_TYPE="$1"
|
||||||
if test -e tests/test_shells/${SH}.ok ; then
|
SH="$2"
|
||||||
diff -u tests/test_shells/${SH}.ok tests/shell/${SH}.log
|
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 $?
|
return $?
|
||||||
else
|
else
|
||||||
cat tests/shell/${SH}.log
|
cat tests/shell/${SH}.${TEST_TYPE}.log
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
run_test() {
|
run_test() {
|
||||||
|
TEST_TYPE="$1"
|
||||||
|
shift
|
||||||
SH="$1"
|
SH="$1"
|
||||||
SESNAME="powerline-shell-test-${SH}-$$"
|
SESNAME="powerline-shell-test-${SH}-$$"
|
||||||
ARGS=( "$@" )
|
ARGS=( "$@" )
|
||||||
@ -32,6 +38,7 @@ run_test() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
export TEST_TYPE
|
||||||
export SH
|
export SH
|
||||||
|
|
||||||
screen -L -c tests/test_shells/screenrc -d -m -S "$SESNAME" \
|
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
|
while screen -S "$SESNAME" -X blankerprg "" > /dev/null ; do
|
||||||
sleep 0.1s
|
sleep 0.1s
|
||||||
done
|
done
|
||||||
./tests/test_shells/postproc.py ${SH}
|
./tests/test_shells/postproc.py ${TEST_TYPE} ${SH}
|
||||||
if ! check_screen_log ${SH} ; then
|
if ! check_screen_log ${TEST_TYPE} ${SH} ; then
|
||||||
echo '____________________________________________________________'
|
echo '____________________________________________________________'
|
||||||
# Repeat the diff to make it better viewable in travis output
|
# Repeat the diff to make it better viewable in travis output
|
||||||
echo "Diff (cat -v):"
|
echo "Diff (cat -v):"
|
||||||
echo '============================================================'
|
echo '============================================================'
|
||||||
check_screen_log ${SH} | cat -v
|
check_screen_log ${TEST_TYPE} ${SH} | cat -v
|
||||||
echo '____________________________________________________________'
|
echo '____________________________________________________________'
|
||||||
echo "Failed ${SH}. Full output:"
|
echo "Failed ${SH}. Full output:"
|
||||||
echo '============================================================'
|
echo '============================================================'
|
||||||
cat tests/shell/${SH}.full.log
|
cat tests/shell/${SH}.${TEST_TYPE}.full.log
|
||||||
echo '____________________________________________________________'
|
echo '____________________________________________________________'
|
||||||
echo "Full output (cat -v):"
|
echo "Full output (cat -v):"
|
||||||
echo '============================================================'
|
echo '============================================================'
|
||||||
cat -v tests/shell/${SH}.full.log
|
cat -v tests/shell/${SH}.${TEST_TYPE}.full.log
|
||||||
echo '____________________________________________________________'
|
echo '____________________________________________________________'
|
||||||
case ${SH} in
|
case ${SH} in
|
||||||
*ksh)
|
*ksh)
|
||||||
@ -112,39 +119,61 @@ mkdir tests/shell/3rd/'(echo)'
|
|||||||
mkdir tests/shell/3rd/'$(echo)'
|
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
|
mkdir tests/shell/fish_home
|
||||||
export XDG_CONFIG_HOME="$PWD/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
|
unset ENV
|
||||||
|
|
||||||
if ! run_test mksh -i ; then
|
powerline-daemon -k || true
|
||||||
FAILED=1
|
sleep 1s
|
||||||
fi
|
|
||||||
|
|
||||||
if ! run_test dash -i ; then
|
scripts/powerline-config shell command
|
||||||
# dash tests are not stable, see #931
|
|
||||||
# FAILED=1
|
for TEST_TYPE in "daemon" "nodaemon" ; do
|
||||||
true
|
if test $TEST_TYPE == daemon ; then
|
||||||
fi
|
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)
|
||||||
|
if ! test -z "$(cat tests/shell/daemon_log)" ; then
|
||||||
|
echo '____________________________________________________________'
|
||||||
|
echo "Daemon log:"
|
||||||
|
echo '============================================================'
|
||||||
|
cat tests/shell/daemon_log
|
||||||
|
FAILED=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
test "x$ONLY_SHELL" = "x" && rm -r tests/shell
|
test "x$ONLY_SHELL" = "x" && rm -r tests/shell
|
||||||
exit $FAILED
|
exit $FAILED
|
||||||
|
BIN
tests/test_shells/zsh.daemon.ok
Normal file
BIN
tests/test_shells/zsh.daemon.ok
Normal file
Binary file not shown.
@ -6,15 +6,7 @@
|
|||||||
[0m[23m[24m[J[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtests [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;49;22m [0mbash -c 'echo $$>pid ; while true ; do sleep 0.1s ; done' &
|
[0m[23m[24m[J[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtests [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;49;22m [0mbash -c 'echo $$>pid ; while true ; do sleep 0.1s ; done' &
|
||||||
[1] PID
|
[1] PID
|
||||||
[0m[23m[24m[J[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtests [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;48;5;166;22m [0;38;5;220;48;5;166m1 [0;38;5;166;49;22m [0mfalse
|
[0m[23m[24m[J[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtests [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;48;5;166;22m [0;38;5;220;48;5;166m1 [0;38;5;166;49;22m [0mfalse
|
||||||
[0m[23m[24m[J[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtests [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;48;5;166;22m [0;38;5;220;48;5;166m1 [0;38;5;166;48;5;52;22m [0;38;5;231;48;5;52m1 [0;38;5;52;49;22m [0mselect abc in def ghi jkl
|
[0m[23m[24m[J[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtests [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;48;5;166;22m [0;38;5;220;48;5;166m1 [0;38;5;166;48;5;52;22m [0;38;5;231;48;5;52m1 [0;38;5;52;49;22m [0mkill `cat pid` ; sleep 1s
|
||||||
[0m[23m[24m[J[0;38;5;252;48;5;240;1m select [0;38;5;240;49;22m [0mdo
|
|
||||||
[0m[23m[24m[J[0;38;5;252;48;5;240;1m select [0;38;5;240;49;22m [0m echo $abc
|
|
||||||
[0m[23m[24m[J[0;38;5;252;48;5;240;1m select [0;38;5;240;49;22m [0m break
|
|
||||||
[0m[23m[24m[J[0;38;5;252;48;5;240;1m select [0;38;5;240;49;22m [0mdone
|
|
||||||
1) def 2) ghi 3) jkl
|
|
||||||
[0m[23m[24m[J[0;38;5;252;48;5;240;1m Select variant [0;38;5;240;49;22m [0m1
|
|
||||||
def
|
|
||||||
[0m[23m[24m[J[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtests [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;48;5;166;22m [0;38;5;220;48;5;166m1 [0;38;5;166;49;22m [0mkill `cat pid` ; sleep 1s
|
|
||||||
[1] + terminated bash -c 'echo $$>pid ; while true ; do sleep 0.1s ; done'
|
[1] + terminated bash -c 'echo $$>pid ; while true ; do sleep 0.1s ; done'
|
||||||
[0m[23m[24m[J[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtests [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;49;22m [0mcd "$DIR1"
|
[0m[23m[24m[J[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtests [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;49;22m [0mcd "$DIR1"
|
||||||
[0m[23m[24m[J[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m^[[32m [0;38;5;240;49;22m [0mcd ../"$DIR2"
|
[0m[23m[24m[J[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m^[[32m [0;38;5;240;49;22m [0mcd ../"$DIR2"
|
||||||
@ -31,3 +23,13 @@ def
|
|||||||
[0m[23m[24m[J[0;38;5;22;48;5;148;1m INSERT [0;38;5;148;48;5;166;22m [0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtests [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;49;22m [0mecho abc
|
[0m[23m[24m[J[0;38;5;22;48;5;148;1m INSERT [0;38;5;148;48;5;166;22m [0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtests [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;49;22m [0mecho abc
|
||||||
abc
|
abc
|
||||||
[0m[23m[24m[J[0;38;5;22;48;5;148;1m INSERT [0;38;5;148;48;5;166;22m [0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtests [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;49;22m [0mfalse
|
[0m[23m[24m[J[0;38;5;22;48;5;148;1m INSERT [0;38;5;148;48;5;166;22m [0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtests [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;49;22m [0mfalse
|
||||||
|
[0m[23m[24m[J[0;38;5;22;48;5;148;1m INSERT [0;38;5;148;48;5;166;22m [0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtests [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;49;22m [0mPOWERLINE_COMMAND=( $POWERLINE_COMMAND -t default.segment_data.hostname.display=false )
|
||||||
|
[0m[23m[24m[J[0;38;5;22;48;5;148;1m INSERT [0;38;5;148;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtests [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;49;22m [0mPOWERLINE_COMMAND=( $POWERLINE_COMMAND -t default.segment_data.user.display=false )
|
||||||
|
[0m[23m[24m[J[0;38;5;22;48;5;148;1m INSERT [0;38;5;148;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtests [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;49;22m [0mselect abc in def ghi jkl
|
||||||
|
[0m[23m[24m[J[0;38;5;252;48;5;240;1m select [0;38;5;240;49;22m [0mdo
|
||||||
|
[0m[23m[24m[J[0;38;5;252;48;5;240;1m select [0;38;5;240;49;22m [0m echo $abc
|
||||||
|
[0m[23m[24m[J[0;38;5;252;48;5;240;1m select [0;38;5;240;49;22m [0m break
|
||||||
|
[0m[23m[24m[J[0;38;5;252;48;5;240;1m select [0;38;5;240;49;22m [0mdone
|
||||||
|
1) def 2) ghi 3) jkl
|
||||||
|
[0m[23m[24m[J[0;38;5;252;48;5;240;1m Select variant [0;38;5;240;49;22m [0m1
|
||||||
|
def
|
Loading…
x
Reference in New Issue
Block a user