Release 2.7

- Added ALE support.
- Added mocp support.
- Added awesome 4+ support.
- Added support for `$pipestatus` in bash.
- Recognize terminal-job mode.
- Fixed i3 bindings when both i3-py and i3ipc are installed.
- Fixed i3 bar bindings.
- Fixed checking for battery in WSL.
- Fixed spotify segment on Mac OS.
- Fixed compiling C client with GCC-7.
This commit is contained in:
Foo 2018-08-12 22:41:44 +03:00
commit 3b85be6836
63 changed files with 1108 additions and 236 deletions

5
.gitignore vendored
View File

@ -10,4 +10,7 @@ build
message.fail
client/powerline
/client/powerline
/tests/tmp
/tests/status

View File

@ -1,4 +1,5 @@
sudo: false
dist: trusty
cache:
directories:
- $HOME/.cache/pip
@ -17,19 +18,25 @@ addons:
language: python
install: tests/install.sh
script: tests/test.sh
matrix:
jobs:
include:
- python: "2.6"
- python: "2.7"
- python: "3.2"
- python: "3.3"
- python: "3.4"
- python: "3.5"
- python: "pypy"
- python: "pypy3"
- python: "2.7"
- stage: UCS2 python
python: "2.7"
env: >-
USE_UCS2_PYTHON=1
UCS2_PYTHON_VARIANT="2.7"
- stage: Old Python
python: "2.6"
- python: "3.2"
- stage: PyPy
python: "pypy"
- python: "pypy3"
- stage: Latest Python
python: "2.7"
- python: "3.6"
- stage: Intermediate versions
python: "3.3"
- python: "3.4"
- python: "3.5"
# vim: et

View File

@ -6,8 +6,8 @@ Powerline
:Version: beta
**Powerline is a statusline plugin for vim, and provides statuslines and
prompts for several other applications, including zsh, bash, tmux, IPython,
Awesome, i3 and Qtile.**
prompts for several other applications, including zsh, bash, fish, tmux,
IPython, Awesome, i3 and Qtile.**
* `Support forum`_ (powerline-support@googlegroups.com)
* `Development discussion`_ (powerline-dev@googlegroups.com)

View File

