Code Folding
Implemented incrementally in Gtef.
Proposal 1
GtefGutterRendererFolds
First iteration done.
Implement a basic gutter renderer for the drawing. This gutter renderer would be at the same level as GtkSourceGutterRendererPixbuf and GtkSourceGutterRendererText.
Initially public, might become private in the future.
GtefFoldRegion
First iteration done.
Simple class that represents a region in a GtkTextBuffer that can be folded.
To fold the region, uses internally a GtkTextTag with the invisible property. But in the API only GtkTextIters are exposed. GtkTextMarks can be used to store the start/end (or store with a GtkTextTag, but this is less convenient).
- new(buffer, start, end);
- get_bounds();
- set_bounds();
- get_folded();
- set_folded();
- gboolean folded property.
GtefFolding
A n-ary tree of FoldRegions. Uses internally a GNode, and keep the FoldRegions sorted.
To implement code folding for a specific language (e.g. XML), a class needs to be written that fills and adapt the GtefFolding tree. That class needs to listen to the insert-text and delete-range buffer signals, and adapt the GtefFolding object accordingly, creating and destroying FoldRegions. I think it gets a bit tricky when the user is editing the text and the tree is temporarily broken (an invalid XML file).
- add_fold_region();
- remove_fold_region(bool remove_all_children);
- get_fold_regions_at_iter();
- get_fold_regions_in_range();?
- get_parent(folding, fold_region);
- get_direct_children(folding, fold_region);
- ...
GtefGutterRendererFolding
Subclass of GtefGutterRendererFolds. Do the connection with a GtefFolding object. At the same level as GtkSourceGutterRendererMarks and GtkSourceGutterRendererLines.
Probably private.
In GtefBuffer
Be able to get/set the GtefFolding object.
In GtkSourceView
Be able to show/hide the GtefGutterRendererFolding.
Proposal 2
Instead of GtefFolding tree, have a more general GtefAst (Abstract Syntax Tree).
Instead of GtefFoldRegion, have a more general GtefAstElement with a foldable property.
Applications could create subclasses of GtefAstElement for different kinds of elements, providing more functions.
The GtefAst could be used to display some of the element types in a GtkTreeView (e.g. in a side panel). Either as a tree (e.g. document structure: chapters, sections, sub-sections, …), or a list (e.g. list of functions).
The idea is to create and maintain a single AST (per GtkTextBuffer) that can be used for different features. For the code folding, we are interested only by the foldable GtefAstElements. Similarly, for the side panel we might be interested only by some element types, not all.
Gtef would provide the basic infrastructure, the hard part would be to create the parser that builds the AST, and update it on text insertions/deletions, and needs to deal with invalid content when the text is being edited.