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

[folding] API for programmatically folding lines #37682

Closed
fabiospampinato opened this issue Nov 5, 2017 · 11 comments
Closed

[folding] API for programmatically folding lines #37682

fabiospampinato opened this issue Nov 5, 2017 · 11 comments
Assignees
Labels
editor-folding Editor code folding issues feature-request Request for new features or functionality
Milestone

Comments

@fabiospampinato
Copy link
Contributor

fabiospampinato commented Nov 5, 2017

I've got a request for a feature for one of my extensions that can't be implemented without APIs for programmatically folding lines.

In Sublime one can go from this:

screen shot 2017-11-05 at 19 30 29

To this:

screen shot 2017-11-05 at 19 30 58

Basically folding arbitrary lines. I'm not aware of any existent API that can be used for this.

Can this be implemented?

@aeschli
Copy link
Contributor

aeschli commented Nov 7, 2017

No, we don't have any API that lets you fold away lines.

@aeschli aeschli changed the title Missing API for programmatically folding lines [folding] API for programmatically folding lines Nov 7, 2017
@aeschli aeschli added the feature-request Request for new features or functionality label Nov 7, 2017
@aeschli aeschli added this to the Backlog milestone Nov 7, 2017
@alexdima alexdima removed the editor label Nov 24, 2017
@fabiospampinato
Copy link
Contributor Author

I have a nice extension in mind which I can't implement without this API.

I often "divide" my files/functions with some comments:

function foo () {
  /* A DIVIDER */
  const foo = 123;
  const bar = 321;
  /* ANOTHER DIVIDER */
  asd ();
  asd ();
  /* WRAPPING UP */
  qwerty ();
  return 123;
}

And I'd like to have an extension that allows me to fold all the lines between 2 consecutive equally-indented dividers, but I can't implement it without this API.

VSC already supports #region and #endregion but since I'm already dividing my code I don't see the point of littering my code further with those markers when I could get this functionality for free.

I'd submit a PR for this, but I guess it wouldn't be easy to implement this for someone unfamiliar with the codebase. In case it's actually quite doable, and you'd also like this API please do let me know 👍

@aeschli
Copy link
Contributor

aeschli commented Oct 8, 2019

We have API the folding range provider API that lets extensions define folding regions. We also have public fold/unfold commands that extensions can use.
Clearly there are pitfalls, such as range conflicts with other folding provider (which would there be with an explicit API to fold ranges) as well as timing issues on when to know that ranges are available. If ranges need to be folded by default, I agree wen need this. It's #40338
@fabiospampinato What do you think?

@fabiospampinato
Copy link
Contributor Author

fabiospampinato commented Oct 8, 2019

If ranges need to be folded by default, I agree wen need this.

For my personal use cases that's not necessary.

it's #40338 @fabiospampinato What do you think?

If I'm understanding this correctly that would allow us to define custom folding regions, is that correct? That'd be completely useless for my use cases for 2 reasons:

  1. If you check the screenshots in the first post there are really no "regions", just some lines that are programmatically folded if they contain a specific keyword or not.

  2. I also want to make this extension, and in my code there's already all the information necessary for inferring those kind of folding regions, I don't want to litter my code with region/end-region tokens.

@aeschli
Copy link
Contributor

aeschli commented Oct 9, 2019

You are right, UI-wise we don't support what you show in your mock-up: We currently represent folded lines by showing the content of the first line, followed by .... Being able to define what's on the first line is request #70794

I think number 2 you can already do with the current API. You do it by defining a folding range provider that creates folding ranges from the end of the separator to the beginning of the next one.
An alternative approach would be if we allow to customise the folding region markers: #36002

Ok to close this issue? We already have API to defined folded regions, but I understand there are other features you also need for your use case, but we have also issues for these.

@fabiospampinato
Copy link
Contributor Author

fabiospampinato commented Oct 9, 2019

We currently represent folded lines by showing the content of the first line, followed by ...

The perhaps wrong assumption here is that folding regions have to contain more than 1 line.

I don't feel like being able to customize the text displayed would be that useful, just displaying "..." for single folded lines, like Sublime does, would probably be enough for most use cases.

I think number 2 you can already do with the current API. You do it by defining a folding range provider that creates folding ranges from the end of the separator to the beginning of the next one.
An alternative approach would be if we allow to customise the folding region markers: #36002

