1
0
Fork 0
mirror of https://github.com/borgbackup/borg.git synced 2025-01-01 04:37:34 +00:00

Fix broken --progress ellipsis for double-cell paths

This commit is contained in:
Marian Beermann 2016-09-27 11:35:45 +02:00
parent 8164524d99
commit 9cef0a9ed8
3 changed files with 51 additions and 2 deletions

View file

@ -28,7 +28,7 @@
from .helpers import uid2user, user2uid, gid2group, group2gid
from .helpers import parse_timestamp, to_localtime
from .helpers import format_time, format_timedelta, format_file_size, file_status
from .helpers import safe_encode, safe_decode, make_path_safe, remove_surrogates
from .helpers import safe_encode, safe_decode, make_path_safe, remove_surrogates, swidth_slice
from .helpers import decode_dict, StableDict
from .helpers import int_to_bigint, bigint_to_int, bin_to_hex
from .helpers import ProgressIndicatorPercent, log_multi
@ -94,7 +94,8 @@ def show_progress(self, item=None, final=False, stream=None, dt=None):
space = columns - swidth(msg)
if space >= 8:
if space < swidth('...') + swidth(path):
path = '%s...%s' % (path[:(space // 2) - swidth('...')], path[-space // 2:])
path = '%s...%s' % (swidth_slice(path, space // 2 - swidth('...')),
swidth_slice(path, -space // 2))
space -= swidth(path)
msg += path + ' ' * space
else:

View file

@ -1696,3 +1696,29 @@ def write(self, s):
except OSError:
pass
return len(s)
def swidth_slice(string, max_width):
"""
Return a slice of *max_width* cells from *string*.
Negative *max_width* means from the end of string.
*max_width* is in units of character cells (or "columns").
Latin characters are usually one cell wide, many CJK characters are two cells wide.
"""
from .platform import swidth
reverse = max_width < 0
max_width = abs(max_width)
if reverse:
string = reversed(string)
current_swidth = 0
result = []
for character in string:
current_swidth += swidth(character)
if current_swidth > max_width:
break
result.append(character)
if reverse:
result.reverse()
return ''.join(result)

View file

@ -9,6 +9,7 @@
import msgpack
import msgpack.fallback
from .. import platform
from ..helpers import Location
from ..helpers import Buffer
from ..helpers import partial_format, format_file_size, parse_file_size, format_timedelta, format_line, PlaceholderError, replace_placeholders
@ -23,6 +24,7 @@
from ..helpers import load_excludes
from ..helpers import CompressionSpec, CompressionDecider1, CompressionDecider2
from ..helpers import parse_pattern, PatternMatcher, RegexPattern, PathPrefixPattern, FnmatchPattern, ShellPattern
from ..helpers import swidth_slice
from . import BaseTestCase, environment_variable, FakeInputs
@ -1041,3 +1043,23 @@ def test_replace_placeholders():
now = datetime.now()
assert " " not in replace_placeholders('{now}')
assert int(replace_placeholders('{now:%Y}')) == now.year
def working_swidth():
return platform.swidth('') == 2
@pytest.mark.skipif(not working_swidth(), reason='swidth() is not supported / active')
def test_swidth_slice():
string = '나윤선나윤선나윤선나윤선나윤선'
assert swidth_slice(string, 1) == ''
assert swidth_slice(string, -1) == ''
assert swidth_slice(string, 4) == '나윤'
assert swidth_slice(string, -4) == '윤선'
@pytest.mark.skipif(not working_swidth(), reason='swidth() is not supported / active')
def test_swidth_slice_mixed_characters():
string = '나윤a선나윤선나윤선나윤선나윤선'
assert swidth_slice(string, 5) == '나윤a'
assert swidth_slice(string, 6) == '나윤a'