-
Notifications
You must be signed in to change notification settings - Fork 192
/
mini-completion.txt
257 lines (206 loc) · 10.8 KB
/
mini-completion.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
*mini.completion* Completion and signature help
*MiniCompletion*
MIT License Copyright (c) 2021 Evgeni Chasnovski
==============================================================================
Key design ideas:
- Have an async (with customizable "debounce" delay) "two-stage chain
completion": first try to get completion items from LSP client (if set
up) and if no result, fallback to custom action.
- Managing completion is done as much with Neovim's built-in tools as
possible.
Features:
- Two-stage chain completion:
- First stage is an LSP completion implemented via
|MiniCompletion.completefunc_lsp()|. It should be set up as either
|completefunc| or |omnifunc|. It tries to get completion items from
LSP client (via 'textDocument/completion' request). Custom
preprocessing of response items is possible (with
`MiniCompletion.config.lsp_completion.process_items`), for example
with fuzzy matching. By default items which are not snippets and
directly start with completed word are kept and sorted according to
LSP specification. Supports `additionalTextEdits`, like auto-import
and others (see 'Notes').
- If first stage is not set up or resulted into no candidates, fallback
action is executed. The most tested actions are Neovim's built-in
insert completion (see |ins-completion|).
- Automatic display in floating window of completion item info (via
'completionItem/resolve' request) and signature help (with highlighting
of active parameter if LSP server provides such information). After
opening, window for signature help is fixed and is closed when there is
nothing to show, text is different or
when leaving Insert mode.
- Automatic actions are done after some configurable amount of delay. This
reduces computational load and allows fast typing (completion and
signature help) and item selection (item info)
- User can force two-stage completion via
|MiniCompletion.complete_twostage()| (by default is mapped to
`<C-Space>`) or fallback completion via
|MiniCompletion.complete_fallback()| (mapped to `<M-Space>`).
What it doesn't do:
- Snippet expansion.
- Many configurable sources.
- Automatic mapping of `<CR>`, `<Tab>`, etc., as those tend to have highly
variable user expectations. See 'Helpful key mappings' for suggestions.
# Setup~
This module needs a setup with `require('mini.completion').setup({})`
(replace `{}` with your `config` table). It will create global Lua table
`MiniCompletion` which you can use for scripting or manually (with
`:lua MiniCompletion.*`).
See |MiniCompletion.config| for `config` structure and default values.
You can override runtime config settings locally to buffer inside
`vim.b.minicompletion_config` which should have same structure as
`MiniCompletion.config`. See |mini.nvim-buffer-local-config| for more details.
# Notes~
- More appropriate, albeit slightly advanced, LSP completion setup is to set
it not on every `BufEnter` event (default), but on every attach of LSP
client. To do that:
- Use in initial config:
`lsp_completion = {source_func = 'omnifunc', auto_setup = false}`.
- In `on_attach()` of every LSP client set 'omnifunc' option to exactly
`v:lua.MiniCompletion.completefunc_lsp`.
- If you have trouble using custom (overridden) |vim.ui.input| (like from
'stevearc/dressing.nvim'), make automated disable of 'mini.completion'
for input buffer. For example, currently for 'dressing.nvim' it can be
with `au FileType DressingInput lua vim.b.minicompletion_disable = true`.
- Support of `additionalTextEdits` tries to handle both types of servers:
- When `additionalTextEdits` are supplied in response to
'textDocument/completion' request (like currently in 'pyright').
- When `additionalTextEdits` are supplied in response to
'completionItem/resolve' request (like currently in
'typescript-language-server'). In this case to apply edits user needs
to trigger such request, i.e. select completion item and wait for
`MiniCompletion.config.delay.info` time plus server response time.
# Comparisons~
- 'nvim-cmp':
- More complex design which allows multiple sources each in form of
separate plugin. `MiniCompletion` has two built in: LSP and fallback.
- Supports snippet expansion.
- Doesn't have customizable delays for basic actions.
- Doesn't allow fallback action.
- Doesn't provide signature help.
# Helpful key mappings~
To use `<Tab>` and `<S-Tab>` for navigation through completion list, make
these key mappings:
`vim.keymap.set('i', '<Tab>', [[pumvisible() ? "\<C-n>" : "\<Tab>"]], { expr = true })`
`vim.keymap.set('i', '<S-Tab>', [[pumvisible() ? "\<C-p>" : "\<S-Tab>"]], { expr = true })`
To get more consistent behavior of `<CR>`, you can use this template in
your 'init.lua' to make customized mapping: >
local keys = {
['cr'] = vim.api.nvim_replace_termcodes('<CR>', true, true, true),
['ctrl-y'] = vim.api.nvim_replace_termcodes('<C-y>', true, true, true),
['ctrl-y_cr'] = vim.api.nvim_replace_termcodes('<C-y><CR>', true, true, true),
}
_G.cr_action = function()
if vim.fn.pumvisible() ~= 0 then
-- If popup is visible, confirm selected item or add new line otherwise
local item_selected = vim.fn.complete_info()['selected'] ~= -1
return item_selected and keys['ctrl-y'] or keys['ctrl-y_cr']
else
-- If popup is not visible, use plain `<CR>`. You might want to customize
-- according to other plugins. For example, to use 'mini.pairs', replace
-- next line with `return require('mini.pairs').cr()`
return keys['cr']
end
end
vim.keymap.set('i', '<CR>', 'v:lua._G.cr_action()', { expr = true })
<
# Highlight groups~
* `MiniCompletionActiveParameter` - highlighting of signature active parameter.
By default displayed as plain underline.
To change any highlight group, modify it directly with |:highlight|.
# Disabling~
To disable, set `vim.g.minicompletion_disable` (globally) or
`vim.b.minicompletion_disable` (for a buffer) to `true`. Considering high
number of different scenarios and customization intentions, writing exact
rules for disabling module's functionality is left to user. See
|mini.nvim-disabling-recipes| for common recipes.
------------------------------------------------------------------------------
*MiniCompletion.setup()*
`MiniCompletion.setup`({config})
Module setup
Parameters~
{config} `(table|nil)` Module config table. See |MiniCompletion.config|.
Usage~
`require('mini.completion').setup({})` (replace `{}` with your `config` table)
------------------------------------------------------------------------------
*MiniCompletion.config*
`MiniCompletion.config`
Module config
Default values:
>
MiniCompletion.config = {
-- Delay (debounce type, in ms) between certain Neovim event and action.
-- This can be used to (virtually) disable certain automatic actions by
-- setting very high delay time (like 10^7).
delay = { completion = 100, info = 100, signature = 50 },
-- Configuration for action windows:
-- - `height` and `width` are maximum dimensions.
-- - `border` defines border (as in `nvim_open_win()`).
window = {
info = { height = 25, width = 80, border = 'none' },
signature = { height = 25, width = 80, border = 'none' },
},
-- Way of how module does LSP completion
lsp_completion = {
-- `source_func` should be one of 'completefunc' or 'omnifunc'.
source_func = 'completefunc',
-- `auto_setup` should be boolean indicating if LSP completion is set up
-- on every `BufEnter` event.
auto_setup = true,
-- `process_items` should be a function which takes LSP
-- 'textDocument/completion' response items and word to complete. Its
-- output should be a table of the same nature as input items. The most
-- common use-cases are custom filtering and sorting. You can use
-- default `process_items` as `MiniCompletion.default_process_items()`.
process_items = --<function: filters out snippets; sorts by LSP specs>,
},
-- Fallback action. It will always be run in Insert mode. To use Neovim's
-- built-in completion (see `:h ins-completion`), supply its mapping as
-- string. Example: to use 'whole lines' completion, supply '<C-x><C-l>'.
fallback_action = --<function: like `<C-n>` completion>,
-- Module mappings. Use `''` (empty string) to disable one. Some of them
-- might conflict with system mappings.
mappings = {
force_twostep = '<C-Space>', -- Force two-step completion
force_fallback = '<A-Space>', -- Force fallback completion
},
-- Whether to set Vim's settings for better experience (modifies
-- `shortmess` and `completeopt`)
set_vim_settings = true,
}
<
------------------------------------------------------------------------------
*MiniCompletion.complete_twostage()*
`MiniCompletion.complete_twostage`({fallback}, {force})
Run two-stage completion
Parameters~
{fallback} `(boolean|nil)` Whether to use fallback completion. Default: `true`.
{force} `(boolean|nil)` Whether to force update of completion popup.
Default: `true`.
------------------------------------------------------------------------------
*MiniCompletion.complete_fallback()*
`MiniCompletion.complete_fallback`()
Run fallback completion
------------------------------------------------------------------------------
*MiniCompletion.stop()*
`MiniCompletion.stop`({actions})
Stop actions
This stops currently active (because of module delay or LSP answer delay)
actions.
Designed to be used with |autocmd|. No need to use it directly, everything
is setup in |MiniCompletion.setup|.
Parameters~
{actions} `(table|nil)` Array containing any of 'completion', 'info', or
'signature' string. Default: array containing all of them.
------------------------------------------------------------------------------
*MiniCompletion.completefunc_lsp()*
`MiniCompletion.completefunc_lsp`({findstart}, {base})
Module's |complete-function|
This is the main function which enables two-stage completion. It should be
set as one of |completefunc| or |omnifunc|.
No need to use it directly, everything is setup in |MiniCompletion.setup|.
------------------------------------------------------------------------------
*MiniCompletion.default_process_items()*
`MiniCompletion.default_process_items`({items}, {base})
Default `MiniCompletion.config.lsp_completion.process_items`
vim:tw=78:ts=8:noet:ft=help:norl: