Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for nvim-cmp. #2215

Closed
moshiur-raj opened this issue Oct 21, 2021 · 63 comments
Closed

Support for nvim-cmp. #2215

moshiur-raj opened this issue Oct 21, 2021 · 63 comments

Comments

@moshiur-raj
Copy link

Vimtex has documentations for how to make it work with nivm-compe. However nvim-compe is now deprecated and succeeded by nvim-cmp. Can you guys add documentations for nvim-cmp?

@lervag
Copy link
Owner

lervag commented Oct 21, 2021

I would not mind it at all, but I don't use nvim-cmp. Thus it would be very nice to get input from someone who does that can verify that the configuration works as intended.

@moshiur-raj
Copy link
Author

Thank you! I can verify the configs for you,

@lervag
Copy link
Owner

lervag commented Oct 21, 2021

I've found some relevant info here:

hrsh7th/nvim-cmp#258

I'll be bold and ping some of the participants there who might have a working configuration: @DerWeh @ranebrown

@lervag
Copy link
Owner

lervag commented Oct 21, 2021

I'll also ping @hrsh7th, as he seems both friendly and very able to help assist in figuring out a proper configuration for using VimTeXs omnicompletion with nvim-cmp. When we have something that works, we'll add it to the docs. Also, a question: Should I write in the VimTeX docs that nvim-compe is regarded as deprecated and should not be used?

@moshiur-raj
Copy link
Author

moshiur-raj commented Oct 21, 2021

I think you should. It might help stop others from opening bug reports on nvim-compe completion if it ever breaks.

@jhossbach
Copy link

I am experimenting on this although I am a little short on time for a couple days. So far I have followed this issue, and I have come across some interesting behavior: starting the commands with a small letter does not trigger any completion whatsoever, but writing the same command but with a capital letter in the beginning shows completion for all the commands that match, including commands with small letters (e.g. writing \D triggers both suggestions for \Delta and \dag).
I am using NVIM v0.6.0-dev+518-g1dbbaf89b, this is my minimal vimrc:

if has('vim_starting')
  set encoding=utf-8
endif
scriptencoding utf-8

if &compatible
  set nocompatible
endif

set packpath=/tmp/plugged/

let s:plug_dir = expand('/tmp/plugged/vim-plug')
if !filereadable(s:plug_dir .. '/plug.vim')
  execute printf('!curl -fLo %s/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim', s:plug_dir)
end

execute 'set runtimepath+=' . s:plug_dir
call plug#begin(s:plug_dir)
Plug 'lervag/vimtex'
Plug 'hrsh7th/nvim-cmp'
Plug 'hrsh7th/cmp-omni'
call plug#end()
PlugInstall | quit

let g:testpattern = ''

lua << EOF
local cmp = require "cmp"
cmp.setup {
	sources = {
		{ name = "omni" ,
		    keyword_pattern = vim.g["vimtex#re#neocomplete"]},
		},
	}
EOF

I am open to suggestions concerning this minimal vim example.

@ranebrown
Copy link

I think the keyword pattern needs rewritten to be compatible with lua. I tried copying the contents of vimtex#re#neocomplete and using it directly but kept getting errors. That is my guess at least.

@krishnakumarg1984
Copy link
Contributor

Same. I get lots of errors in using this with nvim-cmp.

@lervag
Copy link
Owner

lervag commented Oct 31, 2021

I think the keyword pattern needs rewritten to be compatible with lua. I tried copying the contents of vimtex#re#neocomplete and using it directly but kept getting errors. That is my guess at least.

What does "compatible with lua" mean here? That is, my understanding is that nvim-cmp uses vim regexes, and vimtex#re#neocomplete is a vim regex.

@lervag
Copy link
Owner

lervag commented Oct 31, 2021

One suggestion would be to hard code everything in the first iteration. I.e., copy the regex from here:

