mirror of
https://github.com/powerline/powerline.git
synced 2025-07-28 16:24:57 +02:00
Release 2.6
- Added support for new Vim modes. - Added ability to control output padding. - Added iTunes player segment. - Added support for tmux development builds. - Added a workaround for a fish bug sometimes occurring when using eval from config.fish (upstream status unknown). - Added a workaround for tmux 2.4 bug: excessive CPU usage when having multiple panes (also fixed upstream). - Fixed clean file status support in mercurial. - Fixed error when battery capacity is zero and using DBus. - Fixed mercurial command servers leakage. - Refactored awesome bindings to use powerline daemon.
This commit is contained in:
commit
c3261d4e57
@ -215,6 +215,13 @@ Common configuration is a subdictionary that is a value of ``ext`` key in
|
||||
|
||||
All components are enabled by default.
|
||||
|
||||
.. _config-ext-update_interval:
|
||||
|
||||
``update_interval``
|
||||
Determines how often WM status bars need to be updated, in seconds. Only
|
||||
valid for WM extensions which use ``powerline-daemon``. Defaults to
|
||||
2 seconds.
|
||||
|
||||
.. _config-colors:
|
||||
|
||||
Color definitions
|
||||
@ -361,6 +368,10 @@ ascii Theme without any unicode characters at all
|
||||
is set in the local themes it will be ignored. This option may also be
|
||||
ignored in some bindings.
|
||||
|
||||
``outer_padding``
|
||||
Defines number of spaces at the end of output (on the right side) or at
|
||||
the start of output (on the left side). Defaults to ``1``.
|
||||
|
||||
|
||||
``dividers``
|
||||
Defines the dividers used in all Powerline extensions.
|
||||
@ -391,7 +402,7 @@ ascii Theme without any unicode characters at all
|
||||
:ref:`display <config-themes-seg-display>`.
|
||||
|
||||
Key :ref:`args <config-themes-seg-args>` (only for function and
|
||||
segments_list segments) is handled specially: unlike other values it is
|
||||
segment_list segments) is handled specially: unlike other values it is
|
||||
merged with all other values, except that a single ``{module}.{function}``
|
||||
key if found prevents merging all ``{function}`` values.
|
||||
|
||||
@ -428,7 +439,7 @@ ascii Theme without any unicode characters at all
|
||||
|
||||
``type``
|
||||
The segment type. Can be one of ``function`` (default), ``string`` or
|
||||
``segments_list``:
|
||||
``segment_list``:
|
||||
|
||||
``function``
|
||||
The segment contents is the return value of the function defined in
|
||||
@ -443,7 +454,7 @@ ascii Theme without any unicode characters at all
|
||||
highlighting group is defined in the :ref:`highlight_groups option
|
||||
<config-themes-seg-highlight_groups>`.
|
||||
|
||||
``segments_list``
|
||||
``segment_list``
|
||||
Sub-list of segments. This list only allows :ref:`function
|
||||
<config-themes-seg-function>`, :ref:`segments
|
||||
<config-themes-seg-segments>` and :ref:`args
|
||||
@ -458,7 +469,7 @@ ascii Theme without any unicode characters at all
|
||||
Segment name. If present allows referring to this segment in
|
||||
:ref:`segment_data <config-themes-segment_data>` dictionary by this
|
||||
name. If not ``string`` segments may not be referred there at all and
|
||||
``function`` and ``segments_list`` segments may be referred there using
|
||||
``function`` and ``segment_list`` segments may be referred there using
|
||||
either ``{module}.{function_name}`` or ``{function_name}``, whichever
|
||||
will be found first. Function name is taken from :ref:`function key
|
||||
<config-themes-seg-function>`.
|
||||
|
@ -30,7 +30,7 @@ Generic requirements
|
||||
with bazaar repositories.
|
||||
* ``pyuv`` python package. Required for :ref:`libuv-based watcher
|
||||
<config-common-watcher>` to work.
|
||||
* ``i3-ipc`` python package. Required for i3wm bindings and segments.
|
||||
* ``i3ipc`` python package. Required for i3wm bindings and segments.
|
||||
* ``xrandr`` program. Required for the multi-monitor lemonbar binding and the
|
||||
:py:func:`powerline.listers.i3wm.output_lister`.
|
||||
|
||||
|
@ -111,7 +111,7 @@ following in ``~/.profile``:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
if test "x$0" != "x${0#dash}" ; then
|
||||
if test "$0" != "${0#dash}" ; then
|
||||
export ENV={repository_root}/powerline/bindings/shell/powerline.sh
|
||||
fi
|
||||
|
||||
|
@ -419,6 +419,11 @@ def _get_log_keys(common_config):
|
||||
))
|
||||
|
||||
|
||||
DEFAULT_UPDATE_INTERVAL = 2
|
||||
'''Default value for :ref:`update_interval <config-ext-update_interval>`
|
||||
'''
|
||||
|
||||
|
||||
class Powerline(object):
|
||||
'''Main powerline class, entrance point for all powerline uses. Sets
|
||||
powerline up and loads the configuration.
|
||||
@ -514,6 +519,7 @@ class Powerline(object):
|
||||
self.setup_args = ()
|
||||
self.setup_kwargs = {}
|
||||
self.imported_modules = set()
|
||||
self.update_interval = DEFAULT_UPDATE_INTERVAL
|
||||
|
||||
get_encoding = staticmethod(get_preferred_output_encoding)
|
||||
'''Get encoding used by the current application
|
||||
@ -638,6 +644,7 @@ class Powerline(object):
|
||||
or self.ext_config.get('local_themes') != self.prev_ext_config.get('local_themes')
|
||||
):
|
||||
self.renderer_options['local_themes'] = self.get_local_themes(self.ext_config.get('local_themes'))
|
||||
self.update_interval = self.ext_config.get('update_interval', 2)
|
||||
load_colorscheme = (
|
||||
load_colorscheme
|
||||
or not self.prev_ext_config
|
||||
|
@ -4,38 +4,17 @@ from __future__ import (unicode_literals, division, absolute_import, print_funct
|
||||
|
||||
import sys
|
||||
|
||||
from time import sleep
|
||||
from subprocess import Popen, PIPE
|
||||
from powerline.bindings.wm import DEFAULT_UPDATE_INTERVAL
|
||||
from powerline.bindings.wm.awesome import run
|
||||
|
||||
from powerline import Powerline
|
||||
from powerline.lib.monotonic import monotonic
|
||||
|
||||
powerline = Powerline('wm', renderer_module='pango_markup')
|
||||
powerline.update_renderer()
|
||||
|
||||
try:
|
||||
def main():
|
||||
try:
|
||||
interval = float(sys.argv[1])
|
||||
except IndexError:
|
||||
interval = 2
|
||||
except IndexError:
|
||||
interval = DEFAULT_UPDATE_INTERVAL
|
||||
run(interval=interval)
|
||||
|
||||
|
||||
def read_to_log(pl, client):
|
||||
for line in client.stdout:
|
||||
if line:
|
||||
pl.info(line, prefix='awesome-client')
|
||||
for line in client.stderr:
|
||||
if line:
|
||||
pl.error(line, prefix='awesome-client')
|
||||
if client.wait():
|
||||
pl.error('Client exited with {0}', client.returncode, prefix='awesome')
|
||||
|
||||
|
||||
while True:
|
||||
start_time = monotonic()
|
||||
s = powerline.render(side='right')
|
||||
request = 'powerline_widget:set_markup(\'' + s.replace('\\', '\\\\').replace('\'', '\\\'') + '\')\n'
|
||||
client = Popen(['awesome-client'], shell=False, stdout=PIPE, stderr=PIPE, stdin=PIPE)
|
||||
client.stdin.write(request.encode('utf-8'))
|
||||
client.stdin.close()
|
||||
read_to_log(powerline.pl, client)
|
||||
sleep(max(interval - (monotonic() - start_time), 0.1))
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
@ -6,6 +6,5 @@ powerline_widget:set_align('right')
|
||||
|
||||
function powerline(mode, widget) end
|
||||
|
||||
bindings_path = string.gsub(debug.getinfo(1).source:match('@(.*)$'), '/[^/]+$', '')
|
||||
powerline_cmd = bindings_path .. '/powerline-awesome.py'
|
||||
awful.util.spawn_with_shell('ps -C powerline-awesome.py || ' .. powerline_cmd)
|
||||
awful.util.spawn_with_shell('powerline-daemon -q')
|
||||
awful.util.spawn_with_shell('powerline wm.awesome')
|
||||
|
@ -11,6 +11,7 @@ from argparse import ArgumentParser
|
||||
|
||||
from powerline.lemonbar import LemonbarPowerline
|
||||
from powerline.lib.encoding import get_unicode_writer
|
||||
from powerline.bindings.wm import DEFAULT_UPDATE_INTERVAL
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
@ -29,7 +30,7 @@ if __name__ == '__main__':
|
||||
|
||||
def render(reschedule=False):
|
||||
if reschedule:
|
||||
Timer(0.5, render, kwargs={'reschedule': True}).start()
|
||||
Timer(DEFAULT_UPDATE_INTERVAL, render, kwargs={'reschedule': True}).start()
|
||||
|
||||
global lock
|
||||
with lock:
|
||||
|
@ -21,7 +21,7 @@ _powerline_tmux_setenv() {
|
||||
}
|
||||
|
||||
_powerline_tmux_set_pwd() {
|
||||
if test "x$_POWERLINE_SAVED_PWD" != "x$PWD" ; then
|
||||
if test "$_POWERLINE_SAVED_PWD" != "$PWD" ; then
|
||||
_POWERLINE_SAVED_PWD="$PWD"
|
||||
_powerline_tmux_setenv PWD "$PWD"
|
||||
fi
|
||||
@ -39,8 +39,8 @@ _powerline_init_tmux_support() {
|
||||
trap '_powerline_tmux_set_columns' WINCH
|
||||
_powerline_tmux_set_columns
|
||||
|
||||
test "x$PROMPT_COMMAND" != "x${PROMPT_COMMAND/_powerline_tmux_set_pwd}" ||
|
||||
PROMPT_COMMAND="${PROMPT_COMMAND}"$'\n_powerline_tmux_set_pwd'
|
||||
test "$PROMPT_COMMAND" != "${PROMPT_COMMAND/_powerline_tmux_set_pwd}" \
|
||||
|| PROMPT_COMMAND="${PROMPT_COMMAND}"$'\n_powerline_tmux_set_pwd'
|
||||
fi
|
||||
}
|
||||
|
||||
@ -82,8 +82,8 @@ _powerline_setup_prompt() {
|
||||
if test -z "${POWERLINE_COMMAND}" ; then
|
||||
POWERLINE_COMMAND="$("$POWERLINE_CONFIG_COMMAND" shell command)"
|
||||
fi
|
||||
test "x$PROMPT_COMMAND" != "x${PROMPT_COMMAND%_powerline_set_prompt*}" ||
|
||||
PROMPT_COMMAND=$'_powerline_set_prompt\n'"${PROMPT_COMMAND}"
|
||||
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)"
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ class EmptyArgs(object):
|
||||
def init_tmux_environment(pl, args, set_tmux_environment=set_tmux_environment):
|
||||
'''Initialize tmux environment from tmux configuration
|
||||
'''
|
||||
powerline = ShellPowerline(finish_args(os.environ, EmptyArgs('tmux', args.config_path)))
|
||||
powerline = ShellPowerline(finish_args(None, os.environ, EmptyArgs('tmux', args.config_path)))
|
||||
# TODO Move configuration files loading out of Powerline object and use it
|
||||
# directly
|
||||
powerline.update_renderer()
|
||||
|
@ -34,7 +34,7 @@ function powerline-setup
|
||||
set -g POWERLINE_COMMAND (env $POWERLINE_CONFIG_COMMAND shell command)
|
||||
end
|
||||
function _powerline_set_default_mode --on-variable fish_key_bindings
|
||||
if test x$fish_key_bindings != xfish_vi_key_bindings
|
||||
if test $fish_key_bindings != fish_vi_key_bindings
|
||||
set -g _POWERLINE_DEFAULT_MODE default
|
||||
else
|
||||
set -g -e _POWERLINE_DEFAULT_MODE
|
||||
@ -62,7 +62,7 @@ function powerline-setup
|
||||
set rpromptpast
|
||||
set columnsexpr '(_powerline_columns)'
|
||||
end
|
||||
eval "
|
||||
echo "
|
||||
function fish_prompt
|
||||
env \$POWERLINE_COMMAND $POWERLINE_COMMAND_ARGS shell $promptside $addargs
|
||||
end
|
||||
@ -73,7 +73,7 @@ function powerline-setup
|
||||
function _powerline_set_columns --on-signal WINCH
|
||||
set -g _POWERLINE_COLUMNS $columnsexpr
|
||||
end
|
||||
"
|
||||
" | source
|
||||
_powerline_set_columns
|
||||
end
|
||||
_powerline_set_default_mode
|
||||
|
@ -37,7 +37,7 @@ fn _powerline_common_setup {
|
||||
}
|
||||
|
||||
fn _powerline_tmux_pane {
|
||||
if (test x$TMUX_PANE '!=' x) {
|
||||
if (test -n $TMUX_PANE) {
|
||||
echo $TMUX_PANE | tr -d ' %'
|
||||
} else {
|
||||
TMUX=$_POWERLINE_TMUX tmux display -p '#D' | tr -d ' %'
|
||||
@ -54,9 +54,9 @@ if (test -z $POWERLINE_CONFIG_COMMAND) {
|
||||
echo powerline-config executable not found, unable to proceed >[2=1]
|
||||
}
|
||||
}
|
||||
if (test x$POWERLINE_CONFIG_COMMAND '!=' x) {
|
||||
if (test -n $POWERLINE_CONFIG_COMMAND) {
|
||||
if ($POWERLINE_CONFIG_COMMAND shell --shell rcsh uses prompt) {
|
||||
if (test x$POWERLINE_COMMAND_ARGS '!=' x) {
|
||||
if (test -n $POWERLINE_COMMAND_ARGS) {
|
||||
# Perform splitting
|
||||
POWERLINE_COMMAND_ARGS=( `{echo $POWERLINE_COMMAND_ARGS} )
|
||||
}
|
||||
@ -75,11 +75,11 @@ if (test x$POWERLINE_CONFIG_COMMAND '!=' x) {
|
||||
}
|
||||
_powerline_common_setup
|
||||
}
|
||||
if (test x$TMUX '!=' x) {
|
||||
if (test -n $TMUX) {
|
||||
if ($POWERLINE_CONFIG_COMMAND shell --shell rcsh uses tmux) {
|
||||
_POWERLINE_TMUX=$TMUX
|
||||
fn _powerline_tmux_setenv {
|
||||
if (test x$2 '!=' x) {
|
||||
if (test -n $2) {
|
||||
TMUX=$_POWERLINE_TMUX tmux setenv -g TMUX_$1^_`{
|
||||
_powerline_tmux_pane
|
||||
} $2
|
||||
|
@ -115,7 +115,7 @@ _powerline_tmux_setenv() {
|
||||
}
|
||||
|
||||
_powerline_tmux_set_pwd() {
|
||||
if test "x$_POWERLINE_SAVED_PWD" != "x$PWD" ; then
|
||||
if test "$_POWERLINE_SAVED_PWD" != "$PWD" ; then
|
||||
_POWERLINE_SAVED_PWD="$PWD"
|
||||
_powerline_tmux_setenv PWD "$PWD"
|
||||
fi
|
||||
|
@ -76,6 +76,8 @@ def get_tmux_version(pl):
|
||||
version_string = get_tmux_output(pl, '-V')
|
||||
_, version_string = version_string.split(' ')
|
||||
version_string = version_string.strip()
|
||||
if version_string == 'master':
|
||||
return TmuxVersionInfo(float('inf'), 0, version_string)
|
||||
major, minor = version_string.split('.')
|
||||
suffix = DIGITS.subn('', minor)[0] or None
|
||||
minor = NON_DIGITS.subn('', minor)[0]
|
||||
|
@ -1,11 +1,11 @@
|
||||
set -g status on
|
||||
set -g status-interval 2
|
||||
set -g status-left-length 20
|
||||
set -g status-right '#(env "$POWERLINE_COMMAND" $POWERLINE_COMMAND_ARGS tmux right -R pane_id=\"`tmux display -p "#D"`\")'
|
||||
set -g status-right '#(env "$POWERLINE_COMMAND" $POWERLINE_COMMAND_ARGS tmux right -R pane_id=\"`tmux display -p "#""D"`\")'
|
||||
set -g status-right-length 150
|
||||
set -g window-status-format "#[$_POWERLINE_WINDOW_COLOR]$_POWERLINE_LEFT_HARD_DIVIDER_SPACES#I#F #[$_POWERLINE_WINDOW_DIVIDER_COLOR]$_POWERLINE_LEFT_SOFT_DIVIDER#[default]#W $_POWERLINE_LEFT_HARD_DIVIDER_SPACES"
|
||||
set -g window-status-current-format "#[$_POWERLINE_WINDOW_CURRENT_HARD_DIVIDER_COLOR]$_POWERLINE_LEFT_HARD_DIVIDER#[$_POWERLINE_WINDOW_CURRENT_COLOR]#I#F $_POWERLINE_LEFT_SOFT_DIVIDER#[$_POWERLINE_WINDOW_NAME_COLOR]#W #[$_POWERLINE_WINDOW_CURRENT_HARD_DIVIDER_NEXT_COLOR]$_POWERLINE_LEFT_HARD_DIVIDER"
|
||||
|
||||
# Legacy status-left definition to be overwritten for tmux Versions 1.8+
|
||||
set -g status-left "#[$_POWERLINE_SESSION_COLOR] #S #[$_POWERLINE_SESSION_HARD_DIVIDER_NEXT_COLOR]$_POWERLINE_LEFT_HARD_DIVIDER#(env \"\$POWERLINE_COMMAND\" tmux left -R pane_id=\"`tmux display -p '#D'`\")"
|
||||
set -g status-left "#[$_POWERLINE_SESSION_COLOR] #S #[$_POWERLINE_SESSION_HARD_DIVIDER_NEXT_COLOR]$_POWERLINE_LEFT_HARD_DIVIDER#(env \"\$POWERLINE_COMMAND\" tmux left -R pane_id=\"`tmux display -p '#''D'`\")"
|
||||
# vim: ft=tmux
|
||||
|
@ -1,3 +1,3 @@
|
||||
set -g status-right '#(env "$POWERLINE_COMMAND" $POWERLINE_COMMAND_ARGS tmux right -R pane_id="`tmux display -p "#D"`" --width=`tmux display -p "#{client_width}"` -R width_adjust=`tmux show-options -g status-left-length | cut -d" " -f 2`)'
|
||||
set -g status-left "#[$_POWERLINE_SESSION_COLOR] #S #[$_POWERLINE_SESSION_HARD_DIVIDER_NEXT_COLOR]$_POWERLINE_LEFT_HARD_DIVIDER#(env \"\$POWERLINE_COMMAND\" tmux left --width=`tmux display -p '#{client_width}'` -R width_adjust=`tmux show-options -g status-right-length | cut -d' ' -f2` -R pane_id=\"`tmux display -p '#D'`\")"
|
||||
set -g status-right '#(env "$POWERLINE_COMMAND" $POWERLINE_COMMAND_ARGS tmux right -R pane_id="`tmux display -p "#""D"`" --width=`tmux display -p "#""{client_width}"` -R width_adjust=`tmux show-options -g status-left-length | cut -d" " -f 2`)'
|
||||
set -g status-left "#[$_POWERLINE_SESSION_COLOR] #S #[$_POWERLINE_SESSION_HARD_DIVIDER_NEXT_COLOR]$_POWERLINE_LEFT_HARD_DIVIDER#(env \"\$POWERLINE_COMMAND\" tmux left --width=`tmux display -p '#''{client_width}'` -R width_adjust=`tmux show-options -g status-right-length | cut -d' ' -f2` -R pane_id=\"`tmux display -p '#''D'`\")"
|
||||
# vim: ft=tmux
|
||||
|
@ -1,5 +1,5 @@
|
||||
# powerline_tmux_1.8_plus.conf
|
||||
# tmux Version 1.8 introduces the 'client_prefix' format variable, applicable
|
||||
# for versions 1.8+
|
||||
set -qg status-left "#{?client_prefix,#[fg=$_POWERLINE_SESSION_PREFIX_FG]#[bg=$_POWERLINE_SESSION_PREFIX_BG]#[$_POWERLINE_SESSION_PREFIX_ATTR],#[fg=$_POWERLINE_SESSION_FG]#[bg=$_POWERLINE_SESSION_BG]#[$_POWERLINE_SESSION_ATTR]} #S #{?client_prefix,#[fg=$_POWERLINE_SESSION_PREFIX_BG],#[fg=$_POWERLINE_SESSION_BG]}#[bg=$_POWERLINE_BACKGROUND_BG]#[nobold]$_POWERLINE_LEFT_HARD_DIVIDER#(env \$POWERLINE_COMMAND \$POWERLINE_COMMAND_ARGS tmux left --width=`tmux display -p '#{client_width}'` -R width_adjust=`tmux show-options -g status-right-length | cut -d' ' -f2` -R pane_id=\"`tmux display -p '#D'`\")"
|
||||
set -qg status-left "#{?client_prefix,#[fg=$_POWERLINE_SESSION_PREFIX_FG]#[bg=$_POWERLINE_SESSION_PREFIX_BG]#[$_POWERLINE_SESSION_PREFIX_ATTR],#[fg=$_POWERLINE_SESSION_FG]#[bg=$_POWERLINE_SESSION_BG]#[$_POWERLINE_SESSION_ATTR]} #S #{?client_prefix,#[fg=$_POWERLINE_SESSION_PREFIX_BG],#[fg=$_POWERLINE_SESSION_BG]}#[bg=$_POWERLINE_BACKGROUND_BG]#[nobold]$_POWERLINE_LEFT_HARD_DIVIDER#(env \$POWERLINE_COMMAND \$POWERLINE_COMMAND_ARGS tmux left --width=`tmux display -p '#''{client_width}'` -R width_adjust=`tmux show-options -g status-right-length | cut -d' ' -f2` -R pane_id=\"`tmux display -p '#''D'`\")"
|
||||
# vim: ft=tmux
|
||||
|
@ -1,2 +1,3 @@
|
||||
# Starting from tmux-2.1 escaping of dollar signs inside #() is harmful
|
||||
set -qg status-left "#{?client_prefix,#[fg=$_POWERLINE_SESSION_PREFIX_FG]#[bg=$_POWERLINE_SESSION_PREFIX_BG]#[$_POWERLINE_SESSION_PREFIX_ATTR],#[fg=$_POWERLINE_SESSION_FG]#[bg=$_POWERLINE_SESSION_BG]#[$_POWERLINE_SESSION_ATTR]} #S #{?client_prefix,#[fg=$_POWERLINE_SESSION_PREFIX_BG],#[fg=$_POWERLINE_SESSION_BG]}#[bg=$_POWERLINE_BACKGROUND_BG]#[nobold]$_POWERLINE_LEFT_HARD_DIVIDER#(env $POWERLINE_COMMAND $POWERLINE_COMMAND_ARGS tmux left --width=`tmux display -p '#{client_width}'` -R width_adjust=`tmux show-options -g status-right-length | cut -d' ' -f2` -R pane_id=\"`tmux display -p '#D'`\")"
|
||||
set -qg status-left "#{?client_prefix,#[fg=$_POWERLINE_SESSION_PREFIX_FG]#[bg=$_POWERLINE_SESSION_PREFIX_BG]#[$_POWERLINE_SESSION_PREFIX_ATTR],#[fg=$_POWERLINE_SESSION_FG]#[bg=$_POWERLINE_SESSION_BG]#[$_POWERLINE_SESSION_ATTR]} #S #{?client_prefix,#[fg=$_POWERLINE_SESSION_PREFIX_BG],#[fg=$_POWERLINE_SESSION_BG]}#[bg=$_POWERLINE_BACKGROUND_BG]#[nobold]$_POWERLINE_LEFT_HARD_DIVIDER#(env $POWERLINE_COMMAND $POWERLINE_COMMAND_ARGS tmux left --width=`tmux display -p '#''{client_width}'` -R width_adjust=`tmux show-options -g status-right-length | cut -d' ' -f2` -R pane_id=\"`tmux display -p '#''D'`\")"
|
||||
set -g window-status-format "#[$_POWERLINE_WINDOW_COLOR]$_POWERLINE_LEFT_HARD_DIVIDER_SPACES#I#{?window_flags,#F, } #[$_POWERLINE_WINDOW_DIVIDER_COLOR]$_POWERLINE_LEFT_SOFT_DIVIDER#[default]#W $_POWERLINE_LEFT_HARD_DIVIDER_SPACES"
|
||||
|
@ -5,6 +5,10 @@ import re
|
||||
|
||||
from powerline.theme import requires_segment_info
|
||||
from powerline.lib.shell import run_cmd
|
||||
from powerline.bindings.wm.awesome import AwesomeThread
|
||||
|
||||
|
||||
DEFAULT_UPDATE_INTERVAL = 0.5
|
||||
|
||||
|
||||
conn = None
|
||||
@ -36,3 +40,8 @@ def get_connected_xrandr_outputs(pl):
|
||||
return (match.groupdict() for match in XRANDR_OUTPUT_RE.finditer(
|
||||
run_cmd(pl, ['xrandr', '-q'])
|
||||
))
|
||||
|
||||
|
||||
wm_threads = {
|
||||
'awesome': AwesomeThread,
|
||||
}
|
||||
|
59
powerline/bindings/wm/awesome.py
Normal file
59
powerline/bindings/wm/awesome.py
Normal file
@ -0,0 +1,59 @@
|
||||
# vim:fileencoding=utf-8:noet
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
|
||||
import sys
|
||||
|
||||
from threading import Thread, Event
|
||||
from time import sleep
|
||||
from subprocess import Popen, PIPE
|
||||
|
||||
from powerline import Powerline
|
||||
from powerline.lib.monotonic import monotonic
|
||||
|
||||
|
||||
def read_to_log(pl, client):
|
||||
for line in client.stdout:
|
||||
if line:
|
||||
pl.info(line, prefix='awesome-client')
|
||||
for line in client.stderr:
|
||||
if line:
|
||||
pl.error(line, prefix='awesome-client')
|
||||
if client.wait():
|
||||
pl.error('Client exited with {0}', client.returncode, prefix='awesome')
|
||||
|
||||
|
||||
def run(thread_shutdown_event=None, pl_shutdown_event=None, pl_config_loader=None,
|
||||
interval=None):
|
||||
powerline = Powerline(
|
||||
'wm',
|
||||
renderer_module='pango_markup',
|
||||
shutdown_event=pl_shutdown_event,
|
||||
config_loader=pl_config_loader,
|
||||
)
|
||||
powerline.update_renderer()
|
||||
|
||||
if not thread_shutdown_event:
|
||||
thread_shutdown_event = powerline.shutdown_event
|
||||
|
||||
while not thread_shutdown_event.is_set():
|
||||
# powerline.update_interval may change over time
|
||||
used_interval = interval or powerline.update_interval
|
||||
start_time = monotonic()
|
||||
s = powerline.render(side='right')
|
||||
request = 'powerline_widget:set_markup(\'' + s.translate({'\'': '\\\'', '\\': '\\\\'}) + '\')\n'
|
||||
client = Popen(['awesome-client'], shell=False, stdout=PIPE, stderr=PIPE, stdin=PIPE)
|
||||
client.stdin.write(request.encode('utf-8'))
|
||||
client.stdin.close()
|
||||
read_to_log(powerline.pl, client)
|
||||
thread_shutdown_event.wait(max(used_interval - (monotonic() - start_time), 0.1))
|
||||
|
||||
|
||||
class AwesomeThread(Thread):
|
||||
__slots__ = ('powerline_shutdown_event',)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(AwesomeThread, self).__init__()
|
||||
self.powerline_run_kwargs = kwargs
|
||||
|
||||
def run(self):
|
||||
run(**self.powerline_run_kwargs)
|
@ -111,7 +111,7 @@ if hasattr(zsh, 'expand') and zsh.expand('${:-}') == '':
|
||||
zsh_expand = zsh.expand
|
||||
else:
|
||||
def zsh_expand(s):
|
||||
zsh.eval('_POWERLINE_REPLY="' + s + '"')
|
||||
zsh.eval('local _POWERLINE_REPLY="' + s + '"')
|
||||
ret = zsh.getvalue('_POWERLINE_REPLY')
|
||||
zsh.setvalue('_POWERLINE_REPLY', None)
|
||||
return ret
|
||||
|
@ -25,6 +25,11 @@ _powerline_tmux_pane() {
|
||||
echo "${TMUX_PANE:-`tmux display -p "#D"`}" | tr -d ' %'
|
||||
}
|
||||
|
||||
_powerline_tmux_pane() {
|
||||
local -x TMUX="$_POWERLINE_TMUX"
|
||||
echo "${TMUX_PANE:-`tmux display -p "#D"`}" | tr -d ' %'
|
||||
}
|
||||
|
||||
_powerline_init_tmux_support() {
|
||||
emulate -L zsh
|
||||
if test -n "$TMUX" && tmux refresh -S &>/dev/null ; then
|
||||
|
@ -11,6 +11,7 @@ from powerline.lib.overrides import parsedotval, parse_override_var
|
||||
from powerline.lib.dict import mergeargs
|
||||
from powerline.lib.encoding import get_preferred_arguments_encoding
|
||||
from powerline.lib.unicode import u, unicode
|
||||
from powerline.bindings.wm import wm_threads
|
||||
|
||||
|
||||
if sys.version_info < (3,):
|
||||
@ -23,7 +24,7 @@ else:
|
||||
return s
|
||||
|
||||
|
||||
def finish_args(environ, args):
|
||||
def finish_args(parser, environ, args, is_daemon=False):
|
||||
'''Do some final transformations
|
||||
|
||||
Transforms ``*_override`` arguments into dictionaries, adding overrides from
|
||||
@ -61,7 +62,13 @@ def finish_args(environ, args):
|
||||
[path for path in environ.get('POWERLINE_CONFIG_PATHS', '').split(':') if path]
|
||||
+ (args.config_path or [])
|
||||
)
|
||||
args.side = args.side[0]
|
||||
if args.ext[0].startswith('wm.'):
|
||||
if not is_daemon:
|
||||
parser.error('WM bindings must be used with daemon only')
|
||||
elif args.ext[0][3:] not in wm_threads:
|
||||
parser.error('WM binding not found')
|
||||
elif not args.side:
|
||||
parser.error('expected one argument')
|
||||
return args
|
||||
|
||||
|
||||
@ -77,15 +84,16 @@ def get_argparser(ArgumentParser=argparse.ArgumentParser):
|
||||
parser.add_argument(
|
||||
'ext', nargs=1,
|
||||
help='Extension: application for which powerline command is launched '
|
||||
'(usually `shell\' or `tmux\').'
|
||||
'(usually `shell\' or `tmux\'). Also supports `wm.\' extensions: '
|
||||
+ ', '.join(('`wm.' + key + '\'' for key in wm_threads.keys())) + '.'
|
||||
)
|
||||
parser.add_argument(
|
||||
'side', nargs=1, choices=('left', 'right', 'above', 'aboveleft'),
|
||||
'side', nargs='?', choices=('left', 'right', 'above', 'aboveleft'),
|
||||
help='Side: `left\' and `right\' represent left and right side '
|
||||
'respectively, `above\' emits lines that are supposed to be printed '
|
||||
'just above the prompt and `aboveleft\' is like concatenating '
|
||||
'`above\' with `left\' with the exception that only one Python '
|
||||
'instance is used in this case.'
|
||||
'instance is used in this case. May be omitted for `wm.*\' extensions.'
|
||||
)
|
||||
parser.add_argument(
|
||||
'-r', '--renderer-module', metavar='MODULE', type=str,
|
||||
|
@ -76,6 +76,50 @@
|
||||
"branch:divider": { "fg": "darkcyan", "bg": "darkblue", "attrs": [] }
|
||||
}
|
||||
},
|
||||
"ic": {
|
||||
"colors": {
|
||||
"gray0": "darkestblue",
|
||||
"gray1": "darkestblue",
|
||||
"gray2": "darkestblue",
|
||||
"gray3": "darkblue",
|
||||
"gray4": "darkblue",
|
||||
"gray5": "darkestcyan",
|
||||
"gray6": "darkestcyan",
|
||||
"gray7": "darkestcyan",
|
||||
"gray8": "mediumcyan",
|
||||
"gray9": "mediumcyan",
|
||||
"gray10": "mediumcyan",
|
||||
"green_yellow_red": "gray5",
|
||||
"dark_green_gray": "light_green_gray"
|
||||
},
|
||||
"groups": {
|
||||
"mode": { "fg": "darkestcyan", "bg": "white", "attrs": ["bold"] },
|
||||
"background:divider": { "fg": "darkcyan", "bg": "darkestblue", "attrs": [] },
|
||||
"branch:divider": { "fg": "darkcyan", "bg": "darkblue", "attrs": [] }
|
||||
}
|
||||
},
|
||||
"ix": {
|
||||
"colors": {
|
||||
"gray0": "darkestblue",
|
||||
"gray1": "darkestblue",
|
||||
"gray2": "darkestblue",
|
||||
"gray3": "darkblue",
|
||||
"gray4": "darkblue",
|
||||
"gray5": "darkestcyan",
|
||||
"gray6": "darkestcyan",
|
||||
"gray7": "darkestcyan",
|
||||
"gray8": "mediumcyan",
|
||||
"gray9": "mediumcyan",
|
||||
"gray10": "mediumcyan",
|
||||
"green_yellow_red": "gray5",
|
||||
"dark_green_gray": "light_green_gray"
|
||||
},
|
||||
"groups": {
|
||||
"mode": { "fg": "darkestcyan", "bg": "white", "attrs": ["bold"] },
|
||||
"background:divider": { "fg": "darkcyan", "bg": "darkestblue", "attrs": [] },
|
||||
"branch:divider": { "fg": "darkcyan", "bg": "darkblue", "attrs": [] }
|
||||
}
|
||||
},
|
||||
"v": {
|
||||
"groups": {
|
||||
"mode": { "fg": "darkorange", "bg": "brightestorange", "attrs": ["bold"] }
|
||||
@ -95,6 +139,16 @@
|
||||
"groups": {
|
||||
"mode": { "fg": "white", "bg": "brightred", "attrs": ["bold"] }
|
||||
}
|
||||
},
|
||||
"Rc": {
|
||||
"groups": {
|
||||
"mode": { "fg": "white", "bg": "brightred", "attrs": ["bold"] }
|
||||
}
|
||||
},
|
||||
"Rx": {
|
||||
"groups": {
|
||||
"mode": { "fg": "white", "bg": "brightred", "attrs": ["bold"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -73,6 +73,20 @@
|
||||
"col_current": { "fg": "solarized:base0", "bg": "solarized:base3", "attrs": [] }
|
||||
}
|
||||
},
|
||||
"ic": {
|
||||
"groups": {
|
||||
"background": { "fg": "solarized:base3", "bg": "solarized:base01", "attrs": [] },
|
||||
"background:divider": { "fg": "solarized:base2", "bg": "solarized:base01", "attrs": [] },
|
||||
"mode": { "fg": "solarized:base3", "bg": "solarized:blue", "attrs": ["bold"] }
|
||||
}
|
||||
},
|
||||
"ix": {
|
||||
"groups": {
|
||||
"background": { "fg": "solarized:base3", "bg": "solarized:base01", "attrs": [] },
|
||||
"background:divider": { "fg": "solarized:base2", "bg": "solarized:base01", "attrs": [] },
|
||||
"mode": { "fg": "solarized:base3", "bg": "solarized:blue", "attrs": ["bold"] }
|
||||
}
|
||||
},
|
||||
"v": {
|
||||
"groups": {
|
||||
"mode": { "fg": "solarized:base3", "bg": "solarized:orange", "attrs": ["bold"] }
|
||||
@ -92,6 +106,16 @@
|
||||
"groups": {
|
||||
"mode": { "fg": "solarized:base3", "bg": "solarized:red", "attrs": ["bold"] }
|
||||
}
|
||||
},
|
||||
"Rc": {
|
||||
"groups": {
|
||||
"mode": { "fg": "solarized:base3", "bg": "solarized:red", "attrs": ["bold"] }
|
||||
}
|
||||
},
|
||||
"Rx": {
|
||||
"groups": {
|
||||
"mode": { "fg": "solarized:base3", "bg": "solarized:red", "attrs": ["bold"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -74,6 +74,20 @@
|
||||
"col_current": { "fg": "solarized:base00", "bg": "solarized:base03", "attrs": [] }
|
||||
}
|
||||
},
|
||||
"ic": {
|
||||
"groups": {
|
||||
"background": { "fg": "solarized:base03", "bg": "solarized:base2", "attrs": [] },
|
||||
"background:divider": { "fg": "solarized:base02", "bg": "solarized:base2", "attrs": [] },
|
||||
"mode": { "fg": "solarized:base3", "bg": "solarized:blue", "attrs": ["bold"] }
|
||||
}
|
||||
},
|
||||
"ix": {
|
||||
"groups": {
|
||||
"background": { "fg": "solarized:base03", "bg": "solarized:base2", "attrs": [] },
|
||||
"background:divider": { "fg": "solarized:base02", "bg": "solarized:base2", "attrs": [] },
|
||||
"mode": { "fg": "solarized:base3", "bg": "solarized:blue", "attrs": ["bold"] }
|
||||
}
|
||||
},
|
||||
"v": {
|
||||
"groups": {
|
||||
"mode": { "fg": "solarized:base3", "bg": "solarized:orange", "attrs": ["bold"] }
|
||||
@ -93,6 +107,16 @@
|
||||
"groups": {
|
||||
"mode": { "fg": "solarized:base3", "bg": "solarized:red", "attrs": ["bold"] }
|
||||
}
|
||||
},
|
||||
"Rc": {
|
||||
"groups": {
|
||||
"mode": { "fg": "solarized:base3", "bg": "solarized:red", "attrs": ["bold"] }
|
||||
}
|
||||
},
|
||||
"Rx": {
|
||||
"groups": {
|
||||
"mode": { "fg": "solarized:base3", "bg": "solarized:red", "attrs": ["bold"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,8 @@
|
||||
},
|
||||
"wm": {
|
||||
"colorscheme": "default",
|
||||
"theme": "default"
|
||||
"theme": "default",
|
||||
"update_interval": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -105,8 +105,12 @@
|
||||
"S": "S-LINE",
|
||||
"^S": "S-BLCK",
|
||||
"i": "INSERT",
|
||||
"ic": "I-COMP",
|
||||
"ix": "I-C_X ",
|
||||
"R": "RPLACE",
|
||||
"Rv": "V-RPLC",
|
||||
"Rc": "R-COMP",
|
||||
"Rx": "R-C_X ",
|
||||
"c": "COMMND",
|
||||
"cv": "VIM-EX",
|
||||
"ce": "NRM-EX",
|
||||
|
@ -103,8 +103,12 @@
|
||||
"S": "S·LINE",
|
||||
"^S": "S·BLCK",
|
||||
"i": "INSERT",
|
||||
"ic": "I·COMP",
|
||||
"ix": "I·C-X ",
|
||||
"R": "RPLACE",
|
||||
"Rv": "V·RPLC",
|
||||
"Rc": "R·COMP",
|
||||
"Rx": "R·C-X ",
|
||||
"c": "COMMND",
|
||||
"cv": "VIM·EX",
|
||||
"ce": "NRM·EX",
|
||||
|
@ -103,8 +103,12 @@
|
||||
"S": "S·LINE",
|
||||
"^S": "S·BLCK",
|
||||
"i": "INSERT",
|
||||
"ic": "I·COMP",
|
||||
"ix": "I·C-X ",
|
||||
"R": "RPLACE",
|
||||
"Rv": "V·RPLC",
|
||||
"Rc": "R·COMP",
|
||||
"Rx": "R·C-X ",
|
||||
"c": "COMMND",
|
||||
"cv": "VIM·EX",
|
||||
"ce": "NRM·EX",
|
||||
|
@ -117,8 +117,12 @@
|
||||
"S": "S·LINE",
|
||||
"^S": "S·BLCK",
|
||||
"i": "INSERT",
|
||||
"ic": "I·COMP",
|
||||
"ix": "I·C-X ",
|
||||
"R": "RPLACE",
|
||||
"Rv": "V·RPLC",
|
||||
"Rc": "R·COMP",
|
||||
"Rx": "R·C-X ",
|
||||
"c": "COMMND",
|
||||
"cv": "VIM·EX",
|
||||
"ce": "NRM·EX",
|
||||
|
@ -103,8 +103,12 @@
|
||||
"S": "S·LINE",
|
||||
"^S": "S·BLCK",
|
||||
"i": "INSERT",
|
||||
"ic": "I·COMP",
|
||||
"ix": "I·C-X ",
|
||||
"R": "RPLACE",
|
||||
"Rv": "V·RPLC",
|
||||
"Rc": "R·COMP",
|
||||
"Rx": "R·C-X ",
|
||||
"c": "COMMND",
|
||||
"cv": "VIM·EX",
|
||||
"ce": "NRM·EX",
|
||||
|
@ -103,8 +103,12 @@
|
||||
"S": "S·LINE",
|
||||
"^S": "S·BLCK",
|
||||
"i": "INSERT",
|
||||
"ic": "I·COMP",
|
||||
"ix": "I·C-X ",
|
||||
"R": "RPLACE",
|
||||
"Rv": "V·RPLC",
|
||||
"Rc": "R·COMP",
|
||||
"Rx": "R·C-X ",
|
||||
"c": "COMMND",
|
||||
"cv": "VIM·EX",
|
||||
"ce": "NRM·EX",
|
||||
|
@ -104,8 +104,12 @@
|
||||
"S": "SLN",
|
||||
"^S": "SBL",
|
||||
"i": "INS",
|
||||
"ic": "I-C",
|
||||
"ix": "I^X",
|
||||
"R": "REP",
|
||||
"Rv": "VRP",
|
||||
"Rc": "R-C",
|
||||
"Rx": "R^X",
|
||||
"c": "CMD",
|
||||
"cv": "VEX",
|
||||
"ce": " EX",
|
||||
|
@ -25,7 +25,7 @@ class Repository(object):
|
||||
# hg status -> (powerline file status, repo status flag)
|
||||
statuses = {
|
||||
b'M': ('M', 1), b'A': ('A', 1), b'R': ('R', 1), b'!': ('D', 1),
|
||||
b'?': ('U', 2), b'I': ('I', 0)
|
||||
b'?': ('U', 2), b'I': ('I', 0), b'C': ('', 0),
|
||||
}
|
||||
repo_statuses_str = (None, 'D ', ' U', 'DU')
|
||||
|
||||
@ -63,7 +63,7 @@ class Repository(object):
|
||||
return self.do_status(self.directory, path)
|
||||
|
||||
def do_status(self, directory, path):
|
||||
repo = self._repo(directory)
|
||||
with self._repo(directory) as repo:
|
||||
if path:
|
||||
path = os.path.join(directory, path)
|
||||
statuses = repo.status(include=path, all=True)
|
||||
|
@ -130,7 +130,8 @@ main_spec = (Spec(
|
||||
local_themes=Spec().unknown_spec(
|
||||
Spec().re('^[0-9A-Za-z-]+$'),
|
||||
ext_theme_spec()
|
||||
).optional()
|
||||
).optional(),
|
||||
update_interval=Spec().cmp('gt', 0.0).optional(),
|
||||
).optional(),
|
||||
).unknown_spec(
|
||||
check_ext,
|
||||
|
@ -458,7 +458,7 @@ class Renderer(object):
|
||||
segment is first_segment
|
||||
if side == 'left' else
|
||||
segment is last_segment
|
||||
))
|
||||
)) * theme.outer_padding
|
||||
|
||||
draw_divider = segment['draw_' + divider_type + '_divider']
|
||||
segment_len += outer_padding
|
||||
@ -519,7 +519,7 @@ class Renderer(object):
|
||||
segment is first_segment
|
||||
if side == 'left' else
|
||||
segment is last_segment
|
||||
)) * ' '
|
||||
)) * theme.outer_padding * ' '
|
||||
divider_type = 'soft' if compare_segment['highlight']['bg'] == segment['highlight']['bg'] else 'hard'
|
||||
|
||||
divider_highlighted = ''
|
||||
|
@ -72,7 +72,10 @@ def _fetch_battery_info(pl):
|
||||
devtype_name,
|
||||
'State'
|
||||
) != 2
|
||||
if energy_full > 0:
|
||||
return (energy * 100.0 / energy_full), state
|
||||
else:
|
||||
return 0.0, state
|
||||
return _flatten_battery
|
||||
pl.debug('Not using DBUS+UPower as no batteries were found')
|
||||
|
||||
|
@ -477,3 +477,54 @@ Requires ``osascript`` available in $PATH.
|
||||
|
||||
{0}
|
||||
''').format(_common_args.format('rdio')))
|
||||
|
||||
|
||||
class ITunesPlayerSegment(PlayerSegment):
|
||||
def get_player_status(self, pl):
|
||||
status_delimiter = '-~`/='
|
||||
ascript = '''
|
||||
tell application "System Events"
|
||||
set process_list to (name of every process)
|
||||
end tell
|
||||
|
||||
if process_list contains "iTunes" then
|
||||
tell application "iTunes"
|
||||
if player state is playing then
|
||||
set t_title to name of current track
|
||||
set t_artist to artist of current track
|
||||
set t_album to album of current track
|
||||
set t_duration to duration of current track
|
||||
set t_elapsed to player position
|
||||
set t_state to player state
|
||||
return t_title & "{0}" & t_artist & "{0}" & t_album & "{0}" & t_elapsed & "{0}" & t_duration & "{0}" & t_state
|
||||
end if
|
||||
end tell
|
||||
end if
|
||||
'''.format(status_delimiter)
|
||||
now_playing = asrun(pl, ascript)
|
||||
if not now_playing:
|
||||
return
|
||||
now_playing = now_playing.split(status_delimiter)
|
||||
if len(now_playing) != 6:
|
||||
return
|
||||
title, artist, album = now_playing[0], now_playing[1], now_playing[2]
|
||||
state = _convert_state(now_playing[5])
|
||||
total = _convert_seconds(now_playing[4])
|
||||
elapsed = _convert_seconds(now_playing[3])
|
||||
return {
|
||||
'title': title,
|
||||
'artist': artist,
|
||||
'album': album,
|
||||
'total': total,
|
||||
'elapsed': elapsed,
|
||||
'state': state
|
||||
}
|
||||
|
||||
|
||||
itunes = with_docstring(ITunesPlayerSegment(),
|
||||
('''Return iTunes now playing information
|
||||
|
||||
Requires ``osascript``.
|
||||
|
||||
{0}
|
||||
''').format(_common_args.format('itunes')))
|
||||
|
@ -50,15 +50,19 @@ vim_modes = {
|
||||
'S': 'S-LINE',
|
||||
'^S': 'S-BLCK',
|
||||
'i': 'INSERT',
|
||||
'R': 'REPLACE',
|
||||
'Rv': 'V-RPLCE',
|
||||
'ic': 'I-COMP',
|
||||
'ix': 'I-C_X ',
|
||||
'R': 'RPLACE',
|
||||
'Rv': 'V-RPLC',
|
||||
'Rc': 'R-COMP',
|
||||
'Rx': 'R-C_X ',
|
||||
'c': 'COMMND',
|
||||
'cv': 'VIM EX',
|
||||
'ce': 'EX',
|
||||
'cv': 'VIM-EX',
|
||||
'ce': 'NRM-EX',
|
||||
'r': 'PROMPT',
|
||||
'rm': 'MORE',
|
||||
'r?': 'CONFIRM',
|
||||
'!': 'SHELL',
|
||||
'rm': '-MORE-',
|
||||
'r?': 'CNFIRM',
|
||||
'!': '!SHELL',
|
||||
}
|
||||
|
||||
|
||||
@ -87,18 +91,27 @@ def window_cached(func):
|
||||
def mode(pl, segment_info, override=None):
|
||||
'''Return the current vim mode.
|
||||
|
||||
If mode (returned by ``mode()`` VimL function, see ``:h mode()`` in Vim)
|
||||
consists of multiple characters and necessary mode is not known to powerline
|
||||
then it will fall back to mode with last character(s) ignored.
|
||||
|
||||
:param dict override:
|
||||
dict for overriding default mode strings, e.g. ``{ 'n': 'NORM' }``
|
||||
'''
|
||||
mode = segment_info['mode']
|
||||
if mode == 'nc':
|
||||
return None
|
||||
while mode:
|
||||
try:
|
||||
if not override:
|
||||
return vim_modes[mode]
|
||||
try:
|
||||
return override[mode]
|
||||
except KeyError:
|
||||
return vim_modes[mode]
|
||||
except KeyError:
|
||||
mode = mode[:-1]
|
||||
return 'BUG'
|
||||
|
||||
|
||||
@window_cached
|
||||
|
@ -69,6 +69,7 @@ class Theme(object):
|
||||
self.cursor_space_multiplier = None
|
||||
self.cursor_columns = theme_config.get('cursor_columns')
|
||||
self.spaces = theme_config['spaces']
|
||||
self.outer_padding = int(theme_config.get('outer_padding', 1))
|
||||
self.segments = []
|
||||
self.EMPTY_SEGMENT = {
|
||||
'contents': None,
|
||||
|
@ -6,6 +6,9 @@ import socket
|
||||
import os
|
||||
import errno
|
||||
import sys
|
||||
import fcntl
|
||||
import atexit
|
||||
import stat
|
||||
|
||||
from argparse import ArgumentParser
|
||||
from select import select
|
||||
@ -13,21 +16,21 @@ from signal import signal, SIGTERM
|
||||
from time import sleep
|
||||
from functools import partial
|
||||
from io import BytesIO
|
||||
from threading import Event
|
||||
from itertools import chain
|
||||
from logging import StreamHandler
|
||||
|
||||
from powerline.shell import ShellPowerline
|
||||
from powerline.commands.main import finish_args, write_output
|
||||
from powerline.lib.monotonic import monotonic
|
||||
from powerline.lib.encoding import get_preferred_output_encoding, get_preferred_arguments_encoding, get_unicode_writer
|
||||
from powerline.bindings.wm import wm_threads
|
||||
|
||||
from powerline.commands.main import get_argparser as get_main_argparser
|
||||
from powerline.commands.daemon import get_argparser as get_daemon_argparser
|
||||
|
||||
|
||||
is_daemon = False
|
||||
use_filesystem = not sys.platform.lower().startswith('linux')
|
||||
|
||||
address = None
|
||||
pidfile = None
|
||||
USE_FILESYSTEM = not sys.platform.lower().startswith('linux')
|
||||
|
||||
|
||||
class NonInteractiveArgParser(ArgumentParser):
|
||||
@ -44,31 +47,48 @@ class NonInteractiveArgParser(ArgumentParser):
|
||||
raise Exception(self.format_usage())
|
||||
|
||||
|
||||
parser = get_main_argparser(NonInteractiveArgParser)
|
||||
|
||||
EOF = b'EOF\0\0'
|
||||
|
||||
powerlines = {}
|
||||
logger = None
|
||||
config_loader = None
|
||||
home = os.path.expanduser('~')
|
||||
|
||||
class State(object):
|
||||
__slots__ = ('powerlines', 'logger', 'config_loader', 'started_wm_threads',
|
||||
'ts_shutdown_event')
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.logger = None
|
||||
self.config_loader = None
|
||||
self.started_wm_threads = {}
|
||||
self.powerlines = {}
|
||||
self.ts_shutdown_event = Event()
|
||||
|
||||
|
||||
class PowerlineDaemon(ShellPowerline):
|
||||
HOME = os.path.expanduser('~')
|
||||
|
||||
|
||||
class NonDaemonShellPowerline(ShellPowerline):
|
||||
def get_log_handler(self):
|
||||
if not is_daemon:
|
||||
import logging
|
||||
return logging.StreamHandler()
|
||||
return super(PowerlineDaemon, self).get_log_handler()
|
||||
return StreamHandler()
|
||||
|
||||
|
||||
def render(args, environ, cwd):
|
||||
global logger
|
||||
global config_loader
|
||||
cwd = cwd or environ.get('PWD', '/')
|
||||
def start_wm(args, environ, cwd, is_daemon, state):
|
||||
wm_name = args.ext[0][3:]
|
||||
if wm_name in state.started_wm_threads:
|
||||
return b''
|
||||
thread_shutdown_event = Event()
|
||||
thread = wm_threads[wm_name](
|
||||
thread_shutdown_event=thread_shutdown_event,
|
||||
pl_shutdown_event=state.ts_shutdown_event,
|
||||
pl_config_loader=state.config_loader,
|
||||
)
|
||||
thread.start()
|
||||
state.started_wm_threads[wm_name] = (thread, thread_shutdown_event)
|
||||
return b''
|
||||
|
||||
|
||||
def render(args, environ, cwd, is_daemon, state):
|
||||
segment_info = {
|
||||
'getcwd': lambda: cwd,
|
||||
'home': environ.get('HOME', home),
|
||||
'home': environ.get('HOME', HOME),
|
||||
'environ': environ,
|
||||
'args': args,
|
||||
}
|
||||
@ -82,22 +102,24 @@ def render(args, environ, cwd):
|
||||
environ.get('POWERLINE_CONFIG_OVERRIDES', ''),
|
||||
environ.get('POWERLINE_CONFIG_PATHS', ''),
|
||||
)
|
||||
finish_args(environ, args)
|
||||
|
||||
PowerlineClass = ShellPowerline if is_daemon else NonDaemonShellPowerline
|
||||
powerline = None
|
||||
try:
|
||||
powerline = powerlines[key]
|
||||
powerline = state.powerlines[key]
|
||||
except KeyError:
|
||||
try:
|
||||
powerline = powerlines[key] = PowerlineDaemon(
|
||||
powerline = state.powerlines[key] = PowerlineClass(
|
||||
args,
|
||||
logger=logger,
|
||||
config_loader=config_loader,
|
||||
logger=state.logger,
|
||||
config_loader=state.config_loader,
|
||||
run_once=False,
|
||||
shutdown_event=state.ts_shutdown_event,
|
||||
)
|
||||
if logger is None:
|
||||
logger = powerline.logger
|
||||
if config_loader is None:
|
||||
config_loader = powerline.config_loader
|
||||
if state.logger is None:
|
||||
state.logger = powerline.logger
|
||||
if state.config_loader is None:
|
||||
state.config_loader = powerline.config_loader
|
||||
except SystemExit:
|
||||
# Somebody thought raising system exit was a good idea,
|
||||
return ''
|
||||
@ -168,23 +190,30 @@ def safe_bytes(o, encoding=get_preferred_output_encoding()):
|
||||
return safe_bytes(str(e), encoding)
|
||||
|
||||
|
||||
def parse_args(req, encoding=get_preferred_arguments_encoding()):
|
||||
def parse_args(req, parser, encoding=get_preferred_arguments_encoding()):
|
||||
args = [x.decode(encoding) for x in req.split(b'\0') if x]
|
||||
numargs = int(args[0], 16)
|
||||
shell_args = parser.parse_args(args[1:numargs + 1])
|
||||
cwd = args[numargs + 1]
|
||||
environ = dict(((k, v) for k, v in (x.partition('=')[0::2] for x in args[numargs + 2:])))
|
||||
cwd = cwd or environ.get('PWD', '/')
|
||||
return shell_args, environ, cwd
|
||||
|
||||
|
||||
def do_render(req):
|
||||
def get_answer(req, is_daemon, argparser, state):
|
||||
try:
|
||||
return safe_bytes(render(*parse_args(req)))
|
||||
args, environ, cwd = parse_args(req, argparser)
|
||||
finish_args(argparser, environ, args, is_daemon=True)
|
||||
if args.ext[0].startswith('wm.'):
|
||||
return safe_bytes(start_wm(args, environ, cwd, is_daemon, state))
|
||||
else:
|
||||
return safe_bytes(render(args, environ, cwd, is_daemon, state))
|
||||
except Exception as e:
|
||||
return safe_bytes(str(e))
|
||||
|
||||
|
||||
def do_one(sock, read_sockets, write_sockets, result_map):
|
||||
def do_one(sock, read_sockets, write_sockets, result_map, is_daemon, argparser,
|
||||
state):
|
||||
r, w, e = select(
|
||||
tuple(read_sockets) + (sock,),
|
||||
tuple(write_sockets),
|
||||
@ -214,7 +243,7 @@ def do_one(sock, read_sockets, write_sockets, result_map):
|
||||
if req == EOF:
|
||||
raise SystemExit(0)
|
||||
elif req:
|
||||
ans = do_render(req)
|
||||
ans = get_answer(req, is_daemon, argparser, state)
|
||||
result_map[s] = ans
|
||||
write_sockets.add(s)
|
||||
else:
|
||||
@ -230,17 +259,61 @@ def do_one(sock, read_sockets, write_sockets, result_map):
|
||||
s.close()
|
||||
|
||||
|
||||
def main_loop(sock):
|
||||
def shutdown(sock, read_sockets, write_sockets, state):
|
||||
'''Perform operations necessary for nicely shutting down daemon
|
||||
|
||||
Specifically it
|
||||
|
||||
#. Closes all sockets.
|
||||
#. Notifies segments based on
|
||||
:py:class:`powerline.lib.threaded.ThreadedSegment` and WM-specific
|
||||
threads that daemon is shutting down.
|
||||
#. Waits for threads to finish, but no more then 2 seconds total.
|
||||
#. Waits so that total execution time of this function is 2 seconds in order
|
||||
to allow ThreadedSegments to finish.
|
||||
'''
|
||||
total_wait_time = 2
|
||||
shutdown_start_time = monotonic()
|
||||
|
||||
for s in chain((sock,), read_sockets, write_sockets):
|
||||
s.close()
|
||||
|
||||
# Notify ThreadedSegments
|
||||
state.ts_shutdown_event.set()
|
||||
for thread, shutdown_event in state.started_wm_threads.values():
|
||||
shutdown_event.set()
|
||||
|
||||
for thread, shutdown_event in state.started_wm_threads.values():
|
||||
wait_time = total_wait_time - (monotonic() - shutdown_start_time)
|
||||
if wait_time > 0:
|
||||
thread.join(wait_time)
|
||||
|
||||
wait_time = total_wait_time - (monotonic() - shutdown_start_time)
|
||||
sleep(wait_time)
|
||||
|
||||
|
||||
def main_loop(sock, is_daemon):
|
||||
sock.listen(128)
|
||||
sock.setblocking(0)
|
||||
|
||||
read_sockets, write_sockets = set(), set()
|
||||
result_map = {}
|
||||
parser = get_main_argparser(NonInteractiveArgParser)
|
||||
state = State()
|
||||
try:
|
||||
try:
|
||||
while True:
|
||||
do_one(sock, read_sockets, write_sockets, result_map)
|
||||
do_one(
|
||||
sock, read_sockets, write_sockets, result_map,
|
||||
is_daemon=is_daemon,
|
||||
argparser=parser,
|
||||
state=state,
|
||||
)
|
||||
except KeyboardInterrupt:
|
||||
raise SystemExit(0)
|
||||
except SystemExit as e:
|
||||
shutdown(sock, read_sockets, write_sockets, state)
|
||||
raise e
|
||||
return 0
|
||||
|
||||
|
||||
@ -249,10 +322,10 @@ def daemonize(stdin=os.devnull, stdout=os.devnull, stderr=os.devnull):
|
||||
pid = os.fork()
|
||||
if pid > 0:
|
||||
# exit first parent
|
||||
sys.exit(0)
|
||||
raise SystemExit(0)
|
||||
except OSError as e:
|
||||
sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror))
|
||||
sys.exit(1)
|
||||
raise SystemExit(1)
|
||||
|
||||
# decouple from parent environment
|
||||
os.chdir("/")
|
||||
@ -264,10 +337,10 @@ def daemonize(stdin=os.devnull, stdout=os.devnull, stderr=os.devnull):
|
||||
pid = os.fork()
|
||||
if pid > 0:
|
||||
# exit from second parent
|
||||
sys.exit(0)
|
||||
raise SystemExit(0)
|
||||
except OSError as e:
|
||||
sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror))
|
||||
sys.exit(1)
|
||||
raise SystemExit(1)
|
||||
|
||||
# Redirect standard file descriptors.
|
||||
si = open(stdin, 'rb')
|
||||
@ -276,12 +349,11 @@ def daemonize(stdin=os.devnull, stdout=os.devnull, stderr=os.devnull):
|
||||
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
|
||||
return True
|
||||
|
||||
|
||||
def check_existing():
|
||||
if use_filesystem:
|
||||
def check_existing(address):
|
||||
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:
|
||||
@ -299,7 +371,7 @@ def check_existing():
|
||||
return sock
|
||||
|
||||
|
||||
def kill_daemon():
|
||||
def kill_daemon(address):
|
||||
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
try:
|
||||
try:
|
||||
@ -313,7 +385,7 @@ def kill_daemon():
|
||||
return True
|
||||
|
||||
|
||||
def cleanup_lockfile(fd, *args):
|
||||
def cleanup_lockfile(pidfile, fd, *args):
|
||||
try:
|
||||
# Remove the directory entry for the lock file
|
||||
os.unlink(pidfile)
|
||||
@ -326,10 +398,7 @@ def cleanup_lockfile(fd, *args):
|
||||
raise SystemExit(1)
|
||||
|
||||
|
||||
def lockpidfile():
|
||||
import fcntl
|
||||
import atexit
|
||||
import stat
|
||||
def lockpidfile(pidfile):
|
||||
fd = os.open(
|
||||
pidfile,
|
||||
os.O_WRONLY | os.O_CREAT,
|
||||
@ -344,24 +413,25 @@ def lockpidfile():
|
||||
os.ftruncate(fd, 0)
|
||||
os.write(fd, ('%d' % os.getpid()).encode('ascii'))
|
||||
os.fsync(fd)
|
||||
cleanup = partial(cleanup_lockfile, fd)
|
||||
cleanup = partial(cleanup_lockfile, pidfile, fd)
|
||||
signal(SIGTERM, cleanup)
|
||||
atexit.register(cleanup)
|
||||
return fd
|
||||
|
||||
|
||||
def main():
|
||||
global address
|
||||
global pidfile
|
||||
parser = get_daemon_argparser()
|
||||
args = parser.parse_args()
|
||||
is_daemon = False
|
||||
address = None
|
||||
pidfile = None
|
||||
|
||||
if args.socket:
|
||||
address = args.socket
|
||||
if not use_filesystem:
|
||||
if not USE_FILESYSTEM:
|
||||
address = '\0' + address
|
||||
else:
|
||||
if use_filesystem:
|
||||
if USE_FILESYSTEM:
|
||||
address = '/tmp/powerline-ipc-%d'
|
||||
else:
|
||||
# Use the abstract namespace for sockets rather than the filesystem
|
||||
@ -370,13 +440,13 @@ def main():
|
||||
|
||||
address = address % os.getuid()
|
||||
|
||||
if use_filesystem:
|
||||
if USE_FILESYSTEM:
|
||||
pidfile = address + '.pid'
|
||||
|
||||
if args.kill:
|
||||
if args.foreground or args.replace:
|
||||
parser.error('--kill and --foreground/--replace cannot be used together')
|
||||
if kill_daemon():
|
||||
if kill_daemon(address):
|
||||
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)
|
||||
@ -386,19 +456,19 @@ def main():
|
||||
raise SystemExit(1)
|
||||
|
||||
if args.replace:
|
||||
while kill_daemon():
|
||||
while kill_daemon(address):
|
||||
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:
|
||||
if USE_FILESYSTEM and not args.foreground:
|
||||
# We must daemonize before creating the locked pidfile, unfortunately,
|
||||
# this means further print statements are discarded
|
||||
daemonize()
|
||||
is_daemon = daemonize()
|
||||
|
||||
if use_filesystem:
|
||||
if USE_FILESYSTEM:
|
||||
# Create a locked pid file containing the daemon’s PID
|
||||
if lockpidfile() is None:
|
||||
if lockpidfile(pidfile) is None:
|
||||
if not args.quiet:
|
||||
sys.stderr.write(
|
||||
'The daemon is already running. Use %s -k to kill it.\n' % (
|
||||
@ -406,7 +476,7 @@ def main():
|
||||
raise SystemExit(1)
|
||||
|
||||
# Bind to address or bail if we cannot bind
|
||||
sock = check_existing()
|
||||
sock = check_existing(address)
|
||||
if sock is None:
|
||||
if not args.quiet:
|
||||
sys.stderr.write(
|
||||
@ -414,14 +484,11 @@ def main():
|
||||
os.path.basename(sys.argv[0])))
|
||||
raise SystemExit(1)
|
||||
|
||||
if args.foreground:
|
||||
return main_loop(sock)
|
||||
|
||||
if not use_filesystem:
|
||||
if not USE_FILESYSTEM and not args.foreground:
|
||||
# We daemonize on linux
|
||||
daemonize()
|
||||
is_daemon = daemonize()
|
||||
|
||||
main_loop(sock)
|
||||
return main_loop(sock, is_daemon)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -23,8 +23,9 @@ else:
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = get_argparser().parse_args()
|
||||
finish_args(os.environ, args)
|
||||
parser = get_argparser()
|
||||
args = parser.parse_args()
|
||||
finish_args(parser, os.environ, args)
|
||||
powerline = ShellPowerline(args, run_once=True)
|
||||
segment_info = {'args': args, 'environ': os.environ}
|
||||
write_output(args, powerline, segment_info, get_unicode_writer())
|
||||
|
4
setup.py
4
setup.py
@ -59,7 +59,7 @@ else:
|
||||
|
||||
|
||||
def get_version():
|
||||
base_version = '2.5.2'
|
||||
base_version = '2.6'
|
||||
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.5.2',
|
||||
version='2.6',
|
||||
description='The ultimate statusline/prompt utility.',
|
||||
long_description=README,
|
||||
classifiers=[
|
||||
|
@ -1,11 +0,0 @@
|
||||
# vim:fileencoding=utf-8:noet
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
|
||||
import sys
|
||||
|
||||
if sys.version_info < (2, 7):
|
||||
from unittest2 import TestCase, main # NOQA
|
||||
from unittest2.case import SkipTest # NOQA
|
||||
else:
|
||||
from unittest import TestCase, main # NOQA
|
||||
from unittest.case import SkipTest # NOQA
|
@ -1,42 +0,0 @@
|
||||
. tests/bot-ci/scripts/common/main.sh
|
||||
set +x
|
||||
|
||||
: ${PYTHON:=python}
|
||||
|
||||
FAILED=0
|
||||
|
||||
FAIL_SUMMARY=""
|
||||
|
||||
enter_suite() {
|
||||
local suite_name="$1"
|
||||
export POWERLINE_CURRENT_SUITE="${POWERLINE_CURRENT_SUITE}/$suite_name"
|
||||
}
|
||||
|
||||
exit_suite() {
|
||||
if test $FAILED -ne 0 ; then
|
||||
echo "Suite ${POWERLINE_CURRENT_SUITE} failed, summary:"
|
||||
echo "${FAIL_SUMMARY}"
|
||||
fi
|
||||
export POWERLINE_CURRENT_SUITE="${POWERLINE_CURRENT_SUITE%/*}"
|
||||
if test "x$1" != "x--continue" ; then
|
||||
exit $FAILED
|
||||
fi
|
||||
}
|
||||
|
||||
fail() {
|
||||
local allow_failure=
|
||||
if test "x$1" = "x--allow-failure" ; then
|
||||
shift
|
||||
allow_failure=A
|
||||
fi
|
||||
local test_name="$1"
|
||||
local fail_char="$allow_failure$2"
|
||||
local message="$3"
|
||||
local full_msg="$fail_char $POWERLINE_CURRENT_SUITE|$test_name :: $message"
|
||||
FAIL_SUMMARY="${FAIL_SUMMARY}${NL}${full_msg}"
|
||||
echo "Failed: $full_msg"
|
||||
echo "$full_msg" >> tests/failures
|
||||
if test "x$allow_failure" = "x" ; then
|
||||
FAILED=1
|
||||
fi
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
set -x
|
||||
|
||||
remote_master_hex() {
|
||||
local url="$1"
|
||||
@ -16,7 +17,7 @@ checkout_cached_dir() {
|
||||
fi
|
||||
if ! test -d "$target" ; then
|
||||
git clone --depth=1 "$url" "$target"
|
||||
mv "$target"/.git/refs/heads/master .version
|
||||
git rev-parse HEAD > "$target/.version"
|
||||
rm -rf "$target"/.git
|
||||
fi
|
||||
}
|
||||
|
@ -1,67 +0,0 @@
|
||||
# vim:fileencoding=utf-8:noet
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
|
||||
import threading
|
||||
|
||||
from time import sleep
|
||||
|
||||
import pexpect
|
||||
|
||||
from tests.lib.vterm import VTerm
|
||||
|
||||
|
||||
class ExpectProcess(threading.Thread):
|
||||
def __init__(self, lib, rows, cols, cmd, args, cwd=None, env=None):
|
||||
super(ExpectProcess, self).__init__()
|
||||
self.vterm = VTerm(lib, rows, cols)
|
||||
self.lock = threading.Lock()
|
||||
self.rows = rows
|
||||
self.cols = cols
|
||||
self.cmd = cmd
|
||||
self.args = args
|
||||
self.cwd = cwd
|
||||
self.env = env
|
||||
self.buffer = []
|
||||
self.child_lock = threading.Lock()
|
||||
|
||||
def run(self):
|
||||
child = pexpect.spawn(self.cmd, self.args, cwd=self.cwd, env=self.env)
|
||||
sleep(0.5)
|
||||
child.setwinsize(self.rows, self.cols)
|
||||
sleep(0.5)
|
||||
self.child = child
|
||||
status = None
|
||||
while status is None:
|
||||
try:
|
||||
with self.child_lock:
|
||||
s = child.read_nonblocking(size=1024, timeout=0)
|
||||
status = child.status
|
||||
except pexpect.TIMEOUT:
|
||||
pass
|
||||
except pexpect.EOF:
|
||||
break
|
||||
else:
|
||||
with self.lock:
|
||||
self.vterm.push(s)
|
||||
self.buffer.append(s)
|
||||
|
||||
def resize(self, rows, cols):
|
||||
with self.child_lock:
|
||||
self.rows = rows
|
||||
self.cols = cols
|
||||
self.child.setwinsize(rows, cols)
|
||||
self.vterm.resize(rows, cols)
|
||||
|
||||
def __getitem__(self, position):
|
||||
with self.lock:
|
||||
return self.vterm.vtscreen[position]
|
||||
|
||||
def read(self):
|
||||
with self.lock:
|
||||
ret = b''.join(self.buffer)
|
||||
del self.buffer[:]
|
||||
return ret
|
||||
|
||||
def send(self, data):
|
||||
with self.child_lock:
|
||||
self.child.send(data)
|
11
tests/modules/__init__.py
Normal file
11
tests/modules/__init__.py
Normal file
@ -0,0 +1,11 @@
|
||||
# vim:fileencoding=utf-8:noet
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
|
||||
import sys
|
||||
|
||||
if sys.version_info < (2, 7):
|
||||
from unittest2 import TestCase, main # NOQA
|
||||
from unittest2.case import SkipTest # NOQA
|
||||
else:
|
||||
from unittest import TestCase, main # NOQA
|
||||
from unittest.case import SkipTest # NOQA
|
@ -12,7 +12,7 @@ from powerline.renderer import Renderer
|
||||
from powerline.lib.config import ConfigLoader
|
||||
from powerline import Powerline, get_default_theme
|
||||
|
||||
from tests.lib import Args, replace_attr
|
||||
from tests.modules.lib import Args, replace_attr
|
||||
|
||||
|
||||
UT = get_default_theme(is_unicode=True)
|
||||
@ -175,7 +175,7 @@ def get_powerline(config, **kwargs):
|
||||
TestPowerline,
|
||||
_helpers=helpers,
|
||||
ext='test',
|
||||
renderer_module='tests.lib.config_mock',
|
||||
renderer_module='tests.modules.lib.config_mock',
|
||||
logger=Logger(),
|
||||
**kwargs
|
||||
)
|
@ -59,7 +59,7 @@ class FSTree(object):
|
||||
self.p = TestPowerline(
|
||||
_paths=self.get_config_paths(self.root),
|
||||
ext='test',
|
||||
renderer_module='tests.lib.config_mock',
|
||||
renderer_module='tests.modules.lib.config_mock',
|
||||
**self.p_kwargs
|
||||
)
|
||||
if os.environ.get('POWERLINE_RUN_LINT_DURING_TESTS'):
|
269
tests/modules/lib/terminal.py
Normal file
269
tests/modules/lib/terminal.py
Normal file
@ -0,0 +1,269 @@
|
||||
# vim:fileencoding=utf-8:noet
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
|
||||
import threading
|
||||
import os
|
||||
|
||||
from time import sleep
|
||||
from itertools import groupby
|
||||
from signal import SIGKILL
|
||||
from difflib import ndiff
|
||||
|
||||
import pexpect
|
||||
|
||||
from powerline.lib.unicode import u
|
||||
|
||||
from tests.modules.lib.vterm import VTerm, Dimensions
|
||||
|
||||
|
||||
class MutableDimensions(object):
|
||||
def __init__(self, rows, cols):
|
||||
super(MutableDimensions, self).__init__()
|
||||
self._list = [rows, cols]
|
||||
|
||||
def __getitem__(self, idx):
|
||||
return self._list[idx]
|
||||
|
||||
def __setitem__(self, idx, val):
|
||||
self._list[idx] = val
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self._list)
|
||||
|
||||
def __len__(self):
|
||||
return 2
|
||||
|
||||
def __nonzero__(self):
|
||||
return True
|
||||
|
||||
__bool__ = __nonzero__
|
||||
|
||||
rows = property(
|
||||
fget = lambda self: self._list[0],
|
||||
fset = lambda self, val: self._list.__setitem__(0, val),
|
||||
)
|
||||
cols = property(
|
||||
fget = lambda self: self._list[1],
|
||||
fset = lambda self, val: self._list.__setitem__(1, val),
|
||||
)
|
||||
|
||||
|
||||
class ExpectProcess(threading.Thread):
|
||||
def __init__(self, lib, dim, cmd, args, cwd=None, env=None):
|
||||
super(ExpectProcess, self).__init__()
|
||||
self.vterm = VTerm(lib, dim)
|
||||
self.lock = threading.Lock()
|
||||
self.dim = Dimensions(*dim)
|
||||
self.cmd = cmd
|
||||
self.args = args
|
||||
self.cwd = cwd
|
||||
self.env = env
|
||||
self.buffer = []
|
||||
self.child_lock = threading.Lock()
|
||||
self.shutdown_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
|
||||
status = None
|
||||
while status is None and not self.shutdown_event.is_set():
|
||||
try:
|
||||
with self.child_lock:
|
||||
s = child.read_nonblocking(size=1024, timeout=0)
|
||||
status = child.status
|
||||
except pexpect.TIMEOUT:
|
||||
pass
|
||||
except pexpect.EOF:
|
||||
break
|
||||
else:
|
||||
with self.lock:
|
||||
self.vterm.push(s)
|
||||
self.buffer.append(s)
|
||||
|
||||
if status is None:
|
||||
child.kill(SIGKILL)
|
||||
|
||||
def kill(self):
|
||||
self.shutdown_event.set()
|
||||
|
||||
def resize(self, dim):
|
||||
with self.child_lock:
|
||||
self.dim = Dimensions(*dim)
|
||||
self.child.setwinsize(self.dim.rows, self.dim.cols)
|
||||
self.vterm.resize(self.dim)
|
||||
|
||||
def __getitem__(self, position):
|
||||
with self.lock:
|
||||
return self.vterm.vtscreen[position]
|
||||
|
||||
def read(self):
|
||||
with self.lock:
|
||||
ret = b''.join(self.buffer)
|
||||
del self.buffer[:]
|
||||
return ret
|
||||
|
||||
def send(self, data):
|
||||
with self.child_lock:
|
||||
self.child.send(data)
|
||||
|
||||
def get_highlighted_text(self, text, attrs, default_props=()):
|
||||
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)
|
||||
else:
|
||||
ret.append('{' + str(props_name) + ':' + segment_text + '}')
|
||||
return ''.join(ret), new_attrs
|
||||
|
||||
def get_row(self, row, attrs, default_props=()):
|
||||
with self.lock:
|
||||
return self.get_highlighted_text((
|
||||
(key, ''.join((cell.text for cell in subline)))
|
||||
for key, subline in groupby((
|
||||
self.vterm.vtscreen[row, col]
|
||||
for col in range(self.dim.cols)
|
||||
), lambda cell: cell.cell_properties_key)
|
||||
), attrs, default_props)
|
||||
|
||||
def get_screen(self, attrs, default_props=()):
|
||||
lines = []
|
||||
for row in range(self.dim.rows):
|
||||
line, attrs = self.get_row(row, attrs, default_props)
|
||||
lines.append(line)
|
||||
return '\n'.join(lines), attrs
|
||||
|
||||
|
||||
def test_expected_result(p, test, last_attempt, last_attempt_cb=None):
|
||||
expected_text, attrs = test['expected_result']
|
||||
attempts = 3
|
||||
result = None
|
||||
while attempts:
|
||||
actual_text, all_attrs = p.get_row(test['row'], attrs)
|
||||
if actual_text == expected_text:
|
||||
return True
|
||||
attempts -= 1
|
||||
print('Actual result does not match expected. Attempts left: {0}.'.format(attempts))
|
||||
sleep(2)
|
||||
print('Result:')
|
||||
print(actual_text)
|
||||
print('Expected:')
|
||||
print(expected_text)
|
||||
print('Attributes:')
|
||||
print(all_attrs)
|
||||
print('Screen:')
|
||||
screen, screen_attrs = p.get_screen(attrs)
|
||||
print(screen)
|
||||
print(screen_attrs)
|
||||
print('_' * 80)
|
||||
print('Diff:')
|
||||
print('=' * 80)
|
||||
print(''.join((
|
||||
u(line) for line in ndiff([actual_text + '\n'], [expected_text + '\n']))
|
||||
))
|
||||
if last_attempt and last_attempt_cb:
|
||||
last_attempt_cb()
|
||||
return False
|
||||
|
||||
|
||||
ENV_BASE = {
|
||||
# Reasoning:
|
||||
# 1. vt* TERMs (used to be vt100 here) make tmux-1.9 use different and
|
||||
# identical colors for inactive windows. This is not like tmux-1.6:
|
||||
# foreground color is different from separator color and equal to (0,
|
||||
# 102, 153) for some reason (separator has correct color). tmux-1.8 is
|
||||
# fine, so are older versions (though tmux-1.6 and tmux-1.7 do not have
|
||||
# highlighting for previously active window) and my system tmux-1.9a.
|
||||
# 2. screen, xterm and some other non-256color terminals both have the same
|
||||
# issue and make libvterm emit complains like `Unhandled CSI SGR 3231`.
|
||||
# 3. screen-256color, xterm-256color and other -256color terminals make
|
||||
# libvterm emit complains about unhandled escapes to stderr.
|
||||
# 4. `st-256color` does not have any of the above problems, but it may be
|
||||
# not present on the target system because it is installed with
|
||||
# x11-terms/st and not with sys-libs/ncurses.
|
||||
#
|
||||
# For the given reasons decision was made: to fix tmux-1.9 tests and not
|
||||
# make libvterm emit any data to stderr st-256color $TERM should be used, up
|
||||
# until libvterm has its own terminfo database entry (if it ever will). To
|
||||
# make sure that relevant terminfo entry is present on the target system it
|
||||
# should be distributed with powerline test package. To make distribution
|
||||
# not require modifying anything outside of powerline test directory
|
||||
# TERMINFO variable is set.
|
||||
#
|
||||
# This fix propagates to non-tmux vterm tests just in case.
|
||||
'TERM': 'st-256color',
|
||||
# Also $TERMINFO definition in get_env
|
||||
|
||||
'POWERLINE_CONFIG_PATHS': os.path.abspath('powerline/config_files'),
|
||||
'POWERLINE_COMMAND': 'powerline-render',
|
||||
'LD_LIBRARY_PATH': os.environ.get('LD_LIBRARY_PATH', ''),
|
||||
'PYTHONPATH': os.environ.get('PYTHONPATH', ''),
|
||||
}
|
||||
|
||||
|
||||
def get_env(vterm_path, test_dir, *args, **kwargs):
|
||||
env = ENV_BASE.copy()
|
||||
env.update({
|
||||
'TERMINFO': os.path.join(test_dir, 'terminfo'),
|
||||
'PATH': vterm_path,
|
||||
'SHELL': os.path.join(vterm_path, 'bash'),
|
||||
})
|
||||
env.update(*args, **kwargs)
|
||||
return env
|
||||
|
||||
|
||||
def do_terminal_tests(tests, cmd, dim, args, env, cwd=None, fin_cb=None,
|
||||
last_attempt_cb=None, attempts=3):
|
||||
lib = os.environ.get('POWERLINE_LIBVTERM')
|
||||
if not lib:
|
||||
if os.path.exists('tests/bot-ci/deps/libvterm/libvterm.so'):
|
||||
lib = 'tests/bot-ci/deps/libvterm/libvterm.so'
|
||||
else:
|
||||
lib = 'libvterm.so'
|
||||
|
||||
while attempts:
|
||||
try:
|
||||
p = ExpectProcess(
|
||||
lib=lib,
|
||||
dim=dim,
|
||||
cmd=cmd,
|
||||
args=args,
|
||||
cwd=cwd,
|
||||
env=env,
|
||||
)
|
||||
p.start()
|
||||
|
||||
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)
|
||||
)
|
||||
|
||||
if ret:
|
||||
return ret
|
||||
finally:
|
||||
if fin_cb:
|
||||
fin_cb(p=p, cmd=cmd, env=env)
|
||||
p.kill()
|
||||
p.join(10)
|
||||
assert(not p.isAlive())
|
||||
|
||||
attempts -= 1
|
||||
|
||||
return False
|
@ -3,9 +3,14 @@ from __future__ import (unicode_literals, division, absolute_import, print_funct
|
||||
|
||||
import ctypes
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
from powerline.lib.unicode import unicode, unichr, tointiter
|
||||
|
||||
|
||||
Dimensions = namedtuple('Dimensions', ('rows', 'cols'))
|
||||
|
||||
|
||||
class CTypesFunction(object):
|
||||
def __init__(self, library, name, rettype, args):
|
||||
self.name = name
|
||||
@ -165,9 +170,9 @@ class VTermScreen(object):
|
||||
|
||||
|
||||
class VTerm(object):
|
||||
def __init__(self, lib, rows, cols):
|
||||
def __init__(self, lib, dim):
|
||||
self.functions = get_functions(lib)
|
||||
self.vt = self.functions.vterm_new(rows, cols)
|
||||
self.vt = self.functions.vterm_new(dim.rows, dim.cols)
|
||||
self.vtscreen = VTermScreen(self.functions, self.functions.vterm_obtain_screen(self.vt))
|
||||
self.vtscreen.reset(True)
|
||||
|
||||
@ -176,8 +181,8 @@ class VTerm(object):
|
||||
data = data.encode('utf-8')
|
||||
return self.functions.vterm_input_write(self.vt, data, len(data))
|
||||
|
||||
def resize(self, rows, cols):
|
||||
self.functions.vterm_set_size(self.vt, rows, cols)
|
||||
def resize(self, dim):
|
||||
self.functions.vterm_set_size(self.vt, dim.rows, dim.cols)
|
||||
|
||||
def __del__(self):
|
||||
try:
|
@ -1,40 +0,0 @@
|
||||
#!/bin/sh
|
||||
. tests/common.sh
|
||||
|
||||
enter_suite daemon
|
||||
|
||||
export ADDRESS="powerline-ipc-test-$$"
|
||||
echo "Powerline address: $ADDRESS"
|
||||
if $PYTHON scripts/powerline-daemon -s$ADDRESS ; then
|
||||
sleep 1
|
||||
if ! ( \
|
||||
$PYTHON client/powerline.py --socket $ADDRESS -p/dev/null shell left | \
|
||||
grep 'file not found'
|
||||
) ; then
|
||||
fail "devnull" F "-p/dev/null argument ignored or not treated properly"
|
||||
fi
|
||||
if ( \
|
||||
$PYTHON client/powerline.py --socket $ADDRESS \
|
||||
-p$PWD/powerline/config_files shell left | \
|
||||
grep 'file not found'
|
||||
) ; then
|
||||
fail "nodevnull" F "-p/dev/null argument remembered while it should not"
|
||||
fi
|
||||
if ! ( \
|
||||
cd tests && \
|
||||
$PYTHON ../client/powerline.py --socket $ADDRESS \
|
||||
-p$PWD/../powerline/config_files shell left | \
|
||||
grep 'tests'
|
||||
) ; then
|
||||
fail "segment" F "Output lacks string “tests”"
|
||||
fi
|
||||
else
|
||||
fail "exitcode" E "Daemon exited with status $?"
|
||||
fi
|
||||
if $PYTHON scripts/powerline-daemon -s$ADDRESS -k ; then
|
||||
:
|
||||
else
|
||||
fail "-k" F "powerline-daemon -k failed with exit code $?"
|
||||
fi
|
||||
|
||||
exit_suite
|
@ -1,10 +0,0 @@
|
||||
#!/bin/sh
|
||||
. tests/common.sh
|
||||
|
||||
enter_suite lint
|
||||
|
||||
if ! ${PYTHON} scripts/powerline-lint -p powerline/config_files ; then
|
||||
fail "test" F "Running powerline-lint failed"
|
||||
fi
|
||||
|
||||
exit_suite
|
@ -1,7 +0,0 @@
|
||||
#!/bin/sh
|
||||
FAILED=0
|
||||
if ! sh tests/test_shells/test.sh --fast ; then
|
||||
echo "Failed shells"
|
||||
FAILED=1
|
||||
fi
|
||||
exit $FAILED
|
@ -1,71 +0,0 @@
|
||||
#!/bin/sh
|
||||
. tests/common.sh
|
||||
|
||||
enter_suite vim
|
||||
|
||||
if test -z "$VIM" ; then
|
||||
if test -n "$USE_UCS2_PYTHON" ; then
|
||||
NEW_VIM="$ROOT/tests/bot-ci/deps/vim/master-$UCS2_PYTHON_VARIANT-ucs2-double/vim"
|
||||
OLD_VIM="$ROOT/tests/bot-ci/deps/vim/v7.0.112-$UCS2_PYTHON_VARIANT-ucs2/vim"
|
||||
opt_dir="$HOME/opt/cpython-ucs2-$UCS2_PYTHON_VARIANT"
|
||||
main_path="$opt_dir/lib/python$UCS2_PYTHON_VARIANT"
|
||||
site_path="$main_path/site-packages"
|
||||
venv_main_path="$VIRTUAL_ENV/lib/python$UCS2_PYTHON_VARIANT"
|
||||
venv_site_path="$venv_main_path/site-packages"
|
||||
new_paths="${main_path}:${site_path}:${venv_main_path}:${venv_site_path}"
|
||||
export PYTHONPATH="$new_paths${PYTHONPATH:+:}$PYTHONPATH"
|
||||
else
|
||||
if test "$PYTHON_IMPLEMENTATION" != "CPython" ; then
|
||||
exit 0
|
||||
fi
|
||||
if test -d "$ROOT/tests/bot-ci/deps" ; then
|
||||
NEW_VIM="$ROOT/tests/bot-ci/deps/vim/master-$PYTHON_MM/vim"
|
||||
OLD_VIM="$ROOT/tests/bot-ci/deps/vim/v7.0.112-$PYTHON_MM/vim"
|
||||
else
|
||||
NEW_VIM="vim"
|
||||
fi
|
||||
if test -e "$OLD_VIM" ; then
|
||||
VIMS="NEW_VIM OLD_VIM"
|
||||
else
|
||||
VIMS="NEW_VIM"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
NEW_VIM="$VIM"
|
||||
OLD_VIM="$VIM"
|
||||
fi
|
||||
|
||||
# Define some overrides. These ones must be ignored and do not affect Vim
|
||||
# status/tab lines.
|
||||
export POWERLINE_CONFIG_OVERRIDES='common.default_top_theme=ascii'
|
||||
export POWERLINE_THEME_OVERRIDES='default.segments.left=[]'
|
||||
|
||||
test_script() {
|
||||
local vim="$1"
|
||||
local script="$2"
|
||||
local test_name_prefix="$3"
|
||||
echo "Running script $script with $vim"
|
||||
if ! test -e "$vim" ; then
|
||||
return 0
|
||||
fi
|
||||
if ! "$vim" -u NONE -S $script || test -f message.fail ; then
|
||||
local test_name="$test_name_prefix-${script##*/}"
|
||||
fail "${test_name%.vim}" F "Failed script $script run with $VIM"
|
||||
cat message.fail >&2
|
||||
rm message.fail
|
||||
fi
|
||||
}
|
||||
|
||||
for script in tests/test_*.vim ; do
|
||||
if test "${script%.old.vim}" = "${script}" ; then
|
||||
test_script "$NEW_VIM" "$script" new
|
||||
fi
|
||||
done
|
||||
|
||||
if test -e "$OLD_VIM" ; then
|
||||
for script in tests/test_*.old.vim ; do
|
||||
test_script "$OLD_VIM" "$script" old
|
||||
done
|
||||
fi
|
||||
|
||||
exit_suite
|
98
tests/shlib/common.sh
Normal file
98
tests/shlib/common.sh
Normal file
@ -0,0 +1,98 @@
|
||||
. tests/bot-ci/scripts/common/main.sh
|
||||
set +x
|
||||
|
||||
: ${PYTHON:=python}
|
||||
: ${USER:=`id -un`}
|
||||
: ${HOME:=`getent passwd $USER | cut -d: -f6`}
|
||||
|
||||
export USER HOME
|
||||
|
||||
if test -z "$FAILED" ; then
|
||||
FAILED=0
|
||||
|
||||
FAIL_SUMMARY=""
|
||||
|
||||
TMP_ROOT="$ROOT/tests/tmp"
|
||||
FAILURES_FILE="$ROOT/tests/failures"
|
||||
fi
|
||||
|
||||
ANSI_CLEAR="\033[0K"
|
||||
|
||||
travis_fold() {
|
||||
local action="$1"
|
||||
local name="$2"
|
||||
name="$(echo -n "$name" | tr '\n\0' '--' | sed -r 's/[^A-Za-z0-9]+/-/g')"
|
||||
name="$(echo -n "$name" | sed -r 's/-$//')"
|
||||
echo -en "travis_fold:${action}:${name}\r${ANSI_CLEAR}"
|
||||
}
|
||||
|
||||
enter_suite() {
|
||||
local suite_name="$1" ; shift
|
||||
export POWERLINE_CURRENT_SUITE="${POWERLINE_CURRENT_SUITE}/$suite_name"
|
||||
travis_fold start "$POWERLINE_CURRENT_SUITE"
|
||||
}
|
||||
|
||||
exit_suite() {
|
||||
if test "$POWERLINE_CURRENT_SUITE" = "$POWERLINE_TMP_DIR_SUITE" ; then
|
||||
rm_test_root
|
||||
fi
|
||||
if test $FAILED -ne 0 ; then
|
||||
echo "Suite ${POWERLINE_CURRENT_SUITE} failed, summary:"
|
||||
echo "${FAIL_SUMMARY}"
|
||||
fi
|
||||
travis_fold end "$POWERLINE_CURRENT_SUITE"
|
||||
export POWERLINE_CURRENT_SUITE="${POWERLINE_CURRENT_SUITE%/*}"
|
||||
if test "$1" != "--continue" ; then
|
||||
exit $FAILED
|
||||
fi
|
||||
}
|
||||
|
||||
fail() {
|
||||
local allow_failure=
|
||||
if test "$1" = "--allow-failure" ; then
|
||||
shift
|
||||
allow_failure=A
|
||||
fi
|
||||
local test_name="$1" ; shift
|
||||
local fail_char="$allow_failure$1" ; shift
|
||||
local message="$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 "$full_msg" >> "$FAILURES_FILE"
|
||||
if test -z "$allow_failure" ; then
|
||||
FAILED=1
|
||||
fi
|
||||
}
|
||||
|
||||
make_test_root() {
|
||||
local suffix="${POWERLINE_CURRENT_SUITE##*/}"
|
||||
|
||||
local tmpdir="$TMP_ROOT/$suffix/"
|
||||
export POWERLINE_TMP_DIR_SUITE="$POWERLINE_CURRENT_SUITE"
|
||||
|
||||
if test -d "$tmpdir" ; then
|
||||
rm -r "$tmpdir"
|
||||
fi
|
||||
|
||||
mkdir -p "$tmpdir"
|
||||
|
||||
export TEST_ROOT="$tmpdir"
|
||||
}
|
||||
|
||||
rm_test_root() {
|
||||
if test -e "$FAILURES_FILE" ; then
|
||||
return 0
|
||||
fi
|
||||
local suffix="${POWERLINE_CURRENT_SUITE##*/}"
|
||||
if test -d "$TMP_ROOT/$suffix" ; then
|
||||
rm -r "$TMP_ROOT/$suffix"
|
||||
rmdir "$TMP_ROOT" &>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
if ! which realpath ; then
|
||||
realpath() {
|
||||
$PYTHON -c 'import os, sys; print(os.path.realpath(sys.argv[1]))' "$1"
|
||||
}
|
||||
fi
|
33
tests/shlib/vim.sh
Normal file
33
tests/shlib/vim.sh
Normal file
@ -0,0 +1,33 @@
|
||||
. tests/bot-ci/scripts/common/main.sh
|
||||
|
||||
if test -z "$POWERLINE_VIM_EXE" ; then
|
||||
if test -n "$USE_UCS2_PYTHON" ; then
|
||||
NEW_VIM="$ROOT/tests/bot-ci/deps/vim/master-$UCS2_PYTHON_VARIANT-ucs2-double/vim"
|
||||
OLD_VIM="$ROOT/tests/bot-ci/deps/vim/v7.0.112-$UCS2_PYTHON_VARIANT-ucs2/vim"
|
||||
opt_dir="$HOME/opt/cpython-ucs2-$UCS2_PYTHON_VARIANT"
|
||||
main_path="$opt_dir/lib/python$UCS2_PYTHON_VARIANT"
|
||||
site_path="$main_path/site-packages"
|
||||
venv_main_path="$VIRTUAL_ENV/lib/python$UCS2_PYTHON_VARIANT"
|
||||
venv_site_path="$venv_main_path/site-packages"
|
||||
new_paths="${main_path}:${site_path}:${venv_main_path}:${venv_site_path}"
|
||||
export PYTHONPATH="$new_paths${PYTHONPATH:+:}$PYTHONPATH"
|
||||
else
|
||||
if test "$PYTHON_IMPLEMENTATION" != "CPython" ; then
|
||||
exit 0
|
||||
fi
|
||||
if test -d "$ROOT/tests/bot-ci/deps" ; then
|
||||
NEW_VIM="$ROOT/tests/bot-ci/deps/vim/master-$PYTHON_MM/vim"
|
||||
OLD_VIM="$ROOT/tests/bot-ci/deps/vim/v7.0.112-$PYTHON_MM/vim"
|
||||
else
|
||||
NEW_VIM="vim"
|
||||
fi
|
||||
if test -e "$OLD_VIM" ; then
|
||||
VIMS="NEW_VIM OLD_VIM"
|
||||
else
|
||||
VIMS="NEW_VIM"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
NEW_VIM="$POWERLINE_VIM_EXE"
|
||||
OLD_VIM="$POWERLINE_VIM_EXE"
|
||||
fi
|
26
tests/shlib/vterm.sh
Normal file
26
tests/shlib/vterm.sh
Normal file
@ -0,0 +1,26 @@
|
||||
. tests/shlib/common.sh
|
||||
. tests/bot-ci/scripts/common/main.sh
|
||||
set +x
|
||||
|
||||
vterm_setup() {
|
||||
local test_dir="$1" ; shift
|
||||
|
||||
rm -rf "$test_dir"
|
||||
mkdir "$test_dir"
|
||||
mkdir "$test_dir/path"
|
||||
|
||||
ln -s "$(which "${PYTHON}")" "$test_dir/path/python"
|
||||
ln -s "$(which bash)" "$test_dir/path"
|
||||
|
||||
cp -r "$ROOT/tests/terminfo" "$test_dir"
|
||||
}
|
||||
|
||||
vterm_shutdown() {
|
||||
local test_dir="$1" ; shift
|
||||
|
||||
if test $FAILED -eq 0 ; then
|
||||
rm -rf "$test_dir"
|
||||
else
|
||||
echo "$FAIL_SUMMARY"
|
||||
fi
|
||||
}
|
@ -1,13 +1,8 @@
|
||||
#!/bin/bash
|
||||
. tests/common.sh
|
||||
. tests/shlib/common.sh
|
||||
|
||||
enter_suite root
|
||||
|
||||
: ${USER:=`id -un`}
|
||||
: ${HOME:=`getent passwd $USER | cut -d: -f6`}
|
||||
|
||||
export USER HOME
|
||||
|
||||
if test "$TRAVIS" = true ; then
|
||||
export PATH="$HOME/opt/fish/bin:${PATH}"
|
||||
export PATH="$PWD/tests/bot-ci/deps/rc:$PATH"
|
||||
@ -22,18 +17,16 @@ if test "$TRAVIS" = true ; then
|
||||
. virtualenvwrapper.sh
|
||||
workon cpython-ucs2-$UCS2_PYTHON_VARIANT
|
||||
set -e
|
||||
else
|
||||
LIBRARY_PATH="$(ldd "$(which python)" | grep libpython | sed 's/^.* => //;s/ .*$//')"
|
||||
LIBRARY_DIR="$(dirname "${LIBRARY_PATH}")"
|
||||
export LD_LIBRARY_PATH="$LIBRARY_DIR${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH"
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! which realpath ; then
|
||||
realpath() {
|
||||
$PYTHON -c 'import os, sys; print(os.path.realpath(sys.argv[1]))' "$1"
|
||||
}
|
||||
fi
|
||||
|
||||
export PYTHON="${PYTHON:=python}"
|
||||
export PYTHONPATH="${PYTHONPATH}${PYTHONPATH:+:}`realpath .`"
|
||||
for script in tests/run_*_tests.sh ; do
|
||||
for script in "$ROOT"/tests/test_*/test.sh ; do
|
||||
test_name="${script##*/run_}"
|
||||
if ! sh $script ; then
|
||||
fail "${test_name%_tests.sh}" F "Failed $script"
|
||||
|
3
tests/test_awesome/path/awesome-client
Executable file
3
tests/test_awesome/path/awesome-client
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
echo "$@" >> "$TEST_ROOT/results/args"
|
||||
cat >> "$TEST_ROOT/results/requests"
|
7
tests/test_awesome/powerline/config.json
Normal file
7
tests/test_awesome/powerline/config.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"ext": {
|
||||
"wm": {
|
||||
"update_interval": 0.5
|
||||
}
|
||||
}
|
||||
}
|
18
tests/test_awesome/powerline/themes/wm/default.json
Normal file
18
tests/test_awesome/powerline/themes/wm/default.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"segments": {
|
||||
"left": [
|
||||
{
|
||||
"type": "string",
|
||||
"highlight_groups": ["time"],
|
||||
"contents": "default-left"
|
||||
}
|
||||
],
|
||||
"right": [
|
||||
{
|
||||
"type": "string",
|
||||
"highlight_groups": ["time"],
|
||||
"contents": "default-right"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
18
tests/test_awesome/powerline/themes/wm/dvi.json
Normal file
18
tests/test_awesome/powerline/themes/wm/dvi.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"segments": {
|
||||
"left": [
|
||||
{
|
||||
"type": "string",
|
||||
"highlight_groups": ["time"],
|
||||
"contents": "dvi-left"
|
||||
}
|
||||
],
|
||||
"right": [
|
||||
{
|
||||
"type": "string",
|
||||
"highlight_groups": ["time"],
|
||||
"contents": "dvi-right"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
188
tests/test_awesome/test.sh
Executable file
188
tests/test_awesome/test.sh
Executable file
@ -0,0 +1,188 @@
|
||||
#!/bin/sh
|
||||
. tests/shlib/common.sh
|
||||
|
||||
enter_suite awesome
|
||||
|
||||
make_test_root
|
||||
|
||||
TEST_PATH="$TEST_ROOT/path"
|
||||
TEST_STATIC_ROOT="$ROOT/tests/test_awesome"
|
||||
|
||||
cp -r "$TEST_STATIC_ROOT/path" "$TEST_ROOT"
|
||||
cp -r "$TEST_STATIC_ROOT/powerline" "$TEST_ROOT"
|
||||
|
||||
export PYTHONPATH="$ROOT${PYTHONPATH:+:}$PYTHONPATH"
|
||||
|
||||
ln -s "$(which "${PYTHON}")" "$TEST_PATH"/python
|
||||
ln -s "$(which cat)" "$TEST_PATH"
|
||||
ln -s "$(which sh)" "$TEST_PATH"
|
||||
ln -s "$(which env)" "$TEST_PATH"
|
||||
if which socat ; then
|
||||
ln -s "$(which socat)" "$TEST_PATH"
|
||||
fi
|
||||
for pexe in powerline powerline.sh powerline.py ; do
|
||||
if test -e scripts/$pexe ; then
|
||||
ln -s "$PWD/scripts/$pexe" $TEST_ROOT/path
|
||||
elif test -e client/$pexe ; then
|
||||
ln -s "$PWD/client/$pexe" $TEST_ROOT/path
|
||||
elif which $pexe ; then
|
||||
ln -s "$(which $pexe)" $TEST_ROOT/path
|
||||
else
|
||||
continue
|
||||
fi
|
||||
if test "$pexe" != 'powerline.sh' || test -e "$TEST_PATH/socat" ; then
|
||||
POWERLINE_COMMAND="$pexe"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
DEPRECATED_SCRIPT="$ROOT/powerline/bindings/awesome/powerline-awesome.py"
|
||||
POWERLINE_DAEMON="scripts/powerline-daemon"
|
||||
|
||||
run() {
|
||||
env -i \
|
||||
LANG=C \
|
||||
PATH="$TEST_PATH" \
|
||||
XDG_CONFIG_HOME="$TEST_ROOT" \
|
||||
XDG_CONFIG_DIRS="$TEST_ROOT/dummy" \
|
||||
PYTHONPATH="$PYTHONPATH" \
|
||||
TEST_ROOT="$TEST_ROOT" \
|
||||
LD_LIBRARY_PATH="$LD_LIBRARY_PATH" \
|
||||
"$@" || true
|
||||
}
|
||||
|
||||
display_log() {
|
||||
local log_file="$1"
|
||||
echo "$log_file:"
|
||||
echo '============================================================'
|
||||
cat -v "$log_file"
|
||||
echo
|
||||
echo '____________________________________________________________'
|
||||
}
|
||||
|
||||
check_log() {
|
||||
local args_file="$TEST_ROOT/results/args"
|
||||
local log_file="$TEST_ROOT/results/requests"
|
||||
local line="$(head -n1 "$log_file")"
|
||||
local linenum="$(cat "$log_file" | wc -l)"
|
||||
echo "Number of runs: $linenum (expected approx 5 / 0.5 = 10 runs)"
|
||||
if test $linenum -lt 5 ; then
|
||||
fail "log:lt" F "Script was run not enough times: $linenum < 5"
|
||||
return 1
|
||||
elif test $linenum -gt 15 ; then
|
||||
fail "log:gt" E "Script was run too many times: $linenum > 15"
|
||||
return 1
|
||||
fi
|
||||
local expline="powerline_widget:set_markup('<span foreground=\"#303030\"> </span><span foreground=\"#d0d0d0\" background=\"#303030\" font_weight=\"bold\"> default-right </span>')"
|
||||
if test "$expline" != "$line" ; then
|
||||
echo "Line: '$line'"
|
||||
echo "Expected: '$expline'"
|
||||
fail "log:line" F "Unexpected line"
|
||||
return 1
|
||||
fi
|
||||
local ret=0
|
||||
while test $linenum -gt 0 ; do
|
||||
echo "$line" >> "$TEST_ROOT/ok"
|
||||
linenum=$(( linenum - 1 ))
|
||||
done
|
||||
if ! diff "$TEST_ROOT/ok" "$log_file" ; then
|
||||
fail "log:diff" F "Unexpected output"
|
||||
ret=1
|
||||
fi
|
||||
rm "$TEST_ROOT/ok"
|
||||
return $ret
|
||||
}
|
||||
|
||||
killscript() {
|
||||
kill -KILL $1 || true
|
||||
}
|
||||
|
||||
if ! test -e "$DEPRECATED_SCRIPT" ; then
|
||||
# TODO: uncomment when skip is available
|
||||
# skip "deprecated" "Missing deprecated bar bindings script"
|
||||
:
|
||||
else
|
||||
enter_suite "deprecated"
|
||||
for args in "" "0.5"; do
|
||||
rm -rf "$TEST_ROOT/results"
|
||||
mkdir "$TEST_ROOT/results"
|
||||
DEPRECATED_LOG="$TEST_ROOT/deprecated.log"
|
||||
run env \
|
||||
DEPRECATED_SCRIPT="$DEPRECATED_SCRIPT" \
|
||||
args="$args" \
|
||||
DEPRECATED_LOG="$DEPRECATED_LOG" \
|
||||
TEST_ROOT="$TEST_ROOT" \
|
||||
sh -c '
|
||||
echo $$ > "$TEST_ROOT/$args-pid"
|
||||
exec "$DEPRECATED_SCRIPT" $args > "$DEPRECATED_LOG" 2>&1
|
||||
' &
|
||||
sleep 5
|
||||
killscript "$(cat "$TEST_ROOT/$args-pid")"
|
||||
rm "$TEST_ROOT/$args-pid"
|
||||
if test -n "$(cat "$DEPRECATED_LOG")" ; then
|
||||
display_log "$DEPRECATED_LOG"
|
||||
fail "output" E "Nonempty $DEPRECATED_SCRIPT output"
|
||||
fi
|
||||
rm "$DEPRECATED_LOG"
|
||||
if ! check_log ; then
|
||||
display_log "$TEST_ROOT/results/args"
|
||||
fail "log" F "Checking log failed"
|
||||
fi
|
||||
done
|
||||
exit_suite --continue
|
||||
fi
|
||||
|
||||
enter_suite "awesome"
|
||||
ADDRESS="powerline-ipc-test-$$"
|
||||
echo "Powerline address: $ADDRESS"
|
||||
rm -rf "$TEST_ROOT/results"
|
||||
mkdir "$TEST_ROOT/results"
|
||||
run env \
|
||||
POWERLINE_DAEMON="$POWERLINE_DAEMON" \
|
||||
TEST_ROOT="$TEST_ROOT" \
|
||||
ADDRESS="$ADDRESS" \
|
||||
sh -c '
|
||||
echo $$ > "$TEST_ROOT/dpid"
|
||||
exec python "$POWERLINE_DAEMON" --socket $ADDRESS --foreground > "$TEST_ROOT/daemon.log" 2>&1
|
||||
' &
|
||||
DPID=$!
|
||||
sleep 2
|
||||
run "$POWERLINE_COMMAND" --socket $ADDRESS wm.awesome > "$TEST_ROOT/output.log.1" 2>&1
|
||||
run "$POWERLINE_COMMAND" --socket $ADDRESS wm.awesome > "$TEST_ROOT/output.log.2" 2>&1
|
||||
run "$POWERLINE_COMMAND" --socket $ADDRESS wm.awesome > "$TEST_ROOT/output.log.3" 2>&1
|
||||
run "$POWERLINE_COMMAND" --socket $ADDRESS wm.awesome > "$TEST_ROOT/output.log.4" 2>&1
|
||||
run "$POWERLINE_COMMAND" --socket $ADDRESS wm.awesome > "$TEST_ROOT/output.log.5" 2>&1
|
||||
for log_file in "$TEST_ROOT"/output.log.* ; do
|
||||
if test -n "$(cat "$log_file")" ; then
|
||||
display_log "$log_file"
|
||||
fail "output" E "Nonempty $POWERLINE_COMMAND output at run ${log_file#*.}"
|
||||
fi
|
||||
rm "$log_file"
|
||||
done
|
||||
sleep 5
|
||||
run python "$POWERLINE_DAEMON" --socket $ADDRESS --quiet --kill > "$TEST_ROOT/kill.log" 2>&1
|
||||
if test -n "$(cat "$TEST_ROOT/kill.log")" ; then
|
||||
display_log "$TEST_ROOT/kill.log"
|
||||
fail "daemonlog" E "Nonempty kill log"
|
||||
fi
|
||||
rm "$TEST_ROOT/kill.log"
|
||||
wait $DPID
|
||||
if test -n "$(cat "$TEST_ROOT/daemon.log")" ; then
|
||||
display_log "$TEST_ROOT/daemon.log"
|
||||
fail "daemonlog" E "Nonempty daemon log"
|
||||
fi
|
||||
rm "$TEST_ROOT/daemon.log"
|
||||
if ! check_log ; then
|
||||
display_log "$TEST_ROOT/results/args"
|
||||
fail "log" F "Checking log failed"
|
||||
fi
|
||||
exit_suite --continue
|
||||
|
||||
if ! powerline-lint \
|
||||
-p "$ROOT/powerline/config_files" \
|
||||
-p "$TEST_STATIC_ROOT/powerline"
|
||||
then
|
||||
fail "lint" F "Checking test config failed"
|
||||
fi
|
||||
|
||||
exit_suite
|
@ -1,14 +1,12 @@
|
||||
#!/bin/sh
|
||||
. tests/common.sh
|
||||
. tests/shlib/common.sh
|
||||
|
||||
enter_suite bar
|
||||
|
||||
TEST_ROOT="$ROOT/tests/bar"
|
||||
make_test_root
|
||||
TEST_PATH="$TEST_ROOT/path"
|
||||
TEST_STATIC_ROOT="$ROOT/tests/test_bar"
|
||||
|
||||
test -d "$TEST_ROOT" && rm -r "$TEST_ROOT"
|
||||
mkdir "$TEST_ROOT"
|
||||
cp -r "$TEST_STATIC_ROOT/path" "$TEST_ROOT"
|
||||
cp -r "$TEST_STATIC_ROOT/powerline" "$TEST_ROOT"
|
||||
|
||||
@ -51,7 +49,7 @@ check_log() {
|
||||
if test "$warns" = "warns" ; then
|
||||
local warning="$(head -n1 "$log_file" | sed 's/.*://')"
|
||||
local expwarning="The 'bar' bindings are deprecated, please switch to 'lemonbar'"
|
||||
if test "x$warning" != "x$expwarning" ; then
|
||||
if test "$warning" != "$expwarning" ; then
|
||||
echo "Got: $warning"
|
||||
echo "Exp: $expwarning"
|
||||
fail "warn" F "Expected warning"
|
||||
@ -68,7 +66,7 @@ check_log() {
|
||||
return 1
|
||||
fi
|
||||
local expline="%{l}%{F#ffd0d0d0}%{B#ff303030} $text-left %{F-B--u}%{F#ff303030} %{F-B--u}%{r}%{F#ff303030} %{F-B--u}%{F#ffd0d0d0}%{B#ff303030} $text-right %{F-B--u}"
|
||||
if test "x$expline" != "x$line" ; then
|
||||
if test "$expline" != "$line" ; then
|
||||
echo "Line: '$line'"
|
||||
echo "Expected: '$expline'"
|
||||
fail "log:line" F "Unexpected line"
|
||||
@ -151,14 +149,14 @@ else
|
||||
if test "$fnum" -ne 2 ; then
|
||||
fail "fnum" F "Expected two output files"
|
||||
fi
|
||||
if test "x${args#--height}" != "x$args" ; then
|
||||
if test "${args#--height}" != "$args" ; then
|
||||
height="${args#--height}"
|
||||
height="${height# }"
|
||||
height="${height#=}"
|
||||
height="${height%% *}"
|
||||
fi
|
||||
command="lemonbar"
|
||||
if test "x${args#--bar-command}" != "x$args" ; then
|
||||
if test "${args#--bar-command}" != "$args" ; then
|
||||
command="${args#--bar-command}"
|
||||
command="${command# }"
|
||||
command="${command#=}"
|
||||
@ -168,11 +166,11 @@ else
|
||||
rm "$TEST_ROOT/args.log"
|
||||
script_args="${args#*-- }"
|
||||
script_args="${script_args# }"
|
||||
if test "x${script_args}" '=' "x$args" ; then
|
||||
if test "${script_args}" = "$args" ; then
|
||||
script_args=
|
||||
fi
|
||||
expected_args="$command -g 1920x$height+0${script_args:+ }$script_args${NL}$command -g 1920x$height+1${script_args:+ }$script_args"
|
||||
if test "x$expected_args" != "x$received_args" ; then
|
||||
if test "$expected_args" != "$received_args" ; then
|
||||
echo "args:${NL}<$received_args>"
|
||||
echo "expected:${NL}<$expected_args>"
|
||||
fail "args" F "Expected different args"
|
||||
@ -194,8 +192,4 @@ then
|
||||
fail "lint" F "Checking test config failed"
|
||||
fi
|
||||
|
||||
if test $FAILED -eq 0 ; then
|
||||
rm -r "$TEST_ROOT"
|
||||
fi
|
||||
|
||||
exit_suite
|
41
tests/test_daemon/test.sh
Executable file
41
tests/test_daemon/test.sh
Executable file
@ -0,0 +1,41 @@
|
||||
#!/bin/sh
|
||||
. tests/shlib/common.sh
|
||||
|
||||
enter_suite daemon
|
||||
|
||||
export ADDRESS="powerline-ipc-test-$$"
|
||||
echo "Powerline address: $ADDRESS"
|
||||
if "$PYTHON" "$ROOT/scripts/powerline-daemon" -s"$ADDRESS" ; then
|
||||
sleep 1
|
||||
if ! ( \
|
||||
"$PYTHON" "$ROOT/client/powerline.py" \
|
||||
--socket "$ADDRESS" -p/dev/null shell left \
|
||||
| grep "file not found"
|
||||
) ; then
|
||||
fail "devnull" F "-p/dev/null argument ignored or not treated properly"
|
||||
fi
|
||||
if ( \
|
||||
"$PYTHON" "$ROOT/client/powerline.py" --socket "$ADDRESS" \
|
||||
-p"$ROOT/powerline/config_files" shell left \
|
||||
| grep "file not found"
|
||||
) ; then
|
||||
fail "nodevnull" F "-p/dev/null argument remembered while it should not"
|
||||
fi
|
||||
if ! ( \
|
||||
cd "$ROOT/tests/test_daemon" \
|
||||
&& "$PYTHON" "$ROOT/client/powerline.py" --socket "$ADDRESS" \
|
||||
-p"$ROOT/powerline/config_files" shell left \
|
||||
| grep "test_daemon"
|
||||
) ; then
|
||||
fail "segment" F "Output lacks string “tests”"
|
||||
fi
|
||||
else
|
||||
fail "exitcode" E "Daemon exited with status $?"
|
||||
fi
|
||||
if "$PYTHON" "$ROOT/scripts/powerline-daemon" -s"$ADDRESS" -k ; then
|
||||
:
|
||||
else
|
||||
fail "-k" F "powerline-daemon -k failed with exit code $?"
|
||||
fi
|
||||
|
||||
exit_suite
|
@ -1,11 +1,11 @@
|
||||
#!/bin/sh
|
||||
. tests/common.sh
|
||||
. tests/shlib/common.sh
|
||||
|
||||
enter_suite vterm
|
||||
|
||||
for t in tests/test_in_vterm/test_*.sh ; do
|
||||
for t in "$ROOT"/tests/test_in_vterm/test_*.sh ; do
|
||||
test_name="${t##*/test_}"
|
||||
if ! sh "$t" ; then
|
||||
if ! "$t" ; then
|
||||
fail "${test_name%.sh}" F "Failed running $t"
|
||||
fi
|
||||
done
|
@ -4,317 +4,241 @@ 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 itertools import groupby
|
||||
from difflib import ndiff
|
||||
from glob import glob1
|
||||
from traceback import print_exc
|
||||
|
||||
from powerline.lib.unicode import u
|
||||
from powerline.lib.dict import updated
|
||||
from powerline.bindings.tmux import get_tmux_version
|
||||
from powerline import get_fallback_logger
|
||||
|
||||
from tests.lib.terminal import ExpectProcess
|
||||
from tests.modules.lib.terminal import (ExpectProcess, MutableDimensions,
|
||||
do_terminal_tests, get_env)
|
||||
|
||||
|
||||
VTERM_TEST_DIR = os.path.abspath('tests/vterm_tmux')
|
||||
|
||||
|
||||
def cell_properties_key_to_shell_escape(cell_properties_key):
|
||||
fg, bg, bold, underline, italic = cell_properties_key
|
||||
return('\x1b[38;2;{0};48;2;{1}{bold}{underline}{italic}m'.format(
|
||||
';'.join((str(i) for i in fg)),
|
||||
';'.join((str(i) for i in bg)),
|
||||
bold=(';1' if bold else ''),
|
||||
underline=(';4' if underline else ''),
|
||||
italic=(';3' if italic else ''),
|
||||
))
|
||||
def tmux_logs_iter(test_dir):
|
||||
for tail in glob1(test_dir, '*.log'):
|
||||
yield os.path.join(test_dir, tail)
|
||||
|
||||
|
||||
def test_expected_result(p, expected_result, cols, rows, print_logs):
|
||||
last_line = []
|
||||
for col in range(cols):
|
||||
last_line.append(p[rows - 1, col])
|
||||
attempts = 3
|
||||
result = None
|
||||
while attempts:
|
||||
result = tuple((
|
||||
(key, ''.join((i.text for i in subline)))
|
||||
for key, subline in groupby(last_line, lambda i: i.cell_properties_key)
|
||||
))
|
||||
if result == expected_result:
|
||||
return True
|
||||
attempts -= 1
|
||||
print('Actual result does not match expected. Attempts left: {0}.'.format(attempts))
|
||||
sleep(2)
|
||||
print('Result:')
|
||||
shesc_result = ''.join((
|
||||
'{0}{1}\x1b[m'.format(cell_properties_key_to_shell_escape(key), text)
|
||||
for key, text in result
|
||||
))
|
||||
print(shesc_result)
|
||||
print(result)
|
||||
print('Expected:')
|
||||
shesc_expected_result = ''.join((
|
||||
'{0}{1}\x1b[m'.format(cell_properties_key_to_shell_escape(key), text)
|
||||
for key, text in expected_result
|
||||
))
|
||||
print(shesc_expected_result)
|
||||
p.send(b'powerline-config tmux setup\n')
|
||||
sleep(5)
|
||||
print('Screen:')
|
||||
screen = []
|
||||
for i in range(rows):
|
||||
screen.append([])
|
||||
for j in range(cols):
|
||||
screen[-1].append(p[i, j])
|
||||
print('\n'.join(
|
||||
''.join((
|
||||
'{0}{1}\x1b[m'.format(
|
||||
cell_properties_key_to_shell_escape(i.cell_properties_key),
|
||||
i.text
|
||||
) for i in line
|
||||
))
|
||||
for line in screen
|
||||
))
|
||||
a = shesc_result.replace('\x1b', '\\e') + '\n'
|
||||
b = shesc_expected_result.replace('\x1b', '\\e') + '\n'
|
||||
print('_' * 80)
|
||||
print('Diff:')
|
||||
print('=' * 80)
|
||||
print(''.join((u(line) for line in ndiff([a], [b]))))
|
||||
if print_logs:
|
||||
for f in glob1(VTERM_TEST_DIR, '*.log'):
|
||||
def print_tmux_logs():
|
||||
for f in tmux_logs_iter(VTERM_TEST_DIR):
|
||||
print('_' * 80)
|
||||
print(os.path.basename(f) + ':')
|
||||
print('=' * 80)
|
||||
with open(f, 'r') as F:
|
||||
for line in F:
|
||||
with open(f, 'r') as fp:
|
||||
for line in fp:
|
||||
sys.stdout.write(line)
|
||||
os.unlink(f)
|
||||
return False
|
||||
|
||||
|
||||
def get_expected_result(tmux_version, expected_result_old, expected_result_1_7=None, expected_result_new=None, expected_result_2_0=None):
|
||||
def get_expected_result(tmux_version,
|
||||
expected_result_old,
|
||||
expected_result_1_7=None,
|
||||
expected_result_1_8=None,
|
||||
expected_result_2_0=None):
|
||||
if tmux_version >= (2, 0) and expected_result_2_0:
|
||||
return expected_result_2_0
|
||||
elif tmux_version >= (1, 8) and expected_result_new:
|
||||
return expected_result_new
|
||||
elif tmux_version >= (1, 8) and expected_result_1_8:
|
||||
return expected_result_1_8
|
||||
elif tmux_version >= (1, 7) and expected_result_1_7:
|
||||
return expected_result_1_7
|
||||
else:
|
||||
return expected_result_old
|
||||
|
||||
|
||||
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)
|
||||
except Exception:
|
||||
print_exc()
|
||||
for f in tmux_logs_iter(VTERM_TEST_DIR):
|
||||
os.unlink(f)
|
||||
|
||||
|
||||
def main(attempts=3):
|
||||
vterm_path = os.path.join(VTERM_TEST_DIR, 'path')
|
||||
socket_path = 'tmux-socket'
|
||||
rows = 50
|
||||
cols = 200
|
||||
|
||||
tmux_exe = os.path.join(vterm_path, 'tmux')
|
||||
|
||||
if os.path.exists('tests/bot-ci/deps/libvterm/libvterm.so'):
|
||||
lib = 'tests/bot-ci/deps/libvterm/libvterm.so'
|
||||
else:
|
||||
lib = os.environ.get('POWERLINE_LIBVTERM', 'libvterm.so')
|
||||
socket_path = os.path.abspath('tmux-socket-{0}'.format(attempts))
|
||||
if os.path.exists(socket_path):
|
||||
os.unlink(socket_path)
|
||||
|
||||
try:
|
||||
p = ExpectProcess(
|
||||
lib=lib,
|
||||
rows=rows,
|
||||
cols=cols,
|
||||
cmd=tmux_exe,
|
||||
args=[
|
||||
# Specify full path to tmux socket (testing tmux instance must
|
||||
# not interfere with user one)
|
||||
env = get_env(vterm_path, VTERM_TEST_DIR, {
|
||||
'POWERLINE_THEME_OVERRIDES': ';'.join((
|
||||
key + '=' + json.dumps(val)
|
||||
for key, val in (
|
||||
('default.segments.right', [{
|
||||
'type': 'string',
|
||||
'name': 's1',
|
||||
'highlight_groups': ['cwd'],
|
||||
'priority':50,
|
||||
}]),
|
||||
('default.segments.left', [{
|
||||
'type': 'string',
|
||||
'name': 's2',
|
||||
'highlight_groups': ['background'],
|
||||
'priority':20,
|
||||
}]),
|
||||
('default.segment_data.s1.contents', 'S1 string here'),
|
||||
('default.segment_data.s2.contents', 'S2 string here'),
|
||||
)
|
||||
)),
|
||||
'POWERLINE_TMUX_SOCKET_PATH': socket_path,
|
||||
})
|
||||
|
||||
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'))
|
||||
with open(conf_file, 'w') as cf_fd:
|
||||
cf_fd.write(conf_line)
|
||||
|
||||
tmux_version = get_tmux_version(get_fallback_logger())
|
||||
|
||||
dim = MutableDimensions(rows=50, cols=200)
|
||||
|
||||
def prepare_test_1(p):
|
||||
sleep(5)
|
||||
|
||||
def prepare_test_2(p):
|
||||
dim.cols = 40
|
||||
p.resize(dim)
|
||||
sleep(5)
|
||||
|
||||
base_attrs = {
|
||||
((0, 0, 0), (243, 243, 243), 1, 0, 0): 'lead',
|
||||
((243, 243, 243), (11, 11, 11), 0, 0, 0): 'leadsep',
|
||||
((255, 255, 255), (11, 11, 11), 0, 0, 0): 'bg',
|
||||
((199, 199, 199), (88, 88, 88), 0, 0, 0): 'cwd',
|
||||
((88, 88, 88), (11, 11, 11), 0, 0, 0): 'cwdhsep',
|
||||
((0, 0, 0), (0, 224, 0), 0, 0, 0): 'defstl',
|
||||
}
|
||||
tests = (
|
||||
{
|
||||
'expected_result': get_expected_result(
|
||||
tmux_version,
|
||||
expected_result_old=(
|
||||
'{lead: 0 }{leadsep: }{bg: S2 string here }'
|
||||
'{4: 0 }{cwdhsep:| }{6:bash }'
|
||||
'{bg: }{4: 1- }{cwdhsep:| }{6:bash }'
|
||||
'{bg: }{7: }{8:2* | }{9:bash }{10: }'
|
||||
'{bg:' + (' ' * 124) + '}'
|
||||
'{cwdhsep: }{cwd: S1 string here }', updated(base_attrs, {
|
||||
((133, 133, 133), (11, 11, 11), 0, 0, 0): 4,
|
||||
((188, 188, 188), (11, 11, 11), 0, 0, 0): 6,
|
||||
((11, 11, 11), (0, 102, 153), 0, 0, 0): 7,
|
||||
((102, 204, 255), (0, 102, 153), 0, 0, 0): 8,
|
||||
((255, 255, 255), (0, 102, 153), 1, 0, 0): 9,
|
||||
((0, 102, 153), (11, 11, 11), 0, 0, 0): 10,
|
||||
})),
|
||||
expected_result_1_8=(
|
||||
'{lead: 0 }{leadsep: }{bg: S2 string here }'
|
||||
'{4: 0 }{cwdhsep:| }{6:bash }'
|
||||
'{bg: }{4: 1- }{cwdhsep:| }{7:bash }'
|
||||
'{bg: }{8: }{9:2* | }{10:bash }{7: }'
|
||||
'{bg:' + (' ' * 124) + '}'
|
||||
'{cwdhsep: }{cwd: S1 string here }', updated(base_attrs, {
|
||||
((133, 133, 133), (11, 11, 11), 0, 0, 0): 4,
|
||||
((188, 188, 188), (11, 11, 11), 0, 0, 0): 6,
|
||||
((0, 102, 153), (11, 11, 11), 0, 0, 0): 7,
|
||||
((11, 11, 11), (0, 102, 153), 0, 0, 0): 8,
|
||||
((102, 204, 255), (0, 102, 153), 0, 0, 0): 9,
|
||||
((255, 255, 255), (0, 102, 153), 1, 0, 0): 10,
|
||||
})),
|
||||
expected_result_2_0=(
|
||||
'{lead: 0 }{leadsep: }{bg: S2 string here }'
|
||||
'{4: 0 }{cwdhsep:| }{6:bash }'
|
||||
'{bg: }{4: 1- }{cwdhsep:| }{7:bash }'
|
||||
'{bg: }{8: }{9:2* | }{10:bash }{7: }'
|
||||
'{bg:' + (' ' * 125) + '}'
|
||||
'{cwdhsep: }{cwd: S1 string here }', updated(base_attrs, {
|
||||
((133, 133, 133), (11, 11, 11), 0, 0, 0): 4,
|
||||
((188, 188, 188), (11, 11, 11), 0, 0, 0): 6,
|
||||
((0, 102, 153), (11, 11, 11), 0, 0, 0): 7,
|
||||
((11, 11, 11), (0, 102, 153), 0, 0, 0): 8,
|
||||
((102, 204, 255), (0, 102, 153), 0, 0, 0): 9,
|
||||
((255, 255, 255), (0, 102, 153), 1, 0, 0): 10,
|
||||
})),
|
||||
),
|
||||
'prep_cb': prepare_test_1,
|
||||
'row': dim.rows - 1,
|
||||
}, {
|
||||
'expected_result': get_expected_result(
|
||||
tmux_version,
|
||||
expected_result_old=('{bg:' + (' ' * 40) + '}', base_attrs),
|
||||
expected_result_1_7=(
|
||||
'{lead: 0 }'
|
||||
'{leadsep: }{bg: <}{4:h }{bg: }{5: }'
|
||||
'{6:2* | }{7:bash }{8: }{bg: }{cwdhsep: }'
|
||||
'{cwd: S1 string here }', updated(base_attrs, {
|
||||
((188, 188, 188), (11, 11, 11), 0, 0, 0): 4,
|
||||
((11, 11, 11), (0, 102, 153), 0, 0, 0): 5,
|
||||
((102, 204, 255), (0, 102, 153), 0, 0, 0): 6,
|
||||
((255, 255, 255), (0, 102, 153), 1, 0, 0): 7,
|
||||
((0, 102, 153), (11, 11, 11), 0, 0, 0): 8,
|
||||
})),
|
||||
expected_result_1_8=(
|
||||
'{lead: 0 }'
|
||||
'{leadsep: }{bg: <}{4:h }{bg: }{5: }'
|
||||
'{6:2* | }{7:bash }{4: }{bg: }{cwdhsep: }'
|
||||
'{cwd: S1 string here }', updated(base_attrs, {
|
||||
((0, 102, 153), (11, 11, 11), 0, 0, 0): 4,
|
||||
((11, 11, 11), (0, 102, 153), 0, 0, 0): 5,
|
||||
((102, 204, 255), (0, 102, 153), 0, 0, 0): 6,
|
||||
((255, 255, 255), (0, 102, 153), 1, 0, 0): 7,
|
||||
})),
|
||||
expected_result_2_0=(
|
||||
'{lead: 0 }'
|
||||
'{leadsep: }{bg:<}{4:ash }{bg: }{5: }'
|
||||
'{6:2* | }{7:bash }{4: }{cwdhsep: }'
|
||||
'{cwd: S1 string here }', updated(base_attrs, {
|
||||
((0, 102, 153), (11, 11, 11), 0, 0, 0): 4,
|
||||
((11, 11, 11), (0, 102, 153), 0, 0, 0): 5,
|
||||
((102, 204, 255), (0, 102, 153), 0, 0, 0): 6,
|
||||
((255, 255, 255), (0, 102, 153), 1, 0, 0): 7,
|
||||
})),
|
||||
),
|
||||
'prep_cb': prepare_test_2,
|
||||
'row': dim.rows - 1,
|
||||
}
|
||||
)
|
||||
|
||||
args = [
|
||||
# Specify full path to tmux socket (testing tmux instance must not
|
||||
# interfere with user one)
|
||||
'-S', socket_path,
|
||||
# Force 256-color mode
|
||||
'-2',
|
||||
# Request verbose logging just in case
|
||||
'-v',
|
||||
# Specify configuration file
|
||||
'-f', os.path.abspath('powerline/bindings/tmux/powerline.conf'),
|
||||
'-f', conf_file,
|
||||
# Run bash three times
|
||||
'new-session', 'bash --norc --noprofile -i', ';',
|
||||
'new-window', 'bash --norc --noprofile -i', ';',
|
||||
'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,
|
||||
env={
|
||||
# Reasoning:
|
||||
# 1. vt* TERMs (used to be vt100 here) make tmux-1.9 use
|
||||
# different and identical colors for inactive windows. This
|
||||
# is not like tmux-1.6: foreground color is different from
|
||||
# separator color and equal to (0, 102, 153) for some reason
|
||||
# (separator has correct color). tmux-1.8 is fine, so are
|
||||
# older versions (though tmux-1.6 and tmux-1.7 do not have
|
||||
# highlighting for previously active window) and my system
|
||||
# tmux-1.9a.
|
||||
# 2. screen, xterm and some other non-256color terminals both
|
||||
# have the same issue and make libvterm emit complains like
|
||||
# `Unhandled CSI SGR 3231`.
|
||||
# 3. screen-256color, xterm-256color and other -256color
|
||||
# terminals make libvterm emit complains about unhandled
|
||||
# escapes to stderr.
|
||||
# 4. `st-256color` does not have any of the above problems, but
|
||||
# it may be not present on the target system because it is
|
||||
# installed with x11-terms/st and not with sys-libs/ncurses.
|
||||
#
|
||||
# For the given reasons decision was made: to fix tmux-1.9 tests
|
||||
# and not make libvterm emit any data to stderr st-256color
|
||||
# $TERM should be used, up until libvterm has its own terminfo
|
||||
# database entry (if it ever will). To make sure that relevant
|
||||
# terminfo entry is present on the target system it should be
|
||||
# distributed with powerline test package. To make distribution
|
||||
# not require modifying anything outside of powerline test
|
||||
# directory TERMINFO variable is set.
|
||||
'TERMINFO': os.path.join(VTERM_TEST_DIR, 'terminfo'),
|
||||
'TERM': 'st-256color',
|
||||
'PATH': vterm_path,
|
||||
'SHELL': os.path.join(VTERM_TEST_DIR, 'path', 'bash'),
|
||||
'POWERLINE_CONFIG_PATHS': os.path.abspath('powerline/config_files'),
|
||||
'POWERLINE_COMMAND': 'powerline-render',
|
||||
'POWERLINE_THEME_OVERRIDES': (
|
||||
'default.segments.right=[{"type":"string","name":"s1","highlight_groups":["cwd"],"priority":50}];'
|
||||
'default.segments.left=[{"type":"string","name":"s2","highlight_groups":["background"],"priority":20}];'
|
||||
'default.segment_data.s1.contents=S1 string here;'
|
||||
'default.segment_data.s2.contents=S2 string here;'
|
||||
),
|
||||
'LD_LIBRARY_PATH': os.environ.get('LD_LIBRARY_PATH', ''),
|
||||
'PYTHONPATH': os.environ.get('PYTHONPATH', ''),
|
||||
},
|
||||
fin_cb=tmux_fin_cb,
|
||||
last_attempt_cb=print_tmux_logs,
|
||||
)
|
||||
p.start()
|
||||
sleep(5)
|
||||
tmux_version = get_tmux_version(get_fallback_logger())
|
||||
expected_result = get_expected_result(tmux_version, expected_result_old=(
|
||||
(((0, 0, 0), (243, 243, 243), 1, 0, 0), ' 0 '),
|
||||
(((243, 243, 243), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' S2 string here '),
|
||||
(((133, 133, 133), (11, 11, 11), 0, 0, 0), ' 0 '),
|
||||
(((88, 88, 88), (11, 11, 11), 0, 0, 0), '| '),
|
||||
(((188, 188, 188), (11, 11, 11), 0, 0, 0), 'bash '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((133, 133, 133), (11, 11, 11), 0, 0, 0), ' 1- '),
|
||||
(((88, 88, 88), (11, 11, 11), 0, 0, 0), '| '),
|
||||
(((188, 188, 188), (11, 11, 11), 0, 0, 0), 'bash '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((11, 11, 11), (0, 102, 153), 0, 0, 0), ' '),
|
||||
(((102, 204, 255), (0, 102, 153), 0, 0, 0), '2* | '),
|
||||
(((255, 255, 255), (0, 102, 153), 1, 0, 0), 'bash '),
|
||||
(((0, 102, 153), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' ' * 124),
|
||||
(((88, 88, 88), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((199, 199, 199), (88, 88, 88), 0, 0, 0), ' S1 string here '),
|
||||
), expected_result_new=(
|
||||
(((0, 0, 0), (243, 243, 243), 1, 0, 0), ' 0 '),
|
||||
(((243, 243, 243), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' S2 string here '),
|
||||
(((133, 133, 133), (11, 11, 11), 0, 0, 0), ' 0 '),
|
||||
(((88, 88, 88), (11, 11, 11), 0, 0, 0), '| '),
|
||||
(((188, 188, 188), (11, 11, 11), 0, 0, 0), 'bash '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((133, 133, 133), (11, 11, 11), 0, 0, 0), ' 1- '),
|
||||
(((88, 88, 88), (11, 11, 11), 0, 0, 0), '| '),
|
||||
(((0, 102, 153), (11, 11, 11), 0, 0, 0), 'bash '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((11, 11, 11), (0, 102, 153), 0, 0, 0), ' '),
|
||||
(((102, 204, 255), (0, 102, 153), 0, 0, 0), '2* | '),
|
||||
(((255, 255, 255), (0, 102, 153), 1, 0, 0), 'bash '),
|
||||
(((0, 102, 153), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' ' * 124),
|
||||
(((88, 88, 88), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((199, 199, 199), (88, 88, 88), 0, 0, 0), ' S1 string here '),
|
||||
), expected_result_2_0=(
|
||||
(((0, 0, 0), (243, 243, 243), 1, 0, 0), ' 0 '),
|
||||
(((243, 243, 243), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' S2 string here '),
|
||||
(((133, 133, 133), (11, 11, 11), 0, 0, 0), ' 0 '),
|
||||
(((88, 88, 88), (11, 11, 11), 0, 0, 0), '| '),
|
||||
(((188, 188, 188), (11, 11, 11), 0, 0, 0), 'bash '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((133, 133, 133), (11, 11, 11), 0, 0, 0), ' 1- '),
|
||||
(((88, 88, 88), (11, 11, 11), 0, 0, 0), '| '),
|
||||
(((0, 102, 153), (11, 11, 11), 0, 0, 0), 'bash '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((11, 11, 11), (0, 102, 153), 0, 0, 0), ' '),
|
||||
(((102, 204, 255), (0, 102, 153), 0, 0, 0), '2* | '),
|
||||
(((255, 255, 255), (0, 102, 153), 1, 0, 0), 'bash '),
|
||||
(((0, 102, 153), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' ' * 125),
|
||||
(((88, 88, 88), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((199, 199, 199), (88, 88, 88), 0, 0, 0), ' S1 string here '),
|
||||
))
|
||||
ret = None
|
||||
if not test_expected_result(p, expected_result, cols, rows, not attempts):
|
||||
if attempts:
|
||||
pass
|
||||
# Will rerun main later.
|
||||
else:
|
||||
ret = False
|
||||
elif ret is not False:
|
||||
ret = True
|
||||
cols = 40
|
||||
p.resize(rows, cols)
|
||||
sleep(5)
|
||||
expected_result = get_expected_result(tmux_version, (
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' ' * cols),
|
||||
), expected_result_1_7=(
|
||||
(((0, 0, 0), (243, 243, 243), 1, 0, 0), ' 0 '),
|
||||
(((243, 243, 243), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' <'),
|
||||
(((188, 188, 188), (11, 11, 11), 0, 0, 0), 'h '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((11, 11, 11), (0, 102, 153), 0, 0, 0), ' '),
|
||||
(((102, 204, 255), (0, 102, 153), 0, 0, 0), '2* | '),
|
||||
(((255, 255, 255), (0, 102, 153), 1, 0, 0), 'bash '),
|
||||
(((0, 102, 153), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((88, 88, 88), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((199, 199, 199), (88, 88, 88), 0, 0, 0), ' S1 string here ')
|
||||
), expected_result_new=(
|
||||
(((0, 0, 0), (243, 243, 243), 1, 0, 0), ' 0 '),
|
||||
(((243, 243, 243), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' <'),
|
||||
(((0, 102, 153), (11, 11, 11), 0, 0, 0), 'h '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((11, 11, 11), (0, 102, 153), 0, 0, 0), ' '),
|
||||
(((102, 204, 255), (0, 102, 153), 0, 0, 0), '2* | '),
|
||||
(((255, 255, 255), (0, 102, 153), 1, 0, 0), 'bash '),
|
||||
(((0, 102, 153), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((88, 88, 88), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((199, 199, 199), (88, 88, 88), 0, 0, 0), ' S1 string here ')
|
||||
), expected_result_2_0=(
|
||||
(((0, 0, 0), (243, 243, 243), 1, 0, 0), ' 0 '),
|
||||
(((243, 243, 243), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), '<'),
|
||||
(((0, 102, 153), (11, 11, 11), 0, 0, 0), 'ash '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((11, 11, 11), (0, 102, 153), 0, 0, 0), ' '),
|
||||
(((102, 204, 255), (0, 102, 153), 0, 0, 0), '2* | '),
|
||||
(((255, 255, 255), (0, 102, 153), 1, 0, 0), 'bash '),
|
||||
(((0, 102, 153), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((88, 88, 88), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((199, 199, 199), (88, 88, 88), 0, 0, 0), ' S1 string here ')
|
||||
))
|
||||
if not test_expected_result(p, expected_result, cols, rows, not attempts):
|
||||
if attempts:
|
||||
pass
|
||||
else:
|
||||
ret = False
|
||||
elif ret is not False:
|
||||
ret = True
|
||||
if ret is not None:
|
||||
return ret
|
||||
finally:
|
||||
check_call([tmux_exe, '-S', socket_path, 'kill-server'], env={
|
||||
'PATH': vterm_path,
|
||||
'LD_LIBRARY_PATH': os.environ.get('LD_LIBRARY_PATH', ''),
|
||||
}, cwd=VTERM_TEST_DIR)
|
||||
return main(attempts=(attempts - 1))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -1,20 +1,17 @@
|
||||
#!/bin/sh
|
||||
. tests/common.sh
|
||||
. tests/shlib/common.sh
|
||||
. tests/shlib/vterm.sh
|
||||
|
||||
enter_suite tmux
|
||||
|
||||
rm -rf tests/vterm_tmux
|
||||
mkdir tests/vterm_tmux
|
||||
mkdir tests/vterm_tmux/path
|
||||
VTERM_TEST_DIR="$ROOT/tests/vterm_tmux"
|
||||
|
||||
ln -s "$(which "${PYTHON}")" tests/vterm_tmux/path/python
|
||||
ln -s "$(which bash)" tests/vterm_tmux/path
|
||||
ln -s "$(which env)" tests/vterm_tmux/path
|
||||
ln -s "$(which cut)" tests/vterm_tmux/path
|
||||
ln -s "$PWD/scripts/powerline-render" tests/vterm_tmux/path
|
||||
ln -s "$PWD/scripts/powerline-config" tests/vterm_tmux/path
|
||||
vterm_setup "$VTERM_TEST_DIR"
|
||||
|
||||
cp -r tests/terminfo tests/vterm_tmux
|
||||
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"
|
||||
|
||||
test_tmux() {
|
||||
if test "$PYTHON_IMPLEMENTATION" = PyPy; then
|
||||
@ -25,17 +22,18 @@ test_tmux() {
|
||||
if ! which "${POWERLINE_TMUX_EXE}" ; then
|
||||
return 0
|
||||
fi
|
||||
ln -sf "$(which "${POWERLINE_TMUX_EXE}")" tests/vterm_tmux/path
|
||||
f=tests/test_in_vterm/test_tmux.py
|
||||
if ! "${PYTHON}" $f ; then
|
||||
ln -sf "$(which "${POWERLINE_TMUX_EXE}")" "$VTERM_TEST_DIR/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)"
|
||||
fail "$test_name" F "Failed vterm test $f"
|
||||
fi
|
||||
}
|
||||
|
||||
if test -z "$POWERLINE_TMUX_EXE" && test -d tests/bot-ci/deps/tmux ; then
|
||||
for tmux in tests/bot-ci/deps/tmux/tmux-*/tmux ; do
|
||||
export POWERLINE_TMUX_EXE="$PWD/$tmux"
|
||||
if test -z "$POWERLINE_TMUX_EXE" && test -d "$ROOT/tests/bot-ci/deps/tmux"
|
||||
then
|
||||
for tmux in "$ROOT"/tests/bot-ci/deps/tmux/tmux-*/tmux ; do
|
||||
export POWERLINE_TMUX_EXE="$tmux"
|
||||
test_tmux || true
|
||||
done
|
||||
else
|
||||
@ -43,10 +41,6 @@ else
|
||||
test_tmux || true
|
||||
fi
|
||||
|
||||
if test $FAILED -eq 0 ; then
|
||||
rm -rf tests/vterm_tmux
|
||||
else
|
||||
echo "$FAIL_SUMMARY"
|
||||
fi
|
||||
vterm_shutdown "$VTERM_TEST_DIR"
|
||||
|
||||
exit_suite
|
||||
|
49
tests/test_in_vterm/test_vim.py
Executable file
49
tests/test_in_vterm/test_vim.py
Executable file
@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8:noet
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
|
||||
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 tests.modules.lib.terminal import (ExpectProcess, MutableDimensions,
|
||||
do_terminal_tests, get_env)
|
||||
|
||||
|
||||
VTERM_TEST_DIR = os.path.abspath('tests/vterm_vim')
|
||||
|
||||
|
||||
def main(attempts=3):
|
||||
vterm_path = os.path.join(VTERM_TEST_DIR, 'path')
|
||||
|
||||
vim_exe = os.path.join(vterm_path, 'vim')
|
||||
|
||||
env = get_env(vterm_path, VTERM_TEST_DIR)
|
||||
|
||||
dim = MutableDimensions(rows=50, cols=200)
|
||||
|
||||
tests = (
|
||||
)
|
||||
|
||||
args = []
|
||||
|
||||
return do_terminal_tests(
|
||||
tests=tests,
|
||||
cmd=vim_exe,
|
||||
dim=dim,
|
||||
args=args,
|
||||
env=env,
|
||||
cwd=VTERM_TEST_DIR,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if main():
|
||||
raise SystemExit(0)
|
||||
else:
|
||||
raise SystemExit(1)
|
41
tests/test_in_vterm/test_vim.sh
Executable file
41
tests/test_in_vterm/test_vim.sh
Executable file
@ -0,0 +1,41 @@
|
||||
#!/bin/sh
|
||||
. tests/shlib/common.sh
|
||||
. tests/shlib/vterm.sh
|
||||
. tests/shlib/vim.sh
|
||||
|
||||
enter_suite vim
|
||||
|
||||
VTERM_TEST_DIR="$ROOT/tests/vterm_vim"
|
||||
|
||||
vterm_setup "$VTERM_TEST_DIR"
|
||||
|
||||
test_vim() {
|
||||
if test "$PYTHON_IMPLEMENTATION" != CPython ; then
|
||||
# Can only link with cpython
|
||||
return 0
|
||||
fi
|
||||
if ! which "$POWERLINE_VIM_EXE" ; then
|
||||
return 0
|
||||
fi
|
||||
ln -sf "$(which "${POWERLINE_VIM_EXE}")" "$VTERM_TEST_DIR/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)"
|
||||
fail "$test_name" F "Failed vterm test $f"
|
||||
fi
|
||||
}
|
||||
|
||||
if test -z "$POWERLINE_VIM_EXE" && test -d "$ROOT/tests/bot-ci/deps/vim"
|
||||
then
|
||||
for vim in "$OLD_VIM" "$NEW_VIM" ; do
|
||||
export POWERLINE_VIM_EXE="$vim"
|
||||
test_vim || true
|
||||
done
|
||||
else
|
||||
export POWERLINE_VIM_EXE="${POWERLINE_VIM_EXE:-vim}"
|
||||
test_vim || true
|
||||
fi
|
||||
|
||||
vterm_shutdown "$VTERM_TEST_DIR"
|
||||
|
||||
exit_suite
|
10
tests/test_lint/test.sh
Executable file
10
tests/test_lint/test.sh
Executable file
@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
. tests/shlib/common.sh
|
||||
|
||||
enter_suite lint
|
||||
|
||||
if ! "$PYTHON" "$ROOT/scripts/powerline-lint" -p "$ROOT/powerline/config_files" ; then
|
||||
fail "test" F "Running powerline-lint failed"
|
||||
fi
|
||||
|
||||
exit_suite
|
@ -1,11 +1,11 @@
|
||||
#!/bin/sh
|
||||
. tests/common.sh
|
||||
. tests/shlib/common.sh
|
||||
|
||||
enter_suite python
|
||||
|
||||
for file in tests/test_*.py ; do
|
||||
for file in "$ROOT"/tests/test_python/test_*.py ; do
|
||||
test_name="${file##*/test_}"
|
||||
if ! ${PYTHON} $file --verbose --catch ; then
|
||||
if ! "$PYTHON" "$file" --verbose --catch ; then
|
||||
fail "${test_name%.py}" F "Failed test(s) from $file"
|
||||
fi
|
||||
done
|
@ -13,8 +13,8 @@ else:
|
||||
|
||||
from powerline.commands.main import get_argparser, finish_args
|
||||
|
||||
from tests import TestCase
|
||||
from tests.lib import replace_attr
|
||||
from tests.modules import TestCase
|
||||
from tests.modules.lib import replace_attr
|
||||
|
||||
|
||||
class TestParser(TestCase):
|
||||
@ -127,7 +127,7 @@ class TestParser(TestCase):
|
||||
}),
|
||||
]:
|
||||
args = parser.parse_args(argv)
|
||||
finish_args({}, args)
|
||||
finish_args(parser, {}, args)
|
||||
for key, val in expargs.items():
|
||||
self.assertEqual(getattr(args, key), val)
|
||||
for key, val in args.__dict__.items():
|
||||
@ -140,5 +140,5 @@ class TestParser(TestCase):
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from tests import main
|
||||
from tests.modules import main
|
||||
main()
|
@ -11,8 +11,8 @@ from shutil import rmtree
|
||||
from powerline.lib.dict import mergedicts_copy as mdc
|
||||
from powerline import Powerline
|
||||
|
||||
from tests import TestCase
|
||||
from tests.lib.config_mock import select_renderer, UT
|
||||
from tests.modules import TestCase
|
||||
from tests.modules.lib.config_mock import select_renderer, UT
|
||||
|
||||
|
||||
CONFIG_DIR = 'tests/config'
|
||||
@ -139,7 +139,7 @@ class WithConfigTree(object):
|
||||
select_renderer(simpler_renderer=True)
|
||||
self.p = TestPowerline(
|
||||
ext='test',
|
||||
renderer_module='tests.lib.config_mock',
|
||||
renderer_module='tests.modules.lib.config_mock',
|
||||
**self.p_kwargs
|
||||
)
|
||||
if os.environ.get('POWERLINE_RUN_LINT_DURING_TESTS'):
|
||||
@ -266,5 +266,5 @@ class TestMerging(TestCase):
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from tests import main
|
||||
from tests.modules import main
|
||||
main()
|
@ -5,8 +5,8 @@ from time import sleep
|
||||
from copy import deepcopy
|
||||
from functools import wraps
|
||||
|
||||
from tests import TestCase
|
||||
from tests.lib.config_mock import get_powerline, add_watcher_events, UT
|
||||
from tests.modules import TestCase
|
||||
from tests.modules.lib.config_mock import get_powerline, add_watcher_events, UT
|
||||
|
||||
|
||||
config = {
|
||||
@ -315,5 +315,5 @@ class TestConfigReload(TestCase):
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from tests import main
|
||||
from tests.modules import main
|
||||
main()
|
@ -7,11 +7,12 @@ import os
|
||||
from functools import wraps
|
||||
from copy import deepcopy
|
||||
|
||||
import tests.vim as vim_module
|
||||
import tests.modules.vim as vim_module
|
||||
|
||||
from tests import TestCase
|
||||
from tests.lib.config_mock import get_powerline, get_powerline_raw, swap_attributes, UT
|
||||
from tests.lib import Args, replace_item
|
||||
from tests.modules import TestCase
|
||||
from tests.modules.lib.config_mock import (get_powerline, get_powerline_raw,
|
||||
swap_attributes, UT)
|
||||
from tests.modules.lib import Args, replace_item
|
||||
|
||||
|
||||
def highlighted_string(s, group, **kwargs):
|
||||
@ -550,6 +551,28 @@ class TestDisplayCondition(TestRender):
|
||||
self.assertRenderEqual(p, '{56} s1{6-}>>{--}', mode='m1')
|
||||
|
||||
|
||||
class TestOuterPadding(TestRender):
|
||||
@add_args
|
||||
def test_outer_padding_left(self, p, config):
|
||||
config['themes/' + UT]['outer_padding'] = 5
|
||||
self.assertRenderEqual(p, '{121} s{24}>>{344}g{4-}>>{--}', side='left')
|
||||
|
||||
@add_args
|
||||
def test_outer_padding_right(self, p, config):
|
||||
config['themes/' + UT]['outer_padding'] = 5
|
||||
self.assertRenderEqual(p, '{4-}<<{344}f {--}', side='right')
|
||||
|
||||
@add_args
|
||||
def test_outer_padding_ten(self, p, config):
|
||||
config['themes/' + UT]['outer_padding'] = 10
|
||||
self.assertRenderEqual(p, '{121} s {24}>>{344}g{34}>{34}|{344} f {--}', width=30)
|
||||
|
||||
@add_args
|
||||
def test_outer_padding_zero(self, p, config):
|
||||
config['themes/' + UT]['outer_padding'] = 0
|
||||
self.assertRenderEqual(p, '{121}s {24}>>{344}g{34}>{34}|{344} f{--}', width=30)
|
||||
|
||||
|
||||
class TestSegmentAttributes(TestRender):
|
||||
@add_args
|
||||
def test_no_attributes(self, p, config):
|
||||
@ -775,7 +798,6 @@ class TestVim(TestCase):
|
||||
def test_environ_update(self):
|
||||
# Regression test: test that segment obtains environment from vim, not
|
||||
# from os.environ.
|
||||
import tests.vim as vim_module
|
||||
with vim_module._with('globals', powerline_config_paths=['/']):
|
||||
from powerline.vim import VimPowerline
|
||||
import powerline as powerline_module
|
||||
@ -795,7 +817,7 @@ class TestVim(TestCase):
|
||||
import powerline as powerline_module
|
||||
with swap_attributes(config, powerline_module):
|
||||
with get_powerline_raw(config, VimPowerline, replace_gcp=True) as powerline:
|
||||
powerline.add_local_theme('tests.matchers.always_true', {
|
||||
powerline.add_local_theme('tests.modules.matchers.always_true', {
|
||||
'segment_data': {
|
||||
'foo': {
|
||||
'contents': '“bar”'
|
||||
@ -818,7 +840,7 @@ class TestVim(TestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), 'path')))
|
||||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'vim_sys_path')))
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
@ -851,5 +873,5 @@ class TestLemonbar(TestRender):
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from tests import main
|
||||
from tests.modules import main
|
||||
main()
|
@ -21,8 +21,8 @@ from powerline.lib.shell import run_cmd
|
||||
|
||||
import powerline.lib.unicode as plu
|
||||
|
||||
from tests.lib import Pl, replace_attr
|
||||
from tests import TestCase, SkipTest
|
||||
from tests.modules.lib import Pl, replace_attr
|
||||
from tests.modules import TestCase, SkipTest
|
||||
|
||||
|
||||
try:
|
||||
@ -704,7 +704,7 @@ class TestVCS(TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.powerline_old_cwd = os.getcwd()
|
||||
os.chdir(os.path.dirname(__file__))
|
||||
os.chdir(os.path.dirname(os.path.dirname(__file__)))
|
||||
call(['git', 'init', '--quiet', GIT_REPO])
|
||||
assert os.path.isdir(GIT_REPO)
|
||||
call(['git', 'config', '--local', 'user.name', 'Foo'], cwd=GIT_REPO)
|
||||
@ -736,5 +736,5 @@ class TestVCS(TestCase):
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from tests import main
|
||||
from tests.modules import main
|
||||
main()
|
@ -5,11 +5,11 @@ import os
|
||||
|
||||
from powerline.lib.config import ConfigLoader
|
||||
|
||||
from tests import TestCase
|
||||
from tests.lib.fsconfig import FSTree
|
||||
from tests.modules import TestCase
|
||||
from tests.modules.lib.fsconfig import FSTree
|
||||
|
||||
|
||||
FILE_ROOT = os.path.join(os.path.dirname(__file__), 'cfglib')
|
||||
FILE_ROOT = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'cfglib')
|
||||
|
||||
|
||||
class LoadedList(list):
|
||||
@ -48,5 +48,5 @@ class TestLoaderCondition(TestCase):
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from tests import main
|
||||
from tests.modules import main
|
||||
main()
|
@ -3,8 +3,8 @@ from __future__ import (unicode_literals, division, absolute_import, print_funct
|
||||
|
||||
import powerline.listers.i3wm as i3wm
|
||||
|
||||
from tests.lib import Args, replace_attr, Pl
|
||||
from tests import TestCase
|
||||
from tests.modules.lib import Args, replace_attr, Pl
|
||||
from tests.modules import TestCase
|
||||
|
||||
|
||||
class TestI3WM(TestCase):
|
||||
@ -223,5 +223,5 @@ class TestI3WM(TestCase):
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from tests import main
|
||||
from tests.modules import main
|
||||
main()
|
@ -14,8 +14,8 @@ from shutil import rmtree
|
||||
|
||||
from powerline import finish_common_config, create_logger
|
||||
|
||||
from tests import TestCase
|
||||
from tests.lib import replace_attr
|
||||
from tests.modules import TestCase
|
||||
from tests.modules.lib import replace_attr
|
||||
|
||||
|
||||
TIMESTAMP_RE = r'\d{4}-\d\d-\d\d \d\d:\d\d:\d\d,\d{3}'
|
||||
@ -454,7 +454,7 @@ def setUpModule():
|
||||
global __file__
|
||||
old_cwd = os.getcwd()
|
||||
__file__ = os.path.abspath(__file__)
|
||||
os.chdir(os.path.dirname(__file__))
|
||||
os.chdir(os.path.dirname(os.path.dirname(__file__)))
|
||||
|
||||
|
||||
def tearDownModule():
|
||||
@ -463,5 +463,5 @@ def tearDownModule():
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from tests import main
|
||||
from tests.modules import main
|
||||
main()
|
@ -9,10 +9,10 @@ import os
|
||||
import json
|
||||
import logging
|
||||
|
||||
import tests.vim as vim_module
|
||||
import tests.modules.vim as vim_module
|
||||
|
||||
from tests.lib import Args, urllib_read, replace_attr
|
||||
from tests import TestCase
|
||||
from tests.modules.lib import Args, urllib_read, replace_attr
|
||||
from tests.modules import TestCase
|
||||
|
||||
from powerline import NotInterceptedError
|
||||
from powerline.segments.common import wthr
|
||||
@ -46,7 +46,7 @@ def get_logger(stream=None):
|
||||
class TestVimConfig(TestCase):
|
||||
def test_vim(self):
|
||||
from powerline.vim import VimPowerline
|
||||
cfg_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'powerline', 'config_files')
|
||||
cfg_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), 'powerline', 'config_files')
|
||||
buffers = (
|
||||
(('bufoptions',), {'buftype': 'help'}),
|
||||
(('bufname', '[Command Line]'), {}),
|
||||
@ -101,7 +101,7 @@ class TestVimConfig(TestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), 'path')))
|
||||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'vim_sys_path')))
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
@ -182,7 +182,7 @@ def setUpModule():
|
||||
global saved_get_config_paths
|
||||
import powerline
|
||||
saved_get_config_paths = powerline.get_config_paths
|
||||
path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'powerline', 'config_files')
|
||||
path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), 'powerline', 'config_files')
|
||||
powerline.get_config_paths = lambda: [path]
|
||||
old_cwd = os.getcwd()
|
||||
|
||||
@ -197,5 +197,5 @@ def tearDownModule():
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from tests import main
|
||||
from tests.modules import main
|
||||
main()
|
@ -13,10 +13,11 @@ from powerline.segments import shell, tmux, pdb, i3wm
|
||||
from powerline.lib.vcs import get_fallback_create_watcher
|
||||
from powerline.lib.unicode import out_u
|
||||
|
||||
import tests.vim as vim_module
|
||||
import tests.modules.vim as vim_module
|
||||
|
||||
from tests.lib import Args, urllib_read, replace_attr, new_module, replace_module_module, replace_env, Pl
|
||||
from tests import TestCase, SkipTest
|
||||
from tests.modules.lib import (Args, urllib_read, replace_attr, new_module,
|
||||
replace_module_module, replace_env, Pl)
|
||||
from tests.modules import TestCase, SkipTest
|
||||
|
||||
|
||||
def get_dummy_guess(**kwargs):
|
||||
@ -1159,6 +1160,8 @@ class TestVim(TestCase):
|
||||
self.assertEqual(self.vim.mode(pl=pl, segment_info=segment_info, override={'n': 'NORM'}), 'NORM')
|
||||
with vim_module._with('mode', 'i') as segment_info:
|
||||
self.assertEqual(self.vim.mode(pl=pl, segment_info=segment_info), 'INSERT')
|
||||
with vim_module._with('mode', 'i\0') as segment_info:
|
||||
self.assertEqual(self.vim.mode(pl=pl, segment_info=segment_info), 'INSERT')
|
||||
with vim_module._with('mode', chr(ord('V') - 0x40)) as segment_info:
|
||||
self.assertEqual(self.vim.mode(pl=pl, segment_info=segment_info), 'V-BLCK')
|
||||
self.assertEqual(self.vim.mode(pl=pl, segment_info=segment_info, override={'^V': 'VBLK'}), 'VBLK')
|
||||
@ -1288,7 +1291,11 @@ class TestVim(TestCase):
|
||||
pl = Pl()
|
||||
segment_info = vim_module._get_segment_info()
|
||||
self.assertEqual(self.vim.file_size(pl=pl, segment_info=segment_info), '0 B')
|
||||
with vim_module._with('buffer', os.path.join(os.path.dirname(__file__), 'empty')) as segment_info:
|
||||
with vim_module._with(
|
||||
'buffer',
|
||||
os.path.join(
|
||||
os.path.dirname(os.path.dirname(__file__)), 'empty')
|
||||
) as segment_info:
|
||||
self.assertEqual(self.vim.file_size(pl=pl, segment_info=segment_info), '0 B')
|
||||
|
||||
def test_file_opts(self):
|
||||
@ -1596,7 +1603,7 @@ class TestVim(TestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), 'path')))
|
||||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'vim_sys_path')))
|
||||
from powerline.segments import vim
|
||||
cls.vim = vim
|
||||
from powerline.segments.common import vcs
|
||||
@ -1661,7 +1668,7 @@ def setUpModule():
|
||||
global __file__
|
||||
old_cwd = os.getcwd()
|
||||
__file__ = os.path.abspath(__file__)
|
||||
os.chdir(os.path.dirname(__file__))
|
||||
os.chdir(os.path.dirname(os.path.dirname(__file__)))
|
||||
|
||||
|
||||
def tearDownModule():
|
||||
@ -1670,5 +1677,5 @@ def tearDownModule():
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from tests import main
|
||||
from tests.modules import main
|
||||
main()
|
@ -6,10 +6,10 @@ import sys
|
||||
|
||||
from functools import partial
|
||||
|
||||
import tests.vim as vim_module
|
||||
import tests.modules.vim as vim_module
|
||||
|
||||
from tests.lib import Pl
|
||||
from tests import TestCase
|
||||
from tests.modules.lib import Pl
|
||||
from tests.modules import TestCase
|
||||
|
||||
|
||||
class TestVim(TestCase):
|
||||
@ -22,7 +22,7 @@ class TestVim(TestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), 'path')))
|
||||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'vim_sys_path')))
|
||||
from powerline.selectors import vim
|
||||
cls.vim = vim
|
||||
|
||||
@ -32,5 +32,5 @@ class TestVim(TestCase):
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from tests import main
|
||||
from tests.modules import main
|
||||
main()
|
@ -13,7 +13,7 @@ from powerline.lib.watcher.uv import UvNotFound
|
||||
from powerline import get_fallback_logger
|
||||
from powerline.lib.monotonic import monotonic
|
||||
|
||||
from tests import TestCase, SkipTest
|
||||
from tests.modules import TestCase, SkipTest
|
||||
|
||||
|
||||
INOTIFY_DIR = 'inotify' + os.path.basename(os.environ.get('PYTHON', ''))
|
||||
@ -231,7 +231,7 @@ old_cwd = None
|
||||
def setUpModule():
|
||||
global old_cwd
|
||||
old_cwd = os.getcwd()
|
||||
os.chdir(os.path.dirname(__file__))
|
||||
os.chdir(os.path.dirname(os.path.dirname(__file__)))
|
||||
os.mkdir(INOTIFY_DIR)
|
||||
|
||||
|
||||
@ -241,5 +241,5 @@ def tearDownModule():
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from tests import main
|
||||
from tests.modules import main
|
||||
main()
|
@ -1,7 +0,0 @@
|
||||
print ('cd ' + 'tests/shell/3rd') # Start of the test marker
|
||||
bool 42
|
||||
bool 44
|
||||
class Test(object):
|
||||
pass
|
||||
|
||||
exit
|
@ -32,7 +32,7 @@ ABOVE_FULL='[{
|
||||
set_theme default_leftonly
|
||||
export VIRTUAL_ENV=
|
||||
source powerline/bindings/bash/powerline.sh
|
||||
cd tests/shell/3rd
|
||||
cd "$TEST_ROOT"/3rd
|
||||
cd .git
|
||||
cd ..
|
||||
VIRTUAL_ENV="$HOME/.virtenvs/some-virtual-environment"
|
@ -8,7 +8,7 @@ set_theme_option default_leftonly.segment_data.hostname.args.only_if_ssh false
|
||||
set_theme default_leftonly
|
||||
. powerline/bindings/shell/powerline.sh
|
||||
export VIRTUAL_ENV=
|
||||
cd tests/shell/3rd
|
||||
cd "$TEST_ROOT"/3rd
|
||||
cd .git
|
||||
cd ..
|
||||
VIRTUAL_ENV="$HOME/.virtenvs/some-virtual-environment"
|
@ -8,7 +8,7 @@ set_theme_option default_leftonly.segment_data.hostname.args.only_if_ssh false
|
||||
set_theme default_leftonly
|
||||
. powerline/bindings/shell/powerline.sh
|
||||
export VIRTUAL_ENV=
|
||||
cd tests/shell/3rd
|
||||
cd "$TEST_ROOT"/3rd
|
||||
cd .git
|
||||
cd ..
|
||||
VIRTUAL_ENV="$HOME/.virtenvs/some-virtual-environment"
|
@ -37,7 +37,7 @@ while jobs | grep fish_update_completions
|
||||
end
|
||||
powerline-setup
|
||||
setenv VIRTUAL_ENV
|
||||
cd tests/shell/3rd
|
||||
cd "$TEST_ROOT"/3rd
|
||||
cd .git
|
||||
cd ..
|
||||
setenv VIRTUAL_ENV "$HOME/.virtenvs/some-virtual-environment"
|
7
tests/test_shells/inputs/ipython
Normal file
7
tests/test_shells/inputs/ipython
Normal file
@ -0,0 +1,7 @@
|
||||
print ('cd ' + '"$TEST_ROOT"/3rd') # Start of the test marker
|
||||
bool 42
|
||||
bool 44
|
||||
class Test(object):
|
||||
pass
|
||||
|
||||
exit
|
@ -8,7 +8,7 @@ set_theme default_leftonly
|
||||
set_theme_option default_leftonly.segment_data.hostname.args.only_if_ssh false
|
||||
. powerline/bindings/shell/powerline.sh
|
||||
export VIRTUAL_ENV=
|
||||
cd tests/shell/3rd
|
||||
cd "$TEST_ROOT"/3rd
|
||||
cd .git
|
||||
cd ..
|
||||
VIRTUAL_ENV="$HOME/.virtenvs/some-virtual-environment"
|
@ -5,7 +5,8 @@ set_theme_option default_leftonly.segment_data.hostname.args.only_if_ssh false
|
||||
POWERLINE_CONFIG_OVERRIDES = 'ext.shell.theme=default_leftonly'
|
||||
. powerline/bindings/rc/powerline.rc
|
||||
VIRTUAL_ENV = ()
|
||||
cd tests/shell/3rd
|
||||
cd $TEST_ROOT/3rd
|
||||
true cd "$TEST_ROOT"/3rd # Test start marker
|
||||
cd .git
|
||||
cd ..
|
||||
VIRTUAL_ENV = '/home/foo/.virtenvs/some-virtual-environment'
|
@ -2,7 +2,7 @@ setenv POWERLINE_THEME_OVERRIDES "default_leftonly.segment_data.hostname.args.on
|
||||
setenv POWERLINE_CONFIG_OVERRIDES "ext.shell.theme=default_leftonly"
|
||||
source powerline/bindings/tcsh/powerline.tcsh
|
||||
unsetenv VIRTUAL_ENV
|
||||
cd tests/shell/3rd
|
||||
cd "$TEST_ROOT"/3rd
|
||||
cd .git
|
||||
cd ..
|
||||
setenv VIRTUAL_ENV "/home/foo/.virtenvs/some-virtual-environment"
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user