Skip to content

Commit d0f84d3

Browse files
committed
feat: telescope preview
1. Remove deprecated function `vim.api.nvim_buf_add_highlight`, add a helper buf builder. 2. Add missing annotation style. 2. Use a global variable _G.__fidget_telescope_config is not a good design, and we do not need either. 3. Not need a option `use_previewer`, a option in `previewer = false` in telescope config will just work. Which allow you disable previewer by default, but you can still toggle previewer window. eg: disable preview by default. ```lua require("telescope").setup({ extensions = { fidget = { previewer = false, }, }, }) ``` or in lua api ```lua require("telescope").extensions.fidget.fidget({ previewer = false }) ```
1 parent 7fa433a commit d0f84d3

2 files changed

Lines changed: 179 additions & 68 deletions

File tree

lua/fidget/buf.lua

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
---@class fidget.buf
2+
local M = {}
3+
4+
---@class fidget.buf.BuilderOpts
5+
6+
---@class fidget.buf.Builder
7+
---@field lines string[]
8+
---@field row number
9+
---@field col number
10+
---@field opts fidget.buf.BuilderOpts
11+
---@field hls table[]
12+
local Builder = {}
13+
Builder.__index = Builder
14+
15+
---Write content
16+
---@param text string
17+
---@param hl_group? string | number | vim.api.keyset.highlight
18+
---@return fidget.buf.Builder
19+
function Builder:write(text, hl_group)
20+
local row, col = self.row, self.col
21+
local parts = vim.split(text, "\n", { plain = true })
22+
23+
for i, part in ipairs(parts) do
24+
local line = self.lines[row + 1] or ""
25+
self.lines[row + 1] = line .. part
26+
col = col + #part
27+
28+
-- new line
29+
if i < #parts then
30+
row = row + 1
31+
col = 0
32+
end
33+
end
34+
35+
if hl_group then
36+
table.insert(self.hls, {
37+
row = self.row,
38+
col = self.col,
39+
end_row = row,
40+
end_col = col,
41+
hl_group = hl_group,
42+
})
43+
end
44+
45+
self.row = row
46+
self.col = col
47+
48+
return self
49+
end
50+
51+
---Write new line.
52+
---@param n? number
53+
---@return fidget.buf.Builder
54+
function Builder:ln(n)
55+
n = n or 1
56+
for _ = 1, n do
57+
-- check first line is empty, because row is 0-base, self.lines is a 1-base array
58+
if self.row == 0 and self.lines[1] == nil then
59+
self.lines[1] = ""
60+
end
61+
62+
self.row = self.row + 1
63+
self.lines[self.row + 1] = ""
64+
end
65+
self.col = 0
66+
67+
return self
68+
end
69+
70+
---Write {n} spaces
71+
---@param n? number
72+
---@return fidget.buf.Builder
73+
function Builder:space(n)
74+
return self:write(string.rep(" ", n or 1))
75+
end
76+
77+
function Builder:separator(sep, hl_group)
78+
sep = sep or require("config.icons").icons.sep
79+
hl_group = hl_group or "WinSeparator"
80+
81+
if self.col ~= 0 then
82+
-- new line
83+
self:ln()
84+
end
85+
local row = self.row
86+
87+
table.insert(self.hls, function(bufnr, ns)
88+
vim.api.nvim_buf_set_extmark(bufnr, ns, row, 0, {
89+
virt_text = { { sep:rep(200), hl_group } },
90+
virt_text_pos = "overlay",
91+
virt_text_win_col = 0,
92+
})
93+
end)
94+
95+
self:ln()
96+
97+
return self
98+
end
99+
100+
---Render content, set extmarks.
101+
---@param bufnr number
102+
---@param ns? number namespace
103+
function Builder:render(bufnr, ns)
104+
if #self.lines == 0 then
105+
return
106+
end
107+
108+
ns = ns
109+
or vim.api.nvim_create_namespace(string.format("content_builder_%s", bufnr))
110+
111+
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, self.lines)
112+
113+
local id = 0
114+
local set_extmark = function(hl)
115+
if type(hl) == "function" then
116+
hl(bufnr, ns)
117+
118+
return
119+
end
120+
121+
local hl_name = hl.hl_group
122+
if type(hl_name) == "table" then
123+
hl_name = vim.api.nvim_set_hl(
124+
ns,
125+
string.format("NS_%s_HL_%s", ns, id),
126+
hl.hl_group
127+
)
128+
id = id + 1
129+
end
130+
131+
vim.api.nvim_buf_set_extmark(bufnr, ns, hl.row, hl.col, {
132+
end_row = hl.end_row,
133+
end_col = hl.end_col,
134+
hl_group = hl_name,
135+
})
136+
end
137+
138+
for _, hl in ipairs(self.hls) do
139+
set_extmark(hl)
140+
end
141+
end
142+
143+
---Create a buf content builder.
144+
---@param opts? fidget.buf.BuilderOpts
145+
---@return fidget.buf.Builder
146+
function M.new_builder(opts)
147+
return setmetatable({
148+
row = 0,
149+
col = 0,
150+
lines = {},
151+
hls = {},
152+
opts = opts,
153+
}, Builder)
154+
end
155+
156+
return M

lua/telescope/_extensions/fidget.lua

