mirror of
https://github.com/powerline/powerline.git
synced 2025-07-24 06:15:41 +02:00
commit
1d602204b1
@ -1,2 +1,3 @@
|
|||||||
# Starting from tmux-2.1 escaping of dollar signs inside #() is harmful
|
# 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"
|
||||||
|
@ -4,34 +4,68 @@ from __future__ import (unicode_literals, division, absolute_import, print_funct
|
|||||||
import threading
|
import threading
|
||||||
|
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
from itertools import groupby
|
||||||
|
from signal import SIGKILL
|
||||||
|
|
||||||
import pexpect
|
import pexpect
|
||||||
|
|
||||||
from tests.lib.vterm import VTerm
|
from tests.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):
|
class ExpectProcess(threading.Thread):
|
||||||
def __init__(self, lib, rows, cols, cmd, args, cwd=None, env=None):
|
def __init__(self, lib, dim, cmd, args, cwd=None, env=None):
|
||||||
super(ExpectProcess, self).__init__()
|
super(ExpectProcess, self).__init__()
|
||||||
self.vterm = VTerm(lib, rows, cols)
|
self.vterm = VTerm(lib, dim)
|
||||||
self.lock = threading.Lock()
|
self.lock = threading.Lock()
|
||||||
self.rows = rows
|
self.dim = Dimensions(*dim)
|
||||||
self.cols = cols
|
|
||||||
self.cmd = cmd
|
self.cmd = cmd
|
||||||
self.args = args
|
self.args = args
|
||||||
self.cwd = cwd
|
self.cwd = cwd
|
||||||
self.env = env
|
self.env = env
|
||||||
self.buffer = []
|
self.buffer = []
|
||||||
self.child_lock = threading.Lock()
|
self.child_lock = threading.Lock()
|
||||||
|
self.shutdown_event = threading.Event()
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
child = pexpect.spawn(self.cmd, self.args, cwd=self.cwd, env=self.env)
|
child = pexpect.spawn(self.cmd, self.args, cwd=self.cwd, env=self.env)
|
||||||
sleep(0.5)
|
sleep(0.5)
|
||||||
child.setwinsize(self.rows, self.cols)
|
child.setwinsize(self.dim.rows, self.dim.cols)
|
||||||
sleep(0.5)
|
sleep(0.5)
|
||||||
self.child = child
|
self.child = child
|
||||||
status = None
|
status = None
|
||||||
while status is None:
|
while status is None and not self.shutdown_event.is_set():
|
||||||
try:
|
try:
|
||||||
with self.child_lock:
|
with self.child_lock:
|
||||||
s = child.read_nonblocking(size=1024, timeout=0)
|
s = child.read_nonblocking(size=1024, timeout=0)
|
||||||
@ -45,12 +79,17 @@ class ExpectProcess(threading.Thread):
|
|||||||
self.vterm.push(s)
|
self.vterm.push(s)
|
||||||
self.buffer.append(s)
|
self.buffer.append(s)
|
||||||
|
|
||||||
def resize(self, rows, cols):
|
if status is None:
|
||||||
|
child.kill(SIGKILL)
|
||||||
|
|
||||||
|
def kill(self):
|
||||||
|
self.shutdown_event.set()
|
||||||
|
|
||||||
|
def resize(self, dim):
|
||||||
with self.child_lock:
|
with self.child_lock:
|
||||||
self.rows = rows
|
self.dim = Dimensions(*dim)
|
||||||
self.cols = cols
|
self.child.setwinsize(self.dim.rows, self.dim.cols)
|
||||||
self.child.setwinsize(rows, cols)
|
self.vterm.resize(self.dim)
|
||||||
self.vterm.resize(rows, cols)
|
|
||||||
|
|
||||||
def __getitem__(self, position):
|
def __getitem__(self, position):
|
||||||
with self.lock:
|
with self.lock:
|
||||||
@ -65,3 +104,34 @@ class ExpectProcess(threading.Thread):
|
|||||||
def send(self, data):
|
def send(self, data):
|
||||||
with self.child_lock:
|
with self.child_lock:
|
||||||
self.child.send(data)
|
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
|
||||||
|
@ -3,9 +3,14 @@ from __future__ import (unicode_literals, division, absolute_import, print_funct
|
|||||||
|
|
||||||
import ctypes
|
import ctypes
|
||||||
|
|
||||||
|
from collections import namedtuple
|
||||||
|
|
||||||
from powerline.lib.unicode import unicode, unichr, tointiter
|
from powerline.lib.unicode import unicode, unichr, tointiter
|
||||||
|
|
||||||
|
|
||||||
|
Dimensions = namedtuple('Dimensions', ('rows', 'cols'))
|
||||||
|
|
||||||
|
|
||||||
class CTypesFunction(object):
|
class CTypesFunction(object):
|
||||||
def __init__(self, library, name, rettype, args):
|
def __init__(self, library, name, rettype, args):
|
||||||
self.name = name
|
self.name = name
|
||||||
@ -165,9 +170,9 @@ class VTermScreen(object):
|
|||||||
|
|
||||||
|
|
||||||
class VTerm(object):
|
class VTerm(object):
|
||||||
def __init__(self, lib, rows, cols):
|
def __init__(self, lib, dim):
|
||||||
self.functions = get_functions(lib)
|
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 = VTermScreen(self.functions, self.functions.vterm_obtain_screen(self.vt))
|
||||||
self.vtscreen.reset(True)
|
self.vtscreen.reset(True)
|
||||||
|
|
||||||
@ -176,8 +181,8 @@ class VTerm(object):
|
|||||||
data = data.encode('utf-8')
|
data = data.encode('utf-8')
|
||||||
return self.functions.vterm_input_write(self.vt, data, len(data))
|
return self.functions.vterm_input_write(self.vt, data, len(data))
|
||||||
|
|
||||||
def resize(self, rows, cols):
|
def resize(self, dim):
|
||||||
self.functions.vterm_set_size(self.vt, rows, cols)
|
self.functions.vterm_set_size(self.vt, dim.rows, dim.cols)
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
try:
|
try:
|
||||||
|
@ -4,23 +4,29 @@ from __future__ import (unicode_literals, division, absolute_import, print_funct
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import json
|
||||||
|
|
||||||
from time import sleep
|
from time import sleep
|
||||||
from subprocess import check_call
|
from subprocess import check_call
|
||||||
from itertools import groupby
|
|
||||||
from difflib import ndiff
|
from difflib import ndiff
|
||||||
from glob import glob1
|
from glob import glob1
|
||||||
|
from traceback import print_exc
|
||||||
|
|
||||||
from powerline.lib.unicode import u
|
from powerline.lib.unicode import u
|
||||||
|
from powerline.lib.dict import updated
|
||||||
from powerline.bindings.tmux import get_tmux_version
|
from powerline.bindings.tmux import get_tmux_version
|
||||||
from powerline import get_fallback_logger
|
from powerline import get_fallback_logger
|
||||||
|
|
||||||
from tests.lib.terminal import ExpectProcess
|
from tests.lib.terminal import ExpectProcess, MutableDimensions
|
||||||
|
|
||||||
|
|
||||||
VTERM_TEST_DIR = os.path.abspath('tests/vterm_tmux')
|
VTERM_TEST_DIR = os.path.abspath('tests/vterm_tmux')
|
||||||
|
|
||||||
|
|
||||||
|
def convert_expected_result(p, expected_result):
|
||||||
|
return p.get_highlighted_text(expected_result, {})
|
||||||
|
|
||||||
|
|
||||||
def cell_properties_key_to_shell_escape(cell_properties_key):
|
def cell_properties_key_to_shell_escape(cell_properties_key):
|
||||||
fg, bg, bold, underline, italic = cell_properties_key
|
fg, bg, bold, underline, italic = cell_properties_key
|
||||||
return('\x1b[38;2;{0};48;2;{1}{bold}{underline}{italic}m'.format(
|
return('\x1b[38;2;{0};48;2;{1}{bold}{underline}{italic}m'.format(
|
||||||
@ -32,75 +38,61 @@ def cell_properties_key_to_shell_escape(cell_properties_key):
|
|||||||
))
|
))
|
||||||
|
|
||||||
|
|
||||||
def test_expected_result(p, expected_result, cols, rows, print_logs):
|
def tmux_logs_iter(test_dir):
|
||||||
last_line = []
|
for tail in glob1(test_dir, '*.log'):
|
||||||
for col in range(cols):
|
yield os.path.join(test_dir, tail)
|
||||||
last_line.append(p[rows - 1, col])
|
|
||||||
|
|
||||||
|
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 fp:
|
||||||
|
for line in fp:
|
||||||
|
sys.stdout.write(line)
|
||||||
|
os.unlink(f)
|
||||||
|
|
||||||
|
|
||||||
|
def test_expected_result(p, expected_result, last_attempt, last_attempt_cb):
|
||||||
|
expected_text, attrs = expected_result
|
||||||
attempts = 3
|
attempts = 3
|
||||||
result = None
|
result = None
|
||||||
while attempts:
|
while attempts:
|
||||||
result = tuple((
|
actual_text, all_attrs = p.get_row(p.dim.rows - 1, attrs)
|
||||||
(key, ''.join((i.text for i in subline)))
|
if actual_text == expected_text:
|
||||||
for key, subline in groupby(last_line, lambda i: i.cell_properties_key)
|
|
||||||
))
|
|
||||||
if result == expected_result:
|
|
||||||
return True
|
return True
|
||||||
attempts -= 1
|
attempts -= 1
|
||||||
print('Actual result does not match expected. Attempts left: {0}.'.format(attempts))
|
print('Actual result does not match expected. Attempts left: {0}.'.format(attempts))
|
||||||
sleep(2)
|
sleep(2)
|
||||||
print('Result:')
|
print('Result:')
|
||||||
shesc_result = ''.join((
|
print(actual_text)
|
||||||
'{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:')
|
print('Expected:')
|
||||||
shesc_expected_result = ''.join((
|
print(expected_text)
|
||||||
'{0}{1}\x1b[m'.format(cell_properties_key_to_shell_escape(key), text)
|
print('Attributes:')
|
||||||
for key, text in expected_result
|
print(all_attrs)
|
||||||
))
|
|
||||||
print(shesc_expected_result)
|
|
||||||
p.send(b'powerline-config tmux setup\n')
|
|
||||||
sleep(5)
|
|
||||||
print('Screen:')
|
print('Screen:')
|
||||||
screen = []
|
screen, screen_attrs = p.get_screen(attrs)
|
||||||
for i in range(rows):
|
print(screen)
|
||||||
screen.append([])
|
print(screen_attrs)
|
||||||
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('_' * 80)
|
||||||
print('Diff:')
|
print('Diff:')
|
||||||
print('=' * 80)
|
print('=' * 80)
|
||||||
print(''.join((u(line) for line in ndiff([a], [b]))))
|
print(''.join((u(line) for line in ndiff([actual_text], [expected_text]))))
|
||||||
if print_logs:
|
if last_attempt:
|
||||||
for f in glob1(VTERM_TEST_DIR, '*.log'):
|
last_attempt_cb()
|
||||||
print('_' * 80)
|
|
||||||
print(os.path.basename(f) + ':')
|
|
||||||
print('=' * 80)
|
|
||||||
with open(f, 'r') as F:
|
|
||||||
for line in F:
|
|
||||||
sys.stdout.write(line)
|
|
||||||
os.unlink(f)
|
|
||||||
return False
|
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:
|
if tmux_version >= (2, 0) and expected_result_2_0:
|
||||||
return expected_result_2_0
|
return expected_result_2_0
|
||||||
elif tmux_version >= (1, 8) and expected_result_new:
|
elif tmux_version >= (1, 8) and expected_result_1_8:
|
||||||
return expected_result_new
|
return expected_result_1_8
|
||||||
elif tmux_version >= (1, 7) and expected_result_1_7:
|
elif tmux_version >= (1, 7) and expected_result_1_7:
|
||||||
return expected_result_1_7
|
return expected_result_1_7
|
||||||
else:
|
else:
|
||||||
@ -109,9 +101,6 @@ def get_expected_result(tmux_version, expected_result_old, expected_result_1_7=N
|
|||||||
|
|
||||||
def main(attempts=3):
|
def main(attempts=3):
|
||||||
vterm_path = os.path.join(VTERM_TEST_DIR, 'path')
|
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')
|
tmux_exe = os.path.join(vterm_path, 'tmux')
|
||||||
|
|
||||||
@ -120,200 +109,232 @@ def main(attempts=3):
|
|||||||
else:
|
else:
|
||||||
lib = os.environ.get('POWERLINE_LIBVTERM', 'libvterm.so')
|
lib = os.environ.get('POWERLINE_LIBVTERM', 'libvterm.so')
|
||||||
|
|
||||||
|
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': ';'.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'),
|
||||||
|
)
|
||||||
|
)),
|
||||||
|
'LD_LIBRARY_PATH': os.environ.get('LD_LIBRARY_PATH', ''),
|
||||||
|
'PYTHONPATH': os.environ.get('PYTHONPATH', ''),
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
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',
|
||||||
|
}
|
||||||
|
expected_results = (
|
||||||
|
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,
|
||||||
|
})),
|
||||||
|
),
|
||||||
|
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,
|
||||||
|
})),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
def prepare_test_1():
|
||||||
|
sleep(5)
|
||||||
|
|
||||||
|
def prepare_test_2():
|
||||||
|
dim.cols = 40
|
||||||
|
p.resize(dim)
|
||||||
|
sleep(5)
|
||||||
|
|
||||||
|
test_preps = (
|
||||||
|
prepare_test_1,
|
||||||
|
prepare_test_2,
|
||||||
|
)
|
||||||
|
|
||||||
|
socket_path = os.path.abspath('tmux-socket-{0}'.format(attempts))
|
||||||
|
if os.path.exists(socket_path):
|
||||||
|
os.unlink(socket_path)
|
||||||
|
|
||||||
|
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', conf_file,
|
||||||
|
# Run bash three times
|
||||||
|
'new-session', 'bash --norc --noprofile -i', ';',
|
||||||
|
'new-window', 'bash --norc --noprofile -i', ';',
|
||||||
|
'new-window', 'bash --norc --noprofile -i', ';',
|
||||||
|
]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
p = ExpectProcess(
|
p = ExpectProcess(
|
||||||
lib=lib,
|
lib=lib,
|
||||||
rows=rows,
|
dim=dim,
|
||||||
cols=cols,
|
|
||||||
cmd=tmux_exe,
|
cmd=tmux_exe,
|
||||||
args=[
|
args=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'),
|
|
||||||
# Run bash three times
|
|
||||||
'new-session', 'bash --norc --noprofile -i', ';',
|
|
||||||
'new-window', 'bash --norc --noprofile -i', ';',
|
|
||||||
'new-window', 'bash --norc --noprofile -i', ';',
|
|
||||||
],
|
|
||||||
cwd=VTERM_TEST_DIR,
|
cwd=VTERM_TEST_DIR,
|
||||||
env={
|
env=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', ''),
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
p.start()
|
p.start()
|
||||||
sleep(5)
|
|
||||||
tmux_version = get_tmux_version(get_fallback_logger())
|
ret = True
|
||||||
expected_result = get_expected_result(tmux_version, expected_result_old=(
|
|
||||||
(((0, 0, 0), (243, 243, 243), 1, 0, 0), ' 0 '),
|
for test_prep, expected_result in zip(test_preps, expected_results):
|
||||||
(((243, 243, 243), (11, 11, 11), 0, 0, 0), ' '),
|
test_prep()
|
||||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' S2 string here '),
|
ret = (
|
||||||
(((133, 133, 133), (11, 11, 11), 0, 0, 0), ' 0 '),
|
ret
|
||||||
(((88, 88, 88), (11, 11, 11), 0, 0, 0), '| '),
|
and test_expected_result(p, expected_result, attempts == 0,
|
||||||
(((188, 188, 188), (11, 11, 11), 0, 0, 0), 'bash '),
|
print_tmux_logs)
|
||||||
(((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), '| '),
|
if ret or attempts == 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
|
return ret
|
||||||
finally:
|
finally:
|
||||||
check_call([tmux_exe, '-S', socket_path, 'kill-server'], env={
|
try:
|
||||||
'PATH': vterm_path,
|
check_call([tmux_exe, '-S', socket_path, 'kill-server'], env=env,
|
||||||
'LD_LIBRARY_PATH': os.environ.get('LD_LIBRARY_PATH', ''),
|
cwd=VTERM_TEST_DIR)
|
||||||
}, cwd=VTERM_TEST_DIR)
|
except Exception:
|
||||||
|
print_exc()
|
||||||
|
p.kill()
|
||||||
|
p.join(10)
|
||||||
|
for f in tmux_logs_iter(VTERM_TEST_DIR):
|
||||||
|
os.unlink(f)
|
||||||
|
assert(not p.isAlive())
|
||||||
return main(attempts=(attempts - 1))
|
return main(attempts=(attempts - 1))
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
exit 0
|
|
||||||
. tests/common.sh
|
. tests/common.sh
|
||||||
|
|
||||||
enter_suite tmux
|
enter_suite tmux
|
||||||
|
Loading…
x
Reference in New Issue
Block a user