let g:vimtex#re#neocomplete =
\ '\v\\%('
\ . '%(\a*cite|Cite)\a*\*?%(\s*\[[^]]*\]){0,2}\s*\{[^}]*'
\ . '|%(\a*cites|Cites)%(\s*\([^)]*\)){0,2}'
\ . '%(%(\s*\[[^]]*\]){0,2}\s*\{[^}]*\})*'
\ . '%(\s*\[[^]]*\]){0,2}\s*\{[^}]*'
\ . '|bibentry\s*\{[^}]*'
\ . '|%(text|block)cquote\*?%(\s*\[[^]]*\]){0,2}\s*\{[^}]*'
\ . '|%(for|hy)\w*cquote\*?\{[^}]*}%(\s*\[[^]]*\]){0,2}\s*\{[^}]*'
\ . '|defbibentryset\{[^}]*}\{[^}]*'
\ . '|\a*ref%(\s*\{[^}]*|range\s*\{[^,}]*%(}\{)?)'
\ . '|hyperref\s*\[[^]]*'
\ . '|includegraphics\*?%(\s*\[[^]]*\]){0,2}\s*\{[^}]*'
\ . '|%(include%(only)?|input|subfile)\s*\{[^}]*'
\ . '|([cpdr]?(gls|Gls|GLS)|acr|Acr|ACR)\a*\s*\{[^}]*'
\ . '|(ac|Ac|AC)\s*\{[^}]*'
\ . '|includepdf%(\s*\[[^]]*\])?\s*\{[^}]*'
\ . '|includestandalone%(\s*\[[^]]*\])?\s*\{[^}]*'
\ . '|%(usepackage|RequirePackage|PassOptionsToPackage)%(\s*\[[^]]*\])?\s*\{[^}]*'
\ . '|documentclass%(\s*\[[^]]*\])?\s*\{[^}]*'
\ . '|begin%(\s*\[[^]]*\])?\s*\{[^}]*'
\ . '|end%(\s*\[[^]]*\])?\s*\{[^}]*'
\ . '|\a*'
\ . ')'

Possibly simplify and only use the part for the commands, so e.g.

  keyword_pattern = '\v\\\a*'

Then add the branches one by one, e.g.

  keyword_pattern = '\v\\%(%(\a*cite|Cite)\a*\*?%(\s*\[[^]]*\]){0,2}\s*\{[^}]*|\a*)'

and test if things works as expected.

@jhossbach
Copy link

What does "compatible with lua" mean here? That is, my understanding is that nvim-cmp uses vim regexes, and vimtex#re#neocomplete is a vim regex.

Patterns are indeed evaluated using vim regex in the lua/cmp/utils/pattern.lua file.

  keyword_pattern = '\v\\\a*'
  keyword_pattern = '\v\\%(%(\a*cite|Cite)\a*\*?%(\s*\[[^]]*\]){0,2}\s*\{[^}]*|\a*)'

None of these patterns trigger nvim-cmp so far, normal omnicompletion via <C-x><C-o> works. My guess is that there is a problem with cmp-omni, but I will look into this as soon as I have more time.

@jhossbach
Copy link

The problem is that the omnifunc is called with the wrong string:
https://github.com/hrsh7th/cmp-omni/blob/3fec8a57d6d230c81d24c03dd80e97c62d4eda63/lua/cmp_omni/init.lua#L20

  local result = self:_invoke(vim.bo.omnifunc, { 0, string.sub(params.context.cursor_before_line, offset) })

The last part is the string that will be passed to the omnifunc. The problem is that the backslash is also passed to the omnifunc, so when typing \b, the string \b would be passed altough it should not (right?). As a workaround, one can by hand set offset to offset + 1 in the above. To immediately get completion, one also has to set keyword_pattern = 0 in the source config for omni, e.g.

cmp = require'cmp'
cmp.setup {
  ...
  sources = cmp.config.sources {
    { name = 'omni', keyword_length = 0 }
  }
}

I think this is a bug on cmp-omni's side, so I will give an update over there as well. As soon as this is fixed I will give an update here.

