From a215adabc107e16525cc4a302d46c412a6dff148 Mon Sep 17 00:00:00 2001 From: Marco Hinz Date: Thu, 8 Apr 2021 19:32:05 +0200 Subject: lsp: make sure borders are always inside of the screen Add a helper function to get the additional width a border adds to a float to make sure that the border is always inside the visible screen. --- runtime/lua/vim/lsp/util.lua | 59 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 49 insertions(+), 10 deletions(-) (limited to 'runtime/lua/vim/lsp/util.lua') diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index a070cb5306..d0d379054d 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -18,6 +18,40 @@ end local M = {} +local default_border = { + {"", "NormalFloat"}, + {"", "NormalFloat"}, + {"", "NormalFloat"}, + {" ", "NormalFloat"}, + {"", "NormalFloat"}, + {"", "NormalFloat"}, + {"", "NormalFloat"}, + {" ", "NormalFloat"}, +} + +--@private +-- Check the border given by opts or the default border for the additional +-- size it adds to a float. +--@returns size of border in height and width +local function get_border_size(opts) + local border = opts and opts.border or default_border + local height = 0 + local width = 0 + + if type(border) == 'string' then + -- 'single', 'double', etc. + height = 2 + width = 2 + else + height = height + vim.fn.strdisplaywidth(border[2][1]) -- top + height = height + vim.fn.strdisplaywidth(border[6][1]) -- bottom + width = width + vim.fn.strdisplaywidth(border[4][1]) -- right + width = width + vim.fn.strdisplaywidth(border[8][1]) -- left + end + + return { height = height, width = width } +end + --@private local function split_lines(value) return split(value, '\n', true) @@ -875,16 +909,7 @@ function M.make_floating_popup_options(width, height, opts) row = row + (opts.offset_y or 0), style = 'minimal', width = width, - border = opts.border or { - {"", "NormalFloat"}, - {"", "NormalFloat"}, - {"", "NormalFloat"}, - {" ", "NormalFloat"}, - {"", "NormalFloat"}, - {"", "NormalFloat"}, - {"", "NormalFloat"}, - {" ", "NormalFloat"} - }, + border = opts.border or default_border, } end @@ -1185,6 +1210,20 @@ function M._make_floating_popup_size(contents, opts) width = math.max(line_widths[i], width) end end + + local border_width = get_border_size(opts).width + local screen_width = api.nvim_win_get_width(0) + width = math.min(width, screen_width) + + -- make sure borders are always inside the screen + if width + border_width > screen_width then + width = width - (width + border_width - screen_width) + end + + if wrap_at > width then + wrap_at = width + end + if max_width then width = math.min(width, max_width) wrap_at = math.min(wrap_at or max_width, max_width) -- cgit From 383182516747153d6e3c9ff3a7e6a19262e42c93 Mon Sep 17 00:00:00 2001 From: Marco Hinz Date: Mon, 12 Apr 2021 19:54:54 +0200 Subject: lsp: correct float placement when using borders Because borders add up to 2 to the height of a float, we need to subtract that from the anchor position, when opening a float in the lower half of the window. --- runtime/lua/vim/lsp/util.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'runtime/lua/vim/lsp/util.lua') diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index d0d379054d..325dc044be 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -890,7 +890,7 @@ function M.make_floating_popup_options(width, height, opts) else anchor = anchor..'S' height = math.min(lines_above, height) - row = 0 + row = -get_border_size(opts).height end if vim.fn.wincol() + width <= api.nvim_get_option('columns') then -- cgit