dev (#813)
* feat: completion menu borders (#472)
* feat(custom_entries_view): pass custom border option
* feat(window): calculate offset needed for borders
* fix(window): adjust window height w/ too many results
* fix(window): center scrollbar with borders
* ref(custom_entries_view): use `FloatBorder` for borders
* fix(window): offset at bottom of window
* ref(window): move height adjustment to more logical place
* fix(window): improve popup placement
* fix(window): `border_offset` always `0` first time
* feat(window): support compact scrollbar with border
* fix(window): completion popup on cursorline
* perf(window): simplify offset calculation
String indexing will result in the same thing as if I gated it behind
`type()` calls here.
* docs(window): add `border` to `cmp.WindowStyle`
* docs(window): correct `border_offset_scrollbar`
* perf(window): calulated row -> `screenrow`
This will also be more accurate since it accounts for wrapped lines, as
well as buffers.
* fix(window): edge case with multiple splits
* ref(winhighlight): don't specify defaults by default
`NormalFloat:NormalFloat` isn't needed, since `NormalFloat` defaults to
`NormalFloat`. As for `FloatBorder`, that should be set to `Floatborder`
rather than `NormalFloat` or else you get unintended artifacts on the
edges of borders.
* fix(window): popup covers cursor when scrollbar disappears
* ref(window): calc `border_offset_col` on `set_style`
* perf(window): remove unecessary `col` calculation
Taking it out didn't change anything about the popup behavior.
* feat: add `CmpItemMenuThumb` group
* feat(window): improve scrollbar appearance
* chore(window): remove references to unused property
* docs: document new option `thin_scrollbar`
* ref(plugin): remove background from `thin_scrollbar`
* feat(view): pass `thin_scrollbar` option to window
* feat(window): gate new `thin_scrollbar` behind option
* fix(window): cmdline bugging out
* fix(cmp): docs_view pops up overlapped when using borders
This is related to 1cfe2f7dfd. The
calculation for how the popup position is calculated was changed, and
so it needed to be reworked to include borders in order to be able to
work.
* ref: `thin_scrollbar` flag -> `scrollbar` option
This change allows users to define which character they will use for
their scrollbar.
* fix(window): use `scrollbar` setting for scrollbar character
Thanks @Astrantia for pointing this one out.
* docs(README): add completion appearance options to FAQ
* fix(): account for `border_offset_row` with `has_bottom_space`
* style(custom_entries_view): group offset with `row`/`col`
* fix(window): scrollbar at full view height
Because the `bar_height` variable must be whole number, and must be rounded up
from a percent, there is a change that we will end up with the maximum
height as a number.
For example, `info.height` = 24 and `total` = 25.
* feat(window): allow scrollbar to be disabled
* fix(window): scrollbar size < 1
* ref(cmp): move border logic to `window.info`
* ref!: window highlighting based on borders
BREAKING CHANGE: `documentation.winhighlight` does not determine the
highlighting of the `documentation` view— `CmpWindow`
or `CmpBorderedWindow` depending on whether it has a
border.
* ref!: float appearance opts -> `cmp.setup.window`
`cmp.setup.completion.border` and `.scrollbar` were both moved to
`cmp.setup.window.completion.border` and `.scrollbar`
BREAKING CHANGE: `cmp.setup.documentation` has been moved to
`cmp.window.documentation`, as all of the pertaining
options were cosmetic.
TODO: document the change
* fix(window): attempt to get scrollbar's border
* fix(cmp): restore `view.menu.hl_group`
* fix(window): wrong scrollbar position
* ref: get default `CmpItemMenu` from border existence
* chore(cmp): remove old PR comments
* fix(window): scrollbar sometimes too big
* fix(window): docs far away with complete menu scrollbar
* perf(docs_view): reuse `border_width` value
* rev(cmp): restore `CmpItemMenu`
* ref(cmp): distinguish between `ScrollBar` and `ScrollThumb`
* fix(plugin): consistently refer to `Thumb` as `Thumb`
* rev(window): `Pmenu`-style scrollbar when no border
* fix(window): docs_view size wrong when first shown
* fix(window): docs_view scrollbar not responding to size
* fix(window): scrollbar sometimes to small, take 2
* fix(window): scrollbar bg not hiding
* ref(docs_view): put docs closer to completion menu
* fix(window): scrollbar position wrong with right border
* ref(config): add default border to documentation
* fix(window): scrollbar too close without border
* ref(plugin): link `CmpWindow` to `Pmenu`
I set `CmpWindow` to `NormalFloat`, because that is what you would
expect a floating window to use for a highlight group. However at
request I changed it to `Pmenu`.
* ref(plugin): link `CmpWindowBorder` to `CmpWindow`
* fix(window): scrollbar following thumb while scrolling
* ref: add more highlight groups
There just weren't enough highlight groups to satisfy the demands of the
project. If you change `CmpWindow` to `Pmenu`, then the `docs_view`
becomes `Pmenu` as well when on `main` it is `NormalFloat`.
* fix(window): scrollbar overlapping `docs_view` by default
* ref: remove `Bordered` highlight variants
* ref(utils): extract whitespace check to func
* feat: `window.completion.zindex` setting
* ref: `maxwidth|height` -> `max_`
* ref: simplify highlight groups
* feat: `window.*.winhighlight` setting
* ref(utils): `is_whitespace_char` -> `is_visible`
As hrsh7th noted, `''` is not a whitespace character. Yet, it is
necessary to group `''` and `' '` together for certain border behaviors
that are based on visibility. Thus I have renamed the function
* feat: specify `window.*.winhighlight` for un/bordered
* fix(custom_entries_view): set `winhighlight` on `open`
* ref: remove `Cmp*Scroll*` variants
There's no way for `window` to know which kind of window it is drawing a
scrollbar on. Simpler to just have one kind of scrollbar
* feat: distinguish between bordered and unbordered
* ref(cmp): `is_visible` -> `is_invisible`
That's what the function was checking for.
* fix(default): mislabeling of `default` and `bordered`
* chore: rebase fixup
* Change default highlight
* Add misc.rep
* Fix left-side docs_view with scrollbar
* Fix scrollbar
* Fix sbar/thumb win
Improve highlights
* Remove scrollbar cutomization for now
* Remove scrollbar option
* Simplify implementation
* Fix doc width
* Fix outdated docs
* Add comments
* Fix configuration schema
* fmt
* Fix for lint
Co-authored-by: Iron-E <36409591+Iron-E@users.noreply.github.com>
Co-authored-by: hrsh7th <>
This commit is contained in:
87
README.md
87
README.md
@@ -75,6 +75,10 @@ lua <<EOF
|
|||||||
-- vim.fn["UltiSnips#Anon"](args.body) -- For `ultisnips` users.
|
-- vim.fn["UltiSnips#Anon"](args.body) -- For `ultisnips` users.
|
||||||
end,
|
end,
|
||||||
},
|
},
|
||||||
|
window = {
|
||||||
|
-- completion = cmp.config.window.bordered(),
|
||||||
|
-- documentation = cmp.config.window.bordered(),
|
||||||
|
},
|
||||||
mapping = {
|
mapping = {
|
||||||
['<C-b>'] = cmp.mapping(cmp.mapping.scroll_docs(-4), { 'i', 'c' }),
|
['<C-b>'] = cmp.mapping(cmp.mapping.scroll_docs(-4), { 'i', 'c' }),
|
||||||
['<C-f>'] = cmp.mapping(cmp.mapping.scroll_docs(4), { 'i', 'c' }),
|
['<C-f>'] = cmp.mapping(cmp.mapping.scroll_docs(4), { 'i', 'c' }),
|
||||||
@@ -131,85 +135,16 @@ lua <<EOF
|
|||||||
EOF
|
EOF
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Where can I find more completion sources?
|
### Where can I find more completion sources?
|
||||||
|
|
||||||
A list of available sources can be found in the [Wiki](https://github.com/hrsh7th/nvim-cmp/wiki/List-of-sources) or by searching for projects that match the nvim-cmp [GitHub topic](https://github.com/topics/nvim-cmp).
|
- See the [Wiki](https://github.com/hrsh7th/nvim-cmp/wiki/List-of-sources)
|
||||||
|
- See the [GitHub topic](https://github.com/topics/nvim-cmp).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Where can I find advanced configuration examples?
|
### Where can I find advanced configuration examples?
|
||||||
|
|
||||||
Please see the corresponding [FAQ](#how-to-show-name-of-item-kind-and-source-like-compe) section or [Wiki pages](https://github.com/hrsh7th/nvim-cmp/wiki).
|
See the [Wiki](https://github.com/hrsh7th/nvim-cmp/wiki)
|
||||||
|
|
||||||
|
|
||||||
Advanced configuration example
|
|
||||||
====================
|
|
||||||
|
|
||||||
### Use nvim-cmp as smart omnifunc handler.
|
|
||||||
|
|
||||||
nvim-cmp can be used as flexible omnifunc manager.
|
|
||||||
|
|
||||||
```lua
|
|
||||||
local cmp = require('cmp')
|
|
||||||
cmp.setup {
|
|
||||||
completion = {
|
|
||||||
autocomplete = false, -- disable auto-completion.
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
_G.vimrc = _G.vimrc or {}
|
|
||||||
_G.vimrc.cmp = _G.vimrc.cmp or {}
|
|
||||||
_G.vimrc.cmp.lsp = function()
|
|
||||||
cmp.complete({
|
|
||||||
config = {
|
|
||||||
sources = {
|
|
||||||
{ name = 'nvim_lsp' }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
end
|
|
||||||
_G.vimrc.cmp.snippet = function()
|
|
||||||
cmp.complete({
|
|
||||||
config = {
|
|
||||||
sources = {
|
|
||||||
{ name = 'vsnip' }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
vim.cmd([[
|
|
||||||
inoremap <C-x><C-o> <Cmd>lua vimrc.cmp.lsp()<CR>
|
|
||||||
inoremap <C-x><C-s> <Cmd>lua vimrc.cmp.snippet()<CR>
|
|
||||||
]])
|
|
||||||
```
|
|
||||||
|
|
||||||
### Full managed completion behavior.
|
|
||||||
|
|
||||||
```lua
|
|
||||||
local cmp = require('cmp')
|
|
||||||
|
|
||||||
cmp.setup {
|
|
||||||
completion = {
|
|
||||||
autocomplete = false, -- disable auto-completion.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_G.vimrc = _G.vimrc or {}
|
|
||||||
_G.vimrc.cmp = _G.vimrc.cmp or {}
|
|
||||||
_G.vimrc.cmp.on_text_changed = function()
|
|
||||||
local cursor = vim.api.nvim_win_get_cursor(0)
|
|
||||||
local line = vim.api.nvim_get_current_line()
|
|
||||||
local before = string.sub(line, 1, cursor[2] + 1)
|
|
||||||
if before:match('%s*$') then
|
|
||||||
cmp.complete() -- Trigger completion only if the cursor is placed at the end of line.
|
|
||||||
end
|
|
||||||
end
|
|
||||||
vim.cmd([[
|
|
||||||
augroup vimrc
|
|
||||||
autocmd
|
|
||||||
autocmd TextChanged,TextChangedI,TextChangedP * call luaeval('vimrc.cmp.on_text_changed()')
|
|
||||||
augroup END
|
|
||||||
]])
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
123
doc/cmp.txt
123
doc/cmp.txt
@@ -14,11 +14,10 @@ Command |cmp-command|
|
|||||||
Highlight |cmp-highlight|
|
Highlight |cmp-highlight|
|
||||||
Autocmd |cmp-autocmd|
|
Autocmd |cmp-autocmd|
|
||||||
Config |cmp-config|
|
Config |cmp-config|
|
||||||
|
Config Helper |cmp-config-helper|
|
||||||
Develop |cmp-develop|
|
Develop |cmp-develop|
|
||||||
FAQ |cmp-faq|
|
FAQ |cmp-faq|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
Abstract *cmp-abstract*
|
Abstract *cmp-abstract*
|
||||||
|
|
||||||
@@ -29,8 +28,6 @@ This is nvim-cmp's document.
|
|||||||
2. The advanced configuration is noted in wiki.
|
2. The advanced configuration is noted in wiki.
|
||||||
- https://github.com/hrsh7th/nvim-cmp/wiki
|
- https://github.com/hrsh7th/nvim-cmp/wiki
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
Concept *cmp-concept*
|
Concept *cmp-concept*
|
||||||
|
|
||||||
@@ -39,8 +36,6 @@ Concept *cmp-concept*
|
|||||||
- Smart handling of key mapping
|
- Smart handling of key mapping
|
||||||
- No flicker
|
- No flicker
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
Usage *cmp-usage*
|
Usage *cmp-usage*
|
||||||
|
|
||||||
@@ -92,6 +87,10 @@ NOTE:
|
|||||||
-- vim.fn["UltiSnips#Anon"](args.body) -- For `ultisnips` users.
|
-- vim.fn["UltiSnips#Anon"](args.body) -- For `ultisnips` users.
|
||||||
end,
|
end,
|
||||||
},
|
},
|
||||||
|
window = {
|
||||||
|
-- completion = cmp.config.window.bordered(),
|
||||||
|
-- documentation = cmp.config.window.bordered(),
|
||||||
|
},
|
||||||
mapping = {
|
mapping = {
|
||||||
['<C-d>'] = cmp.mapping(cmp.mapping.scroll_docs(-4), { 'i', 'c' }),
|
['<C-d>'] = cmp.mapping(cmp.mapping.scroll_docs(-4), { 'i', 'c' }),
|
||||||
['<C-f>'] = cmp.mapping(cmp.mapping.scroll_docs(4), { 'i', 'c' }),
|
['<C-f>'] = cmp.mapping(cmp.mapping.scroll_docs(4), { 'i', 'c' }),
|
||||||
@@ -139,7 +138,6 @@ NOTE:
|
|||||||
EOF
|
EOF
|
||||||
<
|
<
|
||||||
|
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
Function *cmp-function*
|
Function *cmp-function*
|
||||||
|
|
||||||
@@ -232,8 +230,6 @@ NOTE: You can call these functions in mapping via `<Cmd>lua require('cmp').compl
|
|||||||
- `complete_done`: emit after current completion is done.
|
- `complete_done`: emit after current completion is done.
|
||||||
- `confirm_done`: emit after confirmation is done.
|
- `confirm_done`: emit after confirmation is done.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
Mapping *cmp-mapping*
|
Mapping *cmp-mapping*
|
||||||
|
|
||||||
@@ -305,8 +301,6 @@ You can also use built-in mapping helpers.
|
|||||||
The built-in mapping helper is only available as a configuration option.
|
The built-in mapping helper is only available as a configuration option.
|
||||||
If you want to call the nvim-cmp features directly, please use |cmp-function| instead.
|
If you want to call the nvim-cmp features directly, please use |cmp-function| instead.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
Command *cmp-command*
|
Command *cmp-command*
|
||||||
|
|
||||||
@@ -315,8 +309,6 @@ Command *cmp-command*
|
|||||||
Sometimes `unknown` source will be printed but it isn't problem. (e.g. `cmp-nvim-lsp`)
|
Sometimes `unknown` source will be printed but it isn't problem. (e.g. `cmp-nvim-lsp`)
|
||||||
That the reason is the `cmp-nvim-lsp` will registered on the InsertEnter autocmd.
|
That the reason is the `cmp-nvim-lsp` will registered on the InsertEnter autocmd.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
Highlight *cmp-highlight*
|
Highlight *cmp-highlight*
|
||||||
|
|
||||||
@@ -345,7 +337,6 @@ Highlight *cmp-highlight*
|
|||||||
The menu field's highlight group.
|
The menu field's highlight group.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
Autocmd *cmp-autocmd*
|
Autocmd *cmp-autocmd*
|
||||||
|
|
||||||
@@ -524,6 +515,32 @@ view~
|
|||||||
Specify the view class to customize appearance.
|
Specify the view class to customize appearance.
|
||||||
Currently, the possible configurations are:
|
Currently, the possible configurations are:
|
||||||
|
|
||||||
|
*cmp-config.window.{completion,documentation}.border*
|
||||||
|
window.{completion,documentation}.border~
|
||||||
|
`string | string[] | nil`
|
||||||
|
Border characters used for the completion popup menu when
|
||||||
|
|experimental.native_menu| is disabled.
|
||||||
|
|
||||||
|
*cmp-config.window.{completion,documentation}.winhighlight*
|
||||||
|
window.{completion,documentation}.winhighlight~
|
||||||
|
`string | cmp.WinhighlightConfig`
|
||||||
|
Specify the window's winhighlight option.
|
||||||
|
|
||||||
|
*cmp-config.window.{completion,documentation}.zindex*
|
||||||
|
window.{completion,documentation}.zindex~
|
||||||
|
`number`
|
||||||
|
The completion window's zindex.
|
||||||
|
|
||||||
|
*cmp-config.window.documentation.max_width*
|
||||||
|
window.documentation.max_width~
|
||||||
|
`number`
|
||||||
|
The documentation window's max width.
|
||||||
|
|
||||||
|
*cmp-config.window.documentation.max_height*
|
||||||
|
window.documentation.max_height~
|
||||||
|
`number`
|
||||||
|
The documentation window's max height.
|
||||||
|
|
||||||
*cmp-config.experimental.ghost_text*
|
*cmp-config.experimental.ghost_text*
|
||||||
experimental.ghost_text~
|
experimental.ghost_text~
|
||||||
`boolean | { hl_group = string }`
|
`boolean | { hl_group = string }`
|
||||||
@@ -531,6 +548,66 @@ experimental.ghost_text~
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
Config Helper *cmp-config-helper*
|
||||||
|
|
||||||
|
You can use the following configuration helpers.
|
||||||
|
|
||||||
|
cmp.config.compare~
|
||||||
|
|
||||||
|
TBD
|
||||||
|
|
||||||
|
cmp.config.context~
|
||||||
|
|
||||||
|
The `cmp.config.context` can be used to context-aware completion toggling.
|
||||||
|
>
|
||||||
|
cmp.setup {
|
||||||
|
enabled = function()
|
||||||
|
-- disable completion if the cursor is `Comment` syntax group.
|
||||||
|
return not cmp.config.context.in_syntax_group('Comment')
|
||||||
|
end
|
||||||
|
}
|
||||||
|
<
|
||||||
|
*cmp.config.context.in_syntax_group* (group)
|
||||||
|
You can specify the vim's built-in syntax group.
|
||||||
|
If you use tree-sitter, You should use `cmp.config.context.in_treesitter_capture` instead.
|
||||||
|
|
||||||
|
*cmp.config.context.in_treesitter_capture* (capture)
|
||||||
|
You can specify the treesitter capture name.
|
||||||
|
If you don't use `nvim-treesitter`, this helper does not work correctly.
|
||||||
|
|
||||||
|
cmp.config.mapping~
|
||||||
|
|
||||||
|
See |:help cmp-mapping|
|
||||||
|
|
||||||
|
cmp.config.sources~
|
||||||
|
|
||||||
|
*cmp.config.sources* (...sources)
|
||||||
|
You can specify multiple sources arrays.
|
||||||
|
The sources are grouped in the order you specify, and the groups are displayed in a fallback, like chain completion.
|
||||||
|
>
|
||||||
|
cmp.setup {
|
||||||
|
window = {
|
||||||
|
completion = cmp.config.window.bordered(),
|
||||||
|
documentation = cmp.config.window.bordered(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
<
|
||||||
|
cmp.config.window~
|
||||||
|
|
||||||
|
*cmp.config.window.bordered* (option)
|
||||||
|
Specify some window as `bordered`.
|
||||||
|
The option is described in the `cmp.ConfigSchema`.
|
||||||
|
>
|
||||||
|
cmp.setup {
|
||||||
|
window = {
|
||||||
|
completion = cmp.config.window.bordered(),
|
||||||
|
documentation = cmp.config.window.bordered(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
<
|
||||||
|
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
Develop *cmp-develop*
|
Develop *cmp-develop*
|
||||||
|
|
||||||
@@ -611,7 +688,6 @@ You can create custom source like the following example.
|
|||||||
require('cmp').register_source('month', source.new())
|
require('cmp').register_source('month', source.new())
|
||||||
<
|
<
|
||||||
|
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
FAQ *cmp-faq*
|
FAQ *cmp-faq*
|
||||||
|
|
||||||
@@ -628,7 +704,6 @@ How to disable the preselect feature? ~
|
|||||||
}
|
}
|
||||||
<
|
<
|
||||||
|
|
||||||
|
|
||||||
How to disable auto-completion?~
|
How to disable auto-completion?~
|
||||||
How to use nvim-cmp as like omnifunc?~
|
How to use nvim-cmp as like omnifunc?~
|
||||||
|
|
||||||
@@ -660,6 +735,17 @@ How to setup on the specific buffer?~
|
|||||||
})
|
})
|
||||||
<
|
<
|
||||||
|
|
||||||
|
How to disable documentation window?~
|
||||||
|
|
||||||
|
You can specify the following config.
|
||||||
|
>
|
||||||
|
cmp.setup.filetype({ 'markdown', 'help' }, {
|
||||||
|
window = {
|
||||||
|
documentation = cmp.config.disable
|
||||||
|
}
|
||||||
|
})
|
||||||
|
<
|
||||||
|
|
||||||
How to integrate with copilot.vim?~
|
How to integrate with copilot.vim?~
|
||||||
|
|
||||||
The copilot.vim and nvim-cmp both have a `key-mapping fallback` mechanism.
|
The copilot.vim and nvim-cmp both have a `key-mapping fallback` mechanism.
|
||||||
@@ -689,8 +775,5 @@ How to customize menu appearance?~
|
|||||||
|
|
||||||
You can see the nvim-cmp wiki (https://github.com/hrsh7th/nvim-cmp/wiki).
|
You can see the nvim-cmp wiki (https://github.com/hrsh7th/nvim-cmp/wiki).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
vim:tw=78:ts=4:et:ft=help:norl:
|
vim:tw=78:ts=2:et:ft=help:norl:
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ config.onetime = {}
|
|||||||
---Set configuration for global.
|
---Set configuration for global.
|
||||||
---@param c cmp.ConfigSchema
|
---@param c cmp.ConfigSchema
|
||||||
config.set_global = function(c)
|
config.set_global = function(c)
|
||||||
config.global = misc.merge(config.normalize(c), config.normalize(config.global))
|
config.global = config.normalize(misc.merge(c, config.global))
|
||||||
config.global.revision = config.global.revision or 1
|
config.global.revision = config.global.revision or 1
|
||||||
config.global.revision = config.global.revision + 1
|
config.global.revision = config.global.revision + 1
|
||||||
end
|
end
|
||||||
@@ -82,7 +82,7 @@ config.get = function()
|
|||||||
global_config.revision or 0,
|
global_config.revision or 0,
|
||||||
onetime_config.revision or 0,
|
onetime_config.revision or 0,
|
||||||
}, function()
|
}, function()
|
||||||
return misc.merge(config.normalize(onetime_config), config.normalize(global_config))
|
return config.normalize(misc.merge(onetime_config, global_config))
|
||||||
end)
|
end)
|
||||||
elseif api.is_cmdline_mode() then
|
elseif api.is_cmdline_mode() then
|
||||||
local cmdtype = vim.fn.getcmdtype()
|
local cmdtype = vim.fn.getcmdtype()
|
||||||
@@ -94,7 +94,7 @@ config.get = function()
|
|||||||
cmdtype,
|
cmdtype,
|
||||||
cmdline_config.revision or 0,
|
cmdline_config.revision or 0,
|
||||||
}, function()
|
}, function()
|
||||||
return misc.merge(config.normalize(cmdline_config), config.normalize(global_config))
|
return config.normalize(misc.merge(cmdline_config, global_config))
|
||||||
end)
|
end)
|
||||||
else
|
else
|
||||||
local bufnr = vim.api.nvim_get_current_buf()
|
local bufnr = vim.api.nvim_get_current_buf()
|
||||||
@@ -111,9 +111,9 @@ config.get = function()
|
|||||||
buffer_config.revision or 0,
|
buffer_config.revision or 0,
|
||||||
}, function()
|
}, function()
|
||||||
local c = {}
|
local c = {}
|
||||||
c = misc.merge(c, config.normalize(buffer_config))
|
c = config.normalize(misc.merge(c, buffer_config))
|
||||||
c = misc.merge(c, config.normalize(filetype_config))
|
c = config.normalize(misc.merge(c, filetype_config))
|
||||||
c = misc.merge(c, config.normalize(global_config))
|
c = config.normalize(misc.merge(c, global_config))
|
||||||
return c
|
return c
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
@@ -160,6 +160,7 @@ config.normalize = function(c)
|
|||||||
-- make sure c is not 'nil'
|
-- make sure c is not 'nil'
|
||||||
c = c == nil and {} or c
|
c = c == nil and {} or c
|
||||||
|
|
||||||
|
-- Normalize mapping.
|
||||||
if c.mapping then
|
if c.mapping then
|
||||||
local normalized = {}
|
local normalized = {}
|
||||||
for k, v in pairs(c.mapping) do
|
for k, v in pairs(c.mapping) do
|
||||||
@@ -168,6 +169,7 @@ config.normalize = function(c)
|
|||||||
c.mapping = normalized
|
c.mapping = normalized
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Notice experimental.native_menu.
|
||||||
if c.experimental and c.experimental.native_menu then
|
if c.experimental and c.experimental.native_menu then
|
||||||
vim.api.nvim_echo({
|
vim.api.nvim_echo({
|
||||||
{ '[nvim-cmp] ', 'Normal' },
|
{ '[nvim-cmp] ', 'Normal' },
|
||||||
@@ -182,6 +184,7 @@ config.normalize = function(c)
|
|||||||
c.view.entries = c.view.entries or 'native'
|
c.view.entries = c.view.entries or 'native'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Notice sources.[n].opts
|
||||||
if c.sources then
|
if c.sources then
|
||||||
for _, s in ipairs(c.sources) do
|
for _, s in ipairs(c.sources) do
|
||||||
if s.opts and not s.option then
|
if s.opts and not s.option then
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ compare.locality = setmetatable({
|
|||||||
self.locality_map[w] = math.min(self.locality_map[w] or d, math.abs(i - cursor_row))
|
self.locality_map[w] = math.min(self.locality_map[w] or d, math.abs(i - cursor_row))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end,
|
||||||
}, {
|
}, {
|
||||||
__call = function(self, entry1, entry2)
|
__call = function(self, entry1, entry2)
|
||||||
local local1 = self.locality_map[entry1:get_word()]
|
local local1 = self.locality_map[entry1:get_word()]
|
||||||
@@ -159,7 +159,7 @@ compare.locality = setmetatable({
|
|||||||
end
|
end
|
||||||
return local1 < local2
|
return local1 < local2
|
||||||
end
|
end
|
||||||
end
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
-- scopes
|
-- scopes
|
||||||
|
|||||||
@@ -86,12 +86,12 @@ return function()
|
|||||||
},
|
},
|
||||||
|
|
||||||
completion = {
|
completion = {
|
||||||
keyword_length = 1,
|
|
||||||
keyword_pattern = [[\%(-\?\d\+\%(\.\d\+\)\?\|\h\w*\%(-\w*\)*\)]],
|
|
||||||
autocomplete = {
|
autocomplete = {
|
||||||
types.cmp.TriggerEvent.TextChanged,
|
types.cmp.TriggerEvent.TextChanged,
|
||||||
},
|
},
|
||||||
completeopt = 'menu,menuone,noselect',
|
completeopt = 'menu,menuone,noselect',
|
||||||
|
keyword_pattern = [[\%(-\?\d\+\%(\.\d\+\)\?\|\h\w*\%(-\w*\)*\)]],
|
||||||
|
keyword_length = 1,
|
||||||
},
|
},
|
||||||
|
|
||||||
formatting = {
|
formatting = {
|
||||||
@@ -125,13 +125,6 @@ return function()
|
|||||||
|
|
||||||
sources = {},
|
sources = {},
|
||||||
|
|
||||||
documentation = {
|
|
||||||
border = { '', '', '', ' ', '', '', '', ' ' },
|
|
||||||
winhighlight = 'NormalFloat:NormalFloat,FloatBorder:NormalFloat',
|
|
||||||
maxwidth = math.floor((WIDE_HEIGHT * 2) * (vim.o.columns / (WIDE_HEIGHT * 2 * 16 / 9))),
|
|
||||||
maxheight = math.floor(WIDE_HEIGHT * (WIDE_HEIGHT / vim.o.lines)),
|
|
||||||
},
|
|
||||||
|
|
||||||
confirmation = {
|
confirmation = {
|
||||||
default_behavior = types.cmp.ConfirmBehavior.Insert,
|
default_behavior = types.cmp.ConfirmBehavior.Insert,
|
||||||
get_commit_characters = function(commit_characters)
|
get_commit_characters = function(commit_characters)
|
||||||
@@ -148,5 +141,18 @@ return function()
|
|||||||
view = {
|
view = {
|
||||||
entries = { name = 'custom', selection_order = 'top_down' },
|
entries = { name = 'custom', selection_order = 'top_down' },
|
||||||
},
|
},
|
||||||
|
|
||||||
|
window = {
|
||||||
|
completion = {
|
||||||
|
border = { '', '', '', '', '', '', '', '' },
|
||||||
|
winhighlight = 'Normal:Pmenu,FloatBorder:Pmenu,CursorLine:PmenuSel,Search:None',
|
||||||
|
},
|
||||||
|
documentation = {
|
||||||
|
max_height = math.floor(WIDE_HEIGHT * (WIDE_HEIGHT / vim.o.lines)),
|
||||||
|
max_width = math.floor((WIDE_HEIGHT * 2) * (vim.o.columns / (WIDE_HEIGHT * 2 * 16 / 9))),
|
||||||
|
border = { '', '', '', ' ', '', '', '', ' ' },
|
||||||
|
winhighlight = 'FloatBorder:NormalFloat',
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|||||||
12
lua/cmp/config/window.lua
Normal file
12
lua/cmp/config/window.lua
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
local window = {}
|
||||||
|
|
||||||
|
window.bordered = function(opts)
|
||||||
|
opts = opts or {}
|
||||||
|
return {
|
||||||
|
border = opts.border or 'rounded',
|
||||||
|
winhighlight = opts.winhighlight or 'Normal:Normal,FloatBorder:Normal,CursorLine:Visual,Search:None',
|
||||||
|
zindex = opts.zindex or 1001,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
return window
|
||||||
@@ -29,6 +29,7 @@ cmp.config.disable = misc.none
|
|||||||
cmp.config.compare = require('cmp.config.compare')
|
cmp.config.compare = require('cmp.config.compare')
|
||||||
cmp.config.sources = require('cmp.config.sources')
|
cmp.config.sources = require('cmp.config.sources')
|
||||||
cmp.config.mapping = require('cmp.config.mapping')
|
cmp.config.mapping = require('cmp.config.mapping')
|
||||||
|
cmp.config.window = require('cmp.config.window')
|
||||||
|
|
||||||
---Sync asynchronous process.
|
---Sync asynchronous process.
|
||||||
cmp.sync = function(callback)
|
cmp.sync = function(callback)
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ cmp.ItemField.Menu = 'menu'
|
|||||||
---@field public enabled fun():boolean|boolean
|
---@field public enabled fun():boolean|boolean
|
||||||
---@field public preselect cmp.PreselectMode
|
---@field public preselect cmp.PreselectMode
|
||||||
---@field public completion cmp.CompletionConfig
|
---@field public completion cmp.CompletionConfig
|
||||||
---@field public documentation cmp.DocumentationConfig|"false"
|
---@field public window cmp.WindowConfig|nil
|
||||||
---@field public confirmation cmp.ConfirmationConfig
|
---@field public confirmation cmp.ConfirmationConfig
|
||||||
---@field public matching cmp.MatchingConfig
|
---@field public matching cmp.MatchingConfig
|
||||||
---@field public sorting cmp.SortingConfig
|
---@field public sorting cmp.SortingConfig
|
||||||
@@ -86,19 +86,23 @@ cmp.ItemField.Menu = 'menu'
|
|||||||
---@field public view cmp.ViewConfig
|
---@field public view cmp.ViewConfig
|
||||||
---@field public experimental cmp.ExperimentalConfig
|
---@field public experimental cmp.ExperimentalConfig
|
||||||
|
|
||||||
|
--- @class cmp.WindowConfig
|
||||||
|
--- @field completion cmp.WindowConfig
|
||||||
|
--- @field documentation cmp.WindowConfig|nil
|
||||||
|
|
||||||
---@class cmp.CompletionConfig
|
---@class cmp.CompletionConfig
|
||||||
---@field public autocomplete cmp.TriggerEvent[]
|
---@field public autocomplete cmp.TriggerEvent[]
|
||||||
---@field public completeopt string
|
---@field public completeopt string
|
||||||
---@field public keyword_pattern string
|
|
||||||
---@field public keyword_length number
|
|
||||||
---@field public get_trigger_characters fun(trigger_characters: string[]): string[]
|
---@field public get_trigger_characters fun(trigger_characters: string[]): string[]
|
||||||
|
---@field public keyword_length number
|
||||||
|
---@field public keyword_pattern string
|
||||||
|
|
||||||
---@class cmp.DocumentationConfig
|
---@class cmp.WindowConfig
|
||||||
---@field public border string[]
|
---@field public border string|string[]
|
||||||
---@field public winhighlight string
|
---@field public winhighlight string
|
||||||
---@field public maxwidth number|nil
|
|
||||||
---@field public maxheight number|nil
|
|
||||||
---@field public zindex number|nil
|
---@field public zindex number|nil
|
||||||
|
---@field public max_width number|nil
|
||||||
|
---@field public max_height number|nil
|
||||||
|
|
||||||
---@class cmp.ConfirmationConfig
|
---@class cmp.ConfirmationConfig
|
||||||
---@field public default_behavior cmp.ConfirmBehavior
|
---@field public default_behavior cmp.ConfirmBehavior
|
||||||
|
|||||||
@@ -29,6 +29,24 @@ misc.concat = function(list1, list2)
|
|||||||
return new_list
|
return new_list
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---Repeat values
|
||||||
|
---@generic T
|
||||||
|
---@param str_or_tbl T
|
||||||
|
---@param count number
|
||||||
|
---@return T
|
||||||
|
misc.rep = function(str_or_tbl, count)
|
||||||
|
if type(str_or_tbl) == 'string' then
|
||||||
|
return string.rep(str_or_tbl, count)
|
||||||
|
end
|
||||||
|
local rep = {}
|
||||||
|
for _ = 1, count do
|
||||||
|
for _, v in ipairs(str_or_tbl) do
|
||||||
|
table.insert(rep, v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return rep
|
||||||
|
end
|
||||||
|
|
||||||
---Return the valu is empty or not.
|
---Return the valu is empty or not.
|
||||||
---@param v any
|
---@param v any
|
||||||
---@return boolean
|
---@return boolean
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
local char = require('cmp.utils.char')
|
local char = require('cmp.utils.char')
|
||||||
local pattern = require('cmp.utils.pattern')
|
|
||||||
|
|
||||||
local str = {}
|
local str = {}
|
||||||
|
|
||||||
@@ -73,23 +72,6 @@ str.remove_suffix = function(text, suffix)
|
|||||||
return string.sub(text, 1, -#suffix - 1)
|
return string.sub(text, 1, -#suffix - 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
---strikethrough
|
|
||||||
---@param text string
|
|
||||||
---@return string
|
|
||||||
str.strikethrough = function(text)
|
|
||||||
local r = pattern.regex('.')
|
|
||||||
local buffer = ''
|
|
||||||
while text ~= '' do
|
|
||||||
local s, e = r:match_str(text)
|
|
||||||
if not s then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
buffer = buffer .. string.sub(text, s, e) .. '̶'
|
|
||||||
text = string.sub(text, e + 1)
|
|
||||||
end
|
|
||||||
return buffer
|
|
||||||
end
|
|
||||||
|
|
||||||
---trim
|
---trim
|
||||||
---@param text string
|
---@param text string
|
||||||
---@return string
|
---@return string
|
||||||
|
|||||||
@@ -12,10 +12,6 @@ describe('utils.str', function()
|
|||||||
assert.are.equal(str.get_word('import { GetStaticProps$1 } from "next";', nil, 9), 'import { GetStaticProps')
|
assert.are.equal(str.get_word('import { GetStaticProps$1 } from "next";', nil, 9), 'import { GetStaticProps')
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('strikethrough', function()
|
|
||||||
assert.are.equal(str.strikethrough('あいうえお'), 'あ̶い̶う̶え̶お̶')
|
|
||||||
end)
|
|
||||||
|
|
||||||
it('remove_suffix', function()
|
it('remove_suffix', function()
|
||||||
assert.are.equal(str.remove_suffix('log()', '$0'), 'log()')
|
assert.are.equal(str.remove_suffix('log()', '$0'), 'log()')
|
||||||
assert.are.equal(str.remove_suffix('log()$0', '$0'), 'log()')
|
assert.are.equal(str.remove_suffix('log()$0', '$0'), 'log()')
|
||||||
|
|||||||
@@ -9,13 +9,14 @@ local api = require('cmp.utils.api')
|
|||||||
---@field public col number
|
---@field public col number
|
||||||
---@field public width number
|
---@field public width number
|
||||||
---@field public height number
|
---@field public height number
|
||||||
|
---@field public border string|string[]|nil
|
||||||
---@field public zindex number|nil
|
---@field public zindex number|nil
|
||||||
|
|
||||||
---@class cmp.Window
|
---@class cmp.Window
|
||||||
---@field public name string
|
---@field public name string
|
||||||
---@field public win number|nil
|
---@field public win number|nil
|
||||||
---@field public swin1 number|nil
|
---@field public thumb_win number|nil
|
||||||
---@field public swin2 number|nil
|
---@field public sbar_win number|nil
|
||||||
---@field public style cmp.WindowStyle
|
---@field public style cmp.WindowStyle
|
||||||
---@field public opt table<string, any>
|
---@field public opt table<string, any>
|
||||||
---@field public buffer_opt table<string, any>
|
---@field public buffer_opt table<string, any>
|
||||||
@@ -28,8 +29,8 @@ window.new = function()
|
|||||||
local self = setmetatable({}, { __index = window })
|
local self = setmetatable({}, { __index = window })
|
||||||
self.name = misc.id('cmp.utils.window.new')
|
self.name = misc.id('cmp.utils.window.new')
|
||||||
self.win = nil
|
self.win = nil
|
||||||
self.swin1 = nil
|
self.sbar_win = nil
|
||||||
self.swin2 = nil
|
self.thumb_win = nil
|
||||||
self.style = {}
|
self.style = {}
|
||||||
self.cache = cache.new()
|
self.cache = cache.new()
|
||||||
self.opt = {}
|
self.opt = {}
|
||||||
@@ -79,13 +80,13 @@ end
|
|||||||
---Set style.
|
---Set style.
|
||||||
---@param style cmp.WindowStyle
|
---@param style cmp.WindowStyle
|
||||||
window.set_style = function(self, style)
|
window.set_style = function(self, style)
|
||||||
if vim.o.columns and vim.o.columns <= style.col + style.width then
|
|
||||||
style.width = vim.o.columns - style.col - 1
|
|
||||||
end
|
|
||||||
if vim.o.lines and vim.o.lines <= style.row + style.height then
|
|
||||||
style.height = vim.o.lines - style.row - 1
|
|
||||||
end
|
|
||||||
self.style = style
|
self.style = style
|
||||||
|
local info = self:info()
|
||||||
|
|
||||||
|
if vim.o.lines and vim.o.lines <= info.row + info.height + 1 then
|
||||||
|
self.style.height = vim.o.lines - info.row - info.border_info.vert - 1
|
||||||
|
end
|
||||||
|
|
||||||
self.style.zindex = self.style.zindex or 1
|
self.style.zindex = self.style.zindex or 1
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -127,49 +128,57 @@ end
|
|||||||
|
|
||||||
---Update
|
---Update
|
||||||
window.update = function(self)
|
window.update = function(self)
|
||||||
if self:has_scrollbar() then
|
local info = self:info()
|
||||||
local total = self:get_content_height()
|
if info.scrollable then
|
||||||
local info = self:info()
|
-- Draw the background of the scrollbar
|
||||||
local bar_height = math.ceil(info.height * (info.height / total))
|
|
||||||
local bar_offset = math.min(info.height - bar_height, math.floor(info.height * (vim.fn.getwininfo(self.win)[1].topline / total)))
|
if not info.border_info.visible then
|
||||||
local style1 = {}
|
local style = {
|
||||||
style1.relative = 'editor'
|
relative = 'editor',
|
||||||
style1.style = 'minimal'
|
style = 'minimal',
|
||||||
style1.width = 1
|
width = 1,
|
||||||
style1.height = info.height
|
height = self.style.height,
|
||||||
style1.row = info.row
|
row = info.row,
|
||||||
style1.col = info.col + info.width - (info.has_scrollbar and 1 or 0)
|
col = info.col + info.width - info.scrollbar_offset, -- info.col was already contained the scrollbar offset.
|
||||||
style1.zindex = (self.style.zindex and (self.style.zindex + 1) or 1)
|
zindex = (self.style.zindex and (self.style.zindex + 1) or 1),
|
||||||
if self.swin1 and vim.api.nvim_win_is_valid(self.swin1) then
|
}
|
||||||
vim.api.nvim_win_set_config(self.swin1, style1)
|
if self.sbar_win and vim.api.nvim_win_is_valid(self.sbar_win) then
|
||||||
else
|
vim.api.nvim_win_set_config(self.sbar_win, style)
|
||||||
style1.noautocmd = true
|
else
|
||||||
self.swin1 = vim.api.nvim_open_win(buffer.ensure(self.name .. 'sbuf1'), false, style1)
|
style.noautocmd = true
|
||||||
vim.api.nvim_win_set_option(self.swin1, 'winhighlight', 'EndOfBuffer:PmenuSbar,Normal:PmenuSbar,NormalNC:PmenuSbar,NormalFloat:PmenuSbar')
|
self.sbar_win = vim.api.nvim_open_win(buffer.ensure(self.name .. 'sbar_buf'), false, style)
|
||||||
|
vim.api.nvim_win_set_option(self.sbar_win, 'winhighlight', 'EndOfBuffer:PmenuSbar,NormalFloat:PmenuSbar')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
local style2 = {}
|
|
||||||
style2.relative = 'editor'
|
-- Draw the scrollbar thumb
|
||||||
style2.style = 'minimal'
|
local thumb_height = math.floor(info.inner_height * (info.inner_height / self:get_content_height()) + 0.5)
|
||||||
style2.width = 1
|
local thumb_offset = math.floor(info.inner_height * (vim.fn.getwininfo(self.win)[1].topline / self:get_content_height()))
|
||||||
style2.height = bar_height
|
|
||||||
style2.row = info.row + bar_offset
|
local style = {
|
||||||
style2.col = info.col + info.width - (info.has_scrollbar and 1 or 0)
|
relative = 'editor',
|
||||||
style2.zindex = (self.style.zindex and (self.style.zindex + 2) or 2)
|
style = 'minimal',
|
||||||
if self.swin2 and vim.api.nvim_win_is_valid(self.swin2) then
|
width = 1,
|
||||||
vim.api.nvim_win_set_config(self.swin2, style2)
|
height = math.max(1, thumb_height),
|
||||||
|
row = info.row + thumb_offset + (info.border_info.visible and info.border_info.top or 0),
|
||||||
|
col = info.col + info.width - 1, -- info.col was already added scrollbar offset.
|
||||||
|
zindex = (self.style.zindex and (self.style.zindex + 2) or 2),
|
||||||
|
}
|
||||||
|
if self.thumb_win and vim.api.nvim_win_is_valid(self.thumb_win) then
|
||||||
|
vim.api.nvim_win_set_config(self.thumb_win, style)
|
||||||
else
|
else
|
||||||
style2.noautocmd = true
|
style.noautocmd = true
|
||||||
self.swin2 = vim.api.nvim_open_win(buffer.ensure(self.name .. 'sbuf2'), false, style2)
|
self.thumb_win = vim.api.nvim_open_win(buffer.ensure(self.name .. 'thumb_buf'), false, style)
|
||||||
vim.api.nvim_win_set_option(self.swin2, 'winhighlight', 'EndOfBuffer:PmenuThumb,Normal:PmenuThumb,NormalNC:PmenuThumb,NormalFloat:PmenuThumb')
|
vim.api.nvim_win_set_option(self.thumb_win, 'winhighlight', 'EndOfBuffer:PmenuThumb,NormalFloat:PmenuThumb')
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if self.swin1 and vim.api.nvim_win_is_valid(self.swin1) then
|
if self.sbar_win and vim.api.nvim_win_is_valid(self.sbar_win) then
|
||||||
vim.api.nvim_win_hide(self.swin1)
|
vim.api.nvim_win_hide(self.sbar_win)
|
||||||
self.swin1 = nil
|
self.sbar_win = nil
|
||||||
end
|
end
|
||||||
if self.swin2 and vim.api.nvim_win_is_valid(self.swin2) then
|
if self.thumb_win and vim.api.nvim_win_is_valid(self.thumb_win) then
|
||||||
vim.api.nvim_win_hide(self.swin2)
|
vim.api.nvim_win_hide(self.thumb_win)
|
||||||
self.swin2 = nil
|
self.thumb_win = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -188,13 +197,13 @@ window.close = function(self)
|
|||||||
vim.api.nvim_win_hide(self.win)
|
vim.api.nvim_win_hide(self.win)
|
||||||
self.win = nil
|
self.win = nil
|
||||||
end
|
end
|
||||||
if self.swin1 and vim.api.nvim_win_is_valid(self.swin1) then
|
if self.sbar_win and vim.api.nvim_win_is_valid(self.sbar_win) then
|
||||||
vim.api.nvim_win_hide(self.swin1)
|
vim.api.nvim_win_hide(self.sbar_win)
|
||||||
self.swin1 = nil
|
self.sbar_win = nil
|
||||||
end
|
end
|
||||||
if self.swin2 and vim.api.nvim_win_is_valid(self.swin2) then
|
if self.thumb_win and vim.api.nvim_win_is_valid(self.thumb_win) then
|
||||||
vim.api.nvim_win_hide(self.swin2)
|
vim.api.nvim_win_hide(self.thumb_win)
|
||||||
self.swin2 = nil
|
self.thumb_win = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -204,91 +213,101 @@ window.visible = function(self)
|
|||||||
return self.win and vim.api.nvim_win_is_valid(self.win)
|
return self.win and vim.api.nvim_win_is_valid(self.win)
|
||||||
end
|
end
|
||||||
|
|
||||||
---Return the scrollbar will shown or not.
|
|
||||||
window.has_scrollbar = function(self)
|
|
||||||
return (self.style.height or 0) < self:get_content_height()
|
|
||||||
end
|
|
||||||
|
|
||||||
---Return win info.
|
---Return win info.
|
||||||
window.info = function(self)
|
window.info = function(self)
|
||||||
local border_width = self:get_border_width()
|
local border_info = self:get_border_info()
|
||||||
local has_scrollbar = self:has_scrollbar()
|
local info = {
|
||||||
return {
|
|
||||||
row = self.style.row,
|
row = self.style.row,
|
||||||
col = self.style.col,
|
col = self.style.col,
|
||||||
width = self.style.width + border_width + (has_scrollbar and 1 or 0),
|
width = self.style.width + border_info.left + border_info.right,
|
||||||
height = self.style.height,
|
height = self.style.height + border_info.top + border_info.bottom,
|
||||||
border_width = border_width,
|
inner_width = self.style.width,
|
||||||
has_scrollbar = has_scrollbar,
|
inner_height = self.style.height,
|
||||||
|
border_info = border_info,
|
||||||
|
scrollable = false,
|
||||||
|
scrollbar_offset = 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self:get_content_height() > info.inner_height then
|
||||||
|
info.scrollable = true
|
||||||
|
if not border_info.visible then
|
||||||
|
info.scrollbar_offset = 1
|
||||||
|
info.width = info.width + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return info
|
||||||
end
|
end
|
||||||
|
|
||||||
---Get border width
|
---Return border information.
|
||||||
---@return number
|
---@return { top: number, left: number, right: number, bottom: number, vert: number, horiz: number, visible: boolean }
|
||||||
window.get_border_width = function(self)
|
window.get_border_info = function(self)
|
||||||
local border = self.style.border
|
local border = self.style.border
|
||||||
if type(border) == 'table' then
|
if not border or border == 'none' then
|
||||||
local new_border = {}
|
return {
|
||||||
while #new_border < 8 do
|
top = 0,
|
||||||
for _, b in ipairs(border) do
|
left = 0,
|
||||||
table.insert(new_border, b)
|
right = 0,
|
||||||
end
|
bottom = 0,
|
||||||
|
vert = 0,
|
||||||
|
horiz = 0,
|
||||||
|
visible = false,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
if type(border) == 'string' then
|
||||||
|
if border == 'shadow' then
|
||||||
|
return {
|
||||||
|
top = 0,
|
||||||
|
left = 0,
|
||||||
|
right = 1,
|
||||||
|
bottom = 1,
|
||||||
|
vert = 1,
|
||||||
|
horiz = 1,
|
||||||
|
visible = false,
|
||||||
|
}
|
||||||
end
|
end
|
||||||
border = new_border
|
return {
|
||||||
|
top = 1,
|
||||||
|
left = 1,
|
||||||
|
right = 1,
|
||||||
|
bottom = 1,
|
||||||
|
vert = 2,
|
||||||
|
horiz = 2,
|
||||||
|
visible = true,
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
local w = 0
|
local new_border = {}
|
||||||
if border then
|
while #new_border <= 8 do
|
||||||
if type(border) == 'string' then
|
for _, b in ipairs(border) do
|
||||||
if border == 'single' then
|
table.insert(new_border, type(b) == 'string' and b or b[1])
|
||||||
w = 2
|
|
||||||
elseif border == 'solid' then
|
|
||||||
w = 2
|
|
||||||
elseif border == 'double' then
|
|
||||||
w = 2
|
|
||||||
elseif border == 'rounded' then
|
|
||||||
w = 2
|
|
||||||
elseif border == 'shadow' then
|
|
||||||
w = 1
|
|
||||||
end
|
|
||||||
elseif type(border) == 'table' then
|
|
||||||
local b4 = type(border[4]) == 'table' and border[4][1] or border[4]
|
|
||||||
if #b4 > 0 then
|
|
||||||
w = w + 1
|
|
||||||
end
|
|
||||||
local b8 = type(border[8]) == 'table' and border[8][1] or border[8]
|
|
||||||
if #b8 > 0 then
|
|
||||||
w = w + 1
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return w
|
local info = {}
|
||||||
|
info.top = new_border[2] == '' and 0 or 1
|
||||||
|
info.right = new_border[4] == '' and 0 or 1
|
||||||
|
info.bottom = new_border[6] == '' and 0 or 1
|
||||||
|
info.left = new_border[8] == '' and 0 or 1
|
||||||
|
info.vert = info.top + info.bottom
|
||||||
|
info.horiz = info.left + info.right
|
||||||
|
info.visible = not (vim.tbl_contains({ '', ' ' }, new_border[2]) and vim.tbl_contains({ '', ' ' }, new_border[4]) and vim.tbl_contains({ '', ' ' }, new_border[6]) and vim.tbl_contains({ '', ' ' }, new_border[8]))
|
||||||
|
return info
|
||||||
end
|
end
|
||||||
|
|
||||||
---Get scroll height.
|
---Get scroll height.
|
||||||
|
---NOTE: The result of vim.fn.strdisplaywidth depends on the buffer it was called in (see comment in cmp.Entry.get_view).
|
||||||
---@return number
|
---@return number
|
||||||
window.get_content_height = function(self)
|
window.get_content_height = function(self)
|
||||||
if not self:option('wrap') then
|
if not self:option('wrap') then
|
||||||
return vim.api.nvim_buf_line_count(self:get_buffer())
|
return vim.api.nvim_buf_line_count(self:get_buffer())
|
||||||
end
|
end
|
||||||
|
local height = 0
|
||||||
return self.cache:ensure({
|
vim.api.nvim_buf_call(self:get_buffer(), function()
|
||||||
'get_content_height',
|
for _, text in ipairs(vim.api.nvim_buf_get_lines(self:get_buffer(), 0, -1, false)) do
|
||||||
self.style.width,
|
height = height + math.max(1, math.ceil(vim.fn.strdisplaywidth(text) / self.style.width))
|
||||||
self:get_buffer(),
|
end
|
||||||
vim.api.nvim_buf_get_changedtick(self:get_buffer()),
|
|
||||||
}, function()
|
|
||||||
local height = 0
|
|
||||||
local buf = self:get_buffer()
|
|
||||||
-- The result of vim.fn.strdisplaywidth depends on the buffer it was called
|
|
||||||
-- in (see comment in cmp.Entry.get_view).
|
|
||||||
vim.api.nvim_buf_call(buf, function()
|
|
||||||
for _, text in ipairs(vim.api.nvim_buf_get_lines(buf, 0, -1, false)) do
|
|
||||||
height = height + math.ceil(math.max(1, vim.fn.strdisplaywidth(text)) / self.style.width)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
return height
|
|
||||||
end)
|
end)
|
||||||
|
return height
|
||||||
end
|
end
|
||||||
|
|
||||||
return window
|
return window
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ custom_entries_view.ns = vim.api.nvim_create_namespace('cmp.view.custom_entries_
|
|||||||
|
|
||||||
custom_entries_view.new = function()
|
custom_entries_view.new = function()
|
||||||
local self = setmetatable({}, { __index = custom_entries_view })
|
local self = setmetatable({}, { __index = custom_entries_view })
|
||||||
|
|
||||||
self.entries_win = window.new()
|
self.entries_win = window.new()
|
||||||
self.entries_win:option('conceallevel', 2)
|
self.entries_win:option('conceallevel', 2)
|
||||||
self.entries_win:option('concealcursor', 'n')
|
self.entries_win:option('concealcursor', 'n')
|
||||||
@@ -32,7 +33,6 @@ custom_entries_view.new = function()
|
|||||||
self.entries_win:option('foldenable', false)
|
self.entries_win:option('foldenable', false)
|
||||||
self.entries_win:option('wrap', false)
|
self.entries_win:option('wrap', false)
|
||||||
self.entries_win:option('scrolloff', 0)
|
self.entries_win:option('scrolloff', 0)
|
||||||
self.entries_win:option('winhighlight', 'Normal:Pmenu,FloatBorder:Pmenu,CursorLine:PmenuSel,Search:None')
|
|
||||||
-- This is done so that strdisplaywidth calculations for lines in the
|
-- This is done so that strdisplaywidth calculations for lines in the
|
||||||
-- custom_entries_view window exactly match with what is really displayed,
|
-- custom_entries_view window exactly match with what is really displayed,
|
||||||
-- see comment in cmp.Entry.get_view. Setting tabstop to 1 makes all tabs be
|
-- see comment in cmp.Entry.get_view. Setting tabstop to 1 makes all tabs be
|
||||||
@@ -118,13 +118,11 @@ custom_entries_view.is_direction_top_down = function(self)
|
|||||||
end
|
end
|
||||||
|
|
||||||
custom_entries_view.open = function(self, offset, entries)
|
custom_entries_view.open = function(self, offset, entries)
|
||||||
|
local completion = config.get().window.completion
|
||||||
self.offset = offset
|
self.offset = offset
|
||||||
self.entries = {}
|
self.entries = {}
|
||||||
self.column_width = { abbr = 0, kind = 0, menu = 0 }
|
self.column_width = { abbr = 0, kind = 0, menu = 0 }
|
||||||
|
|
||||||
-- Apply window options (that might be changed) on the custom completion menu.
|
|
||||||
self.entries_win:option('winblend', vim.o.pumblend)
|
|
||||||
|
|
||||||
local entries_buf = self.entries_win:get_buffer()
|
local entries_buf = self.entries_win:get_buffer()
|
||||||
local lines = {}
|
local lines = {}
|
||||||
local dedup = {}
|
local dedup = {}
|
||||||
@@ -159,16 +157,24 @@ custom_entries_view.open = function(self, offset, entries)
|
|||||||
local pos = api.get_screen_cursor()
|
local pos = api.get_screen_cursor()
|
||||||
local cursor = api.get_cursor()
|
local cursor = api.get_cursor()
|
||||||
local delta = cursor[2] + 1 - self.offset
|
local delta = cursor[2] + 1 - self.offset
|
||||||
local has_bottom_space = (vim.o.lines - pos[1]) >= DEFAULT_HEIGHT
|
|
||||||
local row, col = pos[1], pos[2] - delta - 1
|
local row, col = pos[1], pos[2] - delta - 1
|
||||||
|
|
||||||
if not has_bottom_space and math.floor(vim.o.lines * 0.5) <= row and vim.o.lines - row <= height then
|
local border_info = window.get_border_info({ style = completion })
|
||||||
|
local border_offset_row = border_info.top + border_info.bottom
|
||||||
|
local border_offset_col = border_info.left + border_info.right
|
||||||
|
if math.floor(vim.o.lines * 0.5) <= row + border_offset_row and vim.o.lines - row - border_offset_row <= math.min(DEFAULT_HEIGHT, height) then
|
||||||
height = math.min(height, row - 1)
|
height = math.min(height, row - 1)
|
||||||
row = row - height - 1
|
row = row - height - border_offset_row - 1
|
||||||
|
if row < 0 then
|
||||||
|
height = height + row
|
||||||
|
end
|
||||||
end
|
end
|
||||||
if math.floor(vim.o.columns * 0.5) <= col and vim.o.columns - col <= width then
|
if math.floor(vim.o.columns * 0.5) <= col + border_offset_col and vim.o.columns - col - border_offset_col <= width then
|
||||||
width = math.min(width, vim.o.columns - 1)
|
width = math.min(width, vim.o.columns - 1)
|
||||||
col = vim.o.columns - width - 1
|
col = vim.o.columns - width - border_offset_col - 1
|
||||||
|
if col < 0 then
|
||||||
|
width = width + col
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if pos[1] > row then
|
if pos[1] > row then
|
||||||
@@ -187,6 +193,9 @@ custom_entries_view.open = function(self, offset, entries)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Apply window options (that might be changed) on the custom completion menu.
|
||||||
|
self.entries_win:option('winblend', vim.o.pumblend)
|
||||||
|
self.entries_win:option('winhighlight', completion.winhighlight)
|
||||||
self.entries_win:open({
|
self.entries_win:open({
|
||||||
relative = 'editor',
|
relative = 'editor',
|
||||||
style = 'minimal',
|
style = 'minimal',
|
||||||
@@ -194,7 +203,8 @@ custom_entries_view.open = function(self, offset, entries)
|
|||||||
col = math.max(0, col),
|
col = math.max(0, col),
|
||||||
width = width,
|
width = width,
|
||||||
height = height,
|
height = height,
|
||||||
zindex = 1001,
|
border = completion.border,
|
||||||
|
zindex = completion.zindex or 1001,
|
||||||
})
|
})
|
||||||
-- always set cursor when starting. It will be adjusted on the call to _select
|
-- always set cursor when starting. It will be adjusted on the call to _select
|
||||||
vim.api.nvim_win_set_cursor(self.entries_win.win, { 1, 0 })
|
vim.api.nvim_win_set_cursor(self.entries_win.win, { 1, 0 })
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ end
|
|||||||
---@param e cmp.Entry
|
---@param e cmp.Entry
|
||||||
---@param view cmp.WindowStyle
|
---@param view cmp.WindowStyle
|
||||||
docs_view.open = function(self, e, view)
|
docs_view.open = function(self, e, view)
|
||||||
local documentation = config.get().documentation
|
local documentation = config.get().window.documentation
|
||||||
if not documentation then
|
if not documentation then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@@ -32,11 +32,12 @@ docs_view.open = function(self, e, view)
|
|||||||
return self:close()
|
return self:close()
|
||||||
end
|
end
|
||||||
|
|
||||||
local right_space = vim.o.columns - (view.col + view.width) - 2
|
local border_info = window.get_border_info({ style = documentation })
|
||||||
local left_space = view.col - 2
|
local right_space = vim.o.columns - (view.col + view.width) - 1
|
||||||
local maxwidth = math.min(documentation.maxwidth, math.max(left_space, right_space) - 1)
|
local left_space = view.col - 1
|
||||||
|
local max_width = math.min(documentation.max_width, math.max(left_space, right_space))
|
||||||
|
|
||||||
-- update buffer content if needed.
|
-- Update buffer content if needed.
|
||||||
if not self.entry or e.id ~= self.entry.id then
|
if not self.entry or e.id ~= self.entry.id then
|
||||||
local documents = e:get_documentation()
|
local documents = e:get_documentation()
|
||||||
if #documents == 0 then
|
if #documents == 0 then
|
||||||
@@ -46,24 +47,26 @@ docs_view.open = function(self, e, view)
|
|||||||
self.entry = e
|
self.entry = e
|
||||||
vim.api.nvim_buf_call(self.window:get_buffer(), function()
|
vim.api.nvim_buf_call(self.window:get_buffer(), function()
|
||||||
vim.cmd([[syntax clear]])
|
vim.cmd([[syntax clear]])
|
||||||
|
vim.api.nvim_buf_set_lines(self.window:get_buffer(), 0, -1, false, {})
|
||||||
end)
|
end)
|
||||||
vim.lsp.util.stylize_markdown(self.window:get_buffer(), documents, {
|
vim.lsp.util.stylize_markdown(self.window:get_buffer(), documents, {
|
||||||
max_width = maxwidth,
|
max_width = max_width,
|
||||||
max_height = documentation.maxheight,
|
max_height = documentation.max_height,
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Calculate window size.
|
||||||
local width, height = vim.lsp.util._make_floating_popup_size(vim.api.nvim_buf_get_lines(self.window:get_buffer(), 0, -1, false), {
|
local width, height = vim.lsp.util._make_floating_popup_size(vim.api.nvim_buf_get_lines(self.window:get_buffer(), 0, -1, false), {
|
||||||
max_width = maxwidth,
|
max_width = max_width - border_info.horiz,
|
||||||
max_height = documentation.maxheight,
|
max_height = documentation.max_height - border_info.vert,
|
||||||
})
|
})
|
||||||
if width <= 0 or height <= 0 then
|
if width <= 0 or height <= 0 then
|
||||||
return self:close()
|
return self:close()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Calculate window position.
|
||||||
local right_col = view.col + view.width
|
local right_col = view.col + view.width
|
||||||
local left_col = view.col - width - 2
|
local left_col = view.col - width - border_info.horiz
|
||||||
|
|
||||||
local col, left
|
local col, left
|
||||||
if right_space >= width and left_space >= width then
|
if right_space >= width and left_space >= width then
|
||||||
if right_space < left_space then
|
if right_space < left_space then
|
||||||
@@ -81,8 +84,10 @@ docs_view.open = function(self, e, view)
|
|||||||
return self:close()
|
return self:close()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Render window.
|
||||||
|
self.window:option('winblend', vim.o.pumblend)
|
||||||
self.window:option('winhighlight', documentation.winhighlight)
|
self.window:option('winhighlight', documentation.winhighlight)
|
||||||
self.window:set_style({
|
local style = {
|
||||||
relative = 'editor',
|
relative = 'editor',
|
||||||
style = 'minimal',
|
style = 'minimal',
|
||||||
width = width,
|
width = width,
|
||||||
@@ -91,11 +96,14 @@ docs_view.open = function(self, e, view)
|
|||||||
col = col,
|
col = col,
|
||||||
border = documentation.border,
|
border = documentation.border,
|
||||||
zindex = documentation.zindex or 50,
|
zindex = documentation.zindex or 50,
|
||||||
})
|
}
|
||||||
if left and self.window:has_scrollbar() then
|
self.window:open(style)
|
||||||
self.window.style.col = self.window.style.col - 1
|
|
||||||
|
-- Correct left-col for scrollbar existence.
|
||||||
|
if left then
|
||||||
|
style.col = style.col - self.window:info().scrollbar_offset
|
||||||
|
self.window:open(style)
|
||||||
end
|
end
|
||||||
self.window:open()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
---Close floating window
|
---Close floating window
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ native_entries_view.info = function(self)
|
|||||||
if self:visible() then
|
if self:visible() then
|
||||||
local info = vim.fn.pum_getpos()
|
local info = vim.fn.pum_getpos()
|
||||||
return {
|
return {
|
||||||
width = info.width + (info.scrollbar and 1 or 0),
|
width = info.width + (info.scrollable and 1 or 0),
|
||||||
height = info.height,
|
height = info.height,
|
||||||
row = info.row,
|
row = info.row,
|
||||||
col = info.col,
|
col = info.col,
|
||||||
|
|||||||
@@ -80,37 +80,27 @@ misc.set(_G, { 'cmp', 'plugin', 'colorscheme' }, function()
|
|||||||
guibg = 'NONE',
|
guibg = 'NONE',
|
||||||
ctermbg = 'NONE',
|
ctermbg = 'NONE',
|
||||||
})
|
})
|
||||||
|
highlight.inherit('CmpItemMenuDefault', 'Pmenu', {
|
||||||
|
guibg = 'NONE',
|
||||||
|
ctermbg = 'NONE',
|
||||||
|
})
|
||||||
for name in pairs(types.lsp.CompletionItemKind) do
|
for name in pairs(types.lsp.CompletionItemKind) do
|
||||||
if type(name) == 'string' then
|
if type(name) == 'string' then
|
||||||
vim.cmd(([[highlight default link CmpItemKind%sDefault CmpItemKind]]):format(name))
|
vim.cmd(([[highlight default link CmpItemKind%sDefault CmpItemKind]]):format(name))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
highlight.inherit('CmpItemMenuDefault', 'Pmenu', {
|
|
||||||
guibg = 'NONE',
|
|
||||||
ctermbg = 'NONE',
|
|
||||||
})
|
|
||||||
end)
|
end)
|
||||||
_G.cmp.plugin.colorscheme()
|
_G.cmp.plugin.colorscheme()
|
||||||
|
|
||||||
if vim.fn.hlexists('CmpItemAbbr') ~= 1 then
|
vim.cmd [[
|
||||||
vim.cmd [[highlight default link CmpItemAbbr CmpItemAbbrDefault]]
|
highlight default link CmpItemAbbr CmpItemAbbrDefault
|
||||||
end
|
highlight default link CmpItemAbbrDeprecated CmpItemAbbrDeprecatedDefault
|
||||||
|
highlight default link CmpItemAbbrMatch CmpItemAbbrMatchDefault
|
||||||
|
highlight default link CmpItemAbbrMatchFuzzy CmpItemAbbrMatchFuzzyDefault
|
||||||
|
highlight default link CmpItemKind CmpItemKindDefault
|
||||||
|
highlight default link CmpItemMenu CmpItemMenuDefault
|
||||||
|
]]
|
||||||
|
|
||||||
if vim.fn.hlexists('CmpItemAbbrDeprecated') ~= 1 then
|
|
||||||
vim.cmd [[highlight default link CmpItemAbbrDeprecated CmpItemAbbrDeprecatedDefault]]
|
|
||||||
end
|
|
||||||
|
|
||||||
if vim.fn.hlexists('CmpItemAbbrMatch') ~= 1 then
|
|
||||||
vim.cmd [[highlight default link CmpItemAbbrMatch CmpItemAbbrMatchDefault]]
|
|
||||||
end
|
|
||||||
|
|
||||||
if vim.fn.hlexists('CmpItemAbbrMatchFuzzy') ~= 1 then
|
|
||||||
vim.cmd [[highlight default link CmpItemAbbrMatchFuzzy CmpItemAbbrMatchFuzzyDefault]]
|
|
||||||
end
|
|
||||||
|
|
||||||
if vim.fn.hlexists('CmpItemKind') ~= 1 then
|
|
||||||
vim.cmd [[highlight default link CmpItemKind CmpItemKindDefault]]
|
|
||||||
end
|
|
||||||
for name in pairs(types.lsp.CompletionItemKind) do
|
for name in pairs(types.lsp.CompletionItemKind) do
|
||||||
if type(name) == 'string' then
|
if type(name) == 'string' then
|
||||||
local hi = ('CmpItemKind%s'):format(name)
|
local hi = ('CmpItemKind%s'):format(name)
|
||||||
@@ -120,14 +110,6 @@ for name in pairs(types.lsp.CompletionItemKind) do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if vim.fn.hlexists('CmpItemMenu') ~= 1 then
|
|
||||||
vim.cmd [[highlight default link CmpItemMenu CmpItemMenuDefault]]
|
|
||||||
end
|
|
||||||
|
|
||||||
vim.cmd [[command! CmpStatus lua require('cmp').status()]]
|
|
||||||
|
|
||||||
vim.cmd [[doautocmd <nomodeline> User CmpReady]]
|
|
||||||
|
|
||||||
if vim.on_key then
|
if vim.on_key then
|
||||||
vim.on_key(function(keys)
|
vim.on_key(function(keys)
|
||||||
if keys == vim.api.nvim_replace_termcodes('<C-c>', true, true, true) then
|
if keys == vim.api.nvim_replace_termcodes('<C-c>', true, true, true) then
|
||||||
@@ -140,3 +122,7 @@ if vim.on_key then
|
|||||||
end, vim.api.nvim_create_namespace('cmp.plugin'))
|
end, vim.api.nvim_create_namespace('cmp.plugin'))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
vim.cmd [[command! CmpStatus lua require('cmp').status()]]
|
||||||
|
|
||||||
|
vim.cmd [[doautocmd <nomodeline> User CmpReady]]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user