@@ -60,13 +60,33 @@ function MatchListing:icon_getter()
6060 end
6161end
6262
63+ local function str_prefix (str , length )
64+ local trim = 0
65+ while vim .fn .strwidth (str ) > length do
66+ -- For typical strings, we'll do one `sub()`. For the degenerate case with
67+ -- many multi-cell glyphs, we'll loop as many times as needed.
68+ trim = trim + 1
69+ str = sub (str , 1 , length - trim )
70+ end
71+ return str
72+ end
73+
74+ local function str_suffix (str , length )
75+ local trim = 0
76+ while vim .fn .strwidth (str ) > length do
77+ -- For typical strings, we'll do one `sub()`. For the degenerate case with
78+ -- many multi-cell glyphs, we'll loop as many times as needed.
79+ trim = trim + 1
80+ str = sub (str , - (length - trim ))
81+ end
82+ return str
83+ end
84+
6385local format_line = function (line , width , selected , truncate , get_icon )
6486 local prefix = selected and ' > ' or ' '
6587
6688 local icon = get_icon and get_icon (line )
67- local icon_length = 0
6889 if icon then
69- icon_length = vim .fn .strwidth (icon .. ' ' )
7090 prefix = prefix .. icon .. ' '
7191 end
7292
@@ -83,15 +103,15 @@ local format_line = function(line, width, selected, truncate, get_icon)
83103
84104 if vim .fn .strwidth (prefix .. line ) <= width then
85105 -- Line fits without trimming.
86- elseif vim .fn .strwidth (line ) < ( 5 + icon_length ) then
106+ elseif vim .fn .strwidth (prefix .. line ) < 5 then
87107 -- Line is so short that adding an ellipsis is not practical.
88108 elseif truncate == true or truncate == ' true' or truncate == ' middle' then
89109 local half = math.floor ((width - 2 ) / 2 )
90- local left = sub (line , 1 , half - 3 + width % 2 )
91- local right = sub (line , 3 - half )
110+ local left = str_prefix (line , half - 2 + width % 2 )
111+ local right = str_suffix (line , half - 2 )
92112 line = left .. ' … ' .. right
93113 elseif truncate == ' beginning' then
94- line = ' …' .. sub (line , - width + vim .fn .strwidth (prefix ) + 1 )
114+ line = ' …' .. str_suffix (line , width - vim .fn .strwidth (prefix ))
95115 elseif truncate == false or truncate == ' false' or truncate == ' end' then
96116 -- Fall through; truncation will happen before the final `return`.
97117 end
@@ -108,14 +128,7 @@ local format_line = function(line, width, selected, truncate, get_icon)
108128 end
109129
110130 -- Trim to make sure we never wrap.
111- local trim = 0
112- while vim .fn .strwidth (line ) > width do
113- -- For typical strings, we'll do one `sub()`. For the degenerate case with
114- -- many multi-cell glyphs, we'll loop as many times as needed.
115- trim = trim + 1
116- line = sub (line , 1 , width - trim )
117- end
118- return line
131+ return str_prefix (line , width )
119132end
120133
121134function MatchListing :select (selected )
0 commit comments