This plugin has moved to sr.ht and development will continue there
A tree-sitter powered completion framework built for Neovim, configured with functions.
Features and design goals:
- Synchronous
- Configured using functions
- Syntax-aware completion
- No autocompletion
use {'https://git.sr.ht/~vigoux/complementree.nvim', requires = {'L3MON4D3/LuaSnip', 'nvim-treesitter/nvim-treesitter'} }
complementree.nvim
works using functions that are called based on
the syntax tree of the file. An example configuration is the
following:
local comp = require"complementree"
local s = require"complementree.defaults"
local lsp_completion = {
default = s.lsp,
string = s.ins_completion "C-F",
comment = s.dummy
}
comp.setup {
default = s.ins_completion "C-N",
vim = s.ins_completion "C-V",
c = lsp_completion,
lua = lsp_completion,
rust = lsp_completion
}
We define a set of sources
that are triggered when calling the
complementree.complete()
function.
The defaults are:
treesitter
: all names defined in the current file (very basic for now)lsp
: lsp-only source, with LSP snippets enabledluasnip
: luasnip snippetsctags
: tagfile elements, a more configurable form of<C-X><C-]>
filepath
: paths under the current directorydummy
: nothingins_completion
: trigger a<C-X><C-*>
completion
After calling the setup
function, you can trigger completion by
calling complementree.complete()
.
You can combine the matches of sources using things called combinators.
There is a few combinators already existing, that take a matches function as input:
combine
: just concatenates the results of multiple matches functions, returns a matches functionchain
: mimics mucomplete chaining, returns the first non-empty matches of the provided functionsnon_empty_prefix
: checks that the prefix is non-empty before triggering completionoptional
: takes two matches functions, and triggers the second one only if the first one returns at least one resultwrap
: triggers the completion using this matches function.
The currently implemented matches functions are:
lsp_matches
: for lsp-only matchesluasnip_matches
: for LuaSnip matches.filepath_matches
: for files under the current directoryctags_matches
: for matches in the current tagfiletreesitter_matches
: for symbols defined in the current file (basic for now)
All the _matches
function take a table of options as parameters, dig
into the sources file for more info
about that.
Using combinators, you can complete using LSP + LuaSnip with the following:
local s = require"complementree.sources"
local cc = require"complementree.combinators"
lsp_and_luasnip = cc.combine(s.luasnip_matches {}, s.lsp_matches {})
There are two special types of combinators: filters and comparators.
They simply change the order and filter the completion results, and there are quite a bunch of them.
prefix
: only keep suggestions that start with the current written wordstrict_prefix
: same asprefix
but be a strict prefix (different than written word)amount(n)
: only take the firstn
suggestions
alphabetic
: sort results alphabeticallylength
: sort results by length If you haveromgrk/fzy-lua-native
installed, there will also be:fzy
: sort based on the fuzzy score (case sensitive)ifzy
: case insensitive version
In your setup calls, for a specific filetype completion, you can specify your completion filters based on queries. What this will do is use the query to determine whether the provided completion method should be triggered. For example, those are equivalent:
-- This
{
comment = defaults.lsp
}
-- Is equivalent to that
{
["(comment) @c"] = defaults.lsp
}
-- And that
{
["(comment) @c"] = { c = defaults.lsp }
}
As a key, you can specify a table, and in this case, depending on what capture of the query the current cursor position matches, you will trigger the corresponding completion method.
A threading-macro-like function in also provided for convenience,
which looks line combinators.pipeline(source, ...)
and just applies
all combinators in the ...
one by one.
Fuzzy LSP:
combinators.pipeline(sources.lsp_matches {}, comparators.fzy, filters.amount(6))
Fuzzy LSP and LuaSnip only if LSP returns something:
combinators.pipeline(combinators.optional(source.lsp_matches {}, source.luasnip_matches {}), comparators.fzy, filters.amount(6))
Look in the defaults file for more.