Skip to content

Commit

Permalink
feat: dynamic cmp and doc window width
Browse files Browse the repository at this point in the history
  • Loading branch information
Saghen committed Jul 22, 2024
1 parent fae11d1 commit 6b78c89
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 33 deletions.
8 changes: 2 additions & 6 deletions lua/blink/cmp/sources/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,9 @@ function sources.send_completions()
end

-- flatten the items
local flattened_items = nil
local flattened_items = {}
for _, response in pairs(sources.sources_items) do
if flattened_items == nil then
flattened_items = response.items
else
vim.list_extend(flattened_items, response.items)
end
vim.list_extend(flattened_items, response.items)
end

sources.on_completions_callback(flattened_items)
Expand Down
7 changes: 4 additions & 3 deletions lua/blink/cmp/windows/autocomplete.lua
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,12 @@ function autocomplete.draw_item(item)
local kind_icon = config.kind_icons[kind] or config.kind_icons.Field

-- get line text
local max_length = 40
local utf8len = vim.fn.strdisplaywidth
local max_length = autocomplete.win.config.max_width
local utf8len = vim.api.nvim_strwidth
local other_content_length = utf8len(kind_icon) + utf8len(kind) + 5
local remaining_length = math.max(0, max_length - other_content_length - utf8len(item.label))
local abbr = string.sub(item.label, 1, max_length - other_content_length) .. string.rep(' ', remaining_length)
-- + 1 to include the final character, + 1 to account for lua being 1-indexed
local abbr = string.sub(item.label, 1, max_length - other_content_length + 2) .. string.rep(' ', remaining_length)

return string.format(' %s %s %s ', kind_icon, abbr, kind)
end
Expand Down
16 changes: 11 additions & 5 deletions lua/blink/cmp/windows/documentation.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ local docs = {}

function docs.setup()
docs.win = require('blink.cmp.windows.lib').new({
width = 60,
min_width = 10,
max_height = 20,
wrap = true,
-- todo: should be able to use the markdown stuff now?
-- filetype = 'typescript', -- todo: set dynamically
-- todo: is just using markdown enough?
filetype = 'markdown',
padding = true,
})

Expand All @@ -31,18 +31,24 @@ function docs.show_item(item)
end

sources.resolve(item, function(resolved_item)
if resolved_item.detail == nil then
if resolved_item.documentation == nil then
docs.win:close()
return
end

-- todo: respect .kind (MarkupKind) which is markdown or plaintext
local doc_lines = {}
for s in resolved_item.detail:gmatch('[^\r\n]+') do
for s in resolved_item.documentation.value:gmatch('[^\r\n]+') do
table.insert(doc_lines, s)
end
vim.api.nvim_buf_set_lines(docs.win:get_buf(), 0, -1, true, doc_lines)
vim.api.nvim_set_option_value('modified', false, { buf = docs.win:get_buf() })

local filetype = resolved_item.documentation.kind == 'markdown' and 'markdown' or 'plaintext'
if filetype ~= vim.api.nvim_get_option_value('filetype', { buf = docs.win:get_buf() }) then
vim.api.nvim_set_option_value('filetype', filetype, { buf = docs.win:get_buf() })
end

if autocomplete.win:get_win() then
docs.win:open()
docs.win:update_position(autocomplete.win:get_win())
Expand Down
39 changes: 20 additions & 19 deletions lua/blink/cmp/windows/lib.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ function win.new(config)

self.id = nil
self.config = {
width = config.width or 40,
min_width = config.min_width or 30,
max_width = config.max_width or 60,
max_height = config.max_height or 10,
cursorline = config.cursorline or false,
wrap = config.wrap or false,
Expand All @@ -21,8 +22,8 @@ function win:get_buf()
-- create buffer if it doesn't exist
if self.buf == nil or not vim.api.nvim_buf_is_valid(self.buf) then
self.buf = vim.api.nvim_create_buf(false, true)
-- vim.api.nvim_buf_set_option(self.buf, 'tabstop', 1) -- prevents tab widths from being unpredictable
-- vim.api.nvim_buf_set_option(self.buf, 'filetype', self.config.filetype)
vim.api.nvim_set_option_value('tabstop', 1, { buf = self.buf }) -- prevents tab widths from being unpredictable
vim.api.nvim_set_option_value('filetype', self.config.filetype, { buf = self.buf })
end
return self.buf
end
Expand All @@ -43,7 +44,7 @@ function win:open()
self.id = vim.api.nvim_open_win(self:get_buf(), false, {
relative = 'cursor',
style = 'minimal',
width = self.config.width,
width = self.config.min_width,
height = self.config.max_height,
row = 1,
col = 1,
Expand Down Expand Up @@ -80,11 +81,14 @@ function win:update_position(relative_to)
local cursor_row = cursor[1]
local cursor_col = cursor[2]

-- set height to current line count
-- set width to current content width, bounded by min and max
local width = math.max(math.min(self:get_content_width(), config.max_width), config.min_width)
vim.api.nvim_win_set_width(winnr, width)

-- set height to current line count, bounded by max
local height = math.min(self:get_content_height(), config.max_height)
vim.api.nvim_win_set_height(winnr, height)

-- relative to cursor
if relative_to == 'cursor' then
local is_space_below = screen_height - cursor_row > height

Expand All @@ -102,9 +106,7 @@ function win:update_position(relative_to)
local max_width_right = screen_width - cursor_col - relative_win_config.width - 7
local max_width_left = cursor_col

local width = math.min(math.max(max_width_left, max_width_right), config.width)

if max_width_right >= config.width or max_width_right >= max_width_left then
if max_width_right >= width or max_width_right >= max_width_left then
vim.api.nvim_win_set_config(winnr, {
relative = 'win',
win = relative_to,
Expand All @@ -121,7 +123,6 @@ function win:update_position(relative_to)
width = width,
})
end
-- No idea what it's supposed to be relative to
else
error('Invalid relative config')
end
Expand All @@ -131,15 +132,15 @@ end
function win:get_content_height()
if not self:is_open() then return 0 end
return vim.api.nvim_win_text_height(self:get_win(), {}).all
--
-- if not self.config.wrap then return vim.api.nvim_buf_line_count(self.buf) end
-- local height = 0
-- vim.api.nvim_buf_call(self.buf, function()
-- for _, text in ipairs(vim.api.nvim_buf_get_lines(self.buf, 0, -1, false)) do
-- height = height + math.max(1, math.ceil(vim.fn.strdisplaywidth(text) / self.config.width))
-- end
-- end)
-- return height
end

function win:get_content_width()
if not self:is_open() then return 0 end
local max_width = 0
for _, line in ipairs(vim.api.nvim_buf_get_lines(self.buf, 0, -1, false)) do
max_width = math.max(max_width, vim.api.nvim_strwidth(line))
end
return max_width
end

return win

0 comments on commit 6b78c89

Please sign in to comment.