1
1
--- @class blink.cmp.Component
2
2
--- @field [ number] blink.cmp.Component | string
3
- --- @field fill boolean | nil
4
- --- @field hl_group string | nil
5
- --- @field hl_params table | nil
3
+ --- @field fill ? boolean
4
+ --- @field max_width ? number
5
+ --- @field hl_group ? string
6
+ --- @field hl_params ? table
6
7
7
8
--- @class blink.cmp.RenderedComponentTree
8
9
--- @field text string
9
- --- @field highlights { start : number , stop : number , group : string | nil , params : table | nil } []
10
+ --- @field highlights { start : number , stop : number , group ?: string , params ?: table } []
11
+
12
+ --- @class blink.cmp.StringsBuild
13
+ --- @field text string
14
+ --- @field length number
10
15
11
16
local renderer = {}
12
17
18
+ --- @param text string
19
+ --- @param max_width number
20
+ --- @return string
21
+ function renderer .truncate_text (text , max_width )
22
+ if vim .api .nvim_strwidth (text ) > max_width then
23
+ return vim .fn .strcharpart (text , 0 , max_width ) .. ' …'
24
+ else
25
+ return text
26
+ end
27
+ end
28
+
13
29
--- Draws the highlights for the rendered component tree
14
30
--- as ephemeral extmarks
15
31
--- @param rendered blink.cmp.RenderedComponentTree
@@ -25,101 +41,77 @@ function renderer.draw_highlights(rendered, bufnr, ns, line_number)
25
41
end
26
42
end
27
43
28
- --- @param components blink.cmp.Component[]
29
- --- @param length number
30
- --- @return blink.cmp.RenderedComponentTree
31
- function renderer .render (components , length )
32
- local left_of_fill = {}
33
- local right_of_fill = {}
34
- local fill = nil
35
- for _ , component in ipairs (components ) do
36
- if component .fill then
37
- fill = component
38
- else
39
- table.insert (fill and right_of_fill or left_of_fill , component )
40
- end
44
+ --- @param strings string[]
45
+ --- @param max_width ? number
46
+ --- @return blink.cmp.StringsBuild
47
+ function renderer .build_strings (strings , max_width )
48
+ local text = ' '
49
+ for _ , component in ipairs (strings ) do
50
+ text = text .. component
41
51
end
42
52
43
- local left_rendered = renderer .render_components (left_of_fill )
44
- local fill_rendered = renderer .render_components ({ fill })
45
- local right_rendered = renderer .render_components (right_of_fill )
46
-
47
- -- expanad/truncate the fill component to the width
48
- fill_rendered .text = fill_rendered .text
49
- .. string.rep (' ' , length - vim .api .nvim_strwidth (left_rendered .text .. fill_rendered .text .. right_rendered .text ))
50
- fill_rendered .text = fill_rendered .text :sub (
51
- 1 ,
52
- length - vim .api .nvim_strwidth (left_rendered .text ) - vim .api .nvim_strwidth (right_rendered .text )
53
- )
54
-
55
- renderer .add_offset_to_rendered_component (fill_rendered , left_rendered .text :len ())
56
- renderer .add_offset_to_rendered_component (right_rendered , left_rendered .text :len () + fill_rendered .text :len ())
57
-
58
- local highlights = {}
59
- vim .list_extend (highlights , left_rendered .highlights )
60
- vim .list_extend (highlights , fill_rendered .highlights )
61
- vim .list_extend (highlights , right_rendered .highlights )
62
-
63
- return {
64
- text = left_rendered .text .. fill_rendered .text .. right_rendered .text ,
65
- highlights = highlights ,
66
- }
53
+ if max_width then text = renderer .truncate_text (text , max_width ) end
54
+ return { text = text , length = vim .api .nvim_strwidth (text ) }
67
55
end
68
56
69
57
--- @param components (blink.cmp.Component | string )[]
58
+ --- @param lengths number[]
70
59
--- @return blink.cmp.RenderedComponentTree
71
- function renderer .render_components (components )
60
+ function renderer .render (components , lengths )
72
61
local text = ' '
73
62
local offset = 0
74
63
local highlights = {}
75
64
76
- for _ , component in ipairs (components ) do
65
+ for i , component in ipairs (components ) do
77
66
if type (component ) == ' string' then
78
67
text = text .. component
79
68
offset = offset + # component
80
69
else
81
- local rendered = renderer .render_components (component )
70
+ local build = renderer .build_strings (component , component . max_width )
82
71
83
- renderer .add_offset_to_rendered_component (rendered , offset )
84
72
table.insert (highlights , {
85
73
start = offset + 1 ,
86
- stop = offset + # rendered .text + 1 ,
74
+ stop = offset + # build .text + 1 ,
87
75
group = component .hl_group ,
88
76
params = component .hl_params ,
89
77
})
90
- vim .list_extend (highlights , rendered .highlights )
91
78
92
- text = text .. rendered .text
93
- offset = offset + # rendered .text
79
+ text = text .. build .text
80
+ offset = offset + # build .text
81
+
82
+ if component .fill then
83
+ local spaces = lengths [i ] - build .length
84
+ text = text .. string.rep (' ' , spaces )
85
+ offset = offset + spaces
86
+ end
94
87
end
95
88
end
96
89
97
90
return { text = text , highlights = highlights }
98
91
end
99
92
100
- --- @param components blink.cmp.Component[]
93
+ --- @param component blink.cmp.Component | string
101
94
--- @return number
102
- function renderer .get_length (components )
103
- local length = 0
104
- for _ , component in ipairs (components ) do
105
- if type (component ) == ' string' then
106
- length = length + # component
107
- else
108
- length = length + renderer .get_length (component )
109
- end
95
+ function renderer .get_length (component )
96
+ if type (component ) == ' string' then
97
+ return vim .api .nvim_strwidth (component )
98
+ else
99
+ local build = renderer .build_strings (component , component .max_width )
100
+ return build .length
110
101
end
111
- return length
112
102
end
113
103
114
- --- @param arr_of_components blink.cmp.Component[][]
115
- --- @return number
116
- function renderer .get_max_length (arr_of_components )
117
- local max_length = 0
118
- for _ , components in ipairs (arr_of_components ) do
119
- local length = renderer .get_length (components )
120
- if length > max_length then max_length = length end
104
+ --- @param components_list (blink.cmp.Component | string )[][]
105
+ --- @return number[]
106
+ function renderer .get_max_lengths (components_list )
107
+ local lengths = {}
108
+ for _ , components in ipairs (components_list ) do
109
+ for i , component in ipairs (components ) do
110
+ local length = renderer .get_length (component )
111
+ if not lengths [i ] or lengths [i ] < length then lengths [i ] = length end
112
+ end
121
113
end
122
- return max_length
114
+ return lengths
123
115
end
124
116
125
117
--- @param component blink.cmp.RenderedComponentTree
0 commit comments