1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
|
---@tag telescope.pickers.entry_display
---@brief [[
--- Entry Display is used to format each entry shown in the result panel.
---
--- Entry Display create() will give us a function based on the configuration
--- of column widths we pass into it. We then can use this function n times to
--- return a string based on structured input.
---
--- Note that if you call `create()` inside `make_display` it will be called for
--- every single entry. So it is suggested to do this outside of `make_display`
--- for the best performance.
---
--- The create function will use the column widths passed to it in
--- configuration.items. Each item in that table is the number of characters in
--- the column. It's also possible for the final column to not have a fixed
--- width, this will be shown in the configuration as 'remaining = true'.
---
--- An example of this configuration is shown for the buffers picker:
--- <code>
--- local displayer = entry_display.create {
--- separator = " ",
--- items = {
--- { width = opts.bufnr_width },
--- { width = 4 },
--- { width = icon_width },
--- { remaining = true },
--- },
--- }
--- </code>
---
--- This shows 4 columns, the first is defined in the opts as the width we'll
--- use when display_string is the number of the buffer. The second has a fixed
--- width of 4 and the third column's width will be decided by the width of the
--- icons we use. The fourth column will use the remaining space. Finally, we
--- have also defined the separator between each column will be the space " ".
---
--- An example of how the display reference will be used is shown, again for
--- the buffers picker:
--- <code>
--- return displayer {
--- { entry.bufnr, "TelescopeResultsNumber" },
--- { entry.indicator, "TelescopeResultsComment" },
--- { icon, hl_group },
--- display_bufname .. ":" .. entry.lnum,
--- }
--- </code>
---
--- There are two types of values each column can have. Either a simple String
--- or a table containing the String as well as the hl_group.
---
--- The displayer can return values, string and an optional highlights. The string
--- is all the text to be displayed for this entry as a single string. If parts of
--- the string are to be highlighted they will be described in the highlights
--- table.
---
--- For a better understanding of how create() and displayer are used it's best to look
--- at the code in make_entry.lua.
---@brief ]]
local strings = require "plenary.strings"
local state = require "telescope.state"
local resolve = require "telescope.config.resolve"
local entry_display = {}
entry_display.truncate = strings.truncate
entry_display.create = function(configuration)
local generator = {}
for _, v in ipairs(configuration.items) do
if v.width then
local justify = v.right_justify
local width
table.insert(generator, function(item)
if width == nil then
local status = state.get_status(vim.F.if_nil(configuration.prompt_bufnr, vim.api.nvim_get_current_buf()))
local s = {}
s[1] = vim.api.nvim_win_get_width(status.results_win) - #status.picker.selection_caret
s[2] = vim.api.nvim_win_get_height(status.results_win)
width = resolve.resolve_width(v.width)(nil, s[1], s[2])
end
if type(item) == "table" then
return strings.align_str(entry_display.truncate(item[1], width), width, justify), item[2]
else
return strings.align_str(entry_display.truncate(item, width), width, justify)
end
end)
else
table.insert(generator, function(item)
if type(item) == "table" then
return item[1], item[2]
else
return item
end
end)
end
end
return function(self, picker)
local results = {}
local highlights = {}
for i = 1, #generator do
if self[i] ~= nil then
local str, hl = generator[i](self[i], picker)
if hl then
local hl_start = 0
for j = 1, (i - 1) do
hl_start = hl_start + #results[j] + (#configuration.separator or 1)
end
local hl_end = hl_start + #str:gsub("%s*$", "")
if type(hl) == "function" then
for _, hl_res in ipairs(hl()) do
table.insert(highlights, { { hl_res[1][1] + hl_start, hl_res[1][2] + hl_start }, hl_res[2] })
end
else
table.insert(highlights, { { hl_start, hl_end }, hl })
end
end
table.insert(results, str)
end
end
if configuration.separator_hl then
local width = #configuration.separator or 1
local hl_start, hl_end
for _, v in ipairs(results) do
hl_start = (hl_end or 0) + #tostring(v)
hl_end = hl_start + width
table.insert(highlights, { { hl_start, hl_end }, configuration.separator_hl })
end
end
local final_str = table.concat(results, configuration.separator or "│")
if configuration.hl_chars then
for i = 1, #final_str do
local c = final_str:sub(i, i)
local hl = configuration.hl_chars[c]
if hl then
table.insert(highlights, { { i - 1, i }, hl })
end
end
end
return final_str, highlights
end
end
entry_display.resolve = function(self, entry)
local display, display_highlights
if type(entry.display) == "function" then
self:_increment "display_fn"
display, display_highlights = entry:display(self)
if type(display) == "string" then
return display, display_highlights
end
else
display = entry.display
end
if type(display) == "string" then
return display, display_highlights
end
end
return entry_display
|