Jinja2 offers some tests which that share a name with a corresponding literal, i.e., false, true, null. However, they are homographs, since the tests are semantically different from the literals. For example:
{% if test is false %} {# false(test) #}
{# vs #}
{% if test is equalto false %} (# equalto(test, false) #}
The same thing applies to the in test and the in operator:
{% if 1 in [1, 2] %}
{# vs #}
{% if 1 is in [1, 2] %} {# in(1, [1, 2]) #}
It would be nice if BetterJinja distinguishes between these, since it may be a bit confusing otherwise.
Expected Behaviour
{% if test is false %}
## ^^^^^ support.function.test.jinja
{% if test eq false %}
## ^^^^^ constant.language.jinja
{% if 1 is in [1, 2] %}
## ^^ support.function.test.jinja
{% if 1 in [1, 2] %}
## ^^ keyword.operator.word.jinja
Actual Behaviour
{% if test is false %}
## ^^^^^ constant.language.jinja
{% if test eq false %}
## ^^^^^ constant.language.jinja
{% if 1 is in [1, 2] %}
## ^^ keyword.operator.word.jinja
{% if 1 in [1, 2] %}
## ^^ keyword.operator.word.jinja
How to Reproduce
See above.
Problematic Jinja2 template.
{% if test is false %}
{% if test is true %}
{% if test is none %}
{% if 1 is in [1, 2] %}
Environment
Additional context
Potential fix is to greedily check for those literals after the is keyword is found. Perhaps something along the lines of the following:
Summary
Jinja2 offers some tests which that share a name with a corresponding literal, i.e.,
false
,true
,null
. However, they are homographs, since the tests are semantically different from the literals. For example:The same thing applies to the
in
test and thein
operator:It would be nice if BetterJinja distinguishes between these, since it may be a bit confusing otherwise.
Expected Behaviour
Actual Behaviour
How to Reproduce
See above.
Problematic Jinja2 template.
Environment
Additional context
Potential fix is to greedily check for those literals after the
is
keyword is found. Perhaps something along the lines of the following: