mirror of
				https://github.com/neovim/neovim.git
				synced 2025-11-04 09:44:31 +00:00 
			
		
		
		
	feat(lsp): get_border_size(): support repeating border char list #15474
This commit is contained in:
		@@ -43,7 +43,9 @@ local loclist_type_map = {
 | 
				
			|||||||
---@private
 | 
					---@private
 | 
				
			||||||
--- Check the border given by opts or the default border for the additional
 | 
					--- Check the border given by opts or the default border for the additional
 | 
				
			||||||
--- size it adds to a float.
 | 
					--- size it adds to a float.
 | 
				
			||||||
---@returns size of border in height and width
 | 
					---@param opts (table, optional) options for the floating window
 | 
				
			||||||
 | 
					---            - border (string or table) the border
 | 
				
			||||||
 | 
					---@returns (table) size of border in the form of { height = height, width = width }
 | 
				
			||||||
local function get_border_size(opts)
 | 
					local function get_border_size(opts)
 | 
				
			||||||
  local border = opts and opts.border or default_border
 | 
					  local border = opts and opts.border or default_border
 | 
				
			||||||
  local height = 0
 | 
					  local height = 0
 | 
				
			||||||
@@ -52,12 +54,16 @@ local function get_border_size(opts)
 | 
				
			|||||||
  if type(border) == 'string' then
 | 
					  if type(border) == 'string' then
 | 
				
			||||||
    local border_size = {none = {0, 0}, single = {2, 2}, double = {2, 2}, rounded = {2, 2}, solid = {2, 2}, shadow = {1, 1}}
 | 
					    local border_size = {none = {0, 0}, single = {2, 2}, double = {2, 2}, rounded = {2, 2}, solid = {2, 2}, shadow = {1, 1}}
 | 
				
			||||||
    if border_size[border] == nil then
 | 
					    if border_size[border] == nil then
 | 
				
			||||||
      error("floating preview border is not correct. Please refer to the docs |vim.api.nvim_open_win()|"
 | 
					      error(string.format("invalid floating preview border: %s. :help vim.api.nvim_open_win()", vim.inspect(border)))
 | 
				
			||||||
              .. vim.inspect(border))
 | 
					 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
    height, width = unpack(border_size[border])
 | 
					    height, width = unpack(border_size[border])
 | 
				
			||||||
  else
 | 
					  else
 | 
				
			||||||
 | 
					    if 8 % #border ~= 0 then
 | 
				
			||||||
 | 
					      error(string.format("invalid floating preview border: %s. :help vim.api.nvim_open_win()", vim.inspect(border)))
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					    ---@private
 | 
				
			||||||
    local function border_width(id)
 | 
					    local function border_width(id)
 | 
				
			||||||
 | 
					      id = (id - 1) % #border + 1
 | 
				
			||||||
      if type(border[id]) == "table" then
 | 
					      if type(border[id]) == "table" then
 | 
				
			||||||
        -- border specified as a table of <character, highlight group>
 | 
					        -- border specified as a table of <character, highlight group>
 | 
				
			||||||
        return vim.fn.strdisplaywidth(border[id][1])
 | 
					        return vim.fn.strdisplaywidth(border[id][1])
 | 
				
			||||||
@@ -65,9 +71,11 @@ local function get_border_size(opts)
 | 
				
			|||||||
        -- border specified as a list of border characters
 | 
					        -- border specified as a list of border characters
 | 
				
			||||||
        return vim.fn.strdisplaywidth(border[id])
 | 
					        return vim.fn.strdisplaywidth(border[id])
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
      error("floating preview border is not correct. Please refer to the docs |vim.api.nvim_open_win()|" .. vim.inspect(border))
 | 
					      error(string.format("invalid floating preview border: %s. :help vim.api.nvim_open_win()", vim.inspect(border)))
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					    ---@private
 | 
				
			||||||
    local function border_height(id)
 | 
					    local function border_height(id)
 | 
				
			||||||
 | 
					      id = (id - 1) % #border + 1
 | 
				
			||||||
      if type(border[id]) == "table" then
 | 
					      if type(border[id]) == "table" then
 | 
				
			||||||
        -- border specified as a table of <character, highlight group>
 | 
					        -- border specified as a table of <character, highlight group>
 | 
				
			||||||
        return #border[id][1] > 0 and 1 or 0
 | 
					        return #border[id][1] > 0 and 1 or 0
 | 
				
			||||||
@@ -75,7 +83,7 @@ local function get_border_size(opts)
 | 
				
			|||||||
        -- border specified as a list of border characters
 | 
					        -- border specified as a list of border characters
 | 
				
			||||||
        return #border[id] > 0 and 1 or 0
 | 
					        return #border[id] > 0 and 1 or 0
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
      error("floating preview border is not correct. Please refer to the docs |vim.api.nvim_open_win()|" .. vim.inspect(border))
 | 
					      error(string.format("invalid floating preview border: %s. :help vim.api.nvim_open_win()", vim.inspect(border)))
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
    height = height + border_height(2)  -- top
 | 
					    height = height + border_height(2)  -- top
 | 
				
			||||||
    height = height + border_height(6)  -- bottom
 | 
					    height = height + border_height(6)  -- bottom
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,6 +6,7 @@ local buf_lines = helpers.buf_lines
 | 
				
			|||||||
local dedent = helpers.dedent
 | 
					local dedent = helpers.dedent
 | 
				
			||||||
local exec_lua = helpers.exec_lua
 | 
					local exec_lua = helpers.exec_lua
 | 
				
			||||||
local eq = helpers.eq
 | 
					local eq = helpers.eq
 | 
				
			||||||
 | 
					local matches = helpers.matches
 | 
				
			||||||
local pcall_err = helpers.pcall_err
 | 
					local pcall_err = helpers.pcall_err
 | 
				
			||||||
local pesc = helpers.pesc
 | 
					local pesc = helpers.pesc
 | 
				
			||||||
local insert = helpers.insert
 | 
					local insert = helpers.insert
 | 
				
			||||||
@@ -1938,6 +1939,83 @@ describe('LSP', function()
 | 
				
			|||||||
    end)
 | 
					    end)
 | 
				
			||||||
  end)
 | 
					  end)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  describe('lsp.util.make_floating_popup_options', function()
 | 
				
			||||||
 | 
					    before_each(function()
 | 
				
			||||||
 | 
					      exec_lua [[
 | 
				
			||||||
 | 
					        local bufnr = vim.uri_to_bufnr("file:///fake/uri")
 | 
				
			||||||
 | 
					        local winheight = vim.fn.winheight(0)
 | 
				
			||||||
 | 
					        for i = 1, winheight do
 | 
				
			||||||
 | 
					          vim.api.nvim_buf_set_lines(bufnr, 0, 0, false, {''})
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					        vim.api.nvim_win_set_buf(0, bufnr)
 | 
				
			||||||
 | 
					        vim.api.nvim_win_set_cursor(0, {winheight, 0})
 | 
				
			||||||
 | 
					      ]]
 | 
				
			||||||
 | 
					    end)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    local function popup_row(opts)
 | 
				
			||||||
 | 
					      return exec_lua([[
 | 
				
			||||||
 | 
					        return vim.lsp.util.make_floating_popup_options(...).row
 | 
				
			||||||
 | 
					      ]], 2, 2, opts)
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    local err_pattern = "^Error executing lua: %.%.%./util%.lua:0: invalid floating preview border: .*%. :help vim%.api%.nvim_open_win%(%)$"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('calculates default border height correctly', function()
 | 
				
			||||||
 | 
					      eq(0, popup_row())
 | 
				
			||||||
 | 
					    end)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('calculates string border height correctly', function()
 | 
				
			||||||
 | 
					      eq(0, popup_row({border = 'none'}))
 | 
				
			||||||
 | 
					      eq(-2, popup_row({border = 'single'}))
 | 
				
			||||||
 | 
					      eq(-2, popup_row({border = 'double'}))
 | 
				
			||||||
 | 
					      eq(-2, popup_row({border = 'rounded'}))
 | 
				
			||||||
 | 
					      eq(-2, popup_row({border = 'solid'}))
 | 
				
			||||||
 | 
					      eq(-1, popup_row({border = 'shadow'}))
 | 
				
			||||||
 | 
					    end)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('error on invalid string border', function()
 | 
				
			||||||
 | 
					      matches(err_pattern, pcall_err(popup_row, {border = ''}))
 | 
				
			||||||
 | 
					      matches(err_pattern, pcall_err(popup_row, {border = 'invalid'}))
 | 
				
			||||||
 | 
					    end)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('error on invalid array border length', function()
 | 
				
			||||||
 | 
					      matches(err_pattern, pcall_err(popup_row, {border = {}}))
 | 
				
			||||||
 | 
					      matches(err_pattern, pcall_err(popup_row, {border = {'', '', ''}}))
 | 
				
			||||||
 | 
					      matches(err_pattern, pcall_err(popup_row, {border = {'', '', '', '', ''}}))
 | 
				
			||||||
 | 
					    end)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('error on invalid array border member type', function()
 | 
				
			||||||
 | 
					      matches(err_pattern, pcall_err(popup_row, {border = {0}}))
 | 
				
			||||||
 | 
					    end)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('calculates 8-array border height correctly', function()
 | 
				
			||||||
 | 
					      eq(0, popup_row({border = {'', '', '', '', '', '', '', ''}}))
 | 
				
			||||||
 | 
					      eq(-2, popup_row({border = {'', '~', '', '~', '', '~', '', '~'}}))
 | 
				
			||||||
 | 
					      eq(-1, popup_row({border = {'', '', '', '~', '', '~', '', ''}}))
 | 
				
			||||||
 | 
					      eq(0, popup_row({border = {'', '', '', {'~', 'NormalFloat'}, '', '', '', {'~', 'NormalFloat'}}}))
 | 
				
			||||||
 | 
					      eq(-2, popup_row({border = {'', {'~', 'NormalFloat'}, '', '', '', {'~', 'NormalFloat'}, '', ''}}))
 | 
				
			||||||
 | 
					    end)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('calculates 4-array border height correctly', function()
 | 
				
			||||||
 | 
					      eq(0, popup_row({border = {'', '', '', ''}}))
 | 
				
			||||||
 | 
					      eq(-2, popup_row({border = {'', '~', '', '~'}}))
 | 
				
			||||||
 | 
					      eq(0, popup_row({border = {'', '', '', {'~', 'NormalFloat'}}}))
 | 
				
			||||||
 | 
					      eq(-2, popup_row({border = {'', {'~', 'NormalFloat'}, '', ''}}))
 | 
				
			||||||
 | 
					    end)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('calculates 2-array border height correctly', function()
 | 
				
			||||||
 | 
					      eq(0, popup_row({border = {'', ''}}))
 | 
				
			||||||
 | 
					      eq(-2, popup_row({border = {'', '~'}}))
 | 
				
			||||||
 | 
					      eq(-2, popup_row({border = {'', {'~', 'NormalFloat'}}}))
 | 
				
			||||||
 | 
					    end)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('calculates 1-array border height correctly', function()
 | 
				
			||||||
 | 
					      eq(0, popup_row({border = {''}}))
 | 
				
			||||||
 | 
					      eq(-2, popup_row({border = {'~'}}))
 | 
				
			||||||
 | 
					      eq(-2, popup_row({border = {{'~', 'NormalFloat'}}}))
 | 
				
			||||||
 | 
					    end)
 | 
				
			||||||
 | 
					  end)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  describe('lsp.util._make_floating_popup_size', function()
 | 
					  describe('lsp.util._make_floating_popup_size', function()
 | 
				
			||||||
    before_each(function()
 | 
					    before_each(function()
 | 
				
			||||||
      exec_lua [[ contents =
 | 
					      exec_lua [[ contents =
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user