Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python indentation in nested blocks dedents too much, does not dedent on def meth(): #1370

Closed
krassowski opened this issue Apr 19, 2024 · 5 comments

Comments

@krassowski
Copy link

Describe the issue

lang-python does not continue indentation at the end of a block, which was intentional as per this code comment and the reasoning was given here: codemirror/lang-python#4 (comment)

I think this is the worst example, where the user intends to end the block, leave a blank line and start a new block of code but the indentation is forced into alignment with the body:

gif

However, I think that dedent on enter should only move you one block back, not two blocks back, see:

should-have-dedented-once

Because there is no dedent when typing method definition (indent on input is not implemented for Python for this case):

no-dedent-on-method

the current implementation is de facto fighting the user who tries to add a method to a class definition, they end up with wrong indentation regardless of whether they decide to:

  • (a) add a new line after the first indented line (as per convention in Python there is an empty line between method definitions), or
  • (b) start writing in the first new line

In (a) case they end up with too little indent, in (b) they end up with too much indent (and lack of new line).

I am not sure how difficult this is to implement, but if it is too difficult, could there be a setting to allow the user to opt-in to always continue block indentation, or to say continue block indentation until at least 2 blank lines were entered and only dedent on the third one?

Of note VS Code always continues indentation.

Browser and platform

No response

Reproduction link

https://codemirror.net/try/?c=aW1wb3J0IHtiYXNpY1NldHVwLCBFZGl0b3JWaWV3fSBmcm9tICJjb2RlbWlycm9yIgppbXBvcnQge3B5dGhvbn0gZnJvbSAiQGNvZGVtaXJyb3IvbGFuZy1weXRob24iCmltcG9ydCB7IGluZGVudFVuaXQsIGluZGVudE9uSW5wdXQgfSBmcm9tICJAY29kZW1pcnJvci9sYW5ndWFnZSI7CgpuZXcgRWRpdG9yVmlldyh7CiAgZG9jOiAiZGVmIGZ1bmMoKTpcbiAgICBwYXNzXG5cbmNsYXNzIENsYXNzOlxuICAgIGRlZiBtZXRob2QoKTpcbiAgICAgICAgcGFzc1xuIiwKICBleHRlbnNpb25zOiBbYmFzaWNTZXR1cCwgcHl0aG9uKCksIGluZGVudFVuaXQub2YoJyAgICAnKSwgaW5kZW50T25JbnB1dCgpXSwKICBwYXJlbnQ6IGRvY3VtZW50LmJvZHkKfSkK

@marijnh
Copy link
Member

marijnh commented Apr 19, 2024

Dedenting two units seems pretty arbitrary as well. It's fundamentally impossible to know what the user is trying to do with an indentation-based language like this. I don't think it's a productive road to go down to add increasingly complex heuristics for this.

What VS Code seems to do is just crudely repeating the indentation of the line before without any kind of syntactic awareness. I could add a command that does that, if that's what you want here.

@krassowski
Copy link
Author

It's fundamentally impossible to know what the user is trying to do with an indentation-based language like this.

Right, I now see that my example with def meth() - while useful at demonstrating the struggle of a user - is ambiguous itself because another user may have wanted to define a closure instead in which case this is the correct behaviour.

What VS Code seems to do is just crudely repeating the indentation of the line before without any kind of syntactic awareness. I could add a command that does that, if that's what you want here.

I think this is what a number of Python users might prefer. A new command (or argument to existing insertNewlineAndIndent command?) sounds good to me.

marijnh added a commit to codemirror/commands that referenced this issue Apr 19, 2024
FEATURE: The `insertNewlineKeepIndent` command inserts a newline along
with the same indentation as the line before.

Issue codemirror/dev#1370
@marijnh
Copy link
Member

marijnh commented Apr 19, 2024

Attached patch adds an insertNewlineKeepIndent command that you can bind to enter to get the behavior where it simply preserves indentation.

@marijnh marijnh closed this as completed Apr 23, 2024
@krassowski
Copy link
Author

I tried insertNewlineKeepIndent and it indeed does what the name suggests. It keeps the indent constant always, and does not increase the indent when language rules would encourage it:

problematic

What VS Code seems to do is just crudely repeating the indentation of the line before without any kind of syntactic awareness.

I misunderstood this initially. I thought that you were saying that it repeats the indentation of the line before and never deindents it when in a block - which is correct. However, it does have a very good syntactic awareness, compare the previous GIF with:

vscode

marijnh added a commit to codemirror/lang-python that referenced this issue Apr 29, 2024
FIX: Improve the way indentation for the current body is preserved
when inenting new lines.

Issue codemirror/dev#1370
@marijnh
Copy link
Member

marijnh commented Apr 29, 2024

It seems that there's both the out-of-the-box VS Code Python behavior, which is what I was looking at, and then a slightly smarter auto-indentation when you install a Python-specific package. It still seems to work with simple regexps (indent on colon, dedent on pass), but indeed doesn't simply preserve previous indent.

I don't want to make this configurable. But attached patch might make it work more like what you're looking for.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants