Skip to content

Commit b5fd5ca

Browse files
authored
feat: truncate strings from the middle (#276)
1 parent 68cf987 commit b5fd5ca

File tree

2 files changed

+45
-7
lines changed

2 files changed

+45
-7
lines changed

lua/plenary/strings.lua

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,7 @@ M.strcharpart = (function()
9292
end
9393
end)()
9494

95-
M.truncate = function(str, len, dots, direction)
96-
str = tostring(str) -- We need to make sure its an actually a string and not a number
97-
dots = dots or ""
98-
direction = direction or 1
95+
local truncate = function(str, len, dots, direction)
9996
if M.strdisplaywidth(str) <= len then
10097
return str
10198
end
@@ -123,6 +120,24 @@ M.truncate = function(str, len, dots, direction)
123120
return result
124121
end
125122

123+
M.truncate = function(str, len, dots, direction)
124+
str = tostring(str) -- We need to make sure its an actually a string and not a number
125+
dots = dots or ""
126+
direction = direction or 1
127+
if direction ~= 0 then
128+
return truncate(str, len, dots, direction)
129+
else
130+
if M.strdisplaywidth(str) <= len then
131+
return str
132+
end
133+
local len1 = math.floor((len + M.strdisplaywidth(dots)) / 2)
134+
local s1 = truncate(str, len1, dots, 1)
135+
local len2 = len - M.strdisplaywidth(s1) + M.strdisplaywidth(dots)
136+
local s2 = truncate(str, len2, dots, -1)
137+
return s1 .. s2:sub(dots:len() + 1)
138+
end
139+
end
140+
126141
M.align_str = function(string, width, right_justify)
127142
local str_len = M.strdisplaywidth(string)
128143
return right_justify and string.rep(" ", width - str_len) .. string or string .. string.rep(" ", width - str_len)

tests/plenary/strings_spec.lua

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,11 @@ describe("strings", function()
7171
{ args = { "abcde", 5, nil, -1 }, expected = { single = "abcde", double = "abcde" } },
7272
{ args = { "abcde", 4, nil, -1 }, expected = { single = "…cde", double = "…de" } },
7373
{
74-
args = { "アイウエオ", 11, nil, 1 },
74+
args = { "アイウエオ", 11, nil, -1 },
7575
expected = { single = "アイウエオ", double = "アイウエオ" },
7676
},
7777
{
78-
args = { "アイウエオ", 10, nil, 1 },
78+
args = { "アイウエオ", 10, nil, -1 },
7979
expected = { single = "アイウエオ", double = "アイウエオ" },
8080
},
8181
{
@@ -89,11 +89,34 @@ describe("strings", function()
8989
{ args = { "├─┤", 4, nil, -1 }, expected = { single = "├─┤", double = "…┤" } },
9090
{ args = { "├─┤", 3, nil, -1 }, expected = { single = "├─┤", double = "" } },
9191
{ args = { "├─┤", 2, nil, -1 }, expected = { single = "…┤", double = "" } },
92+
-- truncations from the middle
93+
{ args = { "abcde", 6, nil, 0 }, expected = { single = "abcde", double = "abcde" } },
94+
{ args = { "abcde", 5, nil, 0 }, expected = { single = "abcde", double = "abcde" } },
95+
{ args = { "abcde", 4, nil, 0 }, expected = { single = "a…de", double = "a…e" } },
96+
{
97+
args = { "アイウエオ", 11, nil, 0 },
98+
expected = { single = "アイウエオ", double = "アイウエオ" },
99+
},
100+
{
101+
args = { "アイウエオ", 10, nil, 0 },
102+
expected = { single = "アイウエオ", double = "アイウエオ" },
103+
},
104+
{
105+
args = { "アイウエオ", 9, nil, 0 },
106+
expected = { single = "アイ…エオ", double = "ア…エオ" },
107+
},
108+
{ args = { "アイウエオ", 8, nil, 0 }, expected = { single = "ア…エオ", double = "ア…エオ" } },
109+
{ args = { "├─┤", 7, nil, 0 }, expected = { single = "├─┤", double = "├─┤" } },
110+
{ args = { "├─┤", 6, nil, 0 }, expected = { single = "├─┤", double = "├─┤" } },
111+
{ args = { "├─┤", 5, nil, 0 }, expected = { single = "├─┤", double = "…┤" } },
112+
{ args = { "├─┤", 4, nil, 0 }, expected = { single = "├─┤", double = "…┤" } },
113+
{ args = { "├─┤", 3, nil, 0 }, expected = { single = "├─┤", double = "" } },
114+
{ args = { "├─┤", 2, nil, 0 }, expected = { single = "…┤", double = "" } },
92115
} do
93116
for _, ambiwidth in ipairs { "single", "double" } do
94117
local msg = ("ambiwidth = %s, direction = %s, [%s, %d] -> %s"):format(
95118
ambiwidth,
96-
(case.args[4] > 0) and "right" or "left",
119+
(case.args[4] > 0) and "right" or (case.args[4] < 0) and "left" or "middle",
97120
case.args[1],
98121
case.args[2],
99122
case.expected[ambiwidth]

0 commit comments

Comments
 (0)