Skip to content

Commit 8827b06

Browse files
committed
ui: improved hover popup
this commit creates a custom hover handler which floats above all other windows when trigged from the calltree ui. Signed-off-by: ldelossa <louis.delos@gmail.com>
1 parent 0a3b32e commit 8827b06

File tree

3 files changed

+81
-2
lines changed

3 files changed

+81
-2
lines changed

lua/calltree/ui.lua

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ local help_buf = require('calltree.ui.help_buffer')
77
local marshal = require('calltree.ui.marshal')
88
local jumps = require('calltree.ui.jumps')
99
local deets = require('calltree.ui.details')
10+
local hover = require('calltree.ui.hover')
1011

1112
local M = {}
1213

@@ -274,6 +275,7 @@ end
274275
-- hover will show LSP hover information for the symbol
275276
-- under the cursor.
276277
M.hover = function()
278+
ui_buf.close_all_popups()
277279
local line = vim.api.nvim_get_current_line()
278280
local node = marshal.marshal_line(line)
279281
if node == nil then
@@ -288,12 +290,13 @@ M.hover = function()
288290
character = node.call_hierarchy_obj.range.start.character
289291
}
290292
}
291-
lsp_util.multi_client_request(M.active_lsp_clients, "textDocument/hover", params, nil, M.buffer_handle)
293+
lsp_util.multi_client_request(M.active_lsp_clients, "textDocument/hover", params, hover.hover_handler, M.buffer_handle)
292294
end
293295

294296
-- details opens a popup window for the given symbol
295297
-- showing more information.
296298
M.details = function()
299+
ui_buf.close_all_popups()
297300
local line = vim.api.nvim_get_current_line()
298301
local node = marshal.marshal_line(line)
299302
if node == nil then

lua/calltree/ui/buffer.lua

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ local direction_map = {
55
to = {method="callHierarchy/outgoingCalls", buf_name="outgoingCalls"}
66
}
77

8+
function M.close_all_popups()
9+
require('calltree.ui.hover').close_hover_popup()
10+
require('calltree.ui.details').close_details_popup()
11+
end
12+
813
-- _setup_buffer performs an idempotent creation
914
-- of the calltree buffer
1015
--
@@ -45,7 +50,7 @@ function M._setup_buffer(direction, buffer_handle)
4550
-- au to clear highlights on window close
4651
vim.cmd("au BufWinLeave <buffer=" .. buffer_handle .. "> lua require('calltree.ui.jumps').set_jump_hl(false)")
4752
-- au to close popup with cursor moves or buffer is closed.
48-
vim.cmd("au CursorMoved,BufWinLeave,WinLeave <buffer=" .. buffer_handle .. "> lua require('calltree.ui.details').close_details_popup()")
53+
vim.cmd("au CursorMoved,BufWinLeave,WinLeave <buffer=" .. buffer_handle .. "> lua require('calltree.ui.buffer').close_all_popups()")
4954

5055
-- set buffer local keymaps
5156
local opts = {silent=true}

lua/calltree/ui/hover.lua

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
local M = {}
2+
3+
local float_win = nil
4+
5+
-- close_hover_popups closes the created popup window
6+
-- if it exists.
7+
function M.close_hover_popup()
8+
if float_win ~= nil and
9+
vim.api.nvim_win_is_valid(float_win) then
10+
vim.api.nvim_win_close(float_win, true)
11+
float_win = nil
12+
end
13+
end
14+
15+
-- modified from neovim runtime/lua/vim/lsp/handlers.lua
16+
-- function conforms to client LSP handler signature.
17+
function M.hover_handler(_, result, ctx, config)
18+
M.close_hover_popup()
19+
-- get lines from result
20+
config = config or {}
21+
config.focus_id = ctx.method
22+
if not (result and result.contents) then
23+
-- return { 'No information available' }
24+
return
25+
end
26+
local lines = vim.lsp.util.convert_input_to_markdown_lines(result.contents)
27+
lines = vim.lsp.util.trim_empty_lines(lines)
28+
if vim.tbl_isempty(lines) then
29+
-- return { 'No information available' }
30+
return
31+
end
32+
33+
-- create buffer for popup
34+
local buf = vim.api.nvim_create_buf(false, false)
35+
if buf == 0 then
36+
vim.api.nvim_err_writeln("details_popup: could not create details buffer")
37+
return
38+
end
39+
vim.api.nvim_buf_set_option(buf, 'bufhidden', 'delete')
40+
vim.api.nvim_buf_set_option(buf, 'syntax', 'markdown')
41+
vim.api.nvim_buf_set_option(buf, 'filetype', 'markdown')
42+
43+
lines = vim.lsp.util.stylize_markdown(buf, lines, {})
44+
45+
local width = 20
46+
for _, line in ipairs(lines) do
47+
local line_width = vim.fn.strdisplaywidth(line)
48+
if line_width > width then
49+
width = line_width
50+
end
51+
end
52+
53+
vim.api.nvim_buf_set_option(buf, 'modifiable', true)
54+
vim.api.nvim_buf_set_lines(buf, 0, #lines, false, lines)
55+
vim.api.nvim_buf_set_option(buf, 'modifiable', false)
56+
local popup_conf = vim.lsp.util.make_floating_popup_options(
57+
width,
58+
#lines,
59+
{
60+
border= "rounded",
61+
focusable= false,
62+
zindex = 99,
63+
}
64+
)
65+
float_win = vim.api.nvim_open_win(buf, false, popup_conf)
66+
67+
return float_win
68+
end
69+
70+
71+
return M

0 commit comments

Comments
 (0)