mirror of
https://github.com/powerline/powerline.git
synced 2025-07-23 13:55:45 +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
|
||||
|
||||
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
|
||||
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
|
||||
=================
|
||||
|
||||
|
@ -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
|
||||
----------------
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
--------------
|
||||
|
||||
|
@ -54,13 +54,12 @@ _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
|
||||
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 "$BASH_SOURCE")/../../.."
|
||||
export POWERLINE_COMMAND="$($powerline_dir/scripts/powerline-config shell command)"
|
||||
fi
|
||||
fi
|
||||
test "x$PROMPT_COMMAND" != "x${PROMPT_COMMAND%_powerline_set_prompt*}" ||
|
||||
|
@ -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'))
|
||||
@ -110,6 +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)
|
||||
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):
|
||||
@ -119,3 +125,44 @@ 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):
|
||||
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_COMMAND"
|
||||
if which powerline-client >/dev/null
|
||||
set -g -x POWERLINE_COMMAND powerline-client
|
||||
else if which powerline >/dev/null
|
||||
set -g -x POWERLINE_COMMAND powerline
|
||||
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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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-client > /dev/null } ) then
|
||||
setenv POWERLINE_COMMAND powerline-client
|
||||
else if ( { which powerline > /dev/null } ) then
|
||||
setenv POWERLINE_COMMAND powerline
|
||||
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
|
||||
|
||||
|
@ -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'
|
||||
|
||||
# Don't version-check for this core functionality -- anything too old to
|
||||
|
@ -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-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
|
||||
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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
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__':
|
||||
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)
|
||||
|
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
|
||||
|
||||
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)
|
68
setup.py
68
setup.py
@ -3,16 +3,52 @@
|
||||
from __future__ import unicode_literals
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import logging
|
||||
|
||||
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()
|
||||
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(
|
||||
name='Powerline',
|
||||
@ -23,11 +59,31 @@ setup(
|
||||
author='Kim Silkebaekken',
|
||||
author_email='kim.silkebaekken+vim@gmail.com',
|
||||
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/powerline',
|
||||
'scripts/powerline-lint',
|
||||
'scripts/powerline-daemon',
|
||||
'scripts/powerline-render',
|
||||
'scripts/powerline-config',
|
||||
],
|
||||
] + (['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,
|
||||
@ -38,5 +94,5 @@ setup(
|
||||
'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 -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -1,26 +1,21 @@
|
||||
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 )
|
||||
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 )
|
||||
# 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"
|
||||
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"
|
||||
@ -36,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
|
||||
|
@ -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')
|
||||
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
width 1024
|
||||
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"
|
||||
|
||||
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,61 @@ 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
|
||||
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' &
|
||||
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
|
||||
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' &
|
||||
[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;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;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
|
||||
[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
|
||||
[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;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
|
||||
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 [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