coala-bears icon indicating copy to clipboard operation
coala-bears copied to clipboard

Jinja2Bear: Add support for indentation

Open Naveenaidu opened this issue 5 years ago • 6 comments

This adds the indentation feature to the Jinja2 language. This indentation is applied only to the tags of Jinja2.

Closes https://github.com/coala/coala-bears/issues/2763

For short term contributors: we understand that getting your commits well defined like we require is a hard task and takes some learning. If you look to help without wanting to contribute long term there's no need for you to learn this. Just drop us a message and we'll take care of brushing up your stuff for merge!

Checklist

  • [x] I read the commit guidelines and I've followed them.
  • [x] I ran coala over my code locally. (All commits have to pass individually. It is not sufficient to have "fixup commits" on your PR, our bot will still report the issues for the previous commit.) You will likely receive a lot of bot comments and build failures if coala does not pass on every single commit!

After you submit your pull request, DO NOT click the 'Update Branch' button. When asked for a rebase, consult coala.io/rebase instead.

Please consider helping us by reviewing other peoples pull requests as well:

The more you review, the more your score will grow at coala.io and we will review your PRs faster!

Naveenaidu avatar Dec 02 '18 13:12 Naveenaidu

~~WIP - Writing the tests.~~ Implemented the TESTS

Naveenaidu avatar Dec 02 '18 13:12 Naveenaidu

Asciineam - https://asciinema.org/a/yFCyH8m2hYIeFdQj0AniVV5qE

Naveenaidu avatar Feb 04 '19 17:02 Naveenaidu

The basic working of the patch can be explained as follows [For future reference]

We have three things -

  1. Label_stack: Used to store all the control tags
  2. Indent Level: This tells the indentation level of the line.
  3. Indent step: Number of spaces for each indentation

Initially the stack starts with no elements. As soon as it encounters a control label(eg: for,if,set etc..), it appends those labels into the stack. Note that, we also maintain the end control label where ever necessary. Whenever an control tag is added and if it doesn't find it's endtag in the next line, The Indent step is increased. This is done, because if the endtag is not found on the nextline it basically means that we have nesting of instructions.

Eg:

{% for tony in avengers %}
{% for thanos in enemy %}
{% set thanos == 'EVIL' %}
{% endfor %}{# for thanos in enemy #}
{% endfor %}{# for tony in avengers #}

As you see above after the first for, we do not have an endfor, that means we have a nesting in our Code. In such cases we append the first for in the stack. Now when it goes to the next line, it checks if the next label matches the end label for the element present in the stack. That means, here we are checking if the next label is endfor. If it is then do nothing.

If it's not, then increase the Indent step , which is nothing but the number of spaces that has to be appended in front of a line. And check if the next line has that many number of indent steps. If not then create a diff.

Now, when it encounters a endtag for the element present in the stack, it does two things

  1. Decreases the Indentaion Step
  2. Pops out the element from the stack.

This is the basic working of the solution.

The above example get's indented as follows:

{% for tony in avengers %}
  {% for thanos in enemy %}
    {% set thanos == 'EVIL' %}
  {% endfor %}{# for thanos in enemy #}
{% endfor %}{# for tony in avengers #}

For the cases where we have a code which has nested languages such as Jinja2 and Python. The lines from other languages are skipped. coala doesn't yet have the functionality to detect multiple languages. For eg:

import sys
{% for tony in avengers %}
  {% for thanos in enemy %}
                    print("Thanos Rocks!!")
          print("Testing Indentation")
{% set avengers = loose %}
  {% endfor %}{# for thanos in enemy #}
{% endfor %}{# for tony in avengers #}

After the indentation, it would look like

import sys
{% for tony in avengers %}
  {% for thanos in enemy %}
                   print("Thanos Rocks!!")
          print("Testing Indentation")
     {% set avengers = loose %}
  {% endfor %}{# for thanos in enemy #}
{% endfor %}{# for tony in avengers #}

As you see above, we provide no indentation to both the print statements. We just ignore them.

Naveenaidu avatar Feb 04 '19 18:02 Naveenaidu

@gitmate-bot rebase

jayvdb avatar Feb 06 '19 05:02 jayvdb

Hey! I'm GitMate.io! This pull request is being rebased automatically. Please DO NOT push while rebase is in progress or your changes would be lost permanently :warning:

gitmate-bot avatar Feb 06 '19 05:02 gitmate-bot

Automated rebase with GitMate.io was successful! :tada:

gitmate-bot avatar Feb 06 '19 05:02 gitmate-bot