Skip to content

Commit

Permalink
docs: menu appearance/drawing
Browse files Browse the repository at this point in the history
  • Loading branch information
Saghen committed Nov 24, 2024
1 parent dcb83d6 commit b12043f
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 0 deletions.
97 changes: 97 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,7 @@ MiniDeps.add({
selection = 'preselect',
-- Controls how the completion items are rendered on the popup window
draw = {
-- Aligns the keyword you've typed to a component in the menu
align_to_component = 'label', -- or 'none' to disable
-- Left and right padding, optionally { left, right } for different padding on each side
padding = 1,
Expand Down Expand Up @@ -653,6 +654,102 @@ There's currently no `blink.cmp` native source for [luasnip](https://github.com/
}
```

### Menu Appearance/Drawing

<details>
<summary><strong>Default draw configuration</strong></summary>

<!-- config:start -->
```lua
--- @module 'blink.cmp'
--- @type blink.cmp.Draw
windows.autocomplete.draw = {
-- Aligns the keyword you've typed to a component in the menu
align_to_component = 'label', -- or 'none' to disable
-- Left and right padding, optionally { left, right } for different padding on each side
padding = 1,
-- Gap between columns
gap = 1,

-- Components to render, grouped by column
columns = { { 'kind_icon' }, { 'label', 'label_description', gap = 1 } },
-- for a setup similar to nvim-cmp: https://github.com/Saghen/blink.cmp/pull/245#issuecomment-2463659508
-- columns = { { "label", "label_description", gap = 1 }, { "kind_icon", "kind" } },

-- Definitions for possible components to render. Each component defines:
-- ellipsis: whether to add an ellipsis when truncating the text
-- width: control the min, max and fill behavior of the component
-- text function: will be called for each item
-- highlight function: will be called only when the line appears on screen
components = {
kind_icon = {
ellipsis = false,
text = function(ctx) return ctx.kind_icon .. ctx.icon_gap end,
highlight = function(ctx)
return require('blink.cmp.utils').get_tailwind_hl(ctx) or 'BlinkCmpKind' .. ctx.kind
end,
},

kind = {
ellipsis = false,
width = { fill = true },
text = function(ctx) return ctx.kind end,
highlight = function(ctx)
return require('blink.cmp.utils').get_tailwind_hl(ctx) or 'BlinkCmpKind' .. ctx.kind
end,
},

label = {
width = { fill = true, max = 60 },
text = function(ctx) return ctx.label .. ctx.label_detail end,
highlight = function(ctx)
-- label and label details
local highlights = {
{ 0, #ctx.label, group = ctx.deprecated and 'BlinkCmpLabelDeprecated' or 'BlinkCmpLabel' },
}
if ctx.label_detail then
table.insert(highlights, { #ctx.label, #ctx.label + #ctx.label_detail, group = 'BlinkCmpLabelDetail' })
end

-- characters matched on the label by the fuzzy matcher
for _, idx in ipairs(ctx.label_matched_indices) do
table.insert(highlights, { idx, idx + 1, group = 'BlinkCmpLabelMatch' })
end

return highlights
end,
},

label_description = {
width = { max = 30 },
text = function(ctx) return ctx.label_description end,
highlight = 'BlinkCmpLabelDescription',
},
},
},
```

<!-- config:end -->

</details>

blink.cmp uses a grid-based layout to render the completion menu. The components, defined in `draw.components[string]`, define `text` and `highlight` functions, called for each item. The `highlight` function will be called only when the item appears on screen, so expensive operations such as Treesitter highlighting may be performed (contributions welcome!, [for example](https://www.reddit.com/r/neovim/comments/1ca4gm2/colorful_cmp_menu_powered_by_treesitter/)). The components may define their min and max width, where `ellipsis = true` (enabled by default), will draw the `` character when the text is truncated. Setting `width.fill = true` will fill the remaining space, effectively making subsequent components right aligned, with the respect to their column.

Columns effectively allow you to vertically align a set of components. Each column, defined as an array in `draw.columns`, will be rendered for all of the completion items, where the longest rendered row will determine the width of the column. You may define `gap = number` in your column to insert a gap between components.

For a setup similar to nvim-cmp, use the following config:

```lua
{
windows = {
autocomplete = {
draw = {
columns = { { "label", "label_description", gap = 1 }, { "kind_icon", "kind" } },
},
},
}
}

## How it works

The plugin use a 4 stage pipeline: trigger -> sources -> fuzzy -> render
Expand Down
1 change: 1 addition & 0 deletions lua/blink/cmp/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,7 @@ local config = {
selection = 'preselect',
-- Controls how the completion items are rendered on the popup window
draw = {
-- Aligns the keyword you've typed to a component in the menu
align_to_component = 'label', -- or 'none' to disable
-- Left and right padding, optionally { left, right } for different padding on each side
padding = 1,
Expand Down

0 comments on commit b12043f

Please sign in to comment.