cmp-nvim-ultisnips icon indicating copy to clipboard operation
cmp-nvim-ultisnips copied to clipboard

Wrong context matching

Open anstadnik opened this issue 2 years ago • 5 comments

Minimum init.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 = '<Plug>(ultisnips_expand)'
vim.g.UltiSnipsJumpForwardTrigger = '<Plug>(ultisnips_jump_forward)'
vim.g.UltiSnipsJumpBackwardTrigger = '<Plug>(ultisnips_jump_backward)'
vim.g.UltiSnipsListSnippets = '<c-x><c-s>'

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 = {
  ['<C-d>'] = cmp.mapping.scroll_docs(4),
  ['<C-f>'] = cmp.mapping.scroll_docs(-4),
  ['<C-Space>'] = cmp.mapping.complete(),
  ["<C-j>"] = 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("<Plug>(ultisnips_expand)") end,
    }
  ),
  ['<C-p>'] = cmp.mapping.select_prev_item({ behavior = cmp.SelectBehavior.Insert }),
  ['<C-n>'] = cmp.mapping.select_next_item({ behavior = cmp.SelectBehavior.Insert }),
  ["<C-l>"] = cmp.mapping(function(fallback)
    if vim.fn["UltiSnips#CanJumpForwards"]() == 1 then
      t('<Plug>(ultisnips_jump_forward)')
    else
      fallback()
    end
  end, { "i", "s" }),
  ["<C-h>"] = cmp.mapping(function(fallback)
    if vim.fn["UltiSnips#CanJumpBackwards"]() == 1 then
      t('<Plug>(ultisnips_jump_backward)')
    else
      fallback()
    end
  end, { "i", "s" }),
},
sources = cmp.config.sources({ { name = 'ultisnips' } }),
-- preselect = cmp.PreselectMode.None,
}
Example file
\documentclass{scrartcl}
\usepackage{mathtools}

\begin{document}

% \(<cursor_here>\)
\(\)

\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.

anstadnik avatar Jun 01 '22 15:06 anstadnik

Thanks for reporting.

quangnguyen30192 avatar Jun 02 '22 08:06 quangnguyen30192

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

anstadnik avatar Jun 06 '22 12:06 anstadnik

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.

smjonas avatar Jun 15 '22 18:06 smjonas

Any workaround or solution?

fecet avatar Jul 02 '22 15:07 fecet

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.

smjonas avatar Jul 04 '22 09:07 smjonas