-
Notifications
You must be signed in to change notification settings - Fork 196
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
Add textDocument/foldingRange Provider #492
Add textDocument/foldingRange Provider #492
Conversation
Hm, older versions of Elixir all seem to be failing on test
Any ideas why? |
It looks like there is a slight difference in tokenizer output in older versions:
1.11
|
@lukaszsamson Thank you for the insight! That seems to have fixed everything. So here's where we stand: I think the functionality is basically there. I have a few quibbles that we could address:
We could ignore any or all those changes. Or we could make them in a follow on PR. It's up to how quickly y'all want to get this out the door. |
I'm glad I could help. I went through commit history of
Is there any value in returning errors here?
IMO it's good enough. We're not likely to need it pushed to hex docs. |
Agreed. Although code folding is broken already so I don't mind patching if more issues come up.
No, not really other than debugging and testing. I'd be fine dropping the whole I suppose I pointed it out because when I see |
Thanks for this! I just wanted to drop a note that I am working my way through reviewing this PR, and it's looking great so far so I don't expect to request any major changes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great, just two very minor comments. Although I will create a PR to switch to doctests for the examples.
We find strings (regular/charlist strings/heredocs) and sigils in a pass as | ||
they're delimited by a few special tokens. | ||
Ranges from this pass are either | ||
- `kind?: :comment` if the token is paired with `@doc` or `@moduledoc`, or |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we include @typedoc
here as well? (and in the matching code)
apps/language_server/lib/language_server/providers/folding_range/token_pairs.ex
Outdated
Show resolved
Hide resolved
Also add a means to visualize folding range changes in the tests (only shows when there is a test failure)
Here's the PR: billylanchantin#1 |
Thanks again for this ❤️! |
@axelson You all are welcome! Sorry for the delay. I'd wanted to merge your changes in for a while, but I messed up my local build and had trouble getting things working again on my end. That and some life stuff sapped up all my free time. So glad we got this across the finish line! |
No worries! Life happens to all of us (definitely including myself, haha). I'm quite excited for this functionality and I'm hoping to get it out in the next release soon. Maybe next weekend. |
* Add changelog test to verify that the changelog is correctly linked * Update changelog * Add #497 * Specify that the fuzzy completion is only for functions * Fix formatting * update changelog for #505 * Update changelog for #501, #473, and #504 * Update changelog for #507 and vscode #176 * Update changelog for #511 * Update changelog for #492
✅ Status: Ready for Review
This PR is basically where I envisioned it, aka it's ready for review.
Description
This PR creates a folding range provider. See here for more about folding ranges:
https://microsoft.github.io/language-server-protocol/specifications/specification-3-15/#textDocument_foldingRange
Background
I recently raised an issue here:
elixir-lsp/vscode-elixir-ls#170
The tl;dr is that folding ranges stopped working, but as ElixirLS was relying on the default folding ranges implementation to create them, there was no easy way to fix the situation.
@wingyplus made some progress on a home-grown implementation a few months back:
#358
But they did not have the time to devote to finishing the work. I wanna thank them for getting me started -- I took their code as my starting point so I want to make sure they get some credit.
Methodology
High level
I make multiple passes (currently 4) through the source text and create folding ranges from each pass. Then I merge the ranges from each pass to provide the final ranges. Each pass gets a priority to help break ties (the priority is an integer, higher integers win). See:
apps/language_server/lib/language_server/providers/folding_range.ex
Indentation pass (priority: 1)
I use the indentation level -- determined by the column of the first non-whitespace character on each line -- to provide baseline ranges. All ranges from this pass are
kind?: :region
ranges.Comment block pass (priority: 2)
I make a "comment block" -- consecutive lines that start with
#
-- to form regions. All ranges from this pass arekind?: :comment
ranges.Token-pairs pass (priority: 3)
I use pairs of tokens, e.g.
do
andend
, to provide another pass of ranges. All ranges from this pass arekind?: :region
ranges.Special tokens pass (priority: 3)
I find strings (regular and charlist strings and heredocs) and sigils in a pass as they're delimited by a few special tokens. Ranges from this pass are either
kind?: :comment
if the token signifies a@doc
or@moduledoc
heredoc orkind?: :region
otherwise.To Do
kind?: :comment | :region
kind?: :comment
Any others?
|>
chains:kind?: :region
?kind?: :imports
?Testing
Run
What to look out for when reviewing
There's also some extraThis is fixed now.Enum.sort()
s that we'll want to drop. I just got lazy with the tests.