Skip to content

Commit

Permalink
Feat: add support for custom context snippets (#72)
Browse files Browse the repository at this point in the history
Any custom context in a snippet definition is now respected; that means the snippet is only expanded in the correct context (see `:h UltiSnips-custom-context-snippets`).
Note: this commit also changed the behaviour of `show_snippets="all"`. Previously "all" also showed regular expression snippets. `show_snippets="all"` now only shows snippets where caching makes sense (which is not the case for custom regular expression and custom context snippets). To avoid confusion, this option will probably be renamed to `snow_snippets = "cached"` in the future.
  • Loading branch information
smjonas authored Apr 15, 2022
1 parent f90ebb2 commit c6ace8c
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 33 deletions.
16 changes: 7 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
</p>

## Features
- **Composable Mappings**: get rid of boilerplate code in your config
- **Treesitter Integration**: show snippets based on the filetype at your cursor position
- **Regular Expression Snippets**: snippets with the `r` option are supported
- **Composable mappings**: get rid of boilerplate code in your config
- **Treesitter integration**: show snippets based on the filetype at your cursor position
- **Regular expression snippets**: snippets with the `r` option are supported
- **Custom context snippets**: snippets are only shown in the correct context
- **Customization**: change which and how snippets are displayed by cmp

## Dependencies
Expand Down Expand Up @@ -134,17 +135,14 @@ are handled entirely by UltiSnips.
If set to `"expandable"`, only those snippets currently expandable by UltiSnips will be
shown. The snippets will always be in sync with the currently available UltiSnips snippets.

`"all"` will show all snippets for the current filetype. If using this option, be aware
that all snippets for the current buffer will be cached (even if the snippet definitions
changed). You can then manually reload the snippets with the command `:CmpUltisnipsReloadSnippets`
or by using an autocommand:
`"all"` will show all snippets for the current filetype except regex and custom context snippets.
This is due to caching of all snippets for the current buffer. They will not update even if the snippet definitions changed
- you can then manually reload the snippets with the command `:CmpUltisnipsReloadSnippets` or by using an autocommand:

```vim
autocmd BufWritePost *.snippets :CmpUltisnipsReloadSnippets
```

Custom context snippets (option `e`) are currently not available.

**Default:** `"expandable"`

---
Expand Down
27 changes: 19 additions & 8 deletions autoload/cmp_nvim_ultisnips.vim
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,38 @@
" per snippet) with the keys "trigger", "description", "options" and "value".
"
" If 'expandable_only' is "True", only expandable snippets are returned, otherwise all
" snippets for the current filetype are returned.
" snippets except regex and custom context snippets for the current filetype are returned.
function! cmp_nvim_ultisnips#get_current_snippets(expandable_only)
let g:_cmpu_current_snippets = []
python3 << EOF
import vim
from UltiSnips import UltiSnips_Manager, vim_helper

if vim.eval("a:expandable_only") == "True":
before = vim_helper.buf.line_till_cursor
before = vim_helper.buf.line_till_cursor
visual_content = UltiSnips_Manager._visual_content
expandable_only = vim.eval("a:expandable_only") == "True"
if expandable_only:
snippets = UltiSnips_Manager._snips(before, True)
else:
snippets = UltiSnips_Manager._snips("", True)

for snippet in snippets:
is_context_snippet = snippet._context_code != None
is_regex_snippet = "r" in snippet._opts
# If show_snippets == "all", the snippets are cached so ignore "dynamic" snippets.
if not expandable_only and (is_context_snippet or is_regex_snippet):
continue
# For custom context snippets, always check if the context matches.
if is_context_snippet and not snippet._context_match(visual_content, before):
continue

vim.command(
"call add(g:_cmpu_current_snippets, {"
"'trigger': py3eval('str(snippet._trigger)'),"
"'description': py3eval('str(snippet._description)'),"
"'options': py3eval('str(snippet._opts)'),"
"'value': py3eval('str(snippet._value)'),"
"'matched': py3eval('str(snippet._matched)'),"
"'trigger': py3eval('snippet._trigger'),"
"'description': py3eval('snippet._description'),"
"'options': py3eval('snippet._opts'),"
"'value': py3eval('snippet._value'),"
"'matched': py3eval('snippet._matched'),"
"})"
)
EOF
Expand Down
26 changes: 10 additions & 16 deletions lua/cmp_nvim_ultisnips/source.lua
Original file line number Diff line number Diff line change
Expand Up @@ -27,25 +27,19 @@ function source.complete(self, _, callback)
local snippets = cmpu_snippets.load_snippets(self.expandable_only)

for _, snippet in pairs(snippets) do
-- Skip expression snippets for now
if not snippet.options:match("e") then
local is_regex_snippet = snippet.options:match("r")
-- Avoid expanding a regex snippet with an invalid insertText when self.expandable_only == false
-- (_cmpu_line_till_cursor is only set when self.expandable_only == true)
if not is_regex_snippet or is_regex_snippet and self.expandable_only then
local item = {
insertText = (is_regex_snippet and snippet.matched) or snippet.trigger,
label = snippet.trigger,
kind = cmp.lsp.CompletionItemKind.Snippet,
snippet = snippet,
}
table.insert(items, item)
end
end
local is_regex_snippet = snippet.options:match("r")
local item = {
insertText = (is_regex_snippet and snippet.matched) or snippet.trigger,
label = snippet.trigger,
kind = cmp.lsp.CompletionItemKind.Snippet,
snippet = snippet,
}
table.insert(items, item)
end
callback {
items = items,
-- Cmp will update the items on every keystroke
-- If true, cmp will update the items on every keystroke.
-- When self.expandable_only == false, the snippets are cached so no need to update.
isIncomplete = self.expandable_only,
}
end
Expand Down

0 comments on commit c6ace8c

Please sign in to comment.