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?