1
0
Fork 0
mirror of https://github.com/borgbackup/borg.git synced 2025-03-10 06:03:38 +00:00

ProgressIndicatorPercent: fix space computation for wide chars, fixes #3027

needs to use swidth() in case there are wide chars (like CJK)
in the left part of the msg (e.g. an archive name).

(cherry picked from commit 3dd14f4855)
This commit is contained in:
Thomas Waldmann 2023-04-02 19:43:09 +02:00 committed by Sasha Boginsky
parent d1ddd57eaf
commit 21a9458848
2 changed files with 27 additions and 1 deletions

View file

@ -147,10 +147,12 @@ class ProgressIndicatorPercent(ProgressIndicatorBase):
# truncate the last argument, if no space is available
if info is not None:
if not self.json:
from ..platform import swidth # avoid circular import
# no need to truncate if we're not outputting to a terminal
terminal_space = get_terminal_size(fallback=(-1, -1))[0]
if terminal_space != -1:
space = terminal_space - len(self.msg % tuple([pct] + info[:-1] + ['']))
space = terminal_space - swidth(self.msg % tuple([pct] + info[:-1] + ['']))
info[-1] = ellipsis_truncate(info[-1], space)
return self.output(self.msg % tuple([pct] + info), justify=False, info=info)

View file

@ -30,6 +30,7 @@ from ..helpers import popen_with_error_handling
from ..helpers import dash_open
from ..helpers import iter_separated
from ..helpers import eval_escapes
from ..platform import is_win32, swidth
from . import BaseTestCase, FakeInputs
@ -896,6 +897,29 @@ def test_progress_percentage_sameline(capfd, monkeypatch):
assert err == ' ' * 4 + '\r'
@pytest.mark.skipif(is_win32, reason='no working swidth() implementation on this platform')
def test_progress_percentage_widechars(capfd, monkeypatch):
st = 'スター・トレック' # 'startrek' :-)
assert swidth(st) == 16
path = '/カーク船長です。' # 'Captain Kirk'
assert swidth(path) == 17
spaces = ' ' * 4 # to avoid usage of '...'
width = len('100%') + 1 + swidth(st) + 1 + swidth(path) + swidth(spaces)
monkeypatch.setenv('COLUMNS', str(width))
monkeypatch.setenv('LINES', '1')
pi = ProgressIndicatorPercent(100, step=5, start=0, msg=f'%3.0f%% {st} %s')
pi.logger.setLevel('INFO')
pi.show(0, info=[path])
out, err = capfd.readouterr()
assert err == f' 0% {st} {path}{spaces}\r'
pi.show(100, info=[path])
out, err = capfd.readouterr()
assert err == f'100% {st} {path}{spaces}\r'
pi.finish()
out, err = capfd.readouterr()
assert err == ' ' * width + '\r'
def test_progress_percentage_step(capfd, monkeypatch):
# run the test as if it was in a 4x1 terminal
monkeypatch.setenv('COLUMNS', '4')