Skip to content

Commit ce8f7fa

Browse files
authored
feat: allow truncation of strings from left (#236)
* feat: allow truncation of strings from left * test: additional tests for truncations from the left
1 parent e7c5c9f commit ce8f7fa

2 files changed

Lines changed: 43 additions & 19 deletions

File tree

lua/plenary/strings.lua

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,25 +92,33 @@ M.strcharpart = (function()
9292
end
9393
end)()
9494

95-
M.truncate = function(str, len, dots)
95+
M.truncate = function(str, len, dots, direction)
9696
str = tostring(str) -- We need to make sure its an actually a string and not a number
9797
dots = dots or ""
98+
direction = direction or 1
9899
if M.strdisplaywidth(str) <= len then
99100
return str
100101
end
101-
local start = 0
102+
local start = direction > 0 and 0 or str:len()
102103
local current = 0
103104
local result = ""
104105
local len_of_dots = M.strdisplaywidth(dots)
106+
local concat = function(a, b, dir)
107+
if dir > 0 then
108+
return a .. b
109+
else
110+
return b .. a
111+
end
112+
end
105113
while true do
106114
local part = M.strcharpart(str, start, 1)
107115
current = current + M.strdisplaywidth(part)
108116
if (current + len_of_dots) > len then
109-
result = result .. dots
117+
result = concat(result, dots, direction)
110118
break
111119
end
112-
result = result .. part
113-
start = start + 1
120+
result = concat(result, part, direction)
121+
start = start + direction
114122
end
115123
return result
116124
end

tests/plenary/strings_spec.lua

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -46,23 +46,39 @@ describe("strings", function()
4646

4747
describe("truncate", function()
4848
for _, case in ipairs {
49-
{ args = { "abcde", 6 }, expected = { single = "abcde", double = "abcde" } },
50-
{ args = { "abcde", 5 }, expected = { single = "abcde", double = "abcde" } },
51-
{ args = { "abcde", 4 }, expected = { single = "abc…", double = "ab…" } },
52-
{ args = { "アイウエオ", 11 }, expected = { single = "アイウエオ", double = "アイウエオ" } },
53-
{ args = { "アイウエオ", 10 }, expected = { single = "アイウエオ", double = "アイウエオ" } },
54-
{ args = { "アイウエオ", 9 }, expected = { single = "アイウエ…", double = "アイウ…" } },
55-
{ args = { "アイウエオ", 8 }, expected = { single = "アイウ…", double = "アイウ…" } },
56-
{ args = { "├─┤", 7 }, expected = { single = "├─┤", double = "├─┤" } },
57-
{ args = { "├─┤", 6 }, expected = { single = "├─┤", double = "├─┤" } },
58-
{ args = { "├─┤", 5 }, expected = { single = "├─┤", double = "├…" } },
59-
{ args = { "├─┤", 4 }, expected = { single = "├─┤", double = "├…" } },
60-
{ args = { "├─┤", 3 }, expected = { single = "├─┤", double = "" } },
61-
{ args = { "├─┤", 2 }, expected = { single = "├…", double = "" } },
49+
-- truncations from the right
50+
{ args = { "abcde", 6, nil, 1 }, expected = { single = "abcde", double = "abcde" } },
51+
{ args = { "abcde", 5, nil, 1 }, expected = { single = "abcde", double = "abcde" } },
52+
{ args = { "abcde", 4, nil, 1 }, expected = { single = "abc…", double = "ab…" } },
53+
{ args = { "アイウエオ", 11, nil, 1 }, expected = { single = "アイウエオ", double = "アイウエオ" } },
54+
{ args = { "アイウエオ", 10, nil, 1 }, expected = { single = "アイウエオ", double = "アイウエオ" } },
55+
{ args = { "アイウエオ", 9, nil, 1 }, expected = { single = "アイウエ…", double = "アイウ…" } },
56+
{ args = { "アイウエオ", 8, nil, 1 }, expected = { single = "アイウ…", double = "アイウ…" } },
57+
{ args = { "├─┤", 7, nil, 1 }, expected = { single = "├─┤", double = "├─┤" } },
58+
{ args = { "├─┤", 6, nil, 1 }, expected = { single = "├─┤", double = "├─┤" } },
59+
{ args = { "├─┤", 5, nil, 1 }, expected = { single = "├─┤", double = "├…" } },
60+
{ args = { "├─┤", 4, nil, 1 }, expected = { single = "├─┤", double = "├…" } },
61+
{ args = { "├─┤", 3, nil, 1 }, expected = { single = "├─┤", double = "" } },
62+
{ args = { "├─┤", 2, nil, 1 }, expected = { single = "├…", double = "" } },
63+
-- truncations from the left
64+
{ args = { "abcde", 6, nil, -1 }, expected = { single = "abcde", double = "abcde" } },
65+
{ args = { "abcde", 5, nil, -1 }, expected = { single = "abcde", double = "abcde" } },
66+
{ args = { "abcde", 4, nil, -1 }, expected = { single = "…cde", double = "…de" } },
67+
{ args = { "アイウエオ", 11, nil, -1 }, expected = { single = "アイウエオ", double = "アイウエオ" } },
68+
{ args = { "アイウエオ", 10, nil, -1 }, expected = { single = "アイウエオ", double = "アイウエオ" } },
69+
{ args = { "アイウエオ", 9, nil, -1 }, expected = { single = "…イウエオ", double = "…ウエオ" } },
70+
{ args = { "アイウエオ", 8, nil, -1 }, expected = { single = "…ウエオ", double = "…ウエオ" } },
71+
{ args = { "├─┤", 7, nil, -1 }, expected = { single = "├─┤", double = "├─┤" } },
72+
{ args = { "├─┤", 6, nil, -1 }, expected = { single = "├─┤", double = "├─┤" } },
73+
{ args = { "├─┤", 5, nil, -1 }, expected = { single = "├─┤", double = "…┤" } },
74+
{ args = { "├─┤", 4, nil, -1 }, expected = { single = "├─┤", double = "…┤" } },
75+
{ args = { "├─┤", 3, nil, -1 }, expected = { single = "├─┤", double = "" } },
76+
{ args = { "├─┤", 2, nil, -1 }, expected = { single = "…┤", double = "" } },
6277
} do
6378
for _, ambiwidth in ipairs { "single", "double" } do
64-
local msg = ("ambiwidth = %s, [%s, %d] -> %s"):format(
79+
local msg = ("ambiwidth = %s, direction = %s, [%s, %d] -> %s"):format(
6580
ambiwidth,
81+
(case.args[4] > 0) and "right" or "left",
6682
case.args[1],
6783
case.args[2],
6884
case.expected[ambiwidth]

0 commit comments

Comments
 (0)