For best experience, I want to enable some snippets to be expanded only in Tex Math environments. A wonderful person, lacygoill helped me on GitHub to achieve just this with the following setup:
Let the context function and a snippet using the context be given by:
global !p
def isMath():
return int(vim.eval("get(reverse(map(synstack(line('.'), col('.')), {i,v -> synIDattr(v, 'name')})), 0, '') =~# 'texMathZone\%(X\|Y\|V\)'"))
endglobal
context "isMath()"
snippet pow "" iA
^{$1}$0
endsnippet
Now isMath above doesn't work on cases when there's no space inbetween the math delimiters such as $|$ or \(|\), it only works on cases like $ | $ or $\( | \)$, so the other version of isMath that is derived is:
def isMath():
return int(vim.eval("get(reverse(map(synstack(line('.'), col('.') - (col('.')>=2 ? 1 : 0)), {i,v -> synIDattr(v, 'name')})), 0, '') =~# 'texMathZone\%(X\|Y\)'"))
Both seem to work 99% of the time. There's one time that they doesn't work which is important too. Consider the following tex code: $e|$, type pow to expand to e^{|}, now type x followed by pow. I expect it to expand to e^{x^{|}}, instead it doesn't expand pow anymore, it stays as e^{xpow}. (all the expansions should happen automatically because of A and | stands for cursor position).
The second variation of isMath fails in an additional case too, consider the following snippet:
snippet __ "subscript" iA
_{$1}$0
endsnippet
This will not expand in $|$ or $ | $ at all.
How can the two python functions above for context be adjusted to consider the nested curly brace {} cases? I don't understand why this is happening at all either, because even in e{|} position, the cursor is located in texMathZoneV syntax group. I'd prefer to see an adjustment made to the second isMath because it's convenient to expand in $|$ where there are no spaces inbetween $$. However, if that's impossible to achieve, it's not a problem to write $ | $ either so adjustments to the first isMath are very welcome too.
To sum up, I'm looking for a function that correctly identifies it is in math environment and as lacygoill suggested it's a good idea to use syntax groups as they're always right. The isMath() functions above have been doing it well so far, with the nested {} being an exception as described for both functions and with $__$ not expanding at all for the second function. A new function with a different approach is also welcome that'd be working as expected, I think there are more issues than meet the eye with the current ones. If anyone's been through this, I'd really appreciate a hand!
UPDATE:
texMathTextZones = ['texMathText']
texMathTextZoneIds = vim.eval('map('+str(texMathTextZones )+", 'hlID(v:val)')")
...
return not set(texMathZoneIds).isdisjoint(synstackids) and set(texMathTextZoneIds).isdisjoint(synstackids)
I added these lines to ignore some scopes. Is there a better way to do it?

texMathTexteven if in a math environment? This looks something like this$should return true here \text{but no longer true here}$– Jason Zamel Jan 09 '19 at 02:08