aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/lsp/util.lua
diff options
context:
space:
mode:
authorSebastian Lyng Johansen <seblyng98@gmail.com>2023-01-10 11:22:41 +0100
committerGitHub <noreply@github.com>2023-01-10 02:22:41 -0800
commit870ca1de52b240926b88f01afa697cd9b119bdac (patch)
tree2d2d0ecc78ae968a2a955584f2007e357d7e7ba5 /runtime/lua/vim/lsp/util.lua
parentd6cb3328f7e7286fb4aac116ea1bb0e6377fa803 (diff)
downloadrneovim-870ca1de52b240926b88f01afa697cd9b119bdac.tar.gz
rneovim-870ca1de52b240926b88f01afa697cd9b119bdac.tar.bz2
rneovim-870ca1de52b240926b88f01afa697cd9b119bdac.zip
feat(float): open float relative to mouse #21531
Problem: No easy way to position a LSP hover window relative to mouse. Solution: Introduce another option to the `relative` key in `nvim_open_win()`. With this PR it should be possible to override the handler and do something similar to this https://github.com/neovim/neovim/pull/19481#issuecomment-1193248674 to have hover information displayed from the mouse. Test case: ```lua local util = require('vim.lsp.util') local function make_position_param(window, offset_encoding) window = window or 0 local buf = vim.api.nvim_win_get_buf(window) local row, col local mouse = vim.fn.getmousepos() row = mouse.line col = mouse.column offset_encoding = offset_encoding or util._get_offset_encoding(buf) row = row - 1 local line = vim.api.nvim_buf_get_lines(buf, row, row + 1, true)[1] if not line then return { line = 0, character = 0 } end if #line < col then return { line = 0, character = 0 } end col = util._str_utfindex_enc(line, col, offset_encoding) return { line = row, character = col } end local make_params = function(window, offset_encoding) window = window or 0 local buf = vim.api.nvim_win_get_buf(window) offset_encoding = offset_encoding or util._get_offset_encoding(buf) return { textDocument = util.make_text_document_params(buf), position = make_position_param(window, offset_encoding), } end local hover_timer = nil vim.o.mousemoveevent = true vim.keymap.set({ '', 'i' }, '<MouseMove>', function() if hover_timer then hover_timer:close() end hover_timer = vim.defer_fn(function() hover_timer = nil local params = make_params() vim.lsp.buf_request( 0, 'textDocument/hover', params, vim.lsp.with(vim.lsp.handlers.hover, { silent = true, focusable = false, relative = 'mouse', }) ) end, 500) return '<MouseMove>' end, { expr = true }) ```
Diffstat (limited to 'runtime/lua/vim/lsp/util.lua')
-rw-r--r--runtime/lua/vim/lsp/util.lua10
1 files changed, 7 insertions, 3 deletions
diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua
index 2c6ba823db..26f0e180f5 100644
--- a/runtime/lua/vim/lsp/util.lua
+++ b/runtime/lua/vim/lsp/util.lua
@@ -1015,6 +1015,7 @@ end
--- - border (string or table) override `border`
--- - focusable (string or table) override `focusable`
--- - zindex (string or table) override `zindex`, defaults to 50
+--- - relative ("mouse"|"cursor") defaults to "cursor"
---@returns (table) Options
function M.make_floating_popup_options(width, height, opts)
validate({
@@ -1029,7 +1030,8 @@ function M.make_floating_popup_options(width, height, opts)
local anchor = ''
local row, col
- local lines_above = vim.fn.winline() - 1
+ local lines_above = opts.relative == 'mouse' and vim.fn.getmousepos().line - 1
+ or vim.fn.winline() - 1
local lines_below = vim.fn.winheight(0) - lines_above
if lines_above < lines_below then
@@ -1042,7 +1044,9 @@ function M.make_floating_popup_options(width, height, opts)
row = 0
end
- if vim.fn.wincol() + width + (opts.offset_x or 0) <= api.nvim_get_option('columns') then
+ local wincol = opts.relative == 'mouse' and vim.fn.getmousepos().column or vim.fn.wincol()
+
+ if wincol + width + (opts.offset_x or 0) <= api.nvim_get_option('columns') then
anchor = anchor .. 'W'
col = 0
else
@@ -1062,7 +1066,7 @@ function M.make_floating_popup_options(width, height, opts)
col = col + (opts.offset_x or 0),
height = height,
focusable = opts.focusable,
- relative = 'cursor',
+ relative = opts.relative == 'mouse' and 'mouse' or 'cursor',
row = row + (opts.offset_y or 0),
style = 'minimal',
width = width,