I wasn't aware of the existing APIs related to folding regions, it looks like my hypothetical extension could be implemented with those indeed.

I don't necessarily want those folding regions to go from divider to divider though, as the behavior should be indentation-aware and there might not be an ending divider.

Ok to close this issue? We already have API to defined folded regions, but I understand there are other features you also need for your use case, but we have also issues for these.

I don't think the other issues you linked to really cover this and I'd prefer if this remained open, but if you think otherwise feel free to do as you please.

The main issue I see is that while there are some APIs for defining folding regions they are not dynamic enough for allowing me to implement the use case I'm showcasing in the original post. If you try PlainTasks in Sublime you can see that a user can fold all tasks containing a specific tag, that's unimplementable with the current APIs, as a task might have multiple tags just to mention one issue so what would happen when clicking the folding chevron in the gutter? There really shouldn't be any chevron for this (at least for folding, for unfolding it would be unambiguous I think).

What's really needed is an API for programmatically folding lines, which I don't think it's tracked anywhere else, right?

@aeschli
Copy link
Contributor

aeschli commented Oct 9, 2019

I don't feel like being able to customize the text displayed would be that useful, just displaying "..." for single folded lines, like Sublime does, would probably be enough for most use cases.

#70794 speaks about defining the full content of the first line. In your case you would just want .... Other use cases would be show some kind of summary of what's folded.

I don't necessarily want those folding regions to go from divider to divider though, as the behavior should be indentation-aware and there might not be an ending divider.

That's really up to your folding range provider to decide. You have the full freedom do define from where the folding range goes. The restrictions are that we can only fold full lines and the way how we render the first line (the line that contains the folding action and marker).

Looking at PlainTasks, I think that can all be implemented with the current APIs and commands.

  • folding range provider to provides the ranges
  • folding commands to fold/unfold, e.g. based on the tags the ranges contain.

fold all tasks containing a specific tag, that's unimplementable with the current APIs

You would implement a command that e.g. asks the user for a tag or uses the tag at the cursor position. Then you evaluate which ranges have that tag and then you execute the command editor.fold with arguments (1, 'up', arrayOfLinesToFold). arrayOfLinesToFold consists of the first line of each range to fold.

@fabiospampinato
Copy link
Contributor Author

fabiospampinato commented Oct 9, 2019

I wasn't aware of the editor.fold and editor.unfold commands. It sounds like this could be implemented after all, but if I'm understanding this correctly I'd have to:

  1. Define a folding range provider.
    • Which sounds useless really as far as I and my users are concerned for this specific use case.
    • Whose provided ranges will be used for displaying chevrons in the gutter I suppose, and this is not what I want, I don't want potentially all tasks to have a chevron associated with them and there'd be no point in manually folding each one individually anyway.
    • Computing those ranges and especially keeping them up-to-date, as I suppose the folding range providers will be asked to provide updated ranges when the document is edited and/or the mouse moves to the gutter or something, could be expensive, for no benefits that I can see.
  2. Find all the lines that should be folded and pass them to editor.fold.

IMHO point 1 shouldn't be required, I should just be able to tell the editor which lines to fold/unfold and that should be it, at least for this specific use case.

@aeschli
Copy link
Contributor

aeschli commented Oct 9, 2019

The folding range provider API is equivalent to an API that let's you set folding ranges. Instead of you telling, we ask you.
If you don't want that every task is a folding range, don't return one. Note that the indentation based ranges go away once there is at least one provider. Ranges need to be updated on document changes, there's no way around this. You need to reparse to find out if there are new tasks.

@fabiospampinato
Copy link
Contributor Author

If step 1 is not actually required then I'd consider this implemented already 👍 I'll play with editor.fold/unfold later.

@aeschli
Copy link
Contributor

aeschli commented Oct 9, 2019

Cool. I close the issue as we have the APIs, and we have issues for the gaps as discussed.

@aeschli aeschli closed this as completed Oct 9, 2019
@vscodebot vscodebot bot locked and limited conversation to collaborators Nov 25, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
editor-folding Editor code folding issues feature-request Request for new features or functionality
Projects
None yet
Development

No branches or pull requests

3 participants