Currently, the only ways to change the folding is: - toggle current fold - fold all - unfold all
For files with many nodes (fold points) and deep levels of children nodes, it would be great to have commands for efficient navigation of the hierarchical structure , jumping from node to node and expanding/collapsing them as following: * 1)) command for folding current node and moving into parent node. After repeated invokation, it will eventually fold the greatest ancestor, of level 0. * 2)) an opposite command, for unfolding current node and moving into Ist child node. After repeated invokation, it will eventually unfold the Ist path towards a leaf in the tree. * 3)) command to move to next sibling node * 4)) command to move to previous sibling node * These 4 commands would mirror how the navigation is possible in many file managers' tree view of folders, often with the arrow keys (right/left to collapse/expand, and up/down to jump through sibling nodes).
In addition, the following 2 commands would be useful for fast (but controlled) expansion/collapsing at whole document level: * 5)) command to fold current node and all nodes of same level as current node, AND move cursor to parent of current node. With repeated invokation, it will fold upwards all nodes in file, untill only nodes of level 0 are visible. * 6)) opposite command to unfold current node and all nodes of same level as current node, AND move cursor to Ist child of current node. With repeated invokation, it will unfold downwards the nodes in file, untill nodes at the level of the leaf encountered on Ist path from the starting node. * These 2 commands would be more useful, IMO, than the fixed-level fold/unfold of all nodes that other editors provide (for ex , Notepad++ ).
I don't use folding much myself, but this looks reasonable, perhaps fold users could comment.
But a couple of points, the keybindings should have menu equivalents so they are more discoverable or the actions usable if the keys are not bound. I don't like using up additional keys for default bindings, its already getting so there are not many left, so they would be unbound by default and the menu would allow occasional use of the functionality without binding them. Users with a high usage would of course bind keys to the actions.
I would suggest that in the `Document` menu `Fold All` and `Unfold All` with a single `Fold...` and a submenu with all the 9 commands.
To address the last edit about applying to any line, fold points are defined by the lexers in the Scintilla editing widget, they can't be randomly placed. If the lexer isn't defining the fold points you need to address that there.
Thanks for commenting; I understand. My last edit about meaning of "node" was not suggest placing "fold points" at other places than defined by lexers, but to clarify how the navigation might proceed for "nodes at same level". But if it will be too hard to treat lines with fold points and without as being still nodes at same level, then I suppose restricting "nodes" only to fold points can still be useful.
Since you said in C1 that you wanted to fold at a "node" it will have to be a fold point, thats where folding happens.
Scintilla allows fold points to be set randomly by the application, and by the lexers, but since lexers will overwrite random fold points each time they run it is probably impossible to have both at the same time. I'm not sure Geany allows lexer folding to be turned off and anyway it hasn't anything to define fold points in other places.
Of course, folding can only happen at a fold points. But what is considered as "node" in the tree of the file could be made to be more inclusive than the fold points. Because that changes the determination of the current level and thus the navigation and which fold points will be folded/unfolded. For example, in the text my previous comment: - if currently the cursor is in middle of line 2, and one uses C3 to go to next sibling, I think that should be line 4 (as opposed to skiping it b/c it's not a fold point) - if currently in line 8, and one uses C5 (to fold all nodes of same level as current node), then IMO it should fold all folding points of level 1 - judging by current indentation level (as opposed to saying that current fold's level is 0, thus fold all folding points of level 0)
To be clearer, for command C1: if the "node" is a leaf, then only fold if it actually has children (is a fold point, per current lexer definition).
I've corrected C1 and C5 (I realized that in the initial version, they were not trully opposite of C2 and C6, respectively )
I've retained only 2 of the originally suggested commands, as the others as can be already done with existing commands.
For C1, perhaps a more precise formulation that applies to all kind of lines (blank or logical, with fold points or without) is: - if current line is inside another fold region/block, then move cursor to the line with the fold point for this region.
I always wanted (un)fold recursively in Geany and after checking Geany's source code i just discovered, that Geany already supports that folding actions.
So probably it would be nice to have menu items for Fold, Unfold, Toggle Fold, Fold Recursively, Unfold Recursively, Fold All and Unfold All, because all actions are currently supported (but eg toggle only using keybinding and recursive (un)fold only using mouse + configuration +/- shift key).
I just read a couple articles about folding in https://www.scintilla.org/ScintillaDoc.html, in particular https://www.scintilla.org/Lexer.txt, and I see that my notion of "level" in the 1st comment agrees "fold level" scintilla and lexers uses internally to give each line. So then the command to move to parent of comment node could be stated as: * **C1**: Find Ist line above current line, that has a fold level smaller than of current line, and is a fold point. If exists, move cursor there.
@intact In the initial version of the post I suggested a command that combined moving to parent node and folding that, and an opposite command that unfolds a parent node and moves to Ist child node. But for modularity, perhaps better/simpler to implement just the main missing part, C1, and then the combined ones could be made from C1, existing toggle and moving with keyes, with macros or other ways, I guess.
A few more thoughts:
**a)** C1/C2 (Moving to parent node, or child node ), whether or not provided separately from CO1/2, should ideally place the cursor at a regular position in the line ( I guess either Ist non-white space char, or the last one).
**b)** CO1 and CO2, (moving to parent/child **+** fold/unfold) , to be useful for repeated manual invocation, probably need to be based not on "toggle current fold" but "fold current node (line)" and "unfold current node (line)", each with no effect if line is not a folding point.
**c)** C3, C4 ( parallel folding, and unfolding, of all nodes in the file, of same level as current node ) should also be based on "fold current node (line)" and "unfold current node (line)" , instead of "toggle current fold", to ensure the invocation, each tree will be folded or unfolded to the same depth, regardless of the initial state (folded or not) of particular nodes in those trees. These C3 and C4 could be stanalone, or (perhaps even better ) be based on CO1 and CO2, via an added switch.
Here's a first draft for CO1, based on https://www.scintilla.org/ScintillaDoc.html, especially https://www.scintilla.org/ScintillaDoc.html#Folding*/. **But** I'm a beginner in C, I've never contributed code to online projects before, and I have no idea where exactly this would be integrated in Geany. So any advice/info is welcome to make this more fun :) ``` c #include "ScintillaTypes.h" #include "ScintillaMessages.h"
/* move cursor to parent line (if current line has a parent) and fold it (hide its children lines). */ void moveToParentAndFold(line currentLine) { line parentLine= SCI_GETFOLDPARENT(currentLine); // if currently at level 0 (no parents), then effect will be folding current line if (parentLine == -1) parentLine=currentLine;
//set caret at first non-whitespace char in parentLine SCI_GOTOPOS(SCI_GETLINEINDENTPOSITION(parentLine) );
// fold parentLine SCI_FOLDLINE(parentLine, SC_FOLDACTION_CONTRACT); } ```
Here's a first draft for CO1, based on https://www.scintilla.org/ScintillaDoc.html, especially https://www.scintilla.org/ScintillaDoc.html#Folding. **But** I'm a beginner in C, I've never contributed code to online projects before, and I have no idea where exactly this would be integrated in Geany. So any advice/info is welcome to make this more fun :) ``` c // for `line` type, https://www.scintilla.org/ScintillaDoc.html #include "ScintillaTypes.h" #include "ScintillaMessages.h"
/* move cursor to parent line (if current line has a parent) and fold it (hide its children lines). * if currently at level 0 (no parents), then effect will be folding current line */ void moveToParentAndFold() { currentLine = SCI_LINEFROMPOSITION(SCI_GETCURRENTPOS);
line parentLine= SCI_GETFOLDPARENT(currentLine); if (parentLine == -1) parentLine=currentLine;
//set caret at first non-whitespace char in parentLine SCI_GOTOPOS(SCI_GETLINEINDENTPOSITION(parentLine) );
SCI_FOLDLINE(parentLine, SC_FOLDACTION_CONTRACT);
} ```
Since the primary motivation for folding is to prevent visual information overload, I think there's not much value in expanding nodes, at same level, across _all trees _ in the entire file. (By the way, for the same reason, I'd choose to have all my files open by default with all nodes folded. ) So that's why I made the changes above to C3 and C4, to be able to fold/unfold all nodes _locally_, belonging to same parent node/subtree (As complement to fold/unfold at whole file level, and individual node level).
@intact , what did you have in mind with Fold Recursively, Unfold Recursively ?
Fold All folds all nodes and subnodes in document. I can click on folding icon and unpack that node and subnodes stay folded. If i use Shift + click, i can unfold subnodes too (or Shift key may unfold only one level, depends on "Editor / Features / Fold/unfold all children of a fold point" configuration).
Btw looks like "Toggle current fold" use that "Fold/unfold all children of a fold point" configuration too.
Right; except the Shift switch doesn't work to change the behavior of the Toggle current command.
So then your (un)fold recursive is almost the same as what I got to in C3/C4. With just one difference: to apply to descendants (= to children, recursively) only, not to parent node. Here's why it may be better: when you come to a parent node: 1. if it's initially closed, your first action will probably be just to toggle it open. You wouldn't want to open it and its children recursively, as that will reveal too much infor at once. 2. Now once you opened it, if children happen to be closed, that's fine, you can select one of them to explore (in particular with CO1/CO2 if want). If you really want to pop them all open at once, then the Unfold All descendants I suggest still does the job. But if all/most chilren are already opened (let alone if their descendants too), you'll want to close them (too much info at once!). So here the Fold All Descendants will come in very handy: will fold the children of children, but you'll still see curent (parent) and its children. 3. If instead the node is initially open... see 2.
(This formulation also logically agrees with what (Un)Fold All does, if imagine that the ancestor node of all nodes in file is the file itself..)
So we have 3 existing, + 4 new suggested. In addition, we could also include a command to open/unfold All nodes of Ist (top) level, and another to close/fold them - just b/c we're at it... Though I'm personally not convinced these fixed-level of all nodes are useful; or at least not useful beyond Ist level (b/c usually you dont' want to see too much at once, and you'll work in a local region anyway, where toggle current and/or (Un)Fold Descendants and CO1/CO2 will do a better job ).
I'll have to leave others to take it from here, as I found out windows32 bit OS (which unfortunately I have) won't be supported any more. Maybe I'll come back to this after I install Linux.
I'm a simple hobbyist, enjoying Geany as my main editor when coding for use under the Arduino IDE. When both applications run simultaneously, Geany correctly detects an opened file being changed by another application, for example due to edits made and saved via the Arduino IDE. Re-loading the file in Geany causes all code-folding that was previously set, to be lost. It's a small irritation given the many features Geany that offers, but of course "another nice to have". Many thanks
@PthDE IIRC one of the plugins might remember folding, but how good (or not) it is if the folds have changed I don't know.
github-comments@lists.geany.org