Add various other shell implementations support

Tested in busybox, mksh, ksh and dash. Ksh has issues described in 
troubleshooting.
This commit is contained in:
ZyX 2014-07-20 00:24:12 +04:00
parent 3d12662f8b
commit a8da67e2aa
4 changed files with 240 additions and 0 deletions

View File

@ -132,3 +132,10 @@ To get rid of these lags there currently are two options:
the future.
* Compile and install ``libzpython`` module that lives in
https://bitbucket.org/ZyX_I/zpython. This variant is zsh-specific.
Prompt is spoiled after completing files in ksh
-----------------------------------------------
This is exactly why powerline has official mksh support, but not official ksh
support. If you know the solution feel free to share it in `powerline bug
tracker <https://github.com/Lokaltog/powerline/issues/new>`_.

View File

@ -166,6 +166,38 @@ is the absolute path to your Powerline installation directory:
.. _tmux-statusline:
Busybox (ash), mksh and dash prompt
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
After launching busybox run the following command:
.. code-block:: bash
. {repository_root}/powerline/bindings/shell/powerline.sh
Mksh users may put this line into ``~/.mkshrc`` file. Dash users may use the
following in ``~/.profile``:
.. code-block:: bash
if test "x$0" != "x${0#dash}" ; then
export ENV={repository_root}/powerline/bindings/shell/powerline.sh
fi
.. note::
Dash users that already have ``$ENV`` defined should either put the ``.
…/shell/powerline.sh`` line in the ``$ENV`` file or create a new file which
will source (using ``.`` command) both former ``$ENV`` file and
:file:`powerline.sh` files and set ``$ENV`` to the path of this new file.
.. warning::
Job count is using some weird hack that uses signals and temporary files for
interprocess communication. It may be wrong sometimes. Not the case in mksh.
.. warning::
Busybox has two shells: ``ash`` and ``hush``. Second is known to segfault in
busybox 1.22.1 when using :file:`powerline.sh` script.
Tmux statusline
---------------

View File