@lervag
Copy link
Owner

lervag commented Nov 28, 2021

Great, glad to get help on this one!

@avonmoll
Copy link

Thanks for the update on this. I have another question:

Pressing <C-x><C-o> after \cite{ shows the citekey as well as a parsed version of the reference (i.e. Author1 & Author2 (2021), "Title of the reference"). Is it possible to have this information in the nvim-cmp window? For, e.g., UltiSnips entries the actual snippet code shows up on hover.

@jhossbach
Copy link

I think the best thing is to write a new source for nvim-cmp and pass everything that the vimtex omnifunc provides. I'll work on that if I have some free time

@hrsh7th
Copy link

hrsh7th commented Nov 29, 2021

Hmm ... I don't think the offset should be a + 1 value ...

I think it's a matter of keyword pattern regex. What's wrong?

@jhossbach
Copy link

Let's move the discussion here and get back when the issue is solved.

@jhossbach
Copy link

@lervag I am a little confused about the mode entry in vimtex's omnifunc, I can't find it anywhere in the vim docs. Is that a deprecated entry? I can only think of those from here: https://vimhelp.org/insert.txt.html#complete-items

@clason
Copy link
Contributor

clason commented Nov 29, 2021

Isn't that a custom thing for VimTeX to indicate whether you're in math mode or not (so you can get context-dependent completion)?

let l:mode = vimtex#syntax#in_mathzone() ? 'm' : 'n'

@jhossbach
Copy link

Ok, so completion should work now out-of-the-box when using cmp-omni and the above config.
However, the menu item is not yet implemented, to change this one has to tweak the code in line 32-35 in lua/cmp_omni/init.lua to something like

    elseif type(v) == 'table' then
      if v.menu then -- Add this
        table.insert(items, {
	  label = v.abbr or v.word .. '\t' .. v.menu,
	  insertText = v.word,
	})
      else  --
      table.insert(items, {
        label = v.abbr or v.word,
        insertText = v.word,
      })
      end  --
    end

However, this only does part of the trick, see this screenshot:

image

On the other hand, vimtex's omnifunc beautifully indents and increases the popup window:
image

As for the menu item, this should be implemented into cmp-omni. For the popup window we could maybe reuse some of vimtex's logic, but this is as far as I can go right now.

@lervag
Copy link
Owner

lervag commented Nov 29, 2021

@lervag I am a little confused about the mode entry in vimtex's omnifunc ...

Isn't that a custom thing for VimTeX ...

Precisely. VimTeX "abuses" the completion entry dicts in this case and adds some context to help filter candidates.

Ok, so completion should work now out-of-the-box when using cmp-omni and the above config.

Great! For reference, could you be specific which configuration would be the corret to use? Did you refer to what you wrote here?

I'd be happy to write out some descriptions in the docs to guide users to a functional configuration, but it helps to be sure what would be considered good.

However, the menu item is not yet implemented, ...

Vim's internal completion automatically displays the completion in a nicely aligned table. VimTeX does not need to do anything except providing the candidates with the standard dictionaries with e.g. word, abbr, and menu.

I don't know any of the nvim-cmp or cmp-omni internals and I'm not sure how I could help with the formatting here. But perhaps one could use some logic/snippet from coc.nvim or similar that has a similar omnifunc interaction?

@moshiur-raj
Copy link
Author

moshiur-raj commented Nov 30, 2021

@lervag It works fine with the config given by @jhossbach.

cmp = require'cmp'
cmp.setup {
  ...
  sources = cmp.config.sources {
    { name = 'omni', keyword_length = 0 }
  }
}

Omitting keyword_length = 0 part disables triggering suggestion if no key is pressed. Both configurations are working fine as far as I've seen. However I don't know how much beneficial omitting keyword_length = 0 will be from a performance standpoint.
Also, nvim-cmp's doc says using omni may hurt performance. So enabling omni only for tex filetypes might be a good idea.

@jhossbach
Copy link

The menu key is now also displayed in the completion menu similar to the omnifunc, great thanks to @hrsh7th for helping on that!

However I don't know how much beneficial omitting keyword_length = 0 will be from a performance standpoint.

I think you're right, the keyword_length should be omitted.
As for the documentation, you can write something like: (parts are copied from the old entry for nvim-compe)

nvim-cmp is the successor of nvim-compe. It provides completion for different sources, including omni-completion, making it easy to use for VimTex. The plugin is available here:
https://github.com/hrsh7th/nvim-cmp

To include omni-completion, the cmp-omni package has to be installed and added to the list of sources in your config. For example, in Lua, it should look something like this:

cmp = require'cmp'
cmp.setup {
 -- additional config
 sources = cmp.config.sources {
   { name = 'omni'},
   -- additional sources
 }
}

lervag added a commit that referenced this issue Nov 30, 2021
@lervag
Copy link
Owner

lervag commented Nov 30, 2021

@lervag It works fine with the config given by @jhossbach.

cmp = require'cmp'
cmp.setup {
  ...
  sources = cmp.config.sources {
    { name = 'omni', keyword_length = 0 }
  }
}

Thanks! Silly question: do I understand correctly that require'cmp' is equivalent to require("cmp")? Is there a reason to prefer the latter form?

Omitting keyword_length = 0 part disables triggering suggestion if no key is pressed.

The default value is 1, right? Which means that omni completion would only be triggered after typing at least 1 character, e.g. \a and not \?

Also, do I understand correctly that there is no keyword pattern? Does this mean that nvim-cmp will attempt omni completion after every single key press?

So enabling omni only for tex filetypes might be a good idea.

How would one do that? It could be useful to add that as an example in the docs.

The menu key is now also displayed in the completion menu similar to the omnifunc, great thanks to @hrsh7th for helping on that!

Great! Good work!

I think you're right, the keyword_length should be omitted. As for the documentation, you can write something like: (parts are copied from the old entry for nvim-compe)

Thanks! I'm pushing a first version now.

@clason
Copy link
Contributor

clason commented Nov 30, 2021

Thanks! Silly question: do I understand correctly that require'cmp' is equivalent to require("cmp")? Is there a reason to prefer the latter form?

Yes, that's a Lua specialty: you can omit parentheses around single arguments that are either string or table literals, so foo('bar') == foo("bar") == foo 'bar' == foo "bar" (and similarly for foo({bar=baz}).

Which you prefer is a matter of taste (without parentheses, you can mimic "casts", like u"foo" to convert a string to utf8 or something. (Many projects use https://github.com/JohnnyMorganz/StyLua as a code formatter, so it doesn't really matter how people write it.)

@hrsh7th
Copy link

hrsh7th commented Jan 8, 2022

The trigger characters is for force invoking the completion with specific characters.
For example, if the user press /, the completion engine should display path source results. This situation is keyword length is zero. But the trigger character will achieve this.

@lervag
Copy link
Owner

lervag commented Jan 8, 2022

Thanks, @jhossbach! I've pushed a minor update now.

Is there a simple, built-in way to make this configuration only applicable to tex files? I.e., let's say one wants the omni source to be active for .tex files with the specified keyword_pattern?

One way, of course, is to use the autocmd approach. But it seems quite verbose from a user perspective. Say I want nvim-cmp with cmp-omni completion for three different file types with different configs and patterns - then I suddenly need several autocommand based config snippets.

Or - let's say I activate the omni source at the global level, perhaps with a preferred global keyword_pattern. In addition, I use a FileType autocommand like this:

augroup VimTeX
  autocmd!
  autocmd FileType tex
        \ lua require('cmp').setup.buffer { sources = { { name = 'omni', keyword_pattern = ... } } }
augroup END

Do I understand correctly that this will override the global settings?

@hrsh7th
Copy link

hrsh7th commented Jan 8, 2022

The sources field is array of source config. The nvim-cmp doesn't merge array so the sources option will overwrite the global config.

The sources[n].keyrod_pattern is source-specific keyword pattern. It is preferred over a global one. (but global keyword length isn't overwrite)

@lervag
Copy link
Owner

lervag commented Jan 8, 2022

@hrsh7th Ok. Let's say I wanted one keyword_pattern for the omni source in LaTeX, and another keyword_pattern for the omni source in another filetype (e.g. .foo). If I understand correctly, this would not really work, since one would override the setting globally whenever the config is changed.

@Xystel
Copy link

Xystel commented Jan 8, 2022

Hello, I tried the suggested settings from 0f8b4f0, but it ended up in following error:

Error detected while processing TextChangedI Autocommands for "*":                                                                                                                                                  
E5108: Error executing lua .../site/pack/packer/start/nvim-cmp/lua/cmp/utils/cache.lua:15: invalid value (table) at index 2 in table for 'concat'                                                                   
stack traceback:                                                                                                                                                                                                    
        [C]: in function 'key'                                                                                                                                                                                      
        .../site/pack/packer/start/nvim-cmp/lua/cmp/utils/cache.lua:15: in function 'get'                                                                                                                           
        .../site/pack/packer/start/nvim-cmp/lua/cmp/utils/cache.lua:34: in function 'get_offset'                                                                                                                    
        .../nvim/site/pack/packer/start/nvim-cmp/lua/cmp/source.lua:234: in function 'complete'                                                                                                                     
        ...re/nvim/site/pack/packer/start/nvim-cmp/lua/cmp/core.lua:253: in function 'complete'                                                                                                                     
        ...re/nvim/site/pack/packer/start/nvim-cmp/lua/cmp/core.lua:166: in function 'callback'                                                                                                                     
        ...re/nvim/site/pack/packer/start/nvim-cmp/lua/cmp/core.lua:216: in function 'autoindent'                                                                                                                   
        ...re/nvim/site/pack/packer/start/nvim-cmp/lua/cmp/core.lua:158: in function 'on_change'                                                                                                                    
        ...re/nvim/site/pack/packer/start/nvim-cmp/lua/cmp/init.lua:301: in function 'callback'                                                                                                                     
        ...ite/pack/packer/start/nvim-cmp/lua/cmp/utils/autocmd.lua:31: in function 'emit'                                                                                                                          
        [string ":lua"]:1: in main chunk

I then tried trigger_characters as suggested from @jhossbach, but I'm not sure if this does that expected behaviour of only trigger omni completion when \ is typed.

But as I'm here, I may also have a proposal for improvement of the documentation. In nvim-cmp it is possible to format the completion menu. But then the additional information from vimtex are lost, for example from which package the command is from. We discussed that in this Issue.

I currently load following snippet in after/ftplugin/tex.lua and invoke cmp.setup.buffer function, to only apply to tex files:

local cmp = require('cmp')
cmp.setup.buffer {
	formatting = {
		format = function(entry, vim_item)
			vim_item.menu = ({
				omni = (vim.inspect(vim_item.menu):gsub('%"', "")),
				luasnip = "[LuaSnip]",
				buffer = "[Buffer]",
			})[entry.source.name]
		return vim_item
		end,
	},
	sources = {
		{ name = 'omni' },
		{ name = 'luasnip' },
		{ name = 'buffer' },
	},
}

This results in a completion window like this:

image

As you can see it uses the information provided by vimtex in the menu, and for the other sources it uses the custom defined descriptions. Maybe it would be interesting to mention that in the documentation too.

@lervag
Copy link
Owner

lervag commented Jan 8, 2022

Thanks! I'm updating the docs again. I'll remove the mention of keyword_patterns as it seems to be faulty for now. I hope the latest iteration is closer to decent!

I'll also take the liberty of closing this issue. Feel free to continue the discussion or opening related issues.

@jdhao
Copy link

jdhao commented Mar 13, 2022

@lervag It seems that now the config does not work anymore. I have the following conf under ~/.config/nvim/after/ftplugin/tex.lua:

local cmp = require('cmp')
cmp.setup.buffer {
	formatting = {
		format = function(entry, vim_item)
			vim_item.menu = ({
				omni = (vim.inspect(vim_item.menu):gsub('%"', "")),
				buffer = "[Buffer]",
			})[entry.source.name]
		return vim_item
		end,
	},
	sources = {
		{ name = 'omni' },
		{ name = 'buffer' },
	},
}

But the autocompletion does not work. I run the CmpStatus command and it says that omni source is unkown? (I have installed cmp-omni already)
image

Tested on latest master of nvim-cmp, cmp-omni and vimtex.

@Xystel
Copy link

Xystel commented Mar 14, 2022

For me it works with that config. I don't know why it does not for you.

Have you double checked, that the cmp-omni plugin is installed properly? If you use packer.nvim as package manager you could run :PackerStatus.

Another thing you could test is, if the omni source works if you specify it in the main cmp config.

Also note that the :CmpStatus command isn't always reliable. See nvim-cmp/doc.

@jdhao
Copy link

jdhao commented Mar 15, 2022

I have tried to specify cmp-omni source in main cmp config. It does not work either.

PackerStatus shows that both nvim-cmp and cmp-omni is loaded.

@jhossbach
Copy link

@jdhao I can also confirm it works for me. Can you check if removing buffer as source and in the function changes anything?
Also check that echo &omnifunc still returns vimtex#complete#omnifunc

@jdhao
Copy link

jdhao commented Mar 15, 2022

This is my full cmp config for now:

local cmp = require'cmp'
local lspkind = require'lspkind'

cmp.setup({
  snippet = {
    expand = function(args)
      -- For `ultisnips` user.
      vim.fn["UltiSnips#Anon"](args.body)
    end,
  },
  mapping = {
    ['<Tab>'] = function(fallback)
      if cmp.visible() then
        cmp.select_next_item()
      else
        fallback()
      end
    end,
    ['<S-Tab>'] = function(fallback)
      if cmp.visible() then
        cmp.select_prev_item()
      else
        fallback()
      end
    end,
    ['<Esc>'] = cmp.mapping.close(),
    ['<CR>'] = cmp.mapping.confirm({ select = true }),
    ['<C-d>'] = cmp.mapping.scroll_docs(-4),
    ['<C-f>'] = cmp.mapping.scroll_docs(4),
  },
  sources = {
    { name = 'nvim_lsp' }, -- For nvim-lsp
    { name = 'ultisnips' }, -- For ultisnips user.
    { name = 'nvim_lua' }, -- for nvim lua function
    { name = 'path' }, -- for path completion
    { name = 'omni' },
    { name = 'emoji', insert = true, } -- emoji completion
  },
  completion = {
    keyword_length = 1,
    completeopt = "menu,noselect"
  },
  view = {
    entries = 'custom',
  },
  formatting = {
    format = lspkind.cmp_format({
      mode = "symbol_text",
      menu = {
        nvim_lsp = "[LSP]",
        ultisnips = "[US]",
        nvim_lua = "[Lua]",
        path = "[Path]",
        buffer = "[Buffer]",
        emoji = "[Emoji]",
      },
    }),
  },
})

set omnifunc shows the correct result:

image

I can trigger omni completion with Ctrl-X Ctrl-O, but no luck with auto-completion.

My nvim version: 0.6.1, nvim-cmp, cmp-omni, and vimtex are in the latest master.

What is your nvim version? Maybe my env is wrong? I have no ideas...

@lervag
Copy link
Owner

lervag commented Mar 15, 2022

@jdhao Thanks for sharing your problems. I'm sorry to say I can't be of much help, but I'm glad to see @Xystel and @jhossbach is pitching in and trying to assist. I'll follow the discussion, and if I notice anything where I can be of help, I'll let you know!

Also, to all of you: If you notice something that should be fixed or update (e.g. in docs), please let me know!

@jdhao
Copy link

jdhao commented Mar 15, 2022

@lervag On a sidenote, the following conf can not start vimtex properly:

set runtimepath+=/Users/jdhao/.local/share/nvim/site/pack/packer/opt/vimtex

filetype plugin indent on
syntax enable

set runtimepath+=/Users/jdhao/.local/share/nvim/site/pack/packer/opt/nvim-cmp/
set runtimepath+=/Users/jdhao/.local/share/nvim/site/pack/packer/opt/cmp-omni/

lua << EOF
  local cmp = require('cmp')
  cmp.setup {
    sources = { { name = 'omni' }, },
  }
EOF

I open a test.tex file like this: nvim -u init.vim test.tex. Upon openning it, the only available command for vimtex is VimtexInverseSearch:

image

It seems that vimtex is not properly initialized. I manually run this command: call vimtex#init() here. Then vimtex is initialized properly.

Still the autocompletion won't work if I type \ e.g.,, I have to press Ctrl-X Ctrl-O to activate the completion menu. Then the autocompletion seems to work as long as \ is retained.

@lervag
Copy link
Owner

lervag commented Mar 15, 2022

@lervag On a sidenote, the following conf can not start vimtex properly:

set runtimepath+=/Users/jdhao/.local/share/nvim/site/pack/packer/opt/vimtex

Don't put VimTeX in /opt! It should be in /start. See :help runtime-search-path and :help pack-add. VimTeX is a proper filetype plugin that is already only loaded when necessary, and there is more or less no penalty of keeping it in /start.

@jdhao
Copy link

jdhao commented Mar 15, 2022

okay, I will put vimtex in start directory.

Still the autocompletion won't work if I type \ e.g.,, I have to press Ctrl-X Ctrl-O to activate the completion menu. Then the autocompletion seems to work as long as \ is retained.

I have also recorded a screen shot to show the issue:

vimtex-completion

@lervag
Copy link
Owner

lervag commented Mar 15, 2022

The autocompletion issue is what I referred to when I stated that I can't be of much more help. As we see from the earlier posts, things seem to work well for others who use nvim-cmp.

@jdhao
Copy link

jdhao commented Mar 15, 2022

@jhossbach Can you try my minimal conf here (change the plugin path to your actual path) and confirm if it works for you?

@Xystel
Copy link

Xystel commented Mar 15, 2022

I just tried to use your provided cmp config to make a minimal example in one file. This is my result:

require('packer').startup(function(use)
  use { 'wbthomason/packer.nvim' }
  use { 'lervag/vimtex' }
  use { 'hrsh7th/nvim-cmp' }
  use { 'hrsh7th/cmp-omni' }
  use { 'hrsh7th/cmp-buffer' }
  use { 'SirVer/ultisnips' }
  use { 'onsails/lspkind-nvim' }
  use { 'hrsh7th/cmp-nvim-lsp' }
  use { 'hrsh7th/cmp-nvim-lua' }
  use { 'hrsh7th/cmp-path' }
  use { 'hrsh7th/cmp-emoji' }
end)

-- Setup nvim-cmp.
local cmp = require'cmp'
local lspkind = require'lspkind'

cmp.setup({
  snippet = {
    expand = function(args)
      -- For `ultisnips` user.
      vim.fn["UltiSnips#Anon"](args.body)
    end,
  },
  mapping = {
    ['<Tab>'] = function(fallback)
      if cmp.visible() then
        cmp.select_next_item()
      else
        fallback()
      end
    end,
    ['<S-Tab>'] = function(fallback)
      if cmp.visible() then
        cmp.select_prev_item()
      else
        fallback()
      end
    end,
    ['<Esc>'] = cmp.mapping.close(),
    ['<CR>'] = cmp.mapping.confirm({ select = true }),
    ['<C-d>'] = cmp.mapping.scroll_docs(-4),
    ['<C-f>'] = cmp.mapping.scroll_docs(4),
    ['<C-Space>'] = cmp.mapping.complete(),
  },
  sources = {
    { name = 'nvim_lsp' }, -- For nvim-lsp
    { name = 'ultisnips' }, -- For ultisnips user.
    { name = 'nvim_lua' }, -- for nvim lua function
    { name = 'path' }, -- for path completion
    { name = 'omni' },
    { name = 'buffer' },
    { name = 'emoji', insert = true, } -- emoji completion
  },
  completion = {
    keyword_length = 1,
    completeopt = "menu,noselect"
  },
  view = {
    entries = 'custom',
  },
  formatting = {
    format = lspkind.cmp_format({
      mode = "symbol_text",
      menu = ({
        nvim_lsp = "[LSP]",
        ultisnips = "[US]",
        nvim_lua = "[Lua]",
        path = "[Path]",
        buffer = "[Buffer]",
        emoji = "[Emoji]",
	omni = "[Omni]",
      }),
    }),
  },
})

For me it worked. I added a shortcut <C-Space> that can invoke the completion menu from cmp.

Can you make a backup of your ~/.config/nvim folder and place this code I provided in your ~/.config/nvim/init.lua?

@jdhao
Copy link

jdhao commented Mar 15, 2022

@Xystel Thanks, your config works for me, autocompletion now starts immediately as I type \ followed by some characters. I think the issue may have something to do with lazyloading, since I am lazy loading all nvim-cmp related plugins. It can be hell to make all those plugins work together with lazyloading. I will dig into this. Thanks a million, at least I have got a working config 😅

@Xystel
Copy link

Xystel commented Mar 15, 2022

@jdhao Glad to help. :) If you want to lazy load things, maybe NvChad provides a good reference. But I'm unsure, if you don't get the same error with it. For me there isn't a reason to lazy load plugins. I have a total of 42 Plugins and it still loads in 120ms. But most of my plugins are in lua, which is AFAIK much faster parsed then vimscript.

As I'm talking about lua and vimscript plugins: Is there a special reason, why you are using UltiSnips over LuaSnip?

@jdhao
Copy link

jdhao commented Mar 15, 2022

I have been using Ultisnips for over three years, and I have written quite a few snippets for ultisnips. The transition cost for me would be huge, with no perceivable benefit. With its powerful Python interpolation feature, I am sure that no snippet plugin can compete with Ultisnips. So there is no reason for switching to LuaSnip or other similar plugins.

@lervag
Copy link
Owner

lervag commented Mar 15, 2022

Good to hear things are working now! Btw., I do agree with @jdhao reg. UltiSnips. Perhaps LuaSnip is good, even great, but I also use Ultisnips - it works very well, and I don't see any reason to change it. There is no significant performance cost either. So, if it ain't broke, don't fix it.

@Xystel
Copy link

Xystel commented Mar 15, 2022

That sounds like a good reason. I agree that switching for no explicit benefit is pointless. I was curious, I never used UltiSnips, thanks for the answers. From my point of view, I wouldn't change to UltiSnips either. That Python interpolation feature sounds great. But in LuaSnip you could use Lua functions, which is also powerful. So I assume they are both good choices.

@lervag
Copy link
Owner

lervag commented Mar 16, 2022

Yes, exactly: I also have the impression that both are good choices. I can see how one can be tempted to change to LuaSnip if one is going into a pure neovim Lua configuration, but essentially I don't think there is much to gain. And in some cases, it can be a big job to convert existing snippets to a new format.

@clason
Copy link
Contributor

clason commented Mar 16, 2022

One benefit of LuaSnip (or similar) is that you remove the need for the external dependency (Python3), which some (but not all, clearly) will consider an advantage. And LuaSnip can (now) load snippets in SnipMate format (https://github.com/L3MON4D3/LuaSnip#add-snippets), so in many cases there will be no need to rewrite existing snippets.

(Not that that will convince anybody; just wanted to add these data points.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants