Merge pull request #1775 from ZyX-I/bash-pipestatus
Add support for pipestatus in bash
This commit is contained in:
commit
b5fe29eff5
|
@ -143,6 +143,40 @@ started from.*
|
|||
Shell issues
|
||||
============
|
||||
|
||||
Pipe status segment displays only last value in bash
|
||||
----------------------------------------------------
|
||||
|
||||
Make sure that powerline command that sets prompt appears the very first in
|
||||
``$PROMPT_COMMAND``. To do this ``powerline.sh`` needs to be sourced the very
|
||||
last, after all other users of ``$PROMPT_COMMAND``.
|
||||
|
||||
Bash prompt stopped updating
|
||||
----------------------------
|
||||
|
||||
Make sure that powerline commands appear in ``$PROMPT_COMMAND``: some users of
|
||||
``$PROMPT_COMMAND`` have a habit of overwriting the value instead of
|
||||
prepending/appending to it. All powerline commands start with ``_powerline`` or
|
||||
``powerline``, e.g. ``_powerline_set_prompt``.
|
||||
|
||||
Bash prompt does not show last exit code
|
||||
----------------------------------------
|
||||
|
||||
There are two possibilities here:
|
||||
|
||||
* You are using ``default`` theme in place of ``default_leftonly``. Unlike
|
||||
``default_leftonly`` ``default`` theme was designed for shells with right
|
||||
prompt support (e.g. zsh, tcsh, fish) and status in question is supposed to be
|
||||
shown on the right side which bash cannot display.
|
||||
|
||||
* There is some other user of ``$PROMPT_COMMAND`` which prepended to this
|
||||
variable, but did not bother keeping the exit code. For the best experience
|
||||
powerline must appear first in ``$PROMPT_COMMAND`` which may be achieved by
|
||||
sourcing powerline bindings the last.
|
||||
|
||||
.. note::
|
||||
Resourcing bash bindings will not resolve the problem unless you clear
|
||||
powerline commands from ``$PROMPT_COMMAND`` first.
|
||||
|
||||
When sourcing shell bindings it complains about missing command or file
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -27,6 +27,31 @@ _powerline_tmux_set_pwd() {
|
|||
fi
|
||||
}
|
||||
|
||||
_powerline_return() {
|
||||
return $1
|
||||
}
|
||||
|
||||
_powerline_status_wrapper() {
|
||||
local last_exit_code=$? last_pipe_status=( "${PIPESTATUS[@]}" )
|
||||
|
||||
if test "$last_exit_code" != "${last_pipe_status[-1]}" ; then
|
||||
last_pipe_status=()
|
||||
fi
|
||||
"$@" $last_exit_code "${last_pipe_status[*]}"
|
||||
return $last_exit_code
|
||||
}
|
||||
|
||||
_powerline_add_status_wrapped_command() {
|
||||
local action="$1" ; shift
|
||||
local cmd="$1" ; shift
|
||||
full_cmd="_powerline_status_wrapper $cmd"
|
||||
if test "$action" = "append" ; then
|
||||
PROMPT_COMMAND="$PROMPT_COMMAND"$'\n'"$full_cmd"
|
||||
else
|
||||
PROMPT_COMMAND="$full_cmd"$'\n'"$PROMPT_COMMAND"
|
||||
fi
|
||||
}
|
||||
|
||||
_powerline_tmux_set_columns() {
|
||||
_powerline_tmux_setenv COLUMNS "${COLUMNS:-`_powerline_columns_fallback`}"
|
||||
}
|
||||
|
@ -40,41 +65,53 @@ _powerline_init_tmux_support() {
|
|||
_powerline_tmux_set_columns
|
||||
|
||||
test "$PROMPT_COMMAND" != "${PROMPT_COMMAND/_powerline_tmux_set_pwd}" \
|
||||
|| PROMPT_COMMAND="${PROMPT_COMMAND}"$'\n_powerline_tmux_set_pwd'
|
||||
|| _powerline_add_status_wrapped_command append _powerline_tmux_set_pwd
|
||||
fi
|
||||
}
|
||||
|
||||
_powerline_local_prompt() {
|
||||
# Arguments: side, renderer_module arg, last_exit_code, jobnum, local theme
|
||||
# Arguments:
|
||||
# 1: side
|
||||
# 2: renderer_module arg
|
||||
# 3: last_exit_code
|
||||
# 4: last_pipe_status
|
||||
# 5: jobnum
|
||||
# 6: local theme
|
||||
"$POWERLINE_COMMAND" $POWERLINE_COMMAND_ARGS shell $1 \
|
||||
$2 \
|
||||
--last-exit-code=$3 \
|
||||
--jobnum=$4 \
|
||||
--last-pipe-status="$4" \
|
||||
--jobnum=$5 \
|
||||
--renderer-arg="client_id=$$" \
|
||||
--renderer-arg="local_theme=$5"
|
||||
--renderer-arg="local_theme=$6"
|
||||
}
|
||||
|
||||
_powerline_prompt() {
|
||||
# Arguments: side, last_exit_code, jobnum
|
||||
# Arguments:
|
||||
# 1: side
|
||||
# 2: last_exit_code
|
||||
# 3: last_pipe_status
|
||||
# 4: jobnum
|
||||
"$POWERLINE_COMMAND" $POWERLINE_COMMAND_ARGS shell $1 \
|
||||
--width="${COLUMNS:-$(_powerline_columns_fallback)}" \
|
||||
-r.bash \
|
||||
--last-exit-code=$2 \
|
||||
--jobnum=$3 \
|
||||
--last-pipe-status="$3" \
|
||||
--jobnum=$4 \
|
||||
--renderer-arg="client_id=$$"
|
||||
}
|
||||
|
||||
_powerline_set_prompt() {
|
||||
local last_exit_code=$?
|
||||
local last_exit_code=$1 ; shift
|
||||
local last_pipe_status=$1 ; shift
|
||||
local jobnum="$(jobs -p|wc -l)"
|
||||
PS1="$(_powerline_prompt aboveleft $last_exit_code $jobnum)"
|
||||
PS1="$(_powerline_prompt aboveleft $last_exit_code "$last_pipe_status" $jobnum)"
|
||||
if test -n "$POWERLINE_SHELL_CONTINUATION$POWERLINE_BASH_CONTINUATION" ; then
|
||||
PS2="$(_powerline_local_prompt left -r.bash $last_exit_code $jobnum continuation)"
|
||||
PS2="$(_powerline_local_prompt left -r.bash $last_exit_code "$last_pipe_status" $jobnum continuation)"
|
||||
fi
|
||||
if test -n "$POWERLINE_SHELL_SELECT$POWERLINE_BASH_SELECT" ; then
|
||||
PS3="$(_powerline_local_prompt left '' $last_exit_code $jobnum select)"
|
||||
PS3="$(_powerline_local_prompt left '' $last_exit_code "$last_pipe_status" $jobnum select)"
|
||||
fi
|
||||
return $last_exit_code
|
||||
}
|
||||
|
||||
_powerline_setup_prompt() {
|
||||
|
@ -83,9 +120,9 @@ _powerline_setup_prompt() {
|
|||
POWERLINE_COMMAND="$("$POWERLINE_CONFIG_COMMAND" shell command)"
|
||||
fi
|
||||
test "$PROMPT_COMMAND" != "${PROMPT_COMMAND%_powerline_set_prompt*}" \
|
||||
|| PROMPT_COMMAND=$'_powerline_set_prompt\n'"${PROMPT_COMMAND}"
|
||||
PS2="$(_powerline_local_prompt left -r.bash 0 0 continuation)"
|
||||
PS3="$(_powerline_local_prompt left '' 0 0 select)"
|
||||
|| _powerline_add_status_wrapped_command prepend _powerline_set_prompt
|
||||
PS2="$(_powerline_local_prompt left -r.bash 0 0 0 continuation)"
|
||||
PS3="$(_powerline_local_prompt left '' 0 0 0 select)"
|
||||
}
|
||||
|
||||
if test -z "${POWERLINE_CONFIG_COMMAND}" ; then
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
"priority": 20
|
||||
},
|
||||
{
|
||||
"function": "powerline.segments.shell.last_status",
|
||||
"function": "powerline.segments.shell.last_pipe_status",
|
||||
"priority": 10
|
||||
}
|
||||
]
|
||||
|
|
|
@ -39,7 +39,10 @@ def last_pipe_status(pl, segment_info):
|
|||
|
||||
Highlight groups used: ``exit_fail``, ``exit_success``
|
||||
'''
|
||||
last_pipe_status = segment_info['args'].last_pipe_status
|
||||
last_pipe_status = (
|
||||
segment_info['args'].last_pipe_status
|
||||
or (segment_info['args'].last_exit_code,)
|
||||
)
|
||||
if any(last_pipe_status):
|
||||
return [
|
||||
{
|
||||
|
|
|
@ -125,6 +125,11 @@ class TestParser(TestCase):
|
|||
'side': 'left',
|
||||
'config_override': {'common': {}},
|
||||
}),
|
||||
(['shell', 'left', '--last-pipe-status='], {
|
||||
'ext': ['shell'],
|
||||
'side': 'left',
|
||||
'last_pipe_status': [],
|
||||
}),
|
||||
]:
|
||||
args = parser.parse_args(argv)
|
||||
finish_args(parser, {}, args)
|
||||
|
|
|
@ -138,7 +138,7 @@ class TestConfig(TestCase):
|
|||
|
||||
def test_bash(self):
|
||||
from powerline.shell import ShellPowerline
|
||||
args = Args(last_exit_code=1, jobnum=0, ext=['shell'], renderer_module='.bash', config_override={'ext': {'shell': {'theme': 'default_leftonly'}}})
|
||||
args = Args(last_exit_code=1, last_pipe_status=[], jobnum=0, ext=['shell'], renderer_module='.bash', config_override={'ext': {'shell': {'theme': 'default_leftonly'}}})
|
||||
with ShellPowerline(args, logger=get_logger(), run_once=False) as powerline:
|
||||
powerline.render(segment_info={'args': args})
|
||||
with ShellPowerline(args, logger=get_logger(), run_once=False) as powerline:
|
||||
|
|
|
@ -52,15 +52,35 @@ class TestShell(TestCase):
|
|||
|
||||
def test_last_pipe_status(self):
|
||||
pl = Pl()
|
||||
segment_info = {'args': Args(last_pipe_status=[])}
|
||||
segment_info = {'args': Args(last_pipe_status=[], last_exit_code=0)}
|
||||
self.assertEqual(shell.last_pipe_status(pl=pl, segment_info=segment_info), None)
|
||||
segment_info['args'].last_pipe_status = [0, 0, 0]
|
||||
self.assertEqual(shell.last_pipe_status(pl=pl, segment_info=segment_info), None)
|
||||
segment_info['args'].last_pipe_status = [0, 0]
|
||||
self.assertEqual(shell.last_pipe_status(pl=pl, segment_info=segment_info), None)
|
||||
segment_info['args'].last_pipe_status = [0]
|
||||
self.assertEqual(shell.last_pipe_status(pl=pl, segment_info=segment_info), None)
|
||||
segment_info['args'].last_pipe_status = [0, 2, 0]
|
||||
self.assertEqual(shell.last_pipe_status(pl=pl, segment_info=segment_info), [
|
||||
{'contents': '0', 'highlight_groups': ['exit_success'], 'draw_inner_divider': True},
|
||||
{'contents': '2', 'highlight_groups': ['exit_fail'], 'draw_inner_divider': True},
|
||||
{'contents': '0', 'highlight_groups': ['exit_success'], 'draw_inner_divider': True}
|
||||
{'contents': '0', 'highlight_groups': ['exit_success'], 'draw_inner_divider': True},
|
||||
])
|
||||
segment_info['args'].last_pipe_status = [2, 0, 0]
|
||||
self.assertEqual(shell.last_pipe_status(pl=pl, segment_info=segment_info), [
|
||||
{'contents': '2', 'highlight_groups': ['exit_fail'], 'draw_inner_divider': True},
|
||||
{'contents': '0', 'highlight_groups': ['exit_success'], 'draw_inner_divider': True},
|
||||
{'contents': '0', 'highlight_groups': ['exit_success'], 'draw_inner_divider': True},
|
||||
])
|
||||
segment_info['args'].last_pipe_status = [0, 0, 2]
|
||||
self.assertEqual(shell.last_pipe_status(pl=pl, segment_info=segment_info), [
|
||||
{'contents': '0', 'highlight_groups': ['exit_success'], 'draw_inner_divider': True},
|
||||
{'contents': '0', 'highlight_groups': ['exit_success'], 'draw_inner_divider': True},
|
||||
{'contents': '2', 'highlight_groups': ['exit_fail'], 'draw_inner_divider': True},
|
||||
])
|
||||
segment_info['args'].last_pipe_status = [2]
|
||||
self.assertEqual(shell.last_pipe_status(pl=pl, segment_info=segment_info), [
|
||||
{'contents': '2', 'highlight_groups': ['exit_fail'], 'draw_inner_divider': True},
|
||||
])
|
||||
segment_info['args'].last_pipe_status = [0, 'sigsegv', 'sigsegv+core']
|
||||
self.assertEqual(shell.last_pipe_status(pl=pl, segment_info=segment_info), [
|
||||
|
@ -80,6 +100,11 @@ class TestShell(TestCase):
|
|||
{'contents': 'sigsegv+core', 'highlight_groups': ['exit_fail'], 'draw_inner_divider': True},
|
||||
{'contents': '0', 'highlight_groups': ['exit_success'], 'draw_inner_divider': True}
|
||||
])
|
||||
segment_info['args'].last_pipe_status = []
|
||||
segment_info['args'].last_exit_code = 5
|
||||
self.assertEqual(shell.last_pipe_status(pl=pl, segment_info=segment_info), [
|
||||
{'contents': '5', 'highlight_groups': ['exit_fail'], 'draw_inner_divider': True},
|
||||
])
|
||||
|
||||
def test_jobnum(self):
|
||||
pl = Pl()
|
||||
|
|
|
@ -55,6 +55,7 @@ cd ../'(echo)'
|
|||
cd ../'$(echo)'
|
||||
cd ../'`echo`'
|
||||
cd ../'«Unicode!»'
|
||||
(exit 42)|(exit 43)
|
||||
set_theme_option default_leftonly.segments.above "$ABOVE_LEFT"
|
||||
export DISPLAYED_ENV_VAR=foo
|
||||
unset DISPLAYED_ENV_VAR
|
||||
|
|
|
@ -26,7 +26,8 @@ def
|
|||
[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(echo) [0;38;5;240;49;22m [0mcd ../'$(echo)'
|
||||
[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$(echo) [0;38;5;240;49;22m [0mcd ../'`echo`'
|
||||
[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`echo` [0;38;5;240;49;22m [0mcd ../'«Unicode!»'
|
||||
[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«Unicode!» [0;38;5;240;49;22m [0mset_theme_option default_leftonly.segments.above "$ABOVE_LEFT"
|
||||
[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«Unicode!» [0;38;5;240;49;22m [0m(exit 42)|(exit 43)
|
||||
[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«Unicode!» [0;38;5;240;48;5;52;22m [0;38;5;231;48;5;52m42 [0;38;5;231;48;5;52;22m [0;38;5;231;48;5;52m43 [0;38;5;52;49;22m [0mset_theme_option default_leftonly.segments.above "$ABOVE_LEFT"
|
||||
[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«Unicode!» [0;38;5;240;49;22m [0mexport DISPLAYED_ENV_VAR=foo
|
||||
[0;38;5;231;48;5;22m foo [0;38;5;22;49;22m [0m
|
||||
[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«Unicode!» [0;38;5;240;49;22m [0munset DISPLAYED_ENV_VAR
|
||||
|
|
|
@ -26,7 +26,8 @@ def
|
|||
[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(echo) [0;38;5;240;49;22m [0mcd ../'$(echo)'
|
||||
[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$(echo) [0;38;5;240;49;22m [0mcd ../'`echo`'
|
||||
[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`echo` [0;38;5;240;49;22m [0mcd ../'«Unicode!»'
|
||||
[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«Unicode!» [0;38;5;240;49;22m [0mset_theme_option default_leftonly.segments.above "$ABOVE_LEFT"
|
||||
[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«Unicode!» [0;38;5;240;49;22m [0m(exit 42)|(exit 43)
|
||||
[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«Unicode!» [0;38;5;240;48;5;52;22m [0;38;5;231;48;5;52m42 [0;38;5;231;48;5;52;22m [0;38;5;231;48;5;52m43 [0;38;5;52;49;22m [0mset_theme_option default_leftonly.segments.above "$ABOVE_LEFT"
|
||||
[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«Unicode!» [0;38;5;240;49;22m [0mexport DISPLAYED_ENV_VAR=foo
|
||||
[0;38;5;231;48;5;22m foo [0;38;5;22;49;22m [0m
|
||||
[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«Unicode!» [0;38;5;240;49;22m [0munset DISPLAYED_ENV_VAR
|
||||
|
|
Loading…
Reference in New Issue