Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
156 changes: 156 additions & 0 deletions lua/fidget/buf.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
---@class fidget.buf
local M = {}

---@class fidget.buf.BuilderOpts

---@class fidget.buf.Builder
---@field lines string[]
---@field row number
---@field col number
---@field opts fidget.buf.BuilderOpts
---@field hls table[]
local Builder = {}
Builder.__index = Builder

---Write content
---@param text string
---@param hl_group? string | number | vim.api.keyset.highlight
---@return fidget.buf.Builder
function Builder:write(text, hl_group)
local row, col = self.row, self.col
local parts = vim.split(text, "\n", { plain = true })

for i, part in ipairs(parts) do
local line = self.lines[row + 1] or ""
self.lines[row + 1] = line .. part
col = col + #part

-- new line
if i < #parts then
row = row + 1
col = 0
end
end

if hl_group then
table.insert(self.hls, {
row = self.row,
col = self.col,
end_row = row,
end_col = col,
hl_group = hl_group,
})
end

self.row = row
self.col = col

return self
end

---Write new line.
---@param n? number
---@return fidget.buf.Builder
function Builder:ln(n)
n = n or 1
for _ = 1, n do
-- check first line is empty, because row is 0-base, self.lines is a 1-base array
if self.row == 0 and self.lines[1] == nil then
self.lines[1] = ""
end

self.row = self.row + 1
self.lines[self.row + 1] = ""
end
self.col = 0

return self
end

---Write {n} spaces
---@param n? number
---@return fidget.buf.Builder
function Builder:space(n)
return self:write(string.rep(" ", n or 1))
end

function Builder:separator(sep, hl_group)
sep = sep or require("config.icons").icons.sep
hl_group = hl_group or "WinSeparator"

if self.col ~= 0 then
-- new line
self:ln()
end
local row = self.row

table.insert(self.hls, function(bufnr, ns)
vim.api.nvim_buf_set_extmark(bufnr, ns, row, 0, {
virt_text = { { sep:rep(200), hl_group } },
virt_text_pos = "overlay",
virt_text_win_col = 0,
})
end)

self:ln()

return self
end

---Render content, set extmarks.
---@param bufnr number
---@param ns? number namespace
function Builder:render(bufnr, ns)
if #self.lines == 0 then
return
end

ns = ns
or vim.api.nvim_create_namespace(string.format("content_builder_%s", bufnr))

vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, self.lines)

local id = 0
local set_extmark = function(hl)
if type(hl) == "function" then
hl(bufnr, ns)

return
end

local hl_name = hl.hl_group
if type(hl_name) == "table" then
hl_name = vim.api.nvim_set_hl(
ns,
string.format("NS_%s_HL_%s", ns, id),
hl.hl_group
)
id = id + 1
end

vim.api.nvim_buf_set_extmark(bufnr, ns, hl.row, hl.col, {
end_row = hl.end_row,
end_col = hl.end_col,
hl_group = hl_name,
})
end

for _, hl in ipairs(self.hls) do
set_extmark(hl)
end
end

---Create a buf content builder.
---@param opts? fidget.buf.BuilderOpts
---@return fidget.buf.Builder
function M.new_builder(opts)
return setmetatable({
row = 0,
col = 0,
lines = {},
hls = {},
opts = opts,
}, Builder)
end

return M
91 changes: 23 additions & 68 deletions lua/telescope/_extensions/fidget.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ local notification = require("fidget.notification")
local pickers = require("telescope.pickers")
local telescope = require("telescope")
local previewers = require("telescope.previewers")
local buf = require("fidget.buf")

--- Format HistoryItem, used in Telescope or Neovim messages.
---
Expand Down Expand Up @@ -36,56 +37,22 @@ local format_entry = function(entry)
return chunks
end

local notification_previewer = function()
local function previewer()
return previewers.new_buffer_previewer({
title = "Notification Details",
define_preview = function(self, entry, _)
local notification_entry = entry.value
define_preview = function(self, entry)
local data = entry.value
local bufnr = self.state.bufnr

vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {})

local lines = {
"Timestamp: " .. vim.fn.strftime("%c", notification_entry.last_updated),
"Group: " .. (notification_entry.group_name or ""),
"Annotation: " .. (notification_entry.annote or ""),
"Style: " .. (notification_entry.style or ""),
"",
"Message:",
"--------",
"",
}

local message_lines = vim.split(notification_entry.message, "\n")
for _, line in ipairs(message_lines) do
table.insert(lines, line)
end

vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, lines)

vim.api.nvim_buf_set_option(bufnr, "filetype", "markdown")

local ns_id = vim.api.nvim_create_namespace("fidget_preview")

vim.api.nvim_buf_add_highlight(bufnr, ns_id, "Title", 0, 0, 10)
vim.api.nvim_buf_add_highlight(bufnr, ns_id, "Title", 1, 0, 6)
vim.api.nvim_buf_add_highlight(bufnr, ns_id, "Title", 2, 0, 11)
vim.api.nvim_buf_add_highlight(bufnr, ns_id, "Title", 3, 0, 6)

vim.api.nvim_buf_add_highlight(bufnr, ns_id, "Identifier", 0, 11, -1)
vim.api.nvim_buf_add_highlight(bufnr, ns_id, "Special", 1, 7, -1)
vim.api.nvim_buf_add_highlight(bufnr, ns_id, "String", 2, 12, -1)
vim.api.nvim_buf_add_highlight(bufnr, ns_id, "Comment", 3, 7, -1)

vim.api.nvim_buf_add_highlight(bufnr, ns_id, "Title", 5, 0, -1)
vim.api.nvim_buf_add_highlight(bufnr, ns_id, "Comment", 6, 0, -1)

if notification_entry.style then
local hl_group = notification_entry.style
for i = 8, #lines do
vim.api.nvim_buf_add_highlight(bufnr, ns_id, hl_group, i - 1, 0, -1)
end
end
buf
.new_builder()
:write(string.format(" %s ", data.annote or " "), data.style)
:write(vim.fn.strftime("%c", data.last_updated), "Comment")
:space(1)
:write(data.group_name or "", "Special")
:separator()
:write(data.message or "")
:render(bufnr)
end,
})
end
Expand Down Expand Up @@ -124,29 +91,24 @@ local create_entry_maker = function(wrap)
end
end

local fidget_picker = function(opts)
opts = opts or {}

local default_config = {
wrap_text = false,
use_previewer = true,
}
local default_config = {
wrap_text = false,
previewer = true,
}

local config = vim.tbl_deep_extend("force", default_config, opts)
local fidget_picker = function(opts)
opts = vim.tbl_extend("force", default_config, opts or {})

local picker_opts = {
prompt_title = "Notifications",
finder = finders.new_table({
results = notification.get_history(),
entry_maker = create_entry_maker(config.wrap_text),
entry_maker = create_entry_maker(opts.wrap_text),
}),
sorter = conf.generic_sorter(opts),
previewer = previewer(),
}

if config.use_previewer then
picker_opts.previewer = notification_previewer()
end

picker_opts.attach_mappings = function(prompt_bufnr, _)
actions.select_default:replace(function()
actions.close(prompt_bufnr)
Expand Down Expand Up @@ -179,16 +141,9 @@ end

return telescope.register_extension({
setup = function(ext_config)
_G.__fidget_telescope_config = ext_config or {}
default_config = vim.tbl_extend("force", default_config, ext_config or {})
end,
exports = {
fidget = function(opts)
local config = vim.tbl_deep_extend(
"force",
_G.__fidget_telescope_config or {},
opts or {}
)
fidget_picker(config)
end,
fidget = fidget_picker,
},
})
Loading