-
Notifications
You must be signed in to change notification settings - Fork 34.9k
Description
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?