Sublime-Instincts / BetterJinja

A Sublime Text package that provides enhanced syntax highlighting, completions, snippets & more for Jinja templates.
https://packagecontrol.io/packages/Jinja2
MIT License
15 stars 4 forks source link

[BUG] Homograph tests mistaken as literals. #6

Closed ROpdebee closed 4 years ago

ROpdebee commented 4 years ago

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:

{% 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:

- match: \b(is)\s+(true|false|none|in)\b
  captures:
    0: keyword.operator.word.is.jinja
    1: support.function.test.jinja
- match: \bis\b:
  # Normal operation.