Skip to content

Commit

Permalink
feat(menu.draw): columns can be function
Browse files Browse the repository at this point in the history
may be fix #820
  • Loading branch information
Parsifa1 committed Jan 21, 2025
1 parent 5b83998 commit 9b68a21
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 13 deletions.
4 changes: 2 additions & 2 deletions lua/blink/cmp/completion/windows/menu.lua
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ function menu.open_with_items(context, items)
menu.items = items
menu.selected_item_idx = menu.selected_item_idx ~= nil and math.min(menu.selected_item_idx, #items) or nil

if not menu.renderer then menu.renderer = require('blink.cmp.completion.windows.render').new(config.draw) end
menu.renderer:draw(context, menu.win:get_buf(), items)
if not menu.renderer then menu.renderer = require('blink.cmp.completion.windows.render').new(context, config.draw) end
menu.renderer:draw(context, menu.win:get_buf(), items, config.draw)

local auto_show = menu.auto_show
if type(auto_show) == 'function' then auto_show = auto_show(context, items) end
Expand Down
6 changes: 3 additions & 3 deletions lua/blink/cmp/completion/windows/render/column.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
--- @field ctxs blink.cmp.DrawItemContext[]
---
--- @field new fun(components: blink.cmp.DrawComponent[], gap: number): blink.cmp.DrawColumn
--- @field render fun(self: blink.cmp.DrawColumn, ctxs: blink.cmp.DrawItemContext[])
--- @field render fun(self: blink.cmp.DrawColumn,context: blink.cmp.Context, ctxs: blink.cmp.DrawItemContext[])
--- @field get_line_text fun(self: blink.cmp.DrawColumn, line_idx: number): string
--- @field get_line_highlights fun(self: blink.cmp.DrawColumn, line_idx: number): blink.cmp.DrawHighlight[]

Expand All @@ -26,7 +26,7 @@ function column.new(components, gap)
return self
end

function column:render(ctxs)
function column:render(context, ctxs)
--- render text and get the max widths of each component
--- @type string[][]
local lines = {}
Expand All @@ -35,7 +35,7 @@ function column:render(ctxs)
--- @type string[]
local line = {}
for component_idx, component in ipairs(self.components) do
local text = text_lib.apply_component_width(component.text(ctx) or '', component)
local text = text_lib.apply_component_width(context, component.text(ctx) or '', component)
table.insert(line, text)
max_component_widths[component_idx] =
math.max(max_component_widths[component_idx] or 0, vim.api.nvim_strwidth(text))
Expand Down
40 changes: 35 additions & 5 deletions lua/blink/cmp/completion/windows/render/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
--- @field gap number
--- @field columns blink.cmp.DrawColumn[]
---
--- @field new fun(draw: blink.cmp.Draw): blink.cmp.Renderer
--- @field draw fun(self: blink.cmp.Renderer, context: blink.cmp.Context, bufnr: number, items: blink.cmp.CompletionItem[])
--- @field new fun(context: blink.cmp.Context, draw: blink.cmp.Draw): blink.cmp.Renderer
--- @field draw fun(self: blink.cmp.Renderer, context: blink.cmp.Context, bufnr: number, items: blink.cmp.CompletionItem[], draw: blink.cmp.Draw)
--- @field get_component_column_location fun(self: blink.cmp.Renderer, component_name: string): { column_idx: number, component_idx: number }
--- @field get_component_start_col fun(self: blink.cmp.Renderer, component_name: string): number
--- @field get_alignment_start_col fun(self: blink.cmp.Renderer): number
Expand All @@ -15,9 +15,14 @@ local ns = vim.api.nvim_create_namespace('blink_cmp_renderer')
--- @type blink.cmp.Renderer
--- @diagnostic disable-next-line: missing-fields
local renderer = {}
--- @type blink.cmp.DrawColumn[]
local columns = {}

function renderer.new(draw)
function renderer.new(context, draw)
--- Convert the component names in the columns to the component definitions
columns = draw.columns
if type(columns) == 'function' then draw.columns = columns(context) end

--- @type blink.cmp.DrawComponent[][]
local columns_definitions = vim.tbl_map(function(column)
local components = {}
Expand Down Expand Up @@ -52,13 +57,38 @@ function renderer.new(draw)
return self
end

function renderer:draw(context, bufnr, items)
function renderer:draw(context, bufnr, items, draw)
if type(columns) == 'function' then self.def.columns = columns(context) end

local columns_definitions = vim.tbl_map(function(column)
local components = {}
for _, component_name in ipairs(column) do
local component = draw.components[component_name]
assert(component ~= nil, 'No component definition found for component: "' .. component_name .. '"')
table.insert(components, draw.components[component_name])
end
return {
components = components,
gap = column.gap or 0,
}
end, self.def.columns)

self.columns = vim.tbl_map(
function(column_definition)
return require('blink.cmp.completion.windows.render.column').new(
column_definition.components,
column_definition.gap
)
end,
columns_definitions
)

-- gather contexts
local draw_contexts = require('blink.cmp.completion.windows.render.context').get_from_items(context, self.def, items)

-- render the columns
for _, column in ipairs(self.columns) do
column:render(draw_contexts)
column:render(context, draw_contexts)
end

-- apply to the buffer
Expand Down
7 changes: 5 additions & 2 deletions lua/blink/cmp/completion/windows/render/text.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@ local config = require('blink.cmp.config')
local text_lib = {}

--- Applies the component width settings to the text
--- @param context blink.cmp.Context
--- @param text string
--- @param component blink.cmp.DrawComponent
--- @return string text
function text_lib.apply_component_width(text, component)
function text_lib.apply_component_width(context, text, component)
local width = component.width or {}
if width.fixed ~= nil then return text_lib.set_width(text, width.fixed, component) end
if width.min ~= nil then text = text_lib.pad(text, width.min) end
if width.max ~= nil then text = text_lib.truncate(text, width.max, component.ellipsis) end
local max_width = width.max
if type(width.max) == 'function' then max_width = width.max(context) end
if max_width ~= nil then text = text_lib.truncate(text, max_width, component.ellipsis) end
return text
end

Expand Down
3 changes: 2 additions & 1 deletion lua/blink/cmp/config/completion/menu.lua
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ function window.validate(config)
align_to = {
config.draw.align_to,
function(align)
if type(config.draw.columns) == 'function' then return true end
if align == 'none' or align == 'cursor' then return true end
for _, column in ipairs(config.draw.columns) do
for _, component in ipairs(column) do
Expand Down Expand Up @@ -193,7 +194,7 @@ function window.validate(config)
config.draw.columns,
function(columns)
local available_components = vim.tbl_keys(config.draw.components)

if type(columns) == 'function' then return true end
if type(columns) ~= 'table' or #columns == 0 then return false end
for _, column in ipairs(columns) do
if #column == 0 then return false end
Expand Down

0 comments on commit 9b68a21

Please sign in to comment.