3

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):

enter image description here

But I can fold this function appropriately:

enter image description here

If I modify it to avoid the PEP8 warning:

enter image description here

I can no longer fold it:

enter image description here

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?

MattDMo
  • 100,794
  • 21
  • 241
  • 231
Gabriel
  • 40,504
  • 73
  • 230
  • 404

2 Answers2

1

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:\Users\YourUserName\AppData\Roaming\Sublime Text 3\Packages or C:\Users\YourUserName\AppData\Roaming\Sublime Text\Packages
  • Windows Portable Install: InstallationFolder\Sublime Text 3\Data\Packages or InstallationFolder\Sublime Text\Data\Packages

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.

MattDMo
  • 100,794
  • 21
  • 241
  • 231
  • Thanks for the answer Matt. Unfortunately the first method does nothing, and the second method does not appear to work. When I first open the `Fold.tmPreferences` file the console shows `Unable to open /home/gabriel/.config/sublime-text/Packages/Python/Fold.tmPreferences` although the file is indeed opened. Then I use `view.set_read_only(False)` to comment out those lines, but when I try to save the system asks for my root password to "execute «/bin/cp»" (?). I give the root password but the console shows `unable to reset file info`. When I re-open that file, no change was saved. – Gabriel Dec 27 '22 at 11:29
  • If I don't enter the root password and simply hit Cancel, the console shows `error: Unable to save ~/.config/sublime-text/Packages/Python/Fold.tmPreferences Error: administrator_copy_file(/tmp/.sublc51.tmp, /home/gabriel/.config/sublime-text/Packages/Python/Fold.tmPreferences) failed: Authorization failed` – Gabriel Dec 27 '22 at 11:31
  • I don't understand why it is asking for the root password to edit a file in my account. Also, will commenting out these lines fox the problem of not being able to fold once the PEP8 warning is fixed as shown in the question? – Gabriel Dec 27 '22 at 11:33
  • @Gabriel To answer your last question, yes, this should fix those folding problems. The PEP8 warning is from a plugin, not Sublime itself, so it doesn't affect folding (that I know of). As far as the access issues - first off, what distro are you using? Second, was Sublime installed using `sudo`? That could explain why you need to enter the root password. I tested this answer on Windows using a portable install, but when I get back home I'll fiddle around with Ubuntu and see if I can figure out the problem. – MattDMo Dec 27 '22 at 11:46
  • One thing to try in the meantime - open `Fold.tmPreferences` and then use Save As to either put it in `~/.config/sublime-text/Packages/Python` or `~/.config/sublime-text/Packages/User/Python`. You should definitely be able to write to the `User` directory (you'll need to create the `Python` subdirectory). Another option - after you open the file, copy its entire contents and paste it into a new view, then save that in either location. If it ends up being saved in both places, the one in `Packages/User/Python` will take preference. – MattDMo Dec 27 '22 at 11:51
  • I don't remember how I installed ST, I could have used `sudo` but it doesn't explain why it won't let me edit the file if I use the `sudo` password. I saved a copy of the file in `~/.config/sublime-text/Packages/User/Python` but it made no change. A function with the format shown here https://i.stack.imgur.com/PoDou.png (used to avoid the PEP8 warning) will not be folded entirely (only the lines containing the parameters are folded). I'm running elementary 5.1.7 (based on Ubuntu 18.04) – Gabriel Dec 27 '22 at 14:21
  • @Gabriel It's working for me on Windows with that code. Try moving (not copying) the edited `Fold.tmPreferences` file from `Packages/User/Python` to `Packages/Python` and see if that makes a difference. I have the exact same text as you in a view in Windows, with the edited file in `Packages/Python`, and either using Ctrl-Shift-[ or clicking the fold arrow next to `def` on L3 folds the entire function. https://i.stack.imgur.com/d6GTD.png to https://i.stack.imgur.com/YhBsD.png. Not sure why Linux is acting different. – MattDMo Dec 27 '22 at 14:32
  • Ok, now it's getting weird. The path to the `Fold.tmPreferences` file (which is displayed properly via `View Package File` + `python/fold`) is supposed to be `~/.config/sublime-text/Packages/Python/Fold.tmPreferences` (I double checked) but there is no `~/.config/sublime-text/Packages/Python/` folder! It's not hidden, **it does not exist in the system**. I'm completely lost – Gabriel Dec 27 '22 at 14:43
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/250681/discussion-between-mattdmo-and-gabriel). – MattDMo Dec 27 '22 at 14:51
1

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.

Behaviour screenshot

STerliakov
  • 4,983
  • 3
  • 15
  • 37
  • This is a great answer because it does not require tweaking with STs default behaviour while still being PEP8 compliant. Parameters do not need to be in a single line each, just indented. The closing parenthesis is the key here. I'm changing the selected answer to this one. Thank you! – Gabriel Dec 29 '22 at 20:19