Lines changed: 23 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ local notification = require("fidget.notification")
77
local pickers = require("telescope.pickers")
88
local telescope = require("telescope")
99
local previewers = require("telescope.previewers")
10+
local buf = require("fidget.buf")
1011

1112
--- Format HistoryItem, used in Telescope or Neovim messages.
1213
---
@@ -36,56 +37,22 @@ local format_entry = function(entry)
3637
return chunks
3738
end
3839

39-
local notification_previewer = function()
40+
local function previewer()
4041
return previewers.new_buffer_previewer({
4142
title = "Notification Details",
42-
define_preview = function(self, entry, _)
43-
local notification_entry = entry.value
43+
define_preview = function(self, entry)
44+
local data = entry.value
4445
local bufnr = self.state.bufnr
4546

46-
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {})
47-
48-
local lines = {
49-
"Timestamp: " .. vim.fn.strftime("%c", notification_entry.last_updated),
50-
"Group: " .. (notification_entry.group_name or ""),
51-
"Annotation: " .. (notification_entry.annote or ""),
52-
"Style: " .. (notification_entry.style or ""),
53-
"",
54-
"Message:",
55-
"--------",
56-
"",
57-
}
58-
59-
local message_lines = vim.split(notification_entry.message, "\n")
60-
for _, line in ipairs(message_lines) do
61-
table.insert(lines, line)
62-
end
63-
64-
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, lines)
65-
66-
vim.api.nvim_buf_set_option(bufnr, "filetype", "markdown")
67-
68-
local ns_id = vim.api.nvim_create_namespace("fidget_preview")
69-
70-
vim.api.nvim_buf_add_highlight(bufnr, ns_id, "Title", 0, 0, 10)
71-
vim.api.nvim_buf_add_highlight(bufnr, ns_id, "Title", 1, 0, 6)
72-
vim.api.nvim_buf_add_highlight(bufnr, ns_id, "Title", 2, 0, 11)
73-
vim.api.nvim_buf_add_highlight(bufnr, ns_id, "Title", 3, 0, 6)
74-
75-
vim.api.nvim_buf_add_highlight(bufnr, ns_id, "Identifier", 0, 11, -1)
76-
vim.api.nvim_buf_add_highlight(bufnr, ns_id, "Special", 1, 7, -1)
77-
vim.api.nvim_buf_add_highlight(bufnr, ns_id, "String", 2, 12, -1)
78-
vim.api.nvim_buf_add_highlight(bufnr, ns_id, "Comment", 3, 7, -1)
79-
80-
vim.api.nvim_buf_add_highlight(bufnr, ns_id, "Title", 5, 0, -1)
81-
vim.api.nvim_buf_add_highlight(bufnr, ns_id, "Comment", 6, 0, -1)
82-
83-
if notification_entry.style then
84-
local hl_group = notification_entry.style
85-
for i = 8, #lines do
86-
vim.api.nvim_buf_add_highlight(bufnr, ns_id, hl_group, i - 1, 0, -1)
87-
end
88-
end
47+
buf
48+
.new_builder()
49+
:write(string.format(" %s ", data.annote or " "), data.style)
50+
:write(vim.fn.strftime("%c", data.last_updated), "Comment")
51+
:space(1)
52+
:write(data.group_name or "", "Special")
53+
:separator()
54+
:write(data.message or "")
55+
:render(bufnr)
8956
end,
9057
})
9158
end
@@ -124,29 +91,24 @@ local create_entry_maker = function(wrap)
12491
end
12592
end
12693

127-
local fidget_picker = function(opts)
128-
opts = opts or {}
129-
130-
local default_config = {
131-
wrap_text = false,
132-
use_previewer = true,
133-
}
94+
local default_config = {
95+
wrap_text = false,
96+
previewer = true,
97+
}
13498

135-
local config = vim.tbl_deep_extend("force", default_config, opts)
99+
local fidget_picker = function(opts)
100+
opts = vim.tbl_extend("force", default_config, opts or {})
136101

137102
local picker_opts = {
138103
prompt_title = "Notifications",
139104
finder = finders.new_table({
140105
results = notification.get_history(),
141-
entry_maker = create_entry_maker(config.wrap_text),
106+
entry_maker = create_entry_maker(opts.wrap_text),
142107
}),
143108
sorter = conf.generic_sorter(opts),
109+
previewer = previewer(),
144110
}
145111

146-
if config.use_previewer then
147-
picker_opts.previewer = notification_previewer()
148-
end
149-
150112
picker_opts.attach_mappings = function(prompt_bufnr, _)
151113
actions.select_default:replace(function()
152114
actions.close(prompt_bufnr)
@@ -179,16 +141,9 @@ end
179141

180142
return telescope.register_extension({
181143
setup = function(ext_config)
182-
_G.__fidget_telescope_config = ext_config or {}
144+
default_config = vim.tbl_extend("force", default_config, ext_config or {})
183145
end,
184146
exports = {
185-
fidget = function(opts)
186-
local config = vim.tbl_deep_extend(
187-
"force",
188-
_G.__fidget_telescope_config or {},
189-
opts or {}
190-
)
191-
fidget_picker(config)
192-
end,
147+
fidget = fidget_picker,
193148
},
194149
})

0 commit comments

Comments
 (0)