Skip to content

Implement an indentation provider to support folding of docstrings, comments & multi line strings #1847

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

Closed
DonJayamanne opened this issue Jun 2, 2018 · 22 comments
Labels
area-editor-* User-facing catch-all feature-request Request for new features or functionality

Comments

@DonJayamanne
Copy link

DonJayamanne commented Jun 2, 2018

We might want to consider disabling the folding provider in this release due to a number of issues in VS Code:

Came across this today and found it very annoying. Was unable to collapse a large python file, initially assumed it was an intermittent VSC issue, later looked into this and found that its worse than I suspected.

Basically us introducing a custom folding provider breaks the VSC default folding behavior we won't be able to collapse, any block of Python code

@brettcannon cc

@DonJayamanne
Copy link
Author

Looks like we're getting some weird answers, I'd suggest we disable this new folding provider until things are sorted out in VSC (and I'm having a difficult time thus far).

@DonJayamanne
Copy link
Author

Just realized that, the folding provider PR didn't have a news entry.

@DonJayamanne
Copy link
Author

Based on feedback from VS Code team, we have to implement the indentation provider (i.e. we need to implement everything ourselves) microsoft/vscode#50991 (comment)

@brettcannon brettcannon added feature-request Request for new features or functionality and removed upstream-vscode labels Jun 6, 2018
@brettcannon brettcannon changed the title Code folding in VS Code seems to be broken in insiders build Implement an indentation provider Jun 6, 2018
@brettcannon brettcannon removed their assignment Jun 6, 2018
@brettcannon brettcannon removed this from the May 2018 milestone Jun 6, 2018
@DonJayamanne DonJayamanne changed the title Implement an indentation provider Implement an indentation provider to support folding of docstrings and comments Sep 12, 2018
@DonJayamanne DonJayamanne removed their assignment Dec 6, 2018
@DonJayamanne DonJayamanne changed the title Implement an indentation provider to support folding of docstrings and comments Implement an indentation provider to support folding of docstrings, comments & multi line strings Jul 2, 2019
@beltekylevi
Copy link

Is there any update or alternative solution for this issue?

@brettcannon
Copy link
Member

@beltekylevi no specific update. As for an alternative, you can check the Marketplace to see if someone has provided a separate extension for this.

@MicaelJarniac
Copy link

I've been looking for this as well, and until there's a better solution, we can use # region and # endregion around the docstring to explicitly inform VS Code that it should be a foldable region. From my testings, it worked pretty well, the docstring was still identified correctly, and all other foldable regions remained intact.

Another option is to use an extension such as https://github.com/zokugun/vscode-explicit-folding that allows us to manually define what should be used to delimit foldable regions, for example with a regex. A problem I've had with this one (although I haven't experimented much) was that it seems to completely replace the foldable regions, and not just add to them, so when I was using it, the only foldable regions I had were the ones between """s, that I manually defined. An example configuration for Python is provided on its readme.

Example with # region and # endregion

def greet(name: str) -> str:
    # region
    """Greets a person

    Parameters
    ----------
    name : str
        Name of the person to greet

    Returns
    -------
    str
        Greetings for said person
    """
    # endregion

    return f"Hello, {name}. Nice to meet you!"

@beltekylevi
Copy link

beltekylevi commented Nov 25, 2020

@MicaelJarniac Thank you, I didn't know about this region and endregion thing. It's perfect for now.

Unfortunately, I had the same issue with the vscode-explicit-folding extension.

@yuji96
Copy link

yuji96 commented Mar 29, 2021

2021-03-28.22.18.43.mov

Here's how I solved it:

  1. Copy the Python extension configuration files to own user directory.
source /Applications/Visual Studio Code.app/Contents/Resources/app/extensions/python
target ~/.vscode/extensions/python

The following command is an example for macOS.

$ cp -r /Applications/Visual\ Studio\ Code.app/Contents/Resources/app/extensions/python ~/.vscode/extensions
  1. Add a regex that matches docstrings to the markers in ~/.vscode/extensions/python/language-configuration.json.
{
  "folding": {
    "offSide": true,
    "markers": {
      "start": "^\\s*#\\s*region\\b|^\\ *\"{3}(?!.*\"{3}).+",
      "end": "^\\s*#\\s*endregion\\b|^\\ *\"{3}$"
    }
  }
}

This regex will match if we follow strict constraints such as OpenStack Style Guidelines - Docstrings.

# OK
"""[summary]
"""

# NG
"""
[summary]
"""

# NG
"""[summary]
"""  # comment

@jamilraichouni
Copy link

jamilraichouni commented Mar 29, 2021

Nice one, thanks!

I have a little improvement to propose:

"start": "^\\s*#\\s*region\\b|^\\ *[r]?\"{3}(?!.*\"{3}).+"

That makes raw docstrings collapsable.

def func():
    r"""My docstring summary.

    Foo is located at ``C:\Windows\bar``

    """

@danieltuzes
Copy link

@yuji96 @jamilraichouni I copied the file to "C:\Users\username\.vscode\extensions\python\language-configuration.json" (the target folder python didn't exist, I created it) and modified the relevant lines in the new file to

    "folding": {
        "offSide": true,
        "markers": {
            "start": "^\\s*#\\s*region\\b|^\\ *\"{3}(?!.*\"{3}).+",
            "end": "^\\s*#\\s*endregion\\b|^\\ *\"{3}$"
        }
    },

but I still cannot fold the docstring. I am not sure if VS Code picks up the file. Is there something I missed? Is vscode-explicit-folding required to use this feature?

@jamilraichouni
Copy link

@danieltuzes in fact you end up with a directory named how ever you like it in the directory extensions.
In my case it looks like that:

image

So you see, that there are multiple files needed. The copy command from above
($ cp /Applications/Visual Studio Code.app/Contents/Resources/app/extensions/python ~/.vscode/extensions)
copies a directory.

You need to know that you must reload Visual Studio Code to see the hand made extension.
I named the extension by modifying the following in the file package.json:

"displayName": "Python docstring folding"

and I can see the extension:

image

@danieltuzes
Copy link

@jamilraichouni I indeed missed copying the whole folder, thank you for pointing it out. That's one real advantage of open source software and a strong community, thank you both, @yuji96 !

danieltuzes pushed a commit to danieltuzes/studies that referenced this issue Apr 10, 2021
Instead of generate_r, generate_it relies on an iterable object,
therefore can be called on a list and on range operator too.
To generate from realization_id_start to realization_id_end,
generate_r was able to be called on the tuple
(realization_id_start, realization_id_end.). Now with
generate_it, provide a range with
range(realization_id_start,realization_id_end)
Unittest is also added.

Docstring is improved and the docsstring cannot be folded based
on indentation. PyCharm supports docstring folding without indentation,
and VS Code can be set up to support it too:
microsoft/vscode-python#1847
@sometowngeek
Copy link

sometowngeek commented Sep 30, 2021

I think #4345 was closed in error.

This issue is regarding collapsing/folding docstrings, comments, and multi-line strings, and #4345 is about being able to select the block. CTL+SHIFT+[-> or <-] doesn't work well with Python, and I think that's the thing #4345 is referring to.

I have the same issue as #4345.

Can we please consider re-opening that issue?

I'd appreciate it! Thank you!

@brettcannon
Copy link
Member

@sometowngeek please open a new issue.

@jrom99
Copy link

jrom99 commented Jan 17, 2022

I don't know if this is related to the issue at hand, but the folding of functions ending in comments isn't working.

def test_func():
    print("text")
    # hello world

folds as:

def test_func(): ...
    # hello world

System Information
Version: 1.63.2
Commit: 899d46d82c4c95423fb7e10e68eba52050e30ba3
Date: 2021-12-15T09:39:46.686Z
Electron: 13.5.2
Chromium: 91.0.4472.164
Node.js: 14.16.0
V8: 9.1.269.39-electron.0
OS: Linux x64 5.15.14-200.fc35.x86_64

Python: 3.10.1 (main, Jan 10 2022, 00:00:00) [GCC 11.2.1 20211203 (Red Hat 11.2.1-7)] on linux
Python Extension: v2021.12.1559732655
Pylance: v2022.1.1

@brettcannon
Copy link
Member

@jrom99 this would get fixed by an indentation provider.

@LeonardoGentile
Copy link

Hello, 🖖
Is there any update on this?
Is it going to be implemented any time soon or should we rely on manual hacks as the ones proposed above?

@jamilraichouni
Copy link

jamilraichouni commented Jan 17, 2022

I created a little extension to be able to fold multiline docstrings:

https://marketplace.visualstudio.com/items?itemName=jamilraichouni.python-docstring-folding

@jrom99
Copy link

jrom99 commented Jan 17, 2022

Sorry for my lack of knowledge on this topic, but how was this handled before? I remember that single line comments at the end of functions used to fold correctly, given that the indentation was at least the same as the function's content. Is this due to microsoft/vscode#37682? And how does it keep up with multiple providers?

@brettcannon
Copy link
Member

Our plan is to rely on microsoft/pylance-release#372 to fix this issue.

@ahallermed
Copy link

For someone, who also fell over this issue and wants to have a very nice customizable solution, I can highly recommend this extension: maptz.regionfolder (github).

It is additive to the VSCode folding and doesn't overwrite the settings as vscode-explicit-folding does as discussed above.

You can also define which kind of regex patterns should be folded at file opening, like I did below.

With the following section in the vscode settings.json:

    "maptz.regionfolder": {
        // Defaults per language can be found here: https://github.com/maptz/maptz.vscode.extensions.customfolding/blob/master/src/config/DefaultConfiguration.ts
        "[python]": {
            // regex cheat sheet: https://cheatography.com/davechild/cheat-sheets/regular-expressions/
            // ?! is a negative lookahead
            // works for: '#region'; '# region'; '# region Something else'; '""" + whitespace'; 'r""" + whitespace';
            // doesn't work for" '"""' without trailing whitespace, as start and end for regex would find the same token as start AND end
            // REGEX
            "foldStartRegex": "^[\\]s*#[\\s]*region[\\s]*(.*)[\\s]*$|^[\\ ]*[r]?\"{3}(?!.*\"{3}).+",
            "foldEndRegex": "^[\\s]*#[\\s]*endregion\\b|^[\\ ]*\"{3}$",
            "foldDefinitions": [
                // these imports get folded automatically after file is opened
                {
                    // region imports
                    "foldStartRegex": "^[\\]s*#[\\s]*region[\\s]*(imports)[\\s]*$",
                    "foldEndRegex": "^[\\s]*#[\\s]*endregion\\b",
                    "isFoldedByDefault": true
                },
                {
                    // region header
                    "foldStartRegex": "^[\\]s*#[\\s]*region[\\s]*(header)[\\s]*$",
                    "foldEndRegex": "^[\\s]*#[\\s]*endregion\\b",
                    "isFoldedByDefault": true
                }
            ],
            // INSERTION TAGS
            "foldStart": "# region [NAME]", //Text inserted at the start of the fold.  Use the `[NAME]` placeholder to indicate where the cursor should be placed after insertion
            "foldEnd": "# endregion", //Text inserted at the end of the fold
            "disableFolding": false
        }
    }

And customized keysettings with explanations:

    // folding regions in e.g. python code
    // -> fold regions -> which are collapsed by default or not, it doesn't matter
    {
        "key": "ctrl+r",
        "command": "regionfolder.collapseAllRegions",
        "when": "editorTextFocus"
    },
    // -> fold defaults -> which are defined as being folded on file opening.
    {
        "key": "ctrl+shift+/",
        "command": "regionfolder.collapseDefault",
        "when": "editorTextFocus"
    },
    {
        "key": "ctrl+shift+m ctrl+shift+r",
        "command": "-regionfolder.collapseDefault",
        "when": "editorTextFocus"
    },
    //*/
    // -> unfold all
    {
        "key": "ctrl+shift+r",
        "command": "editor.unfoldAll",
        "when": "editorTextFocus && foldingEnabled"
    },
    {
        "key": "ctrl+k ctrl+j",
        "command": "-editor.unfoldAll",
        "when": "editorTextFocus && foldingEnabled"
    },

And of course, thank you folks for discussing this issue and support with a solution/regex patterns.

@brettcannon
Copy link
Member

More advanced folding is now being handled by the latest version of Pylance, so if there's any existing issues with it then please open an issue at https://github.com/microsoft/pylance-release .

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 28, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-editor-* User-facing catch-all feature-request Request for new features or functionality
Projects
None yet
Development

No branches or pull requests