Add/Show/Delete Emojis on Notes (#181)
This MR adds the ability to view, add, and delete emojis from notes and comments. This action can be performed by default with the `Ea` (emoji add) keybinding, and the `Ed` (emoji delete) keybinding. Only emojis added by the current user are eligible for deletion. The MR also implements a popup functionality which shows the user who added emojis on hover. Implements #179
This commit is contained in:
committed by
GitHub
parent
99741178f9
commit
baee20b279
140
lua/gitlab/emoji.lua
Normal file
140
lua/gitlab/emoji.lua
Normal file
@@ -0,0 +1,140 @@
|
||||
local u = require("gitlab.utils")
|
||||
local state = require("gitlab.state")
|
||||
|
||||
local M = {
|
||||
---@type EmojiMap|nil
|
||||
emoji_map = {},
|
||||
---@type Emoji[]
|
||||
emoji_list = {},
|
||||
}
|
||||
|
||||
M.init = function()
|
||||
local bin_path = state.settings.bin_path
|
||||
local emoji_path = bin_path
|
||||
.. state.settings.file_separator
|
||||
.. "config"
|
||||
.. state.settings.file_separator
|
||||
.. "emojis.json"
|
||||
local emojis = u.read_file(emoji_path)
|
||||
if emojis == nil then
|
||||
u.notify("Could not read emoji file at " .. emoji_path, vim.log.levels.WARN)
|
||||
end
|
||||
|
||||
local data_ok, data = pcall(vim.json.decode, emojis)
|
||||
if not data_ok then
|
||||
u.notify("Could not parse emoji file at " .. emoji_path, vim.log.levels.WARN)
|
||||
end
|
||||
|
||||
M.emoji_map = data
|
||||
M.emoji_list = {}
|
||||
for _, v in pairs(M.emoji_map) do
|
||||
table.insert(M.emoji_list, v)
|
||||
end
|
||||
end
|
||||
|
||||
-- Define the popup window options
|
||||
M.popup_opts = {
|
||||
relative = "cursor",
|
||||
row = -2,
|
||||
col = 0,
|
||||
width = 2, -- Width set dynamically later
|
||||
height = 1,
|
||||
style = "minimal",
|
||||
border = "single",
|
||||
}
|
||||
|
||||
M.show_popup = function(char)
|
||||
-- Close existing popup if it's open
|
||||
if M.popup_win_id and vim.api.nvim_win_is_valid(M.popup_win_id) then
|
||||
vim.api.nvim_win_close(M.popup_win_id, true)
|
||||
end
|
||||
|
||||
-- Create a buffer for the popup window
|
||||
local buf = vim.api.nvim_create_buf(false, true)
|
||||
|
||||
-- Set the content of the popup buffer to the character
|
||||
vim.api.nvim_buf_set_lines(buf, 0, -1, false, { char })
|
||||
|
||||
-- Open the popup window and store its ID
|
||||
M.popup_win_id = vim.api.nvim_open_win(buf, false, M.popup_opts)
|
||||
end
|
||||
|
||||
M.close_popup = function()
|
||||
if M.popup_win_id and vim.api.nvim_win_is_valid(M.popup_win_id) then
|
||||
vim.api.nvim_win_close(M.popup_win_id, true)
|
||||
M.popup_win_id = nil -- Reset the window ID
|
||||
end
|
||||
end
|
||||
|
||||
M.init_popup = function(tree, bufnr)
|
||||
vim.api.nvim_create_autocmd({ "CursorHold" }, {
|
||||
callback = function()
|
||||
local node = tree:get_node()
|
||||
if node == nil then
|
||||
return
|
||||
end
|
||||
|
||||
local note_node = require("gitlab.actions.discussions").get_note_node(tree, node)
|
||||
local root_node = require("gitlab.actions.discussions").get_root_node(tree, node)
|
||||
local note_id_str = tostring(note_node.is_root and root_node.root_note_id or note_node.id)
|
||||
|
||||
local emojis = require("gitlab.actions.discussions").emojis
|
||||
local note_emojis = emojis[note_id_str]
|
||||
if note_emojis == nil then
|
||||
return
|
||||
end
|
||||
|
||||
local cursor_pos = vim.api.nvim_win_get_cursor(0)
|
||||
vim.api.nvim_command('normal! "zyiw')
|
||||
vim.api.nvim_win_set_cursor(0, cursor_pos)
|
||||
local word = vim.fn.getreg("z")
|
||||
|
||||
for k, v in pairs(M.emoji_map) do
|
||||
if v.moji == word then
|
||||
local names = M.get_users_who_reacted_with_emoji(k, note_emojis)
|
||||
M.popup_opts.width = string.len(names)
|
||||
if M.popup_opts.width > 0 then
|
||||
M.show_popup(names)
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
buffer = bufnr,
|
||||
})
|
||||
|
||||
vim.api.nvim_create_autocmd({ "CursorMoved", "CursorMovedI" }, {
|
||||
callback = function()
|
||||
M.close_popup()
|
||||
end,
|
||||
buffer = bufnr,
|
||||
})
|
||||
end
|
||||
|
||||
---@param name string
|
||||
---@return string
|
||||
M.get_users_who_reacted_with_emoji = function(name, note_emojis)
|
||||
local result = ""
|
||||
for _, v in pairs(note_emojis) do
|
||||
if v.name == name then
|
||||
result = result .. v.user.name .. ", "
|
||||
end
|
||||
end
|
||||
return string.len(result) > 3 and result:sub(1, -3) or result
|
||||
end
|
||||
|
||||
M.pick_emoji = function(options, cb)
|
||||
vim.ui.select(options, {
|
||||
prompt = "Choose emoji",
|
||||
format_item = function(val)
|
||||
return string.format("%s %s", val.moji, val.name)
|
||||
end,
|
||||
}, function(choice)
|
||||
if not choice then
|
||||
return
|
||||
end
|
||||
local name = choice.shortname:sub(2, -2)
|
||||
cb(name, choice)
|
||||
end)
|
||||
end
|
||||
|
||||
return M
|
||||
Reference in New Issue
Block a user