-
Notifications
You must be signed in to change notification settings - Fork 39
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 code folding event. #547
base: default
Are you sure you want to change the base?
Conversation
This event `events.FOLDED` is required to be able to manually perform code folding on `buffer.fold_level` when built-in facilities for code folding aren't sufficient. One example is markdown frontmatter.
Hey, please don't merge this yet. When I tested there seemed to be an issue: I didn't assign a value to |
Kudos to you for spending the time trying to decipher that fold function. It's difficult for me to follow in places... Before I consider adding this event, I need to understand what the benefit is. It sounds like you are using a stock lexer that has some pre-existing folding behavior, and you want to modify those folds after the fact. I'm wondering if modifying the lexer itself is the better way to go, so folds do not have to be changed after the fact. Basically, if I add Perhaps you can share more information when you are able. There's no hurry though. I don't expect 12.5 to be out until September at the earliest. |
Well, I tried using the provided
The challenge is that frontmatter start tag only matches at a certain location (line number 1) unlike all other folded symbols in other languages. This requires getting the current line number through the usual little dance: local pos = buffer.get_current_pos()
local line = buffer.get_line_from_position(pos)
-- Why is there no function to get it directly? But of course, You may think that it can be solved by matching a line that consists of three dashes, with no lines behind it. Which is still impossible, because it’ll work like this:
Just so if it isn't clear, even though I talked here in a theoritical tone this is the observed behavior when I tried to do it. I believe adding an event to indicate the end of the lexer-based folding to let the user handle such edge cases in user configuration is the correct decision here. These edge cases may be arbitrarily complex, I don't think markdown frontmatter is the only construct not fitting in with the current folding paradigm. Typesetting languages come to mind. Re my comment above saying “Don’t merge yet”, I now implemented |
Thanks for writing. I will read, digest, and respond when I have some time. Thanks for your patience! |
No problem, no hurries.
|
Sorry for the delayed response, and thanks for your very well thought out, and well-articulated description of events. I believe this is precisely the reason why Scintilla allows lexers to set line states: https://scintilla.org/ScintillaDoc.html#SCI_SETLINESTATE I think when your folder identifies and processes a line of interest, it can mark that line with a persistent state (an integer, presumably with bit-flags) so that it knows what to do when encountering it again, or it knows what to do when encountering a subsequent line of interest (e.g. look back up the line states and see what it should do with the current line). I don't have any working examples of this, but the output.lua lexer marks recognized warning and error lines for process output (e.g. compiler output): https://github.com/orbitalquark/scintillua/blob/f1375d323c19c6264c3ad56abb1c24f52f3a28b9/lexers/output.lua#L27-L41 Textadept (outside the lexer) looks up line states in order to add colored margin markers (e.g. red for errors, yellow for warnings): textadept/modules/textadept/run.lua Lines 98 to 106 in 32c1c80
As to your question about why there is no Prior to Textadept 12, Textadept used a C++ version of its LPeg lexer (Scintillua), which was bound to Scintilla's IDocument interface. Scintillua supports both versions, so its Lua State doesn't provide any extra functions (there hasn't really been a need for this, honestly). I'm not saying all of this to shut down the idea of adding another event. I'm merely interested in exploring Scintilla's existing facilities for handling your use case. |
TL;DR: This new event
events.FOLDED
is required to be able to manually perform codefolding on
buffer.fold_level
when built-in facilities for code folding aren'tsufficient. The specific one that led to creation of this is markdown frontmatter, but there may be many more.
Hope you're well Mitchell!
I have studied the 150 line long
lexer.fold
function over the course of 3 days, to add support for markdown headings which it was utterly incapable of handling. I explored numerous solutions. In the end, I was able modify it minimally and elegantly, without resorting to a workaround like creating an entirely custom function and falling back to the original one outside of markdown. I hope to upstream this implementation soon.But. Folding the frontmatter separator with the built-in code folding utilities is another beast. I gave up after trying a lot. Now I have a custom function to handle that, which manually manipulates line folding states. It runs after lexer is done folding code, otherwise lexer inevitably interferes and resets fold points and states to what it thinks they should be.
This fork was created a while ago so I merged all the commits you created since then. I hope this change can make it to v12.5.