# Contextual Snippets in UltiSnips not working

I have been using vimtex with UltiSnips for a while on Linux platform and it has been working just fine.

Recently, I switched to MacBook Air M1 for the same and installed the above mentioned plugins to work with MacVim using vim-plug. All UltiSnips snippets are working (expanding) except for those which use a context by which I mean that regular snippets expand as expected whereas the snippets involving a context do not expand. Also, I found out that if I comment out the context "math()" from snippets then they do expand. So basically the problem now is that the context environment is causing problems with snippet expansion. A sample for my snippets is provided below.

I suspect this is due to MacVim running on top of Rosetta 2 but cannot be sure as nothing else has changed (maybe someone using same setup as me but on regular Intel chips can pitch in for more data).

Can someone help me figure out this thing?

Snippets :-

1. Regular snippets which do work :-
snippet pack "creates a usepackage command" bAm
\usepackage{\${1:package_name}}
endsnippet
1. Context snippets which do not work (here the context is math()) :-
global !p
texMathZones = ['texMathZone' + x for x in ['A', 'AS', 'B', 'BS', 'C', 'CS',
'D', 'DS', 'E', 'ES', 'F', 'FS', 'G', 'GS', 'H', 'HS', 'I', 'IS', 'J', 'JS',
'K', 'KS', 'L', 'LS', 'DS', 'V', 'W', 'X', 'Y', 'Z', 'AmsA', 'AmsB', 'AmsC',
'AmsD', 'AmsE', 'AmsF', 'AmsG', 'AmsAS', 'AmsBS', 'AmsCS', 'AmsDS', 'AmsES',
'AmsFS', 'AmsGS' ]]

texIgnoreMathZones = ['texMathText']

texMathZoneIds = vim.eval('map('+str(texMathZones)+", 'hlID(v:val)')")
texIgnoreMathZoneIds = vim.eval('map('+str(texIgnoreMathZones)+", 'hlID(v:val)')")

ignore = texIgnoreMathZoneIds[0]

def math():
synstackids = vim.eval("synstack(line('.'), col('.') - (col('.')>=2 ? 1 : 0))")
try:
first = next(i for i in reversed(synstackids) if i in texIgnoreMathZoneIds or i in texMathZoneIds)
return first != ignore
except StopIteration:
return False

keywords1 = { 'a' : '\\alpha',   'b' : '\\beta',   'g' : '\\gamma', 'd' : '\\delta', 'e' : '\\epsilon', 'z' : '\\zeta',   't' : '\\theta', 'i' : '\\iota', 'k' : '\\kappa',   'l' : '\\lambda', 's' : '\\sigma', 'o' : '\\omega',  'p' : '\\psi',  'A' : '\\Alpha',   'B' : '\\Beta',   'G' : '\\Gamma', 'D' : '\\Delta', 'E' : '\\Epsilon', 'Z' : '\\Zeta',   'T' : '\\Theta', 'I' : '\\Iota', 'K' : '\\Kappa', 'L' : '\\Lambda', 'S' : '\\Sigma', 'O' : '\\Omega', 'P' : '\\Psi' }

keywords2 = { 't' : '\\tau', 'p' : '\\pi', 'f' : '\\phi' , 'm' : '\\mu', 'n' : '\\nu', 'e' : '\\eta', 'T' : '\\Tau', 'P' : '\\Pi', 'F' : '\\Phi', 'M' : '\\Mu', 'N' : '\\Nu', 'E' : '\\Eta'}
endglobal

######################################################################

context "math()"
snippet ";([a,b,g,d,e,z,t,i,k,l,s,o,p,A,B,G,D,E,Z,T,I,K,L,S,O,P])" "Greek Letters 1" rAm
!p snip.rv = keywords1[match.group(1)]
endsnippet

######################################################################

context "math()"
snippet "'([t,p,f,m,n,e,T,P,F,M,N,E])" "Greek Letters 2" rAm
!p snip.rv = keywords2[match.group(1)]
endsnippet

######################################################################
• Can you edit to describe "not working"? It's pretty unclear what's wrong from your question Dec 22, 2020 at 19:18
• @D.BenKnoble Done. I also realised that the problem was not with Python but with the context environment (or whatever it is called) but wasn't able to isolate the issue any further. Dec 22, 2020 at 20:24
• @D.BenKnoble maybe the problem is that I am using vim.eval(...) which only works for regular vim and I am using MacVim? Dec 22, 2020 at 20:26

The problem is that you have updated your plugins in the transition Linux to Mac. This also brings a major update of Vimtex, in which the syntax plugin has been included as part of Vimtex. Part of the syntax script changes are to simplify the math zones.

The exact issue you raise is discussed here, and this comment should provide the required change, repeated here for convenience. Change the top lines of your context script to this:

global !p
texMathZones = ['texMathZone' + x for x in ['', 'X', 'XX', 'Env', 'EnvStarred', 'Ensured']]

Edit: One can simplify the global part by using a built in function from vimtex:

global !p
def math():
return vim.eval('vimtex#syntax#in_mathzone()') == '1'
endglobal
• Is this a good fix? context "vim.eval('vimtex#syntax#in_mathzone()')" (instead of rolling out a custom def math(): function.) I was just browsing vimtex code looking for such a function... Dec 22, 2020 at 21:08
• Worked perfectly. Thanks a lot. Should have figured out to check for updates on Plugins. Dec 22, 2020 at 22:00
• @filbranden Yes, that looks like a good idea. I assume the returned value of vim.eval is still an integer. The function returns 1 for True and 0 for False, which should be compatible with Python. It will also handle the texMathText part. So, it seems the entire snippet code can be significantly simplified. Dec 23, 2020 at 7:45
• @GillesCastel I'm curious: Is it necessary to add == '1'? Did you check it? I expected the vim.eval(...) to return a number, as written above, in which case this should not be necessary... Dec 23, 2020 at 13:05
• Yes, I checked it. Without == '1', the function always returns True. I also expected it to return a number but apparently it returns a string. Dec 24, 2020 at 10:34