Skip to content
Draft

V2 #2232

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 0 additions & 15 deletions build.rs

This file was deleted.

4 changes: 2 additions & 2 deletions doc/configuration/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ completion.trigger = {
show_on_insert = false,

-- LSPs can indicate when to show the completion window via trigger characters
-- however, some LSPs (i.e. tsserver) return characters that would essentially
-- however, some LSPs (e.g. tsserver) return characters that would essentially
-- always show the window. We block these by default.
show_on_blocked_trigger_characters = { ' ', '\n', '\t' },
-- You can also block per filetype with a function:
Expand Down Expand Up @@ -414,7 +414,7 @@ fuzzy = {
-- Location of the frecency database
path = vim.fn.stdpath('state') .. '/blink/cmp/frecency.dat',
-- UNSAFE!! When enabled, disables the lock and fsync when writing to the frecency database.
-- This should only be used on unsupported platforms (i.e. alpine termux)
-- This should only be used on unsupported platforms (e.g. alpine termux)
unsafe_no_lock = false,
},
use_frecency = true, -- deprecated alias for frecency.enabled, will be removed in v2.0
Expand Down
2 changes: 1 addition & 1 deletion doc/development/architecture.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Architecture

The plugin use a 4 stage pipeline: trigger -> sources -> fuzzy -> render
1. **Trigger:** Controls when to request completion items from the sources and provides a context downstream with the current query (i.e. `hello.wo|`, the query would be `wo`) and the treesitter object under the cursor (i.e. for intelligently enabling/disabling sources). It respects trigger characters passed by the LSP (or any other source) and includes it in the context for sending to the LSP.
1. **Trigger:** Controls when to request completion items from the sources and provides a context downstream with the current query (e.g. `hello.wo|`, the query would be `wo`) and the treesitter object under the cursor (i.e. for intelligently enabling/disabling sources). It respects trigger characters passed by the LSP (or any other source) and includes it in the context for sending to the LSP.
2. **Sources:** Provides a common interface for and merges the results of completion, trigger character, resolution of additional information and cancellation. Some sources are builtin: `LSP`, `buffer`, `path`, `snippets`
3. **Fuzzy:** Rust <-> Lua FFI which performs both filtering and sorting of the items
- **Filtering:** The fuzzy matching uses smith-waterman, same as FZF, but implemented in SIMD for ~6x the performance of FZF (TODO: add benchmarks). Due to the SIMD's performance, the prefiltering phase on FZF was dropped to allow for typos. Similar to fzy/fzf, additional points are given to prefix matches, characters with capitals (to promote camelCase/PascalCase first char matching) and matches after delimiters (to promote snake_case first char matching)
Expand Down
6 changes: 3 additions & 3 deletions doc/development/source-boilerplate.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,12 @@ function source:get_completions(ctx, callback)
callback({
items = items,
-- Whether blink.cmp should request items when deleting characters
-- from the keyword (i.e. "foo|" -> "fo|")
-- from the keyword (e.g. "foo|" -> "fo|")
-- Note that any non-alphanumeric characters will always request
-- new items (excluding `-` and `_`)
is_incomplete_backward = false,
-- Whether blink.cmp should request items when adding characters
-- to the keyword (i.e. "fo|" -> "foo|")
-- to the keyword (e.g. "fo|" -> "foo|")
-- Note that any non-alphanumeric characters will always request
-- new items (excluding `-` and `_`)
is_incomplete_forward = false,
Expand All @@ -121,7 +121,7 @@ function source:get_completions(ctx, callback)
end

-- (Optional) Before accepting the item or showing documentation, blink.cmp will call this function
-- so you may avoid calculating expensive fields (i.e. documentation) for only when they're actually needed
-- so you may avoid calculating expensive fields (e.g. documentation) for only when they're actually needed
-- Note only some fields may be resolved lazily. You may check the LSP capabilities for a complete list:
-- `textDocument.completion.completionItem.resolveSupport`
-- At the time of writing: 'documentation', 'detail', 'additionalTextEdits', 'command', 'data'
Expand Down
4 changes: 2 additions & 2 deletions doc/recipes.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ vim.b.completion = false

### Disable completion in *only* shell command mode

When inside of git bash or WSL on windows, you may experience a hang with shell commands. The following disables cmdline completions only when running shell commands (i.e. `[':!' , ':%!']`), but still allows completion in other command modes (i.e. `[':' , ':help', '/' , '?', ...]`).
When inside of git bash or WSL on windows, you may experience a hang with shell commands. The following disables cmdline completions only when running shell commands (e.g. `[':!' , ':%!']`), but still allows completion in other command modes (i.e. `[':' , ':help', '/' , '?', ...]`).

```lua
sources = {
Expand Down Expand Up @@ -279,7 +279,7 @@ sources = {

### Buffer completion from all open buffers

The default behavior is to only show completions from **visible** "normal" buffers (i.e. it wouldn't include neo-tree). This will instead show completions from all buffers, even if they're not visible on screen. Note that the performance impact of this has not been tested.
The default behavior is to only show completions from **visible** "normal" buffers (e.g. it wouldn't include neo-tree). This will instead show completions from all buffers, even if they're not visible on screen. Note that the performance impact of this has not been tested.

```lua
sources = {
Expand Down
180 changes: 180 additions & 0 deletions layout.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
--[[
V2 Overall goals:
- Adopt vim.task: https://github.com/lewis6991/async.nvim
- First-class vim help documentation
- Adopt `iskeyword` for keyword regex by default
- Synchronous API when possible
- Remove sources in favor of LSPs
- Include compat layer for existing blink.cmp sources to in-process LSPs
- Promote building in-process LSPs across the ecosystem (include boilerplate)
- Simplify codebase as much as possible
- Consider removing auto brackets, LSPs should support this themselves
- Switch keymap system to `vim.on_key`
- User calls `cmp.download()` to download prebuilt-binaries or `cmp.build()` to build from source. No automatic download
- Drop custom documentation rendering, in favor of vim.lsp.utils.convert_input_to_markdown_lines (we have conceal lines now!)
- Adopt scrollbar when it's merged: https://github.com/neovim/neovim/pull/35729

Configuration goals:
- Programmatic over declarative
- Follow neovim patterns as much as possible (refer to vim.lsp.*, vim.lsp.inlay_hint.*, etc.)
- Easily configure per-buffer, per-LSP, and dynamically
- First-class vim.pack support
- All on_* event handlers also emit `User` autocommands
--]]

--- @alias filter { bufnr: number?, mode: '*' | ('default' | 'cmdline' | 'term')[] | nil }

local cmp = require('blink.cmp')

-- seek community adoption
vim.g.completion = true -- or vim.b.completion
vim.g.nerd_font_variant = 'mono' -- for 'normal', icons are double-width
vim.g.lsp_item_kind_icons = { Text = '󰉿', ... }

-- blink specific, supports `vim.b` too
vim.g.blink_cmp = true -- equivalent to vim.g.completion, but takes precedence

--- Global ---
cmp.enable(enable?, filter?) -- enabled by default
cmp.is_enabled(filter?)

cmp.show({ lsps = {}, select_item_idx = nil }) -- vim.Task
cmp.hide()

cmp.accept({ select = false, index = nil }) -- vim.Task
cmp.select_next({ count = 1, cycle = true, preview = true })
cmp.select_prev({ count = 1, cycle = true, preview = true })
cmp.select(idx, { preview = true })

--- Keymaps ---
-- now optional, since users can define keymaps themselves and use the (mostly) synchronous `cmp.*` API
-- filter excludes modes
cmp.keymap.preset(mode, preset, filter?) -- cmp.keymap.preset('*', 'tab')
cmp.keymap.set(mode, key, function(cmp) ... end, filter?)
cmp.keymap.del(mode, key, filter?)

cmp.keymap.enable(enable?, filter?) -- enabled by default, but no keybinds are assigned
cmp.keymap.is_enabled(filter?)

--- Completion ---
---- Trigger ----
cmp.trigger.config({
keyword = { range = 'prefix', regex = nil },
on_keyword = true,
on_trigger_character = true,
on_accept_on_trigger_character = true,
on_insert_enter_on_trigger_character = true,
}, filter?)
cmp.trigger.enable(enable?, filter?) -- enabled by default
cmp.trigger.is_enabled(filter?)

cmp.trigger.on_show(function(ctx) end)
cmp.trigger.on_hide(function(ctx) end)

---- List ----
cmp.list.config({
preselect = true,
sorts = { 'score', 'sort_text' },
filters = { function(item) return item.label == 'foo' end },
fuzzy = cmp.fuzzy.rust({
max_typos = function(keyword) return math.floor(#keyword / 4) end,
frecency_path = vim.fn.stdpath('state') .. '/blink/cmp/frecency.dat',
}),
}, filter?) -- ephemeral option? e.g. could set the sort/filter options for a single completion context

cmp.list.get_items()
cmp.list.get_selected_item()
cmp.list.get_selected_item_idx()

cmp.list.on_show(function(ctx, items) end)
cmp.list.on_hide(function(ctx) end)
cmp.list.on_update(function(ctx, items) end)
cmp.list.on_select(function(ctx, item, idx) end)
cmp.list.on_accept(function(ctx, item) end)

---- Menu ----
cmp.menu.config({ ..., docs = { ... } }, filter?)
cmp.menu.enable(enable?, filter?) -- enabled by default
cmp.menu.is_enabled(filter?)

cmp.menu.is_visible()
cmp.menu.get_win()

cmp.menu.on_show(function(ctx) end)
cmp.menu.on_hide(function(ctx) end)

-- Menu Docs --
cmp.menu.docs.show()
cmp.menu.docs.hide()
cmp.menu.docs.scroll_up(count)
cmp.menu.docs.scroll_down(count)

cmp.menu.docs.is_visible()
cmp.menu.docs.get_win()

cmp.menu.docs.on_show(function(ctx) end)
cmp.menu.docs.on_hide(function(ctx) end)

---- Ghost text ----
cmp.ghost_text.enable(enable?, filter?)
cmp.ghost_text.is_enabled(filter?)

cmp.ghost_text.is_visible()
cmp.ghost_text.get_extmark_id()

cmp.ghost_text.on_show(function(ctx) end)
cmp.ghost_text.on_hide(function(ctx) end)

--- LSPs ---
-- sources system is no more, LSPs only, with compat layer for existing sources
cmp.lsp.config(client, options, filter?)
cmp.lsp.config('*', { ... }) -- global
cmp.lsp.config('lua_ls', { min_keyword_length = 2 })
cmp.lsp.config('buffer', { fallback_for = { "*", "!snippets", "!path" } })

-- default configs built-in for some LSPs, for example
cmp.lsp.config('ts_ls', { blocked_trigger_characters = { ' ', '\t', '\n' } })
cmp.lsp.config('emmet', { blocked_trigger_characters = function(char) return not char:match('[A-z]') end })
cmp.lsp.config('rust_analyzer', { bonuses = { frecency = false, proximity = false } })

-- all LSPs are enabled by default, except built-in "buffer", "snippets", "path"
cmp.lsp.enable('buffer', enable?, filter?)
cmp.lsp.enable({ 'buffer', 'path' }, enable?, filter?)
cmp.lsp.is_enabled('buffer', filter?)

--- Snippets ---
-- drop support for pulling snippets from luasnip/mini.snippets. encourage them to support in-process LSPs
-- as a result, this only affects how snippets are expanded/navigated
cmp.snippet.preset('luasnip', filter?) -- use a preset
cmp.snippet.config({ ... }, filter?) -- or define yourself

cmp.snippet.active(filter?)
cmp.snippet.jump(direction)

cmp.snippet.registry.add({ ... })
cmp.snippet.registry.remove({ ... })
cmp.snippet.registry.load({ ...paths }) -- vim.Task
cmp.snippet.registry.load_friendly_snippets()
cmp.snippet.registry.reload() -- vim.Task (reloads from .load() paths only)
cmp.snippet.registry.clear()

--- Signature ---
cmp.signature.config({
docs = false,
direction_priority = { 'n', 's' },
window = { ... }
}, filter?)
cmp.signature.enable(enable?, filter?) -- enabled by default
cmp.signature.is_enabled(filter?)

cmp.signature.show() -- vim.Task
cmp.signature.hide()
cmp.signature.scroll_up(count)
cmp.signature.scroll_down(count)

cmp.signature.get_signatures()
cmp.signature.is_visible()
cmp.signature.get_win()

cmp.signature.on_show(function(ctx, signatures) end)
cmp.signature.on_hide(function(ctx) end)
125 changes: 0 additions & 125 deletions lua/blink/cmp/completion/accept/init.lua

This file was deleted.

Loading
Loading