Sublime Text 4: folding Python functions with a line break
Question:
I’m running Sublime Text Build 4143. Given a function with parameters that spill over the 80 character limit like so:
def func(parameter_1, parameter_2, parameter_3, parameter_4, parameter_5, parameter_6):
"""
"""
print("hello world")
return
ST will show a PEP8 E501: line too long
warning and highlight the line (which is fine):
But I can fold this function appropriately:
If I modify it to avoid the PEP8 warning:
I can no longer fold it:
This changed in the last update I think, because I used to be able to fold these functions without issues. How can I get around ths?
Answers:
There are a couple of solutions. The first is to use the folding keyboard shortcut (CtrlShift[ on Windows/Linux, ⌘Shift[ on Mac) with the cursor either before or after the colon :
at the very end of the function signature – outside the parentheses ()
. You can unfold using CtrlShift] (⌘Shift]), or by using the arrow in the gutter just to the left of the def
keyword.
The second method is a little more involved, but allows you to use the fold arrows as well as the keyboard shortcuts, and your cursor can be anywhere when you fold. Open the Command Palette with CtrlShiftP (⌘ShiftP on Mac) and type v
, then select the View Package File
option. Next, type in python/fold
and select Python/Fold.tmPreferences
. A PLIST/XML file will open up, containing language-specific rules for folding.
Before we can edit the file, we need to save it and turn off its read-only protection. First, save the file by selecting File → Save As…
. It should automagically select the Packages/Python
directory, where Packages
is
- Linux:
~/.config/sublime-text-3/Packages
or ~/.config/sublime-text/Packages
- macOS/OS X:
~/Library/Application Support/Sublime Text 3/Packages
or ~/Library/Application Support/Sublime Text/Packages
- Windows Regular Install:
C:UsersYourUserNameAppDataRoamingSublime Text 3Packages
or C:UsersYourUserNameAppDataRoamingSublime TextPackages
- Windows Portable Install:
InstallationFolderSublime Text 3DataPackages
or InstallationFolderSublime TextDataPackages
The exact path depends on whether or not you upgraded from Sublime Text 3.
Next, select View → Show Console
and type in
view.set_read_only(False)
You can close the Console by hitting Esc or selecting View → Hide Console
.
In Fold.tmPreferences
, select lines 24-29 and comment them out – Ctrl/ for Win/Lin, ⌘/ for macOS. It should look something like this:
<string>punctuation.section.arguments.begin</string>
<key>end</key>
<string>punctuation.section.arguments.end</string>
</dict>
<!-- <dict>
<key>begin</key>
<string>punctuation.section.parameters.begin</string>
<key>end</key>
<string>punctuation.section.parameters.end</string>
</dict>
--> <dict>
<key>begin</key>
<string>punctuation.section.sequence.begin</string>
<key>end</key>
lines 20-33
Finally, save your changes. Test that everything worked correctly by closing the file after you save it, then going to File → Open Recent
and verifying that Fold.tmPreferences
is at the top of the list. Click on it to open it, and double-check that lines 24-29 are still commented out. Once you’ve done that, you can close it again.
And that should be it! Once the changes to Fold.tmPreferences
have been saved, they’ll be effective immediately.
A big thank you to the regulars on the Sublime Text Discord server for their suggestions to look at Fold.tmPreferences
.
This is not a "fair" answer, but may be helpful. If you use black-like line folding (or anything similar, but with one important property: the closing parenthesis should be on its own line and be indented to the same level as def
, see below), then folding works even better:
def func(
parameter_1,
parameter_2,
parameter_3,
parameter_4,
parameter_5,
parameter_6,
):
"""
"""
print("hello world")
return
Now you have three arrows: the first folds function arguments, the second folds all function body and the third folds only the docstring.
You can wrap parameters in any way you like, if closing parenthesis remains in place. I personally prefer this style, and it can be auto-formatted with black
. Your solution is PEP8-compatible, but ST doesn’t like it. It folds to the next line with the same level of indentation (so I’m very surprised that it worked before). This line-wrapping style is especially cute if you use type hinting: every argument appears on its own line together with type, and return type is written on the last line – still separate).
This problem also arises in languages with goto
construct and labels, which can be indented to the same level as function body – wrapping dies as well.
I’m running Sublime Text Build 4143. Given a function with parameters that spill over the 80 character limit like so:
def func(parameter_1, parameter_2, parameter_3, parameter_4, parameter_5, parameter_6):
"""
"""
print("hello world")
return
ST will show a PEP8 E501: line too long
warning and highlight the line (which is fine):
But I can fold this function appropriately:
If I modify it to avoid the PEP8 warning:
I can no longer fold it:
This changed in the last update I think, because I used to be able to fold these functions without issues. How can I get around ths?
There are a couple of solutions. The first is to use the folding keyboard shortcut (CtrlShift[ on Windows/Linux, ⌘Shift[ on Mac) with the cursor either before or after the colon :
at the very end of the function signature – outside the parentheses ()
. You can unfold using CtrlShift] (⌘Shift]), or by using the arrow in the gutter just to the left of the def
keyword.
The second method is a little more involved, but allows you to use the fold arrows as well as the keyboard shortcuts, and your cursor can be anywhere when you fold. Open the Command Palette with CtrlShiftP (⌘ShiftP on Mac) and type v
, then select the View Package File
option. Next, type in python/fold
and select Python/Fold.tmPreferences
. A PLIST/XML file will open up, containing language-specific rules for folding.
Before we can edit the file, we need to save it and turn off its read-only protection. First, save the file by selecting File → Save As…
. It should automagically select the Packages/Python
directory, where Packages
is
- Linux:
~/.config/sublime-text-3/Packages
or~/.config/sublime-text/Packages
- macOS/OS X:
~/Library/Application Support/Sublime Text 3/Packages
or~/Library/Application Support/Sublime Text/Packages
- Windows Regular Install:
C:UsersYourUserNameAppDataRoamingSublime Text 3Packages
orC:UsersYourUserNameAppDataRoamingSublime TextPackages
- Windows Portable Install:
InstallationFolderSublime Text 3DataPackages
orInstallationFolderSublime TextDataPackages
The exact path depends on whether or not you upgraded from Sublime Text 3.
Next, select View → Show Console
and type in
view.set_read_only(False)
You can close the Console by hitting Esc or selecting View → Hide Console
.
In Fold.tmPreferences
, select lines 24-29 and comment them out – Ctrl/ for Win/Lin, ⌘/ for macOS. It should look something like this:
<string>punctuation.section.arguments.begin</string>
<key>end</key>
<string>punctuation.section.arguments.end</string>
</dict>
<!-- <dict>
<key>begin</key>
<string>punctuation.section.parameters.begin</string>
<key>end</key>
<string>punctuation.section.parameters.end</string>
</dict>
--> <dict>
<key>begin</key>
<string>punctuation.section.sequence.begin</string>
<key>end</key>
lines 20-33
Finally, save your changes. Test that everything worked correctly by closing the file after you save it, then going to File → Open Recent
and verifying that Fold.tmPreferences
is at the top of the list. Click on it to open it, and double-check that lines 24-29 are still commented out. Once you’ve done that, you can close it again.
And that should be it! Once the changes to Fold.tmPreferences
have been saved, they’ll be effective immediately.
A big thank you to the regulars on the Sublime Text Discord server for their suggestions to look at Fold.tmPreferences
.
This is not a "fair" answer, but may be helpful. If you use black-like line folding (or anything similar, but with one important property: the closing parenthesis should be on its own line and be indented to the same level as def
, see below), then folding works even better:
def func(
parameter_1,
parameter_2,
parameter_3,
parameter_4,
parameter_5,
parameter_6,
):
"""
"""
print("hello world")
return
Now you have three arrows: the first folds function arguments, the second folds all function body and the third folds only the docstring.
You can wrap parameters in any way you like, if closing parenthesis remains in place. I personally prefer this style, and it can be auto-formatted with black
. Your solution is PEP8-compatible, but ST doesn’t like it. It folds to the next line with the same level of indentation (so I’m very surprised that it worked before). This line-wrapping style is especially cute if you use type hinting: every argument appears on its own line together with type, and return type is written on the last line – still separate).
This problem also arises in languages with goto
construct and labels, which can be indented to the same level as function body – wrapping dies as well.