garbas/vim-snipmate

Error detected while processing function snipMate#TriggerSnippet

Opened this issue ยท 14 comments

Minimal working example, of a JavaScript file:

class ClassName{

Upon pressing the tab key in insert mode, with the cursor right after the curly bracket, the following error is shown:
Error detected while processing function snipMate#TriggerSnippet[35]..snipMate#GetSnippetsForWordBelowCursor[31]..funcref#Call[61]..snipMate#GetSnippets[4]..funcref#Call[61]..snipMate#DefaultPool[13]..<SNR>117_Glob: line 5: E220: Missing }.

Other than SnipMate, I've installed the required dependency plugins: vim-addon-mw-utils and tlib. I've also installed vim-snippets.

I'm running the console version of Vim 8 (32bit) on Windows 10.

Sorry for the late response. I can confirm this bug is present, and it looks like there are other issues with SnipMate on Windows as well. I'll have to look into this.

I've determined this to be a bug in Vim in how glob() functions on Windows. I haven't yet determined a proper solution, either to the bug or a workaround in SnipMate. Getting rid of support for single snippet files would work, but I'm not sure I'm ready to do that.

I do confirm that this issue is not resolved yet

Error detected while processing function snipMate#TriggerSnippet[50]..snipMate#GetSnippetsForWordBelowCursor:                                                                         
line   31:
E716: Key not present in Dictionary: "get_snippets"

@ajzafar This appears to not be unique to Windows as I have this exact issue on macos (Catalina, 10.15.7) as well, both in neovim nightly and vim8.

I have the same error in Linux Mint Cinnamon 20.1.

I started getting this with an existing vim session Ubuntu 21.04 at a random moment. Then I nuked ~/.vim/session and next time it started working again. So it's some intermediate state. A minimal repro would be needed.

@************ I do not have ~/.vim/session what is it? and is there anything that can serve as an alternative ?

Sorry, I don't know the exact cause, this was a sledgehammer random fix attempt that worked.

I suggest you try to bisect your configs and tell us the result :-)

It seems like there might be a few related bugs going on here. I want to try something to fix them all. I just pushed a branch that disables support for .snippet files, which changes what SnipMate globs for and should therefore avoid all these issues. Can people try that branch for a while and post here if any issues arise? Thank you in advance

Hi, I have a similar issue. Snipmate works for a while and at some point tab doesn't work anymore, I get this:

Error detected while processing function snipMate#TriggerSnippet[50]..snipMate#GetSnippetsForWordBelowCursor:

Closing and reopening vim solves the issue, although it's quite painful when you are deep into a programming session

I just moved to https://github.com/neoclide/coc.nvim this package and provide many feature . it might help to someone.

erikw commented

I've had this issue for several years in both Vim and Neovim.

Workaround

When this bug occurs:

  • create a sessionfile within Vim: :mksession!
  • then start vim again like: $ vim -S to get back on where you left off.

A restart gets rid of this bug (for a while)

This issue has vexxed me for some time. I tried 'UltiSnips' but that Python-based alternative was buggy to the point it was functionally unusable.

This morning I spent some time exploring the SnipMate ... E716: Key not present in Dictionary: "get_snippets" ... E716: Key not present in Dictionary: "get_snippets" error.

That error originates in the /home/victoria/.vim/bundle/vim-snipmate/autoload/snipMate.vim file. I played with that file; although not a solution, here are my observations - hopefully a developer can debug / fix the code.

Starting at ~:452 in snipMate.vim:

" used by both: completion and insert snippet
fun! snipMate#GetSnippetsForWordBelowCursor(word, exact) abort
   " Split non-word characters into their own piece
   " so 'foo.bar..baz' becomes ['foo', '.', 'bar', '.', '.', 'baz']
   " First split just after a \W and then split each resultant string just
   " before a \W
   let parts = filter(tlib#list#Flatten(
   			\ map(split(a:word, '\W\zs'), 'split(v:val, "\\ze\\W")')),
   			\ '!empty(v:val)')
   " Only look at the last few possibilities. Too many can be slow.
   if len(parts) > 5
   	let parts = parts[-5:]
   endif
   let lookups = [a:word]
   let lookup = ''
   for w in reverse(parts)
   	let lookup = w . lookup
   	if index(lookups, lookup) == -1
   		call add(lookups, lookup)
   	endif
   endfor

   " Remove empty lookup entries, but only if there are other nonempty lookups
   if len(lookups) > 1
   	call filter(lookups, 'v:val != ""')
   endif

   let matching_snippets = []
   let snippet = ''

   " -------------------------------------------------------------------------
   " COMMENT-1 (Victoria, 2022-07-14):
   "
   " /home/victoria/.vim/bundle/vim-snipmate/autoload/snipMate.vim
   "
   " If line above is uncommented, upon restarting Vim this script will be in error,
   " and my 'date' snippet will insert 'date-1' - not the current datetime
   " specified in that snippet.
   "
   " Likewise, syntax errors in other files - e.g. commented lines in ~/.vimrc
   " beginning with # not ", are problematic.  In a fresh Vim instance, you can
   " successfully trigger a snippet in the syntax-incorrect file (preexisting error
   " in previously saved file). However, when save that tile (Vim `:w` write buffer
   " command), that save action will trigger a Vim error that appears to cascade
   " to snipMate:
   "
   "   Error detected while processing /home/victoria/.vimrc:
   "     line    2:
   "     E488: Trailing characters: apple: # apple
   "
   " Under that error condition, you will get the SnipMate
   "
   "   E716: Key not present in Dictionary: "get_snippets"
   "
   " error, and the snippet will show not the snippet name, but whatever
   " characters you typed prior to pressing <TAB>, with '-1' appended; e.g.,
   "   date-1 | ne-1 | kw-1 | a-1 | m-1 | foo-1 | ...
   " 
   " If you quit Vim, then restart Vim and open a saved ~/.vimrc file that
   " contains the syntax error mentioned above, you can execute the 'date' (and
   " other) snippets - until you save that file, triggering the Vim error
   " cascade, and the echoing of '-1' appended characters/words, in place of
   " the intended snippet text.
   "
   " NOTES:
   "   1. debugging: 'echom' messages are overwritten; use the more intrusive
   "      but persistent 'echoe'
   "   2. restart Vim to instantiate edits, here
   " -------------------------------------------------------------------------

   " prefer longest word
   for word in lookups
   	" Victoria - added:
   	echoe 'word: ' word
   	let g:snipMate.word = word
   	for [k,snippetD] in items(funcref#Call(g:snipMate['get_snippets'], [snipMate#ScopesByFile(), word]))
   		" Victoria: this is echoed once per snippet match; e.g. if snippets
   		" file has { snippet date | snippet datelong }, will echo 2x
   		" echoe ' ****************** '
   		" hack: require exact match
   		if a:exact && k !=# word
   			continue
   		endif
   		call add(matching_snippets, [k, snippetD])
   		if a:exact
   			break
   		endif
   	endfor
   endfor
   return matching_snippets
endf

Aside: while I very much appreciate the availability, development, and utility of this code, in my opinion, the code is overly-complex: it should simply exact-match the snippet name / word - period.

snippet date ... | snippet date1 ... | snippet datetime ... | snippet datepublished ... | ... No compound snippet names (snippet date.time ... | snippet date-time ...` | ...

From my reading of the file snipMate.vim, it appears that this approach would avoid much of the code complexity (regex expressions; [key:value] DICT, ... and hence downstream / cascading errors.