1

I'm trying to move to Neovim from regular Vim and while tinkering with UltiSnips I found out that the synID function always returns 0 for some filetypes in Neovim, while it works fine in Vim. For example, I open the same Lua file in Vim and Neovim, focus the cursor on require then I run:

:echo synID(line("."), col("."), 0) 

in both of them. Neovim returns 0, while Vim returns 595.

For now it seems that the only filetype where this does not happen is .snippet (for UltiSnips), but still it returns different values.

What is it that could be breaking synID? I'm using this function to detect different environments in code and expand snippets accordingly. Thanks in advance!

5
  • Maybe could you be interested by the following answer. Commented Nov 3 at 16:27
  • 1
    @VivianDeSmedt the link you provide might even be considered a duplicate question. They look close enough. Commented Nov 3 at 21:27
  • 1
    @Friedrich, indeed but the origin of the question seems to be UltiSnip and some clarifications may come later. Commented Nov 4 at 3:17
  • Welcome to Vi and Vim. Please don't edit your question to contain a solution. Instead, post a self-answer. This is encouraged and will help future readers with the same problem. Commented Nov 4 at 20:47
  • 1
    @Friedrich Hi, thanks for the tip, will do! Commented Nov 5 at 21:11

2 Answers 2

1

Neovim is using TreeSitter.

An alternative to:

:echo synID(line("."), col("."), 0) 

Would be in Lua:

x = vim.treesitter.get_captures_at_pos(vim.fn.bufnr(), vim.fn.line('.') - 1, vim.fn.col('.') - 1) print(vim.fn.hlID('@' .. x[#x].capture)) 

Or if you need a Vim expression:

echo hlID("@" . v:lua.vim.treesitter.get_captures_at_pos(bufnr(), line('.') - 1, col('.') - 1)[-1].capture, 0) 
2

Many thanks to @VivianDeSmedt ! If anyone else is trying to reuse their UltiSnips setup with Neovim, this is the new context function:

global !p def math_env(): is_vim = int(vim.eval("!has('nvim')")) # Check if in Vim or Neovim if is_vim: name = vim.eval("synIDattr(synID(line('.'), col('.')-1, 0), 'name')") patterns = ['typstMarkupDollar', 'typstMathScripts', 'typstMathNumber', 'typstMathSymbol', 'typstMathIdentifier', 'typstMathFunction'] else: here = vim.eval("v:lua.vim.treesitter.get_captures_at_pos(bufnr(), \ line('.')-1, col('.')-1)") if not here: # Empty list if at EOL or in a blank line return False name = f"@{here[-1]['capture']}" patterns = ['@markup.math'] return name in patterns endglobal 

It's specific to Typst but it should be easy enough to adapt this to LaTeX as well: just check the output of synIDattr(...) and change the patterns.

4
  • has('vim') in vim will never evaluate to true, so the if condition is pointless. Commented Nov 5 at 22:28
  • @MaximKim Hi, that's true but I forgot to mention that I'd like this configuration to work seamlessly both in Vim and Neovim, this is why I check what editor I'm using Commented Nov 7 at 13:23
  • And your check is just always goes to else part, cause in both editors main if clause is always false. Commented Nov 7 at 13:31
  • @MaximKim My bad, I misinterpreted your first comment, I've checked and realised has('nvim') is what I was looking for. Thanks for pointing it out! Commented Nov 7 at 17:00

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.