quangnguyen30192 / cmp-nvim-ultisnips

nvim-cmp source for ultisnips
Apache License 2.0
147 stars 19 forks source link

Wrong context matching #78

Open anstadnik opened 2 years ago

anstadnik commented 2 years ago
Minimum init.lua ```lua --------------------------------------------------------------------------------- -- Packer -- --------------------------------------------------------------------------------- local install_path = vim.fn.stdpath('data') .. '/site/pack/packer/start/packer.nvim' if vim.fn.empty(vim.fn.glob(install_path)) > 0 then vim.fn.termopen(('git clone --depth 1 https://github.com/wbthomason/packer.nvim %q'):format(install_path)) end require('packer').startup({ function(use) use 'wbthomason/packer.nvim' use 'nvim-treesitter/nvim-treesitter' use { 'hrsh7th/nvim-cmp', requires = { 'quangnguyen30192/cmp-nvim-ultisnips' } } use 'SirVer/ultisnips' use { 'https://gitlab.com/astadnik/snippets.git', rtp = '.' } end }) --------------------------------------------------------------------------------- -- TreeSitter -- --------------------------------------------------------------------------------- require 'nvim-treesitter.configs'.setup { ensure_installed = "latex" } --------------------------------------------------------------------------------- -- Options -- --------------------------------------------------------------------------------- vim.g.UltiSnipsExpandTrigger = '(ultisnips_expand)' vim.g.UltiSnipsJumpForwardTrigger = '(ultisnips_jump_forward)' vim.g.UltiSnipsJumpBackwardTrigger = '(ultisnips_jump_backward)' vim.g.UltiSnipsListSnippets = '' vim.g.tex_flavor = 'latex' --------------------------------------------------------------------------------- -- Context stuff -- --------------------------------------------------------------------------------- local ts = require 'vim.treesitter' local MATH_NODES = { displayed_equation = true, inline_formula = true, math_environment = true, } local function get_node_at_cursor() local buf = vim.api.nvim_get_current_buf() local row, col = unpack(vim.api.nvim_win_get_cursor(0)) row = row - 1 col = col - 1 local parser = ts.get_parser(buf, 'latex') if not parser then return end local root_tree = parser:parse()[1] local root = root_tree and root_tree:root() if not root then return end return root:named_descendant_for_range(row, col, row, col) end function In_mathzone() local node = get_node_at_cursor() print("HELLO") while node do if node:type() == 'text_mode' then return false elseif MATH_NODES[node:type()] then return true end node = node:parent() end return false end --------------------------------------------------------------------------------- -- CMP -- --------------------------------------------------------------------------------- local cmp = require('cmp') -- local luasnip = require("luasnip") require("cmp_nvim_ultisnips").setup {} local cmp_ultisnips_mappings = require("cmp_nvim_ultisnips.mappings") local function t(keys) vim.api.nvim_feedkeys( vim.api.nvim_replace_termcodes(keys, true, true, true), "m", true) end cmp.setup { snippet = { expand = function(args) vim.fn["UltiSnips#Anon"](args.body) end }, mapping = { [''] = cmp.mapping.scroll_docs(4), [''] = cmp.mapping.scroll_docs(-4), [''] = cmp.mapping.complete(), [""] = cmp.mapping( { i = cmp.mapping.confirm({ behavior = cmp.ConfirmBehavior.Insert, select = true }), c = cmp.mapping.confirm({ behavior = cmp.ConfirmBehavior.Insert, select = true }), x = function() t("(ultisnips_expand)") end, } ), [''] = cmp.mapping.select_prev_item({ behavior = cmp.SelectBehavior.Insert }), [''] = cmp.mapping.select_next_item({ behavior = cmp.SelectBehavior.Insert }), [""] = cmp.mapping(function(fallback) if vim.fn["UltiSnips#CanJumpForwards"]() == 1 then t('(ultisnips_jump_forward)') else fallback() end end, { "i", "s" }), [""] = cmp.mapping(function(fallback) if vim.fn["UltiSnips#CanJumpBackwards"]() == 1 then t('(ultisnips_jump_backward)') else fallback() end end, { "i", "s" }), }, sources = cmp.config.sources({ { name = 'ultisnips' } }), -- preselect = cmp.PreselectMode.None, } ```
Example file ```tex \documentclass{scrartcl} \usepackage{mathtools} \begin{document} % \(\) \(\) \end{document} ```

When I put the cursor between \(\), and write mrm, there is no completion suggestion. If I write mrm (with space before), there is.

Hovewer, if in the snippet file I set the options to iA instead of i (to expand automatically), the snippet is expanded, which IMO indicates that cmp-nvim-ultisnips passes whether to show snippet or not to the cmp wrongly.

quangnguyen30192 commented 2 years ago

Thanks for reporting.

anstadnik commented 2 years ago

Aha, I just understood that it might be wrong handling of the i parameter (in-word expansion), and not the context thing.

smjonas commented 2 years ago

We would need to change the keyword pattern for this. As I understood it, this is a Vim regex that the line needs to match in order to trigger completion of a completion item.

https://github.com/quangnguyen30192/cmp-nvim-ultisnips/blob/21f02b62deb409ce69928a23406076bd0043ddbc/lua/cmp_nvim_ultisnips/source.lua#L17-L19

However changing it to something like "\\.\\*" which should match any characters does not work for whatever reason (the snippet won't even show up then). PR / suggestions welcome.

fecet commented 2 years ago

Any workaround or solution?

smjonas commented 2 years ago

I thought about this a but more and came to the conclusion that the keyword_pattern is not the issue. The problem is that cmp will not invoke completion when typing directly after an existing word.

Let's say that you have a snippet with mrm as the trigger. Also assume that this is the buffer content and | is the cursor position:

end|

Currently, nvim-cmp will only show words that contain all of the characters in end. This is why the mrm snippet will not be suggested.

So what nvim-cmp needs to support is the following: After endm| was typed, besides the words e, en, end and endm cmp needs to also match ndm, dm and m. This way, if you have a snippet mdm, it will be suggested because it starts with m.

So I think you should open an issue on nvim-cmp and include this as usecase.