@ -42,7 +42,7 @@ void do_write(int sd, const char *raw, size_t len) {
}
}
inline size_t true_sun_len(const struct sockaddr_un *ptr) {
static inline size_t true_sun_len(const struct sockaddr_un *ptr) {
#ifdef __linux__
/* Because SUN_LEN uses strlen and abstract namespace paths begin
* with a null byte, SUN_LEN is broken for these. Passing the full
@ -71,7 +71,7 @@ inline size_t true_sun_len(const struct sockaddr_un *ptr) {
#endif
#define ADDRESS_SIZE sizeof(ADDRESS_TEMPLATE) + (sizeof(uid_t) * 4)
#define NUM_ARGS_SIZE (sizeof(int) * 2)
#define NUM_ARGS_SIZE (sizeof(int) * 2 + 1)
#define BUF_SIZE 4096
#define NEW_ARGV_SIZE 200
@ -88,6 +88,7 @@ int main(int argc, char *argv[]) {
char *wd = NULL;
char **envp;
const char *address;
int len;
if (argc < 2) {
printf("Must provide at least one argument.\n");
@ -122,8 +123,8 @@ int main(int argc, char *argv[]) {
execvp("powerline-render", newargv);
}
snprintf(num_args, NUM_ARGS_SIZE, "%x", argc - 1);
do_write(sd, num_args, strlen(num_args));
len = snprintf(num_args, NUM_ARGS_SIZE, "%x", argc - 1);
do_write(sd, num_args, len);
do_write(sd, eof, 1);
for (i = 1; i < argc; i++) {

View File

@ -9,6 +9,12 @@ Vim segments
Plugin-specific segments
========================
Asynchronous Linter Engine (ALE) segments
-----------------------------------------
.. automodule:: powerline.segments.vim.plugin.ale
:members:
Syntastic segments
------------------

View File

@ -41,7 +41,7 @@ Generic requirements
.. _repository-root:
.. note::
When using ``pip`` ``{repository_root}`` directory referenced in
When using ``pip``, the ``{repository_root}`` directory referenced in
documentation may be found using ``pip show powerline-status``. In the output
of ``pip show`` there is a line like ``Location: {path}``, that ``{path}`` is
``{repository_root}``. Unless it is ``--editable`` installation this is only

View File

@ -60,12 +60,12 @@ with any coding font.
#. Move the symbol font to a valid X font path. Valid font paths can be
listed with ``xset q``::
mv PowerlineSymbols.otf ~/.fonts/
mv PowerlineSymbols.otf ~/.local/share/fonts/
#. Update font cache for the path the font was moved to (root priveleges may be
needed to update cache for the system-wide paths)::
fc-cache -vf ~/.fonts/
fc-cache -vf ~/.local/share/fonts/
#. Install the fontconfig file. For newer versions of fontconfig the config
path is ``~/.config/fontconfig/conf.d/``, for older versions its
@ -92,12 +92,12 @@ After downloading font the following should be done:
#. Move the patched font to a valid X font path. Valid font paths can be
listed with ``xset q``::
mv 'SomeFont for Powerline.otf' ~/.fonts/
mv 'SomeFont for Powerline.otf' ~/.local/share/fonts/
#. Update font cache for the path the font was moved to (root priveleges may be
#. Update font cache for the path the font was moved to (root privileges may be
needed for updating font cache for some paths)::
fc-cache -vf ~/.fonts/
fc-cache -vf ~/.local/share/fonts/
After installing patched font terminal emulator, GVim or whatever application
powerline should work with must be configured to use the patched font. The

View File

@ -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
-----------------------------------------------------------------------

View File

@ -27,7 +27,7 @@ The colors look weird in iTerm2!
* The arrows may have the wrong colors if you have changed the “minimum
contrast” slider in the color tab of your OS X settings.
* Please disable background transparency to resolve this issue.
* If you're using transparency, check “Keep background colors opaque”.
Statusline is getting wrapped to the next line in iTerm2
--------------------------------------------------------

View File

@ -8,7 +8,7 @@ Application-specific requirements
Vim plugin requirements
^^^^^^^^^^^^^^^^^^^^^^^
The vim plugin requires a vim version with Python support compiled in. Presense
The vim plugin requires a vim version with Python support compiled in. Presence
of Python support in Vim can be checked by running ``vim --version | grep
+python``.

View File

@ -5,7 +5,7 @@ Window manager widgets
Awesome widget
==============
.. note:: Powerline currently only supports awesome 3.5.
.. note:: Powerline currently only supports awesome 3.5 and 4+.
.. note:: The Powerline widget will spawn a shell script that runs in the
background and updates the statusline with ``awesome-client``.
@ -23,7 +23,17 @@ Then add the ``powerline_widget`` to ``wibox``:
.. code-block:: lua
-- awesome3.5
right_layout:add(powerline_widget)
-- awesome4+
s.mywibox:setup {
...
{ -- Right widgets
...
powerline_widget,
},
}
Qtile widget
============
@ -82,20 +92,11 @@ All ``powerline-lemonbar.py`` arguments:
I3 bar
======
.. note::
As the patch to include background-colors in i3bar is likely not to be
merged, it is recommended to instead run ``bar`` (see above). The source for
i3bgbar is however still available `here
<https://github.com/S0lll0s/i3bgbar>`_.
Add the following to :file:`~/.i3/config`::
Add the following to :file:`~/.config/i3/config`::
bar {
i3bar_command i3bgbar
status_command python /path/to/powerline/bindings/i3/powerline-i3.py
font pango:PowerlineFont 12
}
where ``i3bgbar`` may be replaced with the path to the custom i3bar binary and
``PowerlineFont`` is any system font with powerline support.
where ``PowerlineFont`` is any system font with powerline support.

View File

@ -6,5 +6,10 @@ powerline_widget:set_align('right')
function powerline(mode, widget) end
awful.util.spawn_with_shell('powerline-daemon -q')
awful.util.spawn_with_shell('powerline wm.awesome')
if string.find(awesome.version, 'v4') then
awful.spawn.with_shell('powerline-daemon -q')
awful.spawn.with_shell('powerline wm.awesome')
else
awful.util.spawn_with_shell('powerline-daemon -q')
awful.util.spawn_with_shell('powerline wm.awesome')
end

View File

@ -27,6 +27,43 @@ _powerline_tmux_set_pwd() {
fi
}
_powerline_return() {
return $1
}
_POWERLINE_HAS_PIPESTATUS="$(
_powerline_return 0 | _powerline_return 43
test "${PIPESTATUS[*]}" = "0 43"
echo "$?"
)"
_powerline_has_pipestatus() {
return $_POWERLINE_HAS_PIPESTATUS
}
_powerline_status_wrapper() {
local last_exit_code=$? last_pipe_status=( "${PIPESTATUS[@]}" )
if ! _powerline_has_pipestatus \
|| test "${#last_pipe_status[@]}" -eq "0" \
|| test "$last_exit_code" != "${last_pipe_status[$(( ${#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 +77,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 +132,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

View File

@ -164,7 +164,10 @@ def init_tmux_environment(pl, args, set_tmux_environment=set_tmux_environment):
# But it does not support empty attributes as well.
or 'none'))
else:
set_tmux_environment(varname, 'colour' + str(get_highlighting(group)[attr][0]))
if powerline.common_config['term_truecolor']:
set_tmux_environment(varname, '#{0:06x}'.format(get_highlighting(group)[attr][1]))
else:
set_tmux_environment(varname, 'colour' + str(get_highlighting(group)[attr][0]))
left_dividers = powerline.renderer.theme.dividers['left']
set_tmux_environment('_POWERLINE_LEFT_HARD_DIVIDER', left_dividers['hard'])

View File

@ -7,37 +7,44 @@ import time
from threading import Lock
import i3
from powerline.bindings.wm import get_i3_connection, i3_subscribe
from powerline import Powerline
from powerline.lib.monotonic import monotonic
class I3Powerline(Powerline):
'''Powerline child for i3bar
Currently only changes the default log target.
'''
default_log_stream = sys.stderr
if __name__ == '__main__':
name = 'wm'
if len(sys.argv) > 1:
name = sys.argv[1]
powerline = Powerline(name, renderer_module='i3bar')
powerline = I3Powerline(name, renderer_module='i3bar')
powerline.update_renderer()
interval = 0.5
print ('{"version": 1, "custom_workspace": true}')
print ('{"version": 1}')
print ('[')
print ('\t[[],[]]')
print ('[]')
lock = Lock()
def render(event=None, data=None, sub=None):
global lock
with lock:
s = '[\n' + powerline.render(side='right')[:-2] + '\n]\n'
s += ',[\n' + powerline.render(side='left')[:-2] + '\n]'
print (',[\n' + s + '\n]')
print (',[' + powerline.render()[:-1] + ']')
sys.stdout.flush()
sub = i3.Subscription(render, 'workspace')
i3 = get_i3_connection()
i3_subscribe(i3, 'workspace', render)
while True:
start_time = monotonic()

View File

@ -14,6 +14,44 @@ DEFAULT_UPDATE_INTERVAL = 0.5
conn = None
def i3_subscribe(conn, event, callback):
'''Subscribe to i3 workspace event
:param conn:
Connection returned by :py:func:`get_i3_connection`.
:param str event:
Event to subscribe to, e.g. ``'workspace'``.
:param func callback:
Function to run on event.
'''
try:
import i3ipc
except ImportError:
import i3
conn.Subscription(callback, event)
return
else:
pass
conn.on(event, callback)
from threading import Thread
class I3Thread(Thread):
daemon = True
def __init__(self, conn):
super(I3Thread, self).__init__()
self.__conn = conn
def run(self):
self.__conn.main()
thread = I3Thread(conn=conn)
thread.start()
def get_i3_connection():
'''Return a valid, cached i3 Connection instance
'''

View File

@ -117,7 +117,8 @@
"r": "PROMPT",
"rm": "-MORE-",
"r?": "CNFIRM",
"!": "!SHELL"
"!": "!SHELL",
"t": "TERM "
}
}
},

View File

@ -115,7 +115,8 @@
"r": "PROMPT",
"rm": "-MORE-",
"r?": "CNFIRM",
"!": "!SHELL"
"!": "!SHELL",
"t": "TERM "
}
}
},

View File

@ -115,7 +115,8 @@
"r": "PROMPT",
"rm": "-MORE-",
"r?": "CNFIRM",
"!": "!SHELL"
"!": "!SHELL",
"t": "TERM "
}
}
},

View File

@ -129,7 +129,8 @@
"r": "PROMPT",
"rm": "-MORE-",
"r?": "CNFIRM",
"!": "!SHELL"
"!": "!SHELL",
"t": "TERM "
}
}
},

View File

@ -26,7 +26,7 @@
"priority": 20
},
{
"function": "powerline.segments.shell.last_status",
"function": "powerline.segments.shell.last_pipe_status",
"priority": 10
}
]

View File

@ -115,7 +115,8 @@
"r": "PROMPT",
"rm": "-MORE-",
"r?": "CNFIRM",
"!": "!SHELL"
"!": "!SHELL",
"t": "TERM "
}
}
},

View File

@ -115,7 +115,8 @@
"r": "PROMPT",
"rm": "-MORE-",
"r?": "CNFIRM",
"!": "!SHELL"
"!": "!SHELL",
"t": "TERM "
}
}
},

View File

@ -29,9 +29,8 @@ class I3barRenderer(Renderer):
segment['color'] = '#{0:06x}'.format(fg[1])
if bg is not None:
if bg is not False and bg[1] is not False:
segment['background_color'] = '#{0:06x}'.format(bg[1])
# i3bar “pseudo json” requires one line at a time
return json.dumps(segment) + ',\n'
segment['background'] = '#{0:06x}'.format(bg[1])
return json.dumps(segment) + ','
renderer = I3barRenderer

View File

@ -48,12 +48,18 @@ class TmuxRenderer(Renderer):
if fg is False or fg[0] is False:
tmux_attrs += ['fg=default']
else:
tmux_attrs += ['fg=colour' + str(fg[0])]
if self.term_truecolor and fg[1]:
tmux_attrs += ['fg=#{0:06x}'.format(int(fg[1]))]
else:
tmux_attrs += ['fg=colour' + str(fg[0])]
if bg is not None:
if bg is False or bg[0] is False:
tmux_attrs += ['bg=default']
else:
tmux_attrs += ['bg=colour' + str(bg[0])]
if self.term_truecolor and bg[1]:
tmux_attrs += ['bg=#{0:06x}'.format(int(bg[1]))]
else:
tmux_attrs += ['bg=colour' + str(bg[0])]
if attrs is not None:
tmux_attrs += attrs_to_tmux_attrs(attrs)
return '#[' + ','.join(tmux_attrs) + ']'

View File

@ -114,6 +114,21 @@ def _fetch_battery_info(pl):
return (energy * 100.0 / energy_full), state
return _get_battery_status
pl.debug('Not using /sys/class/power_supply as no batteries were found')
else:
pl.debug("Checking for first capacity battery percentage")
for batt in os.listdir('/sys/class/power_supply'):
if os.path.exists('/sys/class/power_supply/{0}/capacity'.format(batt)):
def _get_battery_perc(pl):
state = True
with open('/sys/class/power_supply/{0}/capacity'.format(batt), 'r') as f:
perc = int(f.readline().split()[0])
try:
with open(linux_status_fmt.format(batt), 'r') as f:
state &= (f.readline().strip() != 'Discharging')
except IOError:
state = None
return perc, state
return _get_battery_perc
else:
pl.debug('Not using /sys/class/power_supply: no directory')

View File

@ -159,7 +159,8 @@ username = False
_geteuid = getattr(os, 'geteuid', lambda: 1)
def user(pl, hide_user=None, hide_domain=False):
@requires_segment_info
def user(pl, segment_info, hide_user=None, hide_domain=False):
'''Return the current user.
:param str hide_user:
@ -172,6 +173,11 @@ def user(pl, hide_user=None, hide_domain=False):
Highlight groups used: ``superuser`` or ``user``. It is recommended to define all highlight groups.
'''
global username
if (
segment_info['environ'].get('_POWERLINE_RUNNING_SHELL_TESTS')
== 'ee5bcdc6-b749-11e7-9456-50465d597777'
):
return 'user'
if username is False:
username = _get_user()
if username is None:

View File

@ -22,6 +22,11 @@ def hostname(pl, segment_info, only_if_ssh=False, exclude_domain=False):
:param bool exclude_domain:
return the hostname without domain if there is one
'''
if (
segment_info['environ'].get('_POWERLINE_RUNNING_SHELL_TESTS')
== 'ee5bcdc6-b749-11e7-9456-50465d597777'
):
return 'hostname'
if only_if_ssh and not segment_info['environ'].get('SSH_CLIENT'):
return None
if exclude_domain:

View File

@ -254,6 +254,14 @@ else:
return
if not info:
return
try:
elapsed = iface.Get(iface_player, 'Position')
except dbus.exceptions.DBusException:
pl.warning('Missing player elapsed time')
elapsed = None
else:
elapsed = _convert_seconds(elapsed / 1e6)
album = info.get('xesam:album')
title = info.get('xesam:title')
artist = info.get('xesam:artist')
@ -269,6 +277,7 @@ else:
'album': album,
'artist': artist,
'title': title,
'elapsed': elapsed,
'total': _convert_seconds(info.get('mpris:length') / 1e6),
}
@ -299,6 +308,17 @@ Requires ``dbus`` python module. Only for players that support specific protocol
class SpotifyDbusPlayerSegment(PlayerSegment):
def get_player_status(self, pl):
player_status = _get_dbus_player_status(
pl=pl,
player_name='Spotify',
bus_name='org.mpris.MediaPlayer2.spotify',
player_path='/org/mpris/MediaPlayer2',
iface_prop='org.freedesktop.DBus.Properties',
iface_player='org.mpris.MediaPlayer2.Player',
)
if player_status is not None:
return player_status
# Fallback for legacy spotify client with different DBus protocol
return _get_dbus_player_status(
pl=pl,
player_name='Spotify',
@ -333,7 +353,7 @@ class SpotifyAppleScriptPlayerSegment(PlayerSegment):
set artist_name to artist of current track
set album_name to album of current track
set track_length to duration of current track
set now_playing to "" & player state & "{0}" & album_name & "{0}" & artist_name & "{0}" & track_name & "{0}" & track_length
set now_playing to "" & player state & "{0}" & album_name & "{0}" & artist_name & "{0}" & track_name & "{0}" & track_length & "{0}" & player position
return now_playing
else
return player state
@ -358,7 +378,8 @@ class SpotifyAppleScriptPlayerSegment(PlayerSegment):
'album': spotify_status[1],
'artist': spotify_status[2],
'title': spotify_status[3],
'total': _convert_seconds(int(spotify_status[4]))
'total': _convert_seconds(int(spotify_status[4])/1000),
'elapsed': _convert_seconds(spotify_status[5]),
}
@ -371,7 +392,7 @@ Requires ``osascript`` available in $PATH.
''').format(_common_args.format('spotify_apple_script')))
if 'dbus' in globals() or not sys.platform.startswith('darwin'):
if not sys.platform.startswith('darwin'):
spotify = spotify_dbus
_old_name = 'spotify_dbus'
else:
@ -528,3 +549,59 @@ Requires ``osascript``.
{0}
''').format(_common_args.format('itunes')))
class MocPlayerSegment(PlayerSegment):
def get_player_status(self, pl):
'''Return Music On Console (mocp) player information.
``mocp -i`` returns current information i.e.
.. code-block::
File: filename.format
Title: full title
Artist: artist name
SongTitle: song title
Album: album name
TotalTime: 00:00
TimeLeft: 00:00
TotalSec: 000
CurrentTime: 00:00
CurrentSec: 000
Bitrate: 000kbps
AvgBitrate: 000kbps
Rate: 00kHz
For the information we are looking for we dont really care if we have
extra-timing information or bit rate level. The dictionary comprehension
in this method takes anything in ignore_info and brings the key inside
that to the right info of the dictionary.
'''
now_playing_str = run_cmd(pl, ['mocp', '-i'])
if not now_playing_str:
return
now_playing = dict((
line.split(': ', 1)
for line in now_playing_str.split('\n')[:-1]
))
state = _convert_state(now_playing.get('State', 'stop'))
return {
'state': state,
'album': now_playing.get('Album', ''),
'artist': now_playing.get('Artist', ''),
'title': now_playing.get('SongTitle', ''),
'elapsed': _convert_seconds(now_playing.get('CurrentSec', 0)),
'total': _convert_seconds(now_playing.get('TotalSec', 0)),
}
mocp = with_docstring(MocPlayerSegment(),
('''Return MOC (Music On Console) player information
Requires version >= 2.3.0 and ``mocp`` executable in ``$PATH``.
{0}
''').format(_common_args.format('mocp')))

View File

@ -46,7 +46,7 @@ branch = with_docstring(BranchSegment(),
:param bool status_colors:
Determines whether repository status will be used to determine highlighting.
Default: False.
:param bool ignore_statuses:
:param list ignore_statuses:
List of statuses which will not result in repo being marked as dirty. Most
useful is setting this option to ``["U"]``: this will ignore repository
which has just untracked files (i.e. repository with modified, deleted or

View File

@ -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 [
{

View File

@ -63,6 +63,7 @@ vim_modes = {
'rm': '-MORE-',
'r?': 'CNFIRM',
'!': '!SHELL',
't': 'TERM ',
}

View File

@ -0,0 +1,52 @@
# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)
try:
import vim
except ImportError:
vim = object()
from powerline.bindings.vim import vim_global_exists
from powerline.theme import requires_segment_info
@requires_segment_info
def ale(segment_info, pl, err_format='ERR: ln {first_line} ({num}) ', warn_format='WARN: ln {first_line} ({num}) '):
'''Show whether ALE has found any errors or warnings
:param str err_format:
Format string for errors.
:param str warn_format:
Format string for warnings.
Highlight groups used: ``ale:warning`` or ``warning``, ``ale:error`` or ``error``.
'''
if not (vim_global_exists('ale_enabled') and int(vim.eval('g:ale_enabled'))):
return None
has_errors = int(vim.eval('ale#statusline#Count(' + str(segment_info['bufnr']) + ').total'))
if not has_errors:
return
error = None
warning = None
errors_count = 0
warnings_count = 0
for issue in vim.eval('ale#engine#GetLoclist(' + str(segment_info['bufnr']) + ')'):
if issue['type'] == 'E':
error = error or issue
errors_count += 1
elif issue['type'] == 'W':
warning = warning or issue
warnings_count += 1
segments = []
if error:
segments.append({
'contents': err_format.format(first_line=error['lnum'], num=errors_count),
'highlight_groups': ['ale:error', 'error'],
})
if warning:
segments.append({
'contents': warn_format.format(first_line=warning['lnum'], num=warnings_count),
'highlight_groups': ['ale:warning', 'warning'],
})
return segments

View File

@ -59,7 +59,7 @@ else:
def get_version():
base_version = '2.6'
base_version = '2.7'
base_version += '.dev9999'
try:
return base_version + '+git.' + str(subprocess.check_output(['git', 'rev-parse', 'HEAD']).strip())
@ -70,7 +70,7 @@ def get_version():
setup(
name='powerline-status',
version='2.6',
version='2.7',
description='The ultimate statusline/prompt utility.',
long_description=README,
classifiers=[
@ -124,7 +124,7 @@ setup(
packages=find_packages(exclude=('tests', 'tests.*')),
include_package_data=True,
zip_safe=False,
install_requires=[],
install_requires=['argparse'] if OLD_PYTHON else [],
extras_require={
'docs': [
'Sphinx',

View File

@ -46,13 +46,13 @@ if test -n "$USE_UCS2_PYTHON" ; then
mkvirtualenv -p "$PYTHON" cpython-ucs2-$UCS2_PYTHON_VARIANT
set -e
. tests/bot-ci/scripts/common/main.sh
pip install .
pip install --verbose --verbose --verbose .
if test "$UCS2_PYTHON_VARIANT" = "2.6" ; then
rm tests/bot-ci/deps/wheels/ucs2-CPython-${UCS2_PYTHON_VARIANT}*/pyuv*.whl
fi
pip install --no-deps tests/bot-ci/deps/wheels/ucs2-CPython-${UCS2_PYTHON_VARIANT}*/*.whl
else
pip install .
pip install --verbose --verbose --verbose .
# FIXME Uv watcher sometimes misses events and INotify is not available in
# Python-2.6, thus pyuv should be removed in order for VCS tests to
# pass.

View File

@ -2,10 +2,93 @@
from __future__ import (unicode_literals, division, absolute_import, print_function)
import sys
import os
if sys.version_info < (2, 7):
from unittest2 import TestCase, main # NOQA
from unittest2 import TestCase as _TestCase # NOQA
from unittest2 import main as _main # NOQA
from unittest2.case import SkipTest # NOQA
else:
from unittest import TestCase, main # NOQA
from unittest import TestCase as _TestCase # NOQA
from unittest import main as _main # NOQA
from unittest.case import SkipTest # NOQA
from tests.modules.lib import PowerlineSingleTest
class PowerlineDummyTest(object):
def __enter__(self):
return self
def __exit__(self, *args):
pass
def fail(self, *args, **kwargs):
pass
def exception(self, *args, **kwargs):
pass
class PowerlineTestSuite(object):
def __init__(self, name):
self.name = name
def __enter__(self):
self.saved_current_suite = os.environ['POWERLINE_CURRENT_SUITE']
os.environ['POWERLINE_CURRENT_SUITE'] = (
self.saved_current_suite + '/' + self.name)
self.suite = self.saved_current_suite + '/' + self.name
return self
def __exit__(self, exc_type, exc_value, traceback):
if exc_type is not None:
self.exception(
'suite_noexcept',
'Exception while running test suite: {0!r}'.format(exc_value),
)
os.environ['POWERLINE_CURRENT_SUITE'] = self.saved_current_suite
def record_test_failure(self, fail_char, test_name, message, allow_failure=False):
if allow_failure:
fail_char = 'A' + fail_char
full_msg = '{fail_char} {suite}|{test_name} :: {message}'.format(
fail_char=fail_char,
suite=self.suite,
test_name=test_name,
message=message,
)
with open(os.environ['FAILURES_FILE'], 'a') as ffd:
ffd.write(full_msg + '\n')
return False
def exception(self, test_name, message, allow_failure=False):
return self.record_test_failure('E', test_name, message, allow_failure)
def fail(self, test_name, message, allow_failure=False):
return self.record_test_failure('F', test_name, message, allow_failure)
def test(self, name, attempts_left=0):
if not attempts_left:
return PowerlineSingleTest(self, name)
else:
return PowerlineDummyTest()
def subsuite(self, name):
return PowerlineTestSuite(name)
suite = None
def main(*args, **kwargs):
global suite
suite = PowerlineTestSuite(sys.argv[0])
_main(*args, **kwargs)
class TestCase(_TestCase):
def fail(self, msg=None):
suite.fail(self.__class__.__name__,
msg or 'Test failed without message')
super(TestCase, self).fail(*args, **kwargs)

View File

@ -161,3 +161,23 @@ def replace_env(key, new, environ=None, **kwargs):
r = kwargs.copy()
r['environ'] = environ or {}
return ItemReplace(r['environ'], key, new, r)
class PowerlineSingleTest(object):
def __init__(self, suite, name):
self.suite = suite
self.name = name
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, traceback):
if exc_type is not None:
self.exception('Exception while running test: {0!r}'.format(
exc_value))
def fail(self, message, allow_failure=False):
return self.suite.fail(self.name, message, allow_failure)
def exception(self, message, allow_failure=False):
return self.suite.exception(self.name, message, allow_failure)

View File

@ -61,13 +61,17 @@ class ExpectProcess(threading.Thread):
self.buffer = []
self.child_lock = threading.Lock()
self.shutdown_event = threading.Event()
self.started_event = threading.Event()
def run(self):
child = pexpect.spawn(self.cmd, self.args, cwd=self.cwd, env=self.env)
sleep(0.5)
child.setwinsize(self.dim.rows, self.dim.cols)
sleep(0.5)
self.child = child
with self.child_lock:
child = pexpect.spawn(self.cmd, self.args, cwd=self.cwd,
env=self.env)
sleep(0.5)
child.setwinsize(self.dim.rows, self.dim.cols)
sleep(0.5)
self.child = child
self.started_event.set()
status = None
while status is None and not self.shutdown_event.is_set():
try:
@ -109,21 +113,33 @@ class ExpectProcess(threading.Thread):
with self.child_lock:
self.child.send(data)
def get_highlighted_text(self, text, attrs, default_props=()):
def get_highlighted_text(self, text, attrs, default_props=(),
use_escapes=False):
ret = []
new_attrs = attrs.copy()
for cell_properties, segment_text in text:
segment_text = segment_text.translate({'{': '{{', '}': '}}'})
if cell_properties not in new_attrs:
new_attrs[cell_properties] = len(new_attrs) + 1
props_name = new_attrs[cell_properties]
if props_name in default_props:
ret.append(segment_text)
if use_escapes:
escapes = ('\033[38;2;{0};{1};{2};48;2;{3};{4};{5}'.format(
*(cell_properties[0] + cell_properties[1]))) + (
';1' if cell_properties[2] else ''
) + (
';3' if cell_properties[3] else ''
) + (
';4' if cell_properties[4] else ''
) + 'm'
ret.append(escapes + segment_text + '\033[0m')
else:
ret.append('{' + str(props_name) + ':' + segment_text + '}')
segment_text = segment_text.translate({'{': '{{', '}': '}}'})
if cell_properties not in new_attrs:
new_attrs[cell_properties] = len(new_attrs) + 1
props_name = new_attrs[cell_properties]
if props_name in default_props:
ret.append(segment_text)
else:
ret.append('{' + str(props_name) + ':' + segment_text + '}')
return ''.join(ret), new_attrs
def get_row(self, row, attrs, default_props=()):
def get_row(self, row, attrs, default_props=(), use_escapes=False):
with self.lock:
return self.get_highlighted_text((
(key, ''.join((cell.text for cell in subline)))
@ -131,35 +147,48 @@ class ExpectProcess(threading.Thread):
self.vterm.vtscreen[row, col]
for col in range(self.dim.cols)
), lambda cell: cell.cell_properties_key)
), attrs, default_props)
), attrs, default_props, use_escapes)
def get_screen(self, attrs, default_props=()):
def get_screen(self, attrs, default_props=(), use_escapes=False):
lines = []
for row in range(self.dim.rows):
line, attrs = self.get_row(row, attrs, default_props)
line, attrs = self.get_row(row, attrs, default_props, use_escapes)
lines.append(line)
return '\n'.join(lines), attrs
def test_expected_result(p, test, last_attempt, last_attempt_cb=None):
def test_expected_result(p, test, last_attempt, last_attempt_cb, attempts):
debugging_tests = not not os.environ.get('_POWERLINE_DEBUGGING_TESTS')
expected_text, attrs = test['expected_result']
attempts = 3
result = None
while attempts:
actual_text, all_attrs = p.get_row(test['row'], attrs)
if 'row' in test:
row = test['row']
else:
row = p.dim.rows - 1
while row >= 0 and not p[row, 0].text:
row -= 1
if row < 0:
row = 0
actual_text, all_attrs = p.get_row(row, attrs)
if actual_text == expected_text:
return True
attempts -= 1
print('Actual result does not match expected. Attempts left: {0}.'.format(attempts))
print('Actual result does not match expected for row {0}. Attempts left: {1}.'.format(
row, attempts))
sleep(2)
print('Result:')
print('Result (row {0}):'.format(row))
print(actual_text)
print('Expected:')
print(expected_text)
print('Attributes:')
print(all_attrs)
for v, k in sorted(
((v, k) for k, v in all_attrs.items()),
key=(lambda t: '%02u'.format(t[0]) if isinstance(t[0], int) else t[0]),
):
print('{k!r}: {v!r},'.format(v=v, k=k))
print('Screen:')
screen, screen_attrs = p.get_screen(attrs)
screen, screen_attrs = p.get_screen(attrs, use_escapes=debugging_tests)
print(screen)
print(screen_attrs)
print('_' * 80)
@ -219,8 +248,12 @@ def get_env(vterm_path, test_dir, *args, **kwargs):
return env
def do_terminal_tests(tests, cmd, dim, args, env, cwd=None, fin_cb=None,
last_attempt_cb=None, attempts=3):
def do_terminal_tests(tests, cmd, dim, args, env, suite, cwd=None, fin_cb=None,
last_attempt_cb=None, attempts=None):
debugging_tests = not not os.environ.get('_POWERLINE_DEBUGGING_TESTS')
default_attempts = 2 if debugging_tests else 3
if attempts is None:
attempts = default_attempts
lib = os.environ.get('POWERLINE_LIBVTERM')
if not lib:
if os.path.exists('tests/bot-ci/deps/libvterm/libvterm.so'):
@ -239,21 +272,26 @@ def do_terminal_tests(tests, cmd, dim, args, env, cwd=None, fin_cb=None,
env=env,
)
p.start()
p.started_event.wait()
ret = True
for test in tests:
try:
test_prep = test['prep_cb']
except KeyError:
pass
else:
test_prep(p)
ret = (
ret
and test_expected_result(p, test, attempts == 0,
last_attempt_cb)
)
for i, test in enumerate(tests):
with suite.test(test.get('name', 'test_{0}'.format(i)),
attempts - 1) as ptest:
try:
test_prep = test['prep_cb']
except KeyError:
pass
else:
test_prep(p)
test_result = test_expected_result(
p, test, attempts == 0, last_attempt_cb,
test.get('attempts', default_attempts)
)
if not test_result:
ptest.fail('Result does not match expected')
ret = ret and test_result
if ret:
return ret

View File

@ -116,6 +116,7 @@ def get_functions(lib):
('cell', ctypes.POINTER(VTermScreenCell_s))
)),
vterm_free=(None, (('vt', VTerm_p),)),
vterm_set_utf8=(None, (('vt', VTerm_p), ('is_utf8', ctypes.c_int))),
)
@ -173,6 +174,7 @@ class VTerm(object):
def __init__(self, lib, dim):
self.functions = get_functions(lib)
self.vt = self.functions.vterm_new(dim.rows, dim.cols)
self.functions.vterm_set_utf8(self.vt, 1)
self.vtscreen = VTermScreen(self.functions, self.functions.vterm_obtain_screen(self.vt))
self.vtscreen.reset(True)

View File

@ -1,10 +1,29 @@
. tests/bot-ci/scripts/common/main.sh
set +x
: ${PYTHON:=python}
: ${USER:=`id -un`}
: ${HOME:=`getent passwd $USER | cut -d: -f6`}
if test -z "${PYTHON}" ; then
if test -n "$USE_UCS2_PYTHON" ; then
LD_LIBRARY_PATH="$HOME/opt/cpython-ucs2-$UCS2_PYTHON_VARIANT/lib${LD_LIBRARY_PATH:+:}${LD_LIBRARY_PATH}"
fi
fi
export LD_LIBRARY_PATH
export USER
export HOME
if test -n "$USE_UCS2_PYTHON" ; then
POWERLINE_VIRTUALENV="cpython-ucs2-$UCS2_PYTHON_VARIANT"
PYTHON="$HOME/.virtualenvs/$POWERLINE_VIRTUALENV/bin/python"
if test -n "$BASH_VERSION" ; then
set +e
. virtualenvwrapper.sh
workon "$POWERLINE_VIRTUALENV"
set -e
fi
fi
. tests/bot-ci/scripts/common/main.sh silent
export USER HOME
if test -z "$FAILED" ; then
@ -13,7 +32,7 @@ if test -z "$FAILED" ; then
FAIL_SUMMARY=""
TMP_ROOT="$ROOT/tests/tmp"
FAILURES_FILE="$ROOT/tests/failures"
export FAILURES_FILE="$ROOT/tests/status"
fi
ANSI_CLEAR="\033[0K"
@ -26,10 +45,29 @@ travis_fold() {
echo -en "travis_fold:${action}:${name}\r${ANSI_CLEAR}"
}
print_environ() {
echo "Using $PYTHON_IMPLEMENTATION version $PYTHON_VERSION."
echo "Path to Python executable: $PYTHON."
echo "Root: $ROOT."
echo "Branch: $BRANCH_NAME."
echo "sys.path:"
"$PYTHON" -c "for path in __import__('sys').path: print(' %r' % path)"
}
enter_suite() {
set +x
local suite_name="$1" ; shift
local final="$1"
export POWERLINE_CURRENT_SUITE="${POWERLINE_CURRENT_SUITE}/$suite_name"
travis_fold start "$POWERLINE_CURRENT_SUITE"
print_environ
if test "$final" = final ; then
if test -n "$POWERLINE_SUITE_FINAL" ; then
fail __suite__/enter/final E "Final suites do not allow nesting"
fi
export POWERLINE_SUITE_FINAL=1
# set -x
fi
}
exit_suite() {
@ -40,14 +78,17 @@ exit_suite() {
echo "Suite ${POWERLINE_CURRENT_SUITE} failed, summary:"
echo "${FAIL_SUMMARY}"
fi
set +x
travis_fold end "$POWERLINE_CURRENT_SUITE"
export POWERLINE_CURRENT_SUITE="${POWERLINE_CURRENT_SUITE%/*}"
if test "$1" != "--continue" ; then
exit $FAILED
else
unset POWERLINE_SUITE_FINAL
fi
}
fail() {
_fail() {
local allow_failure=
if test "$1" = "--allow-failure" ; then
shift
@ -56,15 +97,26 @@ fail() {
local test_name="$1" ; shift
local fail_char="$allow_failure$1" ; shift
local message="$1" ; shift
local verb="$1" ; shift
local full_msg="$fail_char $POWERLINE_CURRENT_SUITE|$test_name :: $message"
FAIL_SUMMARY="${FAIL_SUMMARY}${NL}${full_msg}"
echo "Failed: $full_msg"
echo "$verb: $full_msg"
echo "$full_msg" >> "$FAILURES_FILE"
if test -z "$allow_failure" ; then
FAILED=1
fi
}
fail() {
_fail "$@" "Failed"
}
skip() {
local test_name="$1" ; shift
local message="$1" ; shift
_fail --allow-failure "$test_name" S "$message" "Skipped"
}
make_test_root() {
local suffix="${POWERLINE_CURRENT_SUITE##*/}"

View File

@ -1,26 +1,17 @@
. tests/shlib/common.sh
. tests/bot-ci/scripts/common/main.sh
set +x
vterm_setup() {
local test_dir="$1" ; shift
make_test_root
rm -rf "$test_dir"
mkdir "$test_dir"
mkdir "$test_dir/path"
mkdir "$TEST_ROOT/path"
ln -s "$(which "${PYTHON}")" "$test_dir/path/python"
ln -s "$(which bash)" "$test_dir/path"
ln -s "$(which "${PYTHON}")" "$TEST_ROOT/path/python"
ln -s "$(which bash)" "$TEST_ROOT/path"
cp -r "$ROOT/tests/terminfo" "$test_dir"
cp -r "$ROOT/tests/terminfo" "$TEST_ROOT"
}
vterm_shutdown() {
local test_dir="$1" ; shift
if test $FAILED -eq 0 ; then
rm -rf "$test_dir"
else
echo "$FAIL_SUMMARY"
fi
rm_test_root
}

View File

@ -33,10 +33,10 @@ for script in "$ROOT"/tests/test_*/test.sh ; do
fi
done
if test -e tests/failures ; then
echo "Some tests failed. Summary:"
cat tests/failures
rm tests/failures
if test -e "$FAILURES_FILE" ; then
echo "Fails and skips summary:"
cat "$FAILURES_FILE"
rm "$FAILURES_FILE"
fi
exit_suite

View File

@ -102,7 +102,7 @@ if ! test -e "$DEPRECATED_SCRIPT" ; then
# skip "deprecated" "Missing deprecated bar bindings script"
:
else
enter_suite "deprecated"
enter_suite "deprecated" final
for args in "" "0.5"; do
rm -rf "$TEST_ROOT/results"
mkdir "$TEST_ROOT/results"
@ -132,7 +132,7 @@ else
exit_suite --continue
fi
enter_suite "awesome"
enter_suite "awesome" final
ADDRESS="powerline-ipc-test-$$"
echo "Powerline address: $ADDRESS"
rm -rf "$TEST_ROOT/results"

View File

@ -94,7 +94,7 @@ if ! test -e "$DEPRECATED_SCRIPT" ; then
# skip "deprecated" "Missing deprecated bar bindings script"
:
else
enter_suite "deprecated"
enter_suite "deprecated" final
run python "$DEPRECATED_SCRIPT" $args > "$TEST_ROOT/deprecated.log" 2>&1 &
SPID=$!
sleep 5
@ -122,7 +122,7 @@ else
sleep 5
killscript $SPID
sleep 0.5
enter_suite "args($args)"
enter_suite "args($args)" final
fnum=0
for file in "$TEST_ROOT/results"/*.log ; do
if ! test -e "$file" ; then

View File

@ -1,7 +1,7 @@
#!/bin/sh
. tests/shlib/common.sh
enter_suite daemon
enter_suite daemon final
export ADDRESS="powerline-ipc-test-$$"
echo "Powerline address: $ADDRESS"

View File

@ -0,0 +1,16 @@
# vim: ft=sh
set_theme_option() {
export POWERLINE_THEME_OVERRIDES="${POWERLINE_THEME_OVERRIDES};$1=$2"
}
set_theme() {
export POWERLINE_CONFIG_OVERRIDES="ext.shell.theme=$1"
}
set_virtual_env() {
export VIRTUAL_ENV="$HOME/.virtenvs/$1"
}
set_theme_option default_leftonly.segment_data.hostname.args.only_if_ssh false
set_theme default_leftonly
. "$ROOT/powerline/bindings/shell/powerline.sh"
export VIRTUAL_ENV=
cd "$TEST_ROOT/3rd"

View File

@ -0,0 +1,162 @@
#!/usr/bin/env python
# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)
import os
import sys
from time import sleep
from subprocess import check_call
from glob import glob1
from traceback import print_exc
from argparse import ArgumentParser
from powerline.lib.dict import updated
from tests.modules.lib.terminal import (ExpectProcess, MutableDimensions,
do_terminal_tests, get_env)
from tests.modules import PowerlineTestSuite
TEST_ROOT = os.path.abspath(os.environ['TEST_ROOT'])
def get_parser():
parser = ArgumentParser()
parser.add_argument('--type', action='store')
parser.add_argument('--client', action='store')
parser.add_argument('--binding', action='store')
parser.add_argument('args', action='append')
return parser
BINDING_OPTIONS = {
'dash': {
'cmd': 'dash',
'args': ['-i'],
'init': [
'. "$ROOT/tests/test_in_vterm/shell/inits/dash"',
],
},
}
def main(argv):
script_args = get_parser().parse_args(argv)
vterm_path = os.path.join(TEST_ROOT, 'path')
env = get_env(vterm_path, TEST_ROOT)
env['ROOT'] = os.path.abspath('.')
env['TEST_ROOT'] = TEST_ROOT
env['TEST_TYPE'] = script_args.type
env['TEST_CLIENT'] = script_args.client
env['LANG'] = 'en_US.UTF_8'
env['_POWERLINE_RUNNING_SHELL_TESTS'] = (
'ee5bcdc6-b749-11e7-9456-50465d597777')
dim = MutableDimensions(rows=50, cols=200)
binding_opts = BINDING_OPTIONS[script_args.binding]
cmd = os.path.join(vterm_path, binding_opts['cmd'])
args = binding_opts['args']
def gen_init(binding):
def init(p):
for line in binding_opts['init']:
p.send(line + '\n')
sleep(1)
return init
def gen_feed(line):
def feed(p):
p.send(line + '\n')
sleep(0.1)
return feed
base_attrs = {
((255, 204,0), (204, 51, 0), 0, 0, 0): 'H',
((204, 51, 0), (0, 102, 153), 0, 0, 0): 'sHU',
((255, 255, 255), (0, 102, 153), 1, 0, 0): 'U',
((0, 102, 153), (44, 44, 44), 0, 0, 0): 'sUB',
((199, 199, 199), (44, 44, 44), 0, 0, 0): 'B',
((44, 44, 44), (88, 88, 88), 0, 0, 0): 'sBD',
((199, 199, 199), (88, 88, 88), 0, 0, 0): 'D',
((144, 144, 144), (88, 88, 88), 0, 0, 0): 'sD',
((221, 221, 221), (88, 88, 88), 1, 0, 0): 'C',
((88, 88, 88), (0, 0, 0), 0, 0, 0): 'sDN',
((240, 240, 240), (0, 0, 0), 0, 0, 0): 'N',
((0, 102, 153), (51, 153, 204), 0, 0, 0): 'sUE',
((255, 255, 255), (51, 153, 204), 0, 0, 0): 'E',
((51, 153, 204), (44, 44, 44), 0, 0, 0): 'sEB',
}
tests = (
{
'expected_result': (
'{H:  hostname }{sHU: }'
'{U:user }{sUB: }'
'{B: BRANCH }{sBD: }'
'{D:… }{sD: }{D:tmp }{sD: }{D:vshells }{sD: }{C:3rd }{sDN: }'
'{N:}',
base_attrs,
),
'prep_cb': gen_init(script_args.binding),
},
{
'expected_result': (
'{H:  hostname }{sHU: }'
'{U:user }{sUB: }'
'{B: BRANCH }{sBD: }'
'{D:… }{sD: }{D:vshells }{sD: }{D:3rd }{sD: }{C:.git }{sDN: }'
'{N:}',
base_attrs
),
'prep_cb': gen_feed('cd .git'),
},
{
'expected_result': (
'{H:  hostname }{sHU: }'
'{U:user }{sUB: }'
'{B: BRANCH }{sBD: }'
'{D:… }{sD: }{D:tmp }{sD: }{D:vshells }{sD: }{C:3rd }{sDN: }'
'{N:}',
base_attrs,
),
'prep_cb': gen_feed('cd ..'),
},
{
'expected_result': (
'{H:  hostname }{sHU: }'
'{U:user }{sUE: }'
'{E:(e) some-venv }{sEB: }'
'{B: BRANCH }{sBD: }'
'{D:… }{sD: }{D:tmp }{sD: }{D:vshells }{sD: }{C:3rd }{sDN: }'
'{N:}',
base_attrs,
),
'prep_cb': gen_feed('set_virtual_env some-venv'),
},
)
with PowerlineTestSuite('shell') as suite:
return do_terminal_tests(
tests=tests,
cmd=cmd,
dim=dim,
args=args,
env=env,
cwd=TEST_ROOT,
suite=suite,
)
if __name__ == '__main__':
if main(sys.argv[1:]):
raise SystemExit(0)
else:
raise SystemExit(1)

View File

@ -0,0 +1,119 @@
#!/bin/bash
. tests/shlib/common.sh
. tests/shlib/vterm.sh
enter_suite vshells
vterm_setup
HAS_SOCAT=
HAS_C_CLIENT=
git init "$TEST_ROOT/3rd"
git --git-dir="$TEST_ROOT/3rd/.git" checkout -b BRANCH
export DIR1=""
export DIR2=""
mkdir "$TEST_ROOT/3rd/$DIR1"
mkdir "$TEST_ROOT/3rd/$DIR2"
mkdir "$TEST_ROOT"/3rd/'\[\]'
mkdir "$TEST_ROOT"/3rd/'%%'
mkdir "$TEST_ROOT"/3rd/'#[bold]'
mkdir "$TEST_ROOT"/3rd/'(echo)'
mkdir "$TEST_ROOT"/3rd/'$(echo)'
mkdir "$TEST_ROOT"/3rd/'`echo`'
mkdir "$TEST_ROOT"/3rd/'«Unicode!»'
mkdir "$TEST_ROOT/fish_home"
mkdir "$TEST_ROOT/fish_home/fish"
mkdir "$TEST_ROOT/fish_home/fish/generated_completions"
cp -r "$ROOT/tests/test_shells/ipython_home" "$TEST_ROOT"
ln -s "$(which env)" "$TEST_ROOT/path"
ln -s "$(which git)" "$TEST_ROOT/path"
ln -s "$(which sleep)" "$TEST_ROOT/path"
ln -s "$(which cat)" "$TEST_ROOT/path"
ln -s "$(which false)" "$TEST_ROOT/path"
ln -s "$(which true)" "$TEST_ROOT/path"
ln -s "$(which kill)" "$TEST_ROOT/path"
ln -s "$(which echo)" "$TEST_ROOT/path"
ln -s "$(which which)" "$TEST_ROOT/path"
ln -s "$(which dirname)" "$TEST_ROOT/path"
ln -s "$(which wc)" "$TEST_ROOT/path"
ln -s "$(which stty)" "$TEST_ROOT/path"
ln -s "$(which cut)" "$TEST_ROOT/path"
ln -s "$(which bc)" "$TEST_ROOT/path"
ln -s "$(which expr)" "$TEST_ROOT/path"
ln -s "$(which mktemp)" "$TEST_ROOT/path"
ln -s "$(which grep)" "$TEST_ROOT/path"
ln -s "$(which sed)" "$TEST_ROOT/path"
ln -s "$(which rm)" "$TEST_ROOT/path"
ln -s "$(which tr)" "$TEST_ROOT/path"
ln -s "$(which uname)" "$TEST_ROOT/path"
ln -s "$(which test)" "$TEST_ROOT/path"
ln -s "$(which pwd)" "$TEST_ROOT/path"
ln -s "$(which hostname)" "$TEST_ROOT/path"
ln -s "$ROOT/tests/test_shells/bgscript.sh" "$TEST_ROOT/path"
ln -s "$ROOT/tests/test_shells/waitpid.sh" "$TEST_ROOT/path"
ln -s "$ROOT/scripts/powerline-config" "$TEST_ROOT/path"
ln -s "$ROOT/scripts/powerline-render" "$TEST_ROOT/path"
ln -s "$ROOT/client/powerline.py" "$TEST_ROOT/path"
if test -e "$ROOT/scripts/powerline" ; then
ln -s "$ROOT/scripts/powerline" "$TEST_ROOT/path"
elif test -e client/powerline ; then
ln -s "$ROOT/client/powerline" "$TEST_ROOT/path"
elif which powerline ; then
ln -s "$(which powerline)" "$TEST_ROOT/path"
else
echo "Executable powerline was not found"
exit 1
fi
if test "$(
file --mime-type --brief --dereference "$TEST_ROOT/path/powerline" \
| cut -d/ -f1)" = "application" ; then
HAS_C_CLIENT=1
fi
if which socat ; then
HAS_SOCAT=1
ln -s "$(which socat)" "$TEST_ROOT/path"
ln -s "$ROOT/client/powerline.sh" "$TEST_ROOT/path"
fi
# Test type: daemon, renderer, …
# Test client: python, shell, c, none
# Test binding: *sh, ipython, pdb, …
test_shell() {
local test_type="$1" ; shift
local test_client="$1" ; shift
local test_binding="$1" ; shift
if test "$test_client" = shell && test -z "$HAS_SOCAT" ; then
echo "Skipping test, socat not available"
return
fi
if test "$test_client" = c && test -z "$HAS_C_CLIENT" ; then
echo "Skipping test, C client not available"
return
fi
if which "$test_binding" ; then
ln -s "$(which "$test_binding")" "$TEST_ROOT/path"
fi
if ! "${PYTHON}" "$ROOT/tests/test_in_vterm/test_shells.py" \
--type=$test_type \
--client=$test_client \
--binding=$test_binding \
-- "$@"
then
local test_name="$test_type-$test_client-$test_binding"
fail "$test_name" F "Failed vterm shell test"
fi
}
test_shell renderer python dash -i || true
vterm_shutdown
exit_suite

View File

@ -17,9 +17,10 @@ from powerline import get_fallback_logger
from tests.modules.lib.terminal import (ExpectProcess, MutableDimensions,
do_terminal_tests, get_env)
from tests.modules import PowerlineTestSuite
VTERM_TEST_DIR = os.path.abspath('tests/vterm_tmux')
TEST_ROOT = os.path.abspath(os.environ['TEST_ROOT'])
def tmux_logs_iter(test_dir):
@ -28,7 +29,7 @@ def tmux_logs_iter(test_dir):
def print_tmux_logs():
for f in tmux_logs_iter(VTERM_TEST_DIR):
for f in tmux_logs_iter(TEST_ROOT):
print('_' * 80)
print(os.path.basename(f) + ':')
print('=' * 80)
@ -57,15 +58,15 @@ def tmux_fin_cb(p, cmd, env):
try:
check_call([
cmd, '-S', env['POWERLINE_TMUX_SOCKET_PATH'], 'kill-server'
], env=env, cwd=VTERM_TEST_DIR)
], env=env, cwd=TEST_ROOT)
except Exception:
print_exc()
for f in tmux_logs_iter(VTERM_TEST_DIR):
for f in tmux_logs_iter(TEST_ROOT):
os.unlink(f)
def main(attempts=3):
vterm_path = os.path.join(VTERM_TEST_DIR, 'path')
vterm_path = os.path.join(TEST_ROOT, 'path')
tmux_exe = os.path.join(vterm_path, 'tmux')
@ -73,7 +74,7 @@ def main(attempts=3):
if os.path.exists(socket_path):
os.unlink(socket_path)
env = get_env(vterm_path, VTERM_TEST_DIR, {
env = get_env(vterm_path, TEST_ROOT, {
'POWERLINE_THEME_OVERRIDES': ';'.join((
key + '=' + json.dumps(val)
for key, val in (
@ -99,7 +100,7 @@ def main(attempts=3):
conf_path = os.path.abspath('powerline/bindings/tmux/powerline.conf')
conf_line = 'source "' + (
conf_path.replace('\\', '\\\\').replace('"', '\\"')) + '"\n'
conf_file = os.path.realpath(os.path.join(VTERM_TEST_DIR, 'tmux.conf'))
conf_file = os.path.realpath(os.path.join(TEST_ROOT, 'tmux.conf'))
with open(conf_file, 'w') as cf_fd:
cf_fd.write(conf_line)
@ -229,16 +230,18 @@ def main(attempts=3):
'new-window', 'bash --norc --noprofile -i', ';',
]
return do_terminal_tests(
tests=tests,
cmd=tmux_exe,
dim=dim,
args=args,
env=env,
cwd=VTERM_TEST_DIR,
fin_cb=tmux_fin_cb,
last_attempt_cb=print_tmux_logs,
)
with PowerlineTestSuite('tmux') as suite:
return do_terminal_tests(
tests=tests,
cmd=tmux_exe,
dim=dim,
args=args,
env=env,
cwd=TEST_ROOT,
fin_cb=tmux_fin_cb,
last_attempt_cb=print_tmux_logs,
suite=suite,
)
if __name__ == '__main__':

View File

@ -1,17 +1,15 @@
#!/bin/sh
#!/bin/bash
. tests/shlib/common.sh
. tests/shlib/vterm.sh
enter_suite tmux
enter_suite tmux final
VTERM_TEST_DIR="$ROOT/tests/vterm_tmux"
vterm_setup
vterm_setup "$VTERM_TEST_DIR"
ln -s "$(which env)" "$VTERM_TEST_DIR/path"
ln -s "$(which cut)" "$VTERM_TEST_DIR/path"
ln -s "$ROOT/scripts/powerline-render" "$VTERM_TEST_DIR/path"
ln -s "$ROOT/scripts/powerline-config" "$VTERM_TEST_DIR/path"
ln -s "$(which env)" "$TEST_ROOT/path"
ln -s "$(which cut)" "$TEST_ROOT/path"
ln -s "$ROOT/scripts/powerline-render" "$TEST_ROOT/path"
ln -s "$ROOT/scripts/powerline-config" "$TEST_ROOT/path"
test_tmux() {
if test "$PYTHON_IMPLEMENTATION" = PyPy; then
@ -22,7 +20,7 @@ test_tmux() {
if ! which "${POWERLINE_TMUX_EXE}" ; then
return 0
fi
ln -sf "$(which "${POWERLINE_TMUX_EXE}")" "$VTERM_TEST_DIR/path/tmux"
ln -sf "$(which "${POWERLINE_TMUX_EXE}")" "$TEST_ROOT/path/tmux"
f="$ROOT/tests/test_in_vterm/test_tmux.py"
if ! "${PYTHON}" "$f" ; then
local test_name="$("$POWERLINE_TMUX_EXE" -V 2>&1 | cut -d' ' -f2)"
@ -41,6 +39,6 @@ else
test_tmux || true
fi
vterm_shutdown "$VTERM_TEST_DIR"
vterm_shutdown
exit_suite

View File

@ -4,42 +4,66 @@ from __future__ import (unicode_literals, division, absolute_import, print_funct
import os
import sys
import json
from time import sleep
from subprocess import check_call
from glob import glob1
from traceback import print_exc
from powerline.lib.dict import updated
from tests.modules.lib.terminal import (ExpectProcess, MutableDimensions,
do_terminal_tests, get_env)
from tests.modules import PowerlineTestSuite
VTERM_TEST_DIR = os.path.abspath('tests/vterm_vim')
TEST_ROOT = os.path.abspath(os.environ['TEST_ROOT'])
def main(attempts=3):
vterm_path = os.path.join(VTERM_TEST_DIR, 'path')
vterm_path = os.path.join(TEST_ROOT, 'path')
vim_exe = os.path.join(vterm_path, 'vim')
env = get_env(vterm_path, VTERM_TEST_DIR)
env = get_env(vterm_path, TEST_ROOT)
env['ROOT'] = os.path.abspath('.')
dim = MutableDimensions(rows=50, cols=200)
vimrc = os.path.join(TEST_ROOT, 'init.vim')
vimrc_contents = '''
set laststatus=2
set runtimepath=$ROOT/powerline/bindings/vim
'''
with open(vimrc, 'w') as vd:
vd.write(vimrc_contents)
base_attrs = {
(( 64, 64, 255), (0, 0, 0), 0, 0, 0): 'NT', # NonText
((240, 240, 240), (0, 0, 0), 0, 0, 0): 'N', # Normal
}
args = [
'-u', vimrc,
'-i', 'NONE',
]
def feed(p):
p.send(':echo strtrans(eval(&statusline[2:]))\n')
tests = (
)
args = []
return do_terminal_tests(
tests=tests,
cmd=vim_exe,
dim=dim,
args=args,
env=env,
cwd=VTERM_TEST_DIR,
)
with PowerlineTestSuite('vim') as suite:
return do_terminal_tests(
tests=tests,
cmd=vim_exe,
dim=dim,
args=args,
env=env,
cwd=TEST_ROOT,
suite=suite,
)
if __name__ == '__main__':

View File

@ -3,11 +3,9 @@
. tests/shlib/vterm.sh
. tests/shlib/vim.sh
enter_suite vim
enter_suite vvim final
VTERM_TEST_DIR="$ROOT/tests/vterm_vim"
vterm_setup "$VTERM_TEST_DIR"
vterm_setup
test_vim() {
if test "$PYTHON_IMPLEMENTATION" != CPython ; then
@ -17,10 +15,10 @@ test_vim() {
if ! which "$POWERLINE_VIM_EXE" ; then
return 0
fi
ln -sf "$(which "${POWERLINE_VIM_EXE}")" "$VTERM_TEST_DIR/path/vim"
ln -sf "$(which "${POWERLINE_VIM_EXE}")" "$TEST_ROOT/path/vim"
f="$ROOT/tests/test_in_vterm/test_vim.py"
if ! "${PYTHON}" "$f" ; then
local test_name="$(LANG=C "$POWERLINE_VIM_EXE" --cmd 'echo version' --cmd qa 2>&1)"
local test_name="$(LANG=C "$POWERLINE_VIM_EXE" --cmd 'echo version' --cmd qa 2>&1 | tail -n2)"
fail "$test_name" F "Failed vterm test $f"
fi
}
@ -36,6 +34,6 @@ else
test_vim || true
fi
vterm_shutdown "$VTERM_TEST_DIR"
vterm_shutdown
exit_suite

View File

@ -1,7 +1,7 @@
#!/bin/sh
. tests/shlib/common.sh
enter_suite lint
enter_suite lint final
if ! "$PYTHON" "$ROOT/scripts/powerline-lint" -p "$ROOT/powerline/config_files" ; then
fail "test" F "Running powerline-lint failed"

View File

@ -1,7 +1,7 @@
#!/bin/sh
. tests/shlib/common.sh
enter_suite python
enter_suite python final
for file in "$ROOT"/tests/test_python/test_*.py ; do
test_name="${file##*/test_}"

