You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
ifa:
passifb:
passelse:
pass|# With the cursor here ...
what must I do to get dedenting to work for an else to the top-level if? Do I have to manually dedent once and then let auto-dedent handle the rest? (This is the microsoft/pylance-release#4820 case in this context-insensitive whitespace scenario.)
jkyeung we can potentially borrow from Ruby thanks to how elsif works as it's similar for at least elif. But the whole point of this spike is to figure out what is feasible and what the ramifications are for the potential solutions.
And the Python Indent extension approach can't be used by us as it overrides the the Enter key which is way to intrusive for us to do.
jkyeung we can potentially borrow from Ruby thanks to how elsif works as it's similar for at least elif.
Well, I guess you could say it's "similar", but then it's just as similar as Ruby's else is to Python's else. My concern remains the same: Ruby has an end keyword to mark the end of what we would call a suite. In Ruby (and pretty much all languages with block-ending delimiters) we can know with 100% certainty where elsif or elseshould be indented, no matter how badly formatted the code is, as long as it's valid.
# Rubyifaputs'a'ifbputs'b'elsifc# must go with bputs'c'endend
# Rubyifaputs'a'ifbputs'b'endelsifc# must go with aputs'c'end
Python does not have this property. (Of course, the following code, as-is, isn't even valid, but the point is we can't know for sure which of two valid indentation options is the right one, and if we pick the wrong one, the meaning of the program changes.)
# Pythonifa:
print('a')
ifb:
print('b')
elifc: # no way to knowprint('c')
But the whole point of this spike is to figure out what is feasible and what the ramifications are for the potential solutions.
I get that. Without understanding those Ruby-handling regexes, I was preemptively guarding against "oh, it works for Ruby, so let's just slap it in for Python!". For all I know, it may be that those regexes happen to be doing what the Python Indent extension says it is doing for else and friends, including NOT dedenting if already dedented. And if that's the case, I think I'm OK with it. But for all I know, it could also be making assumptions that don't hold for Python (such as "elsemust be dedented exactly one level relative to the previous line, so no matter where the else is now, we will put it there").
I'll hold further comments until more concrete details are presented.
FWIW, I tried applying just the dedent rules that we reverted and had the exact same problems with inappropriate indent. Presumably the mere presence of indentationRules (or maybe just its "decreaseIndentPattern" property) is enough to trigger the undesirable behavior.
Given everything I've looked at in the sprint, I don't think it's worth it to pursue this further at the moment. From what I can tell, VS Code make some assumptions about the existence of an end-of-block syntax (which Python almost uniquely does not have for "suites").
So at this point I'm not convinced that any of the existing options provided by VS Code will meet our needs. However, it will be worth bringing this up with the VS Code folks as soon as they have interest/time.
Activity
kimadeline commentedon Aug 12, 2019
Seems like removing the
indentationRuleskey fixes some of the issues:vscode-python/src/client/language/languageConfiguration.ts
Lines 37 to 40 in 9c61d0e
This also means that we should probably expand on the old
onEnterRulesregexes we had before.Issues reported by users:
Moving lines up and down:
Pressing return
Copy-pasting:
Another possible broken case:
DonJayamanne commentedon Aug 14, 2019
TODO:
Ruby[ ] Check if there are any issues with their rules
Outcome:
jkyeung commentedon Aug 19, 2019
Re: Adapting Ruby indentation behavior for Python
Please take a step back and carefully consider how much we can really borrow from Ruby.
Crucially, Ruby has an
endkeyword to mark the end of a block (or what is called a "suite" in Python's grammar specs).Please see my comment on a related issue for an illustration of how the proper dedent level for
elsecannot be inferred in Python, in general.If you want to look at existing work to possibly incorporate into this extension, perhaps it should be the highly regarded Python Indent extension.
ericsnowcurrently commentedon Aug 20, 2019
FTR:
Docs:
ericsnowcurrently commentedon Aug 20, 2019
Here are the two regexes from the default VSCode config, expanded verbosely:
increaseIndentPattern
decreaseIndentPattern
Here are the two regexes from the actual Ruby extension (more recent), expanded verbosely:
decreaseIndentPattern
decreaseIndentPattern
ericsnowcurrently commentedon Aug 20, 2019
For our "else"/"elif"/"except"/"finally" needs, the focus is on the decreaseIndentPattern.
brettcannon commentedon Aug 21, 2019
One question I have is if I do:
what must I do to get dedenting to work for an
elseto the top-levelif? Do I have to manually dedent once and then let auto-dedent handle the rest? (This is the microsoft/pylance-release#4820 case in this context-insensitive whitespace scenario.)brettcannon commentedon Aug 21, 2019
jkyeung we can potentially borrow from Ruby thanks to how
elsifworks as it's similar for at leastelif. But the whole point of this spike is to figure out what is feasible and what the ramifications are for the potential solutions.And the Python Indent extension approach can't be used by us as it overrides the the Enter key which is way to intrusive for us to do.
jkyeung commentedon Aug 21, 2019
Well, I guess you could say it's "similar", but then it's just as similar as Ruby's
elseis to Python'selse. My concern remains the same: Ruby has anendkeyword to mark the end of what we would call a suite. In Ruby (and pretty much all languages with block-ending delimiters) we can know with 100% certainty whereelsiforelseshould be indented, no matter how badly formatted the code is, as long as it's valid.Python does not have this property. (Of course, the following code, as-is, isn't even valid, but the point is we can't know for sure which of two valid indentation options is the right one, and if we pick the wrong one, the meaning of the program changes.)
I get that. Without understanding those Ruby-handling regexes, I was preemptively guarding against "oh, it works for Ruby, so let's just slap it in for Python!". For all I know, it may be that those regexes happen to be doing what the Python Indent extension says it is doing for
elseand friends, including NOT dedenting if already dedented. And if that's the case, I think I'm OK with it. But for all I know, it could also be making assumptions that don't hold for Python (such as "elsemust be dedented exactly one level relative to the previous line, so no matter where theelseis now, we will put it there").I'll hold further comments until more concrete details are presented.
ericsnowcurrently commentedon Aug 22, 2019
FWIW, I tried applying just the dedent rules that we reverted and had the exact same problems with inappropriate indent. Presumably the mere presence of
indentationRules(or maybe just its "decreaseIndentPattern" property) is enough to trigger the undesirable behavior.ericsnowcurrently commentedon Aug 22, 2019
Given everything I've looked at in the sprint, I don't think it's worth it to pursue this further at the moment. From what I can tell, VS Code make some assumptions about the existence of an end-of-block syntax (which Python almost uniquely does not have for "suites").
So at this point I'm not convinced that any of the existing options provided by VS Code will meet our needs. However, it will be worth bringing this up with the VS Code folks as soon as they have interest/time.
brettcannon commentedon Aug 26, 2019
If we redo our
editor.formatOnTypeto just do whitespace, then we could use thecontributes.configurationDefaultssetting to turnformatOnTypeon by default.