@ -0,0 +1,181 @@
_powerline_columns_fallback() {
if which stty >/dev/null ; then
# Ksh does not have “local” built-in
_powerline_cols="$(stty size 2>/dev/null)"
if ! test -z "$_powerline_cols" ; then
echo "${_powerline_cols#* }"
return 0
fi
fi
echo 0
return 0
}
_powerline_has_jobs_in_subshell() {
if test -n "$_POWERLINE_HAS_JOBS_IN_SUBSHELL" ; then
return $_POWERLINE_HAS_JOBS_IN_SUBSHELL
elif test -z "$1" ; then
sleep 1 &
# Check whether shell outputs anything in a subshell when using jobs
# built-in. Shells like dash will not output anything meaning that
# I have to bother with temporary files.
test "$(jobs -p|wc -l)" -gt 0
else
case "$1" in
dash|bb|ash) return 1 ;;
mksh|ksh|bash) return 0 ;;
*) _powerline_has_jobs_in_subshell ;;
esac
fi
_POWERLINE_HAS_JOBS_IN_SUBSHELL=$?
return $_POWERLINE_HAS_JOBS_IN_SUBSHELL
}
_powerline_set_append_trap() {
if _powerline_has_jobs_in_subshell "$@" ; then
_powerline_append_trap() {
# Arguments: command, signal
# Ksh does not have “local” built-in
_powerline_traps="$(trap)"
if echo "$_powerline_traps" | grep -cm1 $2'$' >/dev/null ; then
_powerline_traps="$(echo "$_powerline_traps" | sed "s/ $2/'\\n$1' $2/")"
eval "$_powerline_traps"
fi
}
else
_powerline_append_trap() {
# Arguments: command, signal
_powerline_create_temp
trap > $_POWERLINE_TEMP
if grep -cm1 $2'$' $_POWERLINE_TEMP >/dev/null ; then
sed -i -e "s/ $2/'\\n$1' $2/"
. $_POWERLINE_TEMP
else
trap "$1" $2
fi
echo -n > $_POWERLINE_TEMP
}
fi
_powerline_set_append_trap() {
return 0
}
}
_powerline_create_temp() {
if test -z "$_POWERLINE_TEMP" || ! test -e "$_POWERLINE_TEMP" ; then
_POWERLINE_TEMP="$(mktemp)"
_powerline_append_trap 'rm $_POWERLINE_TEMP' EXIT
fi
}
_powerline_set_set_jobs() {
if _powerline_has_jobs_in_subshell "$@" ; then
_powerline_set_jobs() {
_POWERLINE_JOBS="$(jobs -p|wc -l)"
}
else
_powerline_set_append_trap "$@"
_POWERLINE_PID=$$
_powerline_append_trap '_powerline_do_set_jobs' USR1
_powerline_do_set_jobs() {
_powerline_create_temp
jobs -p > $_POWERLINE_TEMP
}
# This command will always be launched from a subshell, thus a hack is
# needed to run `jobs -p` outside of the subshell.
_powerline_set_jobs() {
kill -USR1 $_POWERLINE_PID
# Note: most likely this will read data from the previous run. Tests
# show that it is OK for some reasons.
_POWERLINE_JOBS="$(wc -l < $_POWERLINE_TEMP)"
}
fi
_powerline_set_set_jobs() {
return 0
}
}
_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
else
# `$0` is set to `-bash` when using SSH so that won't work
export POWERLINE_COMMAND="$(dirname "$BASH_SOURCE")/../../../scripts/powerline"
fi
fi
}
_powerline_tmux_setenv() {
TMUX="$_POWERLINE_TMUX" tmux setenv -g TMUX_"$1"_`tmux display -p "#D" | tr -d %` "$2"
TMUX="$_POWERLINE_TMUX" tmux refresh -S
}
_powerline_tmux_set_pwd() {
if test "x$_POWERLINE_SAVED_PWD" != "x$PWD" ; then
_POWERLINE_SAVED_PWD="$PWD"
_powerline_tmux_setenv PWD "$PWD"
fi
}
_powerline_tmux_set_columns() {
_powerline_tmux_setenv COLUMNS "${COLUMNS:-$(_powerline_columns_fallback)}"
}
_powerline_set_renderer_arg() {
case "$1" in
bb|ash) _POWERLINE_RENDERER_ARG="-rbash_prompt" ;;
mksh|ksh) _POWERLINE_RENDERER_ARG="-rksh_prompt" ;;
bash|dash) _POWERLINE_RENDERER_ARG= ;;
esac
}
_powerline_set_jobs() {
_powerline_set_set_jobs
_powerline_set_jobs
}
_powerline_prompt() {
# Arguments: side, exit_code
_powerline_set_jobs
$POWERLINE_COMMAND shell $1 -w "${COLUMNS:-$(_powerline_columns_fallback)}" $_POWERLINE_RENDERER_ARG --last_exit_code=$2 --jobnum=$_POWERLINE_JOBS
}
_powerline_setup_prompt() {
VIRTUAL_ENV_DISABLE_PROMPT=1
_powerline_set_append_trap "$@"
_powerline_set_set_jobs "$@"
_powerline_set_command "$@"
_powerline_set_renderer_arg "$@"
PS1='$(_powerline_prompt aboveleft $?)'
}
_powerline_init_tmux_support() {
# Dash does not have &>/dev/null
if test -n "$TMUX" && tmux refresh -S >/dev/null 2>/dev/null ; then
# TMUX variable may be unset to create new tmux session inside this one
_POWERLINE_TMUX="$TMUX"
_powerline_set_append_trap "$@"
# If _powerline_tmux_set_pwd is used before _powerline_prompt it sets $?
# to zero in ksh.
PS1="$PS1"'$(_powerline_tmux_set_pwd)'
_powerline_append_trap '_powerline_tmux_set_columns' WINCH
_powerline_tmux_set_columns
fi
}
# Strips the leading `-`: it may be present when shell is a login shell
_POWERLINE_USED_SHELL=${0#-}
_POWERLINE_USED_SHELL=${_POWERLINE_USED_SHELL#/usr}
_POWERLINE_USED_SHELL=${_POWERLINE_USED_SHELL#/bin/}
if test -z "$POWERLINE_NO_BB_PROMPT$POWERLINE_NO_SHELL_PROMPT" ; then
_powerline_setup_prompt $_POWERLINE_USED_SHELL
fi
if test -z "$POWERLINE_NO_BB_TMUX_SUPPORT$POWERLINE_NO_SHELL_TMUX_SUPPORT" ; then
_powerline_init_tmux_support $_POWERLINE_USED_SHELL
fi

View File

@ -0,0 +1,20 @@
# vim:fileencoding=utf-8:noet
from __future__ import absolute_import, unicode_literals
from powerline.renderers.shell import ShellRenderer
ESCAPE_CHAR = '\001'
class KshPromptRenderer(ShellRenderer):
'''Powerline bash prompt segment renderer.'''
escape_hl_start = '\001'
escape_hl_end = '\001'
def render(self, *args, **kwargs):
return '\001\r' + super(KshPromptRenderer, self).render(*args, **kwargs)
renderer = KshPromptRenderer