View File

@ -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)

View File

@ -6,6 +6,7 @@ import os
import sys
import re
import shutil
import unicodedata
from time import sleep
from subprocess import call, PIPE
@ -497,22 +498,14 @@ class TestUnicode(TestCase):
if sys.maxunicode < 0x10FFFF:
raise SkipTest('Can only test strwidth_ucs_4 in UCS-4 Pythons')
def east_asian_width(ch):
assert (len(ch) == 1)
assert ord(ch) == 0x1F48E
return 'F'
with replace_attr(plu, 'east_asian_width', east_asian_width):
# Warning: travis unicodedata.east_asian_width for some reason
# thinks this character is 5 symbols wide.
self.assertEqual(2, plu.strwidth_ucs_4(width_data, '\U0001F48E'))
self.assertEqual(1, plu.strwidth_ucs_4(width_data, '\U0001F063'))
def test_strwidth_ucs_2(self):
self.assertEqual(4, plu.strwidth_ucs_2(width_data, 'abcd'))
self.assertEqual(4, plu.strwidth_ucs_2(width_data, ''))
if not sys.maxunicode < 0x10FFFF:
raise SkipTest('Can only test strwidth_ucs_2 in UCS-2 Pythons')
self.assertEqual(2, plu.strwidth_ucs_2(width_data, '\ud83d\udc8e'))
self.assertEqual(1, plu.strwidth_ucs_2(width_data, '\ud83c\udc30'))
class TestVCS(TestCase):

