Conditional indentation based on previous lines, HOW?


#1

I am developing a language package for SAS. Basically, the rule of indentation in SAS is:

  1. Whenever there is a “^\sPROC\b" or "^\sDATA\b”, increase the indentation of the next line;
  2. Whenever there is a “^\sRUN;" or "^\sQUIT;”, decrease the indentation;
  3. However, the “^\sRUN;" and "^\sQUIT;” are optional. So if there is no “RUN” or “QUIT” between two “DATA” or “PROC”, the 2nd “DATA” or “PROC” should decrease the indentation.

There are some more complicated situations when macro commands are involved but I have already had difficulties to implement the 3rd rule.

Could anyone share some idea how to conditionally indent based on previous lines?


#2

Now with Atom became v1.0, I wonder if anyone can share more insight on this topic. Is Atom able to implement more complicated rules for indentation besides the very basic ‘increaseIndentPattern’, ‘decreaseIndentPattern’, and ‘indentNextLinePattern’


#3

I don’t know if this would be all that useful, elastic tabstops might achieve something similar: http://nickgravgaard.com/elastic-tabstops/ , I know there is like 2 sublime plugins and someone was planning to port to Atom. However the sublime plugins implemented the solution with space padding instead of realigning the tabstops.

Have you looked at how similar Atom packages are handling indentation rules? It doesn’t seem too complicated if you can keep track of the current indent and what the last token(PROC DATA RUN QUIT) was. Then once you capture the next token you’d just compare if the previous was PROC/DATA then decrease indent, else increase?

I’ve not done anything like this, I think that’s how formatters/beautifiers work by parsing the code into an AST, with the regex patterns I’m assuming they only work on a single line? JS doesn’t appear to support lookbehind. I’ve had a go at making a regex for the 3rd rule, seems to match what you want, though not sure if they’d be a way to make a JS regex version.

See the regex explained and match results: https://regex101.com/r/lE8mX8/1
A better visualization of the regex: https://www.debuggex.com/r/HjngzPiQGv6SUl9H


#4

I’m having a similar issue trying to get Gherkin files to auto-indent correctly. Gherkin language is more keyword-based, and there really is no “decreateIndentPattern”. Example:

Feature: description of the feature
    ... description can continue here.

    Scenario: describe the scenario
        Given some precondition
        When I take some action
        Then I verify some outcome

    Scenario: another scenario starts here
etc...

So if the increaseIndentPattern is “(Feature|Scenario):”, the indentation is correct for a single Scenario, but once you hit the 2nd Scenario line, Atom keeps it at the indentation of “Then”, and the following lines are then indented further. So if you have 8 Scenarios in the file, the last one is indented 8 times, and that’s obviously wrong.

But setting decreaseIndentPattern to “Scenario:” actually undoes the indentation from “Feature”, so then all the Scenario lines are left-aligned (same level as “Feature”), and that is also wrong.

I can’t seem to find a way to do it the Right Way™ in Atom. It’s kind of similar to Python, where there is no end-of-scope demarcation.

On the other hand, Atom’s code folding does work correctly, and it is able to properly identify that each Scenario can be folded down. So it would be nice if there were a way to treat the code folding patterns as a kind of “tree” (think of a directory structure, where “/” is the root, and each child is indented to the same level of indentation), and automatically indent the file based on the tree.