1+ local config = require (' rustaceanvim.config.internal' )
2+ local lsp_util = vim .lsp .util
3+
14local M = {}
25
6+ --- @class rustaceanvim.hover_range.State
7+ local _state = {
8+ --- @type integer
9+ winnr = nil ,
10+ }
11+
12+ local function close_hover ()
13+ local ui = require (' rustaceanvim.ui' )
14+ ui .close_win (_state .winnr )
15+ end
16+
317-- Converts a tuple of range coordinates into LSP's position argument
418--- @param row1 integer
519--- @param col1 integer
@@ -42,6 +56,58 @@ local function get_visual_selected_range()
4256 return make_lsp_position (row1 , math.min (col1 , col2 ), row1 , math.max (col1 , col2 ))
4357end
4458
59+ --- @type lsp.Handler
60+ local function handler (_ , result , _ )
61+ if not (result and result .contents ) then
62+ return
63+ end
64+
65+ local markdown_lines = lsp_util .convert_input_to_markdown_lines (result .contents , {})
66+
67+ if vim .tbl_isempty (markdown_lines ) then
68+ return
69+ end
70+
71+ -- NOTE: This is for backward compatibility
72+ local win_opt = vim .tbl_deep_extend (' force' , config .tools .float_win_config , config .tools .hover_actions )
73+
74+ local bufnr , winnr = lsp_util .open_floating_preview (
75+ markdown_lines ,
76+ ' markdown' ,
77+ vim .tbl_extend (' keep' , win_opt , {
78+ focusable = true ,
79+ focus_id = ' rust-analyzer-hover-range' ,
80+ close_events = { ' CursorMoved' , ' BufHidden' , ' InsertCharPre' },
81+ })
82+ )
83+
84+ if win_opt .auto_focus then
85+ vim .api .nvim_set_current_win (winnr )
86+ end
87+
88+ if _state .winnr ~= nil then
89+ return
90+ end
91+
92+ -- update the window number here so that we can map escape to close even
93+ -- when there are no actions, update the rest of the state later
94+ _state .winnr = winnr
95+ vim .keymap .set (' n' , ' q' , close_hover , { buffer = bufnr , noremap = true , silent = true })
96+ vim .keymap .set (' n' , ' <Esc>' , close_hover , { buffer = bufnr , noremap = true , silent = true })
97+
98+ vim .api .nvim_buf_attach (bufnr , false , {
99+ on_detach = function ()
100+ _state .winnr = nil
101+ end ,
102+ })
103+
104+ -- makes more sense in a dropdown-ish ui
105+ vim .wo [winnr ].cursorline = true
106+
107+ -- explicitly disable signcolumn
108+ vim .wo [winnr ].signcolumn = ' no'
109+ end
110+
45111function M .hover_range ()
46112 local ra = require (' rustaceanvim.rust_analyzer' )
47113 local clients = ra .get_active_rustaceanvim_clients (0 )
@@ -52,7 +118,7 @@ function M.hover_range()
52118 --- @diagnostic disable-next-line : inject-field
53119 params .position = get_visual_selected_range ()
54120 params .range = nil
55- ra .buf_request (0 , ' textDocument/hover' , params )
121+ ra .buf_request (0 , ' textDocument/hover' , params , handler )
56122end
57123
58124return M .hover_range
0 commit comments