View File

@ -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:

View File

@ -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()
@ -502,6 +527,11 @@ class TestEnv(TestCommon):
if hasattr(self.module, 'psutil') and not callable(self.module.psutil.Process.username):
username = property(username)
segment_info = {'environ': {}}
def user(*args, **kwargs):
return self.module.user(pl=pl, segment_info=segment_info, *args, **kwargs)
struct_passwd = namedtuple('struct_passwd', ('pw_name',))
new_psutil = new_module('psutil', Process=Process)
new_pwd = new_module('pwd', getpwuid=lambda uid: struct_passwd(pw_name='def@DOMAIN.COM'))
@ -512,21 +542,21 @@ class TestEnv(TestCommon):
with replace_attr(self.module, 'os', new_os):
with replace_attr(self.module, 'psutil', new_psutil):
with replace_attr(self.module, '_geteuid', lambda: 5):
self.assertEqual(self.module.user(pl=pl), [
self.assertEqual(user(), [
{'contents': 'def@DOMAIN.COM', 'highlight_groups': ['user']}
])
self.assertEqual(self.module.user(pl=pl, hide_user='abc'), [
self.assertEqual(user(hide_user='abc'), [
{'contents': 'def@DOMAIN.COM', 'highlight_groups': ['user']}
])
self.assertEqual(self.module.user(pl=pl, hide_domain=False), [
self.assertEqual(user(hide_domain=False), [
{'contents': 'def@DOMAIN.COM', 'highlight_groups': ['user']}
])
self.assertEqual(self.module.user(pl=pl, hide_user='def@DOMAIN.COM'), None)
self.assertEqual(self.module.user(pl=pl, hide_domain=True), [
self.assertEqual(user(hide_user='def@DOMAIN.COM'), None)
self.assertEqual(user(hide_domain=True), [
{'contents': 'def', 'highlight_groups': ['user']}
])
with replace_attr(self.module, '_geteuid', lambda: 0):
self.assertEqual(self.module.user(pl=pl), [
self.assertEqual(user(), [
{'contents': 'def', 'highlight_groups': ['superuser', 'user']}
])

View File

@ -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

View File

@ -26,7 +26,8 @@ def
  BRANCH  …  shell  3rd  (echo)  cd ../'$(echo)'
  BRANCH  …  shell  3rd  $(echo)  cd ../'`echo`'
  BRANCH  …  shell  3rd  `echo`  cd ../'«Unicode!»'
  BRANCH  …  shell  3rd  «Unicode!»  set_theme_option default_leftonly.segments.above "$ABOVE_LEFT"
  BRANCH  …  shell  3rd  «Unicode!»  (exit 42)|(exit 43)
  BRANCH  …  shell  3rd  «Unicode!»  42  43  set_theme_option default_leftonly.segments.above "$ABOVE_LEFT"
  BRANCH  …  shell  3rd  «Unicode!»  export DISPLAYED_ENV_VAR=foo
 foo  
  BRANCH  …  shell  3rd  «Unicode!»  unset DISPLAYED_ENV_VAR

View File

@ -26,7 +26,8 @@ def
  BRANCH  …  shell  3rd  (echo)  cd ../'$(echo)'
  BRANCH  …  shell  3rd  $(echo)  cd ../'`echo`'
  BRANCH  …  shell  3rd  `echo`  cd ../'«Unicode!»'
  BRANCH  …  shell  3rd  «Unicode!»  set_theme_option default_leftonly.segments.above "$ABOVE_LEFT"
  BRANCH  …  shell  3rd  «Unicode!»  (exit 42)|(exit 43)
  BRANCH  …  shell  3rd  «Unicode!»  42  43  set_theme_option default_leftonly.segments.above "$ABOVE_LEFT"
  BRANCH  …  shell  3rd  «Unicode!»  export DISPLAYED_ENV_VAR=foo
 foo  
  BRANCH  …  shell  3rd  «Unicode!»  unset DISPLAYED_ENV_VAR

View File

@ -1,7 +1,7 @@
#!/bin/sh
. tests/shlib/common.sh
enter_suite shell
enter_suite shell final
if test $# -eq 0 ; then
FAST=1
@ -453,7 +453,7 @@ if test -z "${ONLY_SHELL}" || test "${ONLY_SHELL}" = "pdb" ; then
if ! run_test subclass python $PDB_PYTHON \
"$ROOT/tests/test_shells/pdb-main.py"
then
fail "pdb-subclass:test" F \
fail --allow-failure "pdb-subclass:test" F \
"Failed checking $PDB_PYTHON $ROOT/tests/test_shells/pdb-main.py"
fi
fi
@ -466,7 +466,7 @@ if test -z "${ONLY_SHELL}" || test "${ONLY_SHELL}" = "pdb" ; then
if ! run_test module python "$PDB_PYTHON" -m"$MODULE" \
"$ROOT/tests/test_shells/pdb-script.py"
then
fail "pdb-module:test" F \
fail --allow-failure "pdb-module:test" F \
"Failed checking $PDB_PYTHON -m$MODULE $ROOT/tests/test_shells/pdb-script"
fi
fi

View File

@ -1,10 +1,11 @@
#!/bin/sh
. tests/shlib/common.sh
. tests/shlib/vterm.sh
. tests/shlib/vim.sh
enter_suite vim
enter_suite vim final
make_test_root
vterm_setup vim
# Define some overrides. These ones must be ignored and do not affect Vim
# status/tab lines.
@ -14,6 +15,7 @@ export POWERLINE_THEME_OVERRIDES='default.segments.left=[]'
test_script() {
local vim="$1" ; shift
local script="$1" ; shift
local allow_failure_arg="$1" ; shift
echo "Running script $script with $vim"
if ! test -e "$vim" ; then
return 0
@ -22,7 +24,8 @@ test_script() {
|| test -f message.fail
then
local test_name="${script##*/}"
fail "${test_name%.vim}" F "Failed script $script run with $vim"
fail $allow_failure_arg "${test_name%.vim}" \
F "Failed script $script run with $vim"
if test -e message.fail ; then
cat message.fail >&2
rm message.fail
@ -36,14 +39,22 @@ cd "$TEST_ROOT"
for script in "$TEST_SCRIPT_ROOT"/*.vim ; do
if test "${script%.old.vim}" = "${script}" ; then
test_script "$NEW_VIM" "$script"
test_script "$NEW_VIM" "$script" ""
fi
done
if test "$PYTHON_VERSION_MAJOR.$PYTHON_VERSION_MINOR" = "2.7" ; then
ALLOW_FAILURE_ARG=--allow-failure
else
ALLOW_FAILURE_ARG=
fi
if test -e "$OLD_VIM" ; then
for script in "$TEST_SCRIPT_ROOT"/*.old.vim ; do
test_script "$OLD_VIM" "$script"
test_script "$OLD_VIM" "$script" "$ALLOW_FAILURE_ARG"
done
fi
vterm_shutdown
exit_suite