Skip to content

Allow more powerful onEnterRules for cursor alignment #66235

@jakebailey

Description

@jakebailey

In the Python extension, we'd like to add support for variable-length indents on enter to better support PEP8 formatting (microsoft/vscode-python#481 and others). For example:

def func(a,
         |

Hitting enter on the first line should stick the cursor where | is, not just a single indent. In this second case, it should do a single indent:

def func(
    |

There appears to only be two ways to handle this:

  • onEnterRules
  • On-type formatting

We'd like to avoid the latter, as we currently support both Jedi and our own language server, which means implementing on-type formatting in two different places (since a single language cannot have multiple on-type formatting providers). Plus, on-type formatting is not enabled by default nor is very popular (and enables a slew of formatting rules other than cursor alignment), so forcing users to enable on-type formatting as a whole would be good to avoid.

The other candidate is onEnterRules, but it's not powerful enough to be able to do something like this, as:

  • The "actions" work in terms of indents, whereas these cursor positions may not be a round multiple of an indent, meaning appendText would be required, but...
  • appendText is only allowed to be a static string, and cannot be generated on the fly.
  • Rules are applied using regex to deduce context, which gets unweildy, and even more difficult without onEnterRules should be multi-line aware #50952.
  • Even with something like Add support for capture groups in onEnterRules #17281, there wouldn't be a way to convert a capture group to "whitespace of the same length of the capture group" (plus the issue of tab indents).

My initial thought was to allow a function to be provided in onEnterRules instead of just specifying appendText. For example, something like:

{
    beforeText: /\s+def\s+\w+\(\w+/,  /* not the real regex */
    action: {
        indentAction: IndentAction.None,
        appendText: (document, position, formatOptions, ... /* something */) => calculateIndent(...) // returns a string
    }
}

However, on closer inspection of how onEnterRules works, it appears that it needs to be serializable, so I'm not sure it'd be able to have a callback like the above.

Is there something that can be added to allow more powerful rules on-enter? Or, is there something that already exists that we've missed?

Metadata

Metadata

Assignees

Labels

editor-autoindentEditor auto indentation issueseditor-inputEditor text inputfeature-requestRequest for new features or functionality

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions