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 code: more advanced commands #2920
Comments
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 |
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, you need to address that there. |
Thanks for commenting; I understand. |
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. |
I've edited my original post, and removed some of the originally suggested commands, (moving between siblings) can be already done with existing commands. |
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 with "fold level" scintilla and lexers uses internally to give each line.
@intact In the initial version of the post I suggested: |
A few more thoughts: CO1 and CO2, (moving to parent/child + fold/unfold) , to be better suited 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. And moving to parent node, or child node , should ideally place the cursor at a regular position in the line ( I guess Ist non-white space char). C3, C4 ( folding, and unfolding, of |
Here's a first draft for CO1, and CO2, based on https://www.scintilla.org/ScintillaDoc.html, especially https://www.scintilla.org/ScintillaDoc.html#Folding. #include "Scintilla.h" //for flags
#include "ScintillaTypes.h" // for 'line' and 'position' types
#include "ScintillaMessages.h"
/* if current line has a parent line, then move cursor to it and fold it (hide its children lines).
* otherwise (no parents), then effect will be folding current line
*/
void moveToParentAndFold()
{
line currentLine = SCI_LINEFROMPOSITION(SCI_GETCURRENTPOS);
line parentLine= SCI_GETFOLDPARENT(currentLine);
// if there is no parent, then will fold current line
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);
}
/* if current line is a parent, unfold it and move cursor to Ist child line.
*/
void unfoldAndMoveToChild()
{
line currentLine = SCI_LINEFROMPOSITION(SCI_GETCURRENTPOS);
// if it's parent line (fold point)
if( SCI_GETFOLDLEVEL(currentLine) & SC_FOLDLEVELHEADERFLAG )
{
SCI_FOLDLINE(currentLine, SC_FOLDACTION_EXPAND );
// find Ist child line, taken to be Ist non-blank line after current line
while( SCI_GETFOLDLEVEL(currentLine + 1) & SC_FOLDLEVELWHITEFLAG )
currentLine++ ;
SCI_GOTOPOS(SCI_GETLINEINDENTPOSITION( currentLine+1 ) );
}
} EDIT: it looks like folding happens here: https://github.com/geany/geany/blob/master/src/editor.c#L4360 . So I guess I can continue preparing such drafts for C3, C4, and then, perhaps with someone's help, change them to be similar to those in |
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. ) @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). So (Un)Fold is for (un)folding one level and (Un)Fold Recursively is for (un)folding subnodes too. 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 fold" 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.
(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. EDIT: an alternative command, that
When cursor is on a 0-level line, it coincides with what (un)fold All does. But if cursor on a 1-level line, it (un)folds only the sibling lines (and their descendants), inside current fold region, not whole file. |
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. |
I'm a simple hobbyist, enjoying Geany as my main editor when coding for use under the Arduino IDE. |
@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. |
EDIT: updated some of suggested commands: fold/ unfold of descendant nodes of given node.
Currently, the only ways to change the folding is:
For files with many nodes and deep levels of children nodes, it would be great to have commands for efficient navigation and (controlled) fold/unfold of the hierarchical structure:
When applied repeatedly, will allows to browse and fold/unfold a full branch / path of nodes. Similar to navigation with arrows in many file managers' tree view of folders (right/left to move across levels and collapse/expand, and up/down to jump through sibling nodes)
parent nodes in the file at same level as current node's leveldescendant nodes of current node.parent nodes in the file at same level as current node's leveldescendant nodes of current node.This will fill the big control gap between what's available currently: folding at current node and at whole document. They are analogous to how current "fold all" and "unfold all" work, if think of the file as the "root node" of all other nodes/lines.
These would be more useful, IMO, than the fold/unfold of all nodes of same fixed-level that some other editors provide (for ex , Notepad++ ). First, it allows local fold-region control (so that does change folding in distand sibling nodes/branches, and don't load your visual memory with too much stuff). Second, it's relative to current node, so you don't not need to know which level exactly you're currently on.
By node I don't mean only something that can be folded, but any "logical line" (non-blank line; with one or more programming statements on it; perhaps comment lines too, depending on language ).
A node is a parent node if it contains a folding point (and the nodes inside the fold - children nodes); otherwise is a leaf node. It's a child node if it's inside the fold of another node.
In my own use case, in addition to coding, I use Geany for organizing notes in
.txt
files, with folding by indentation. With ability to navigate fast, and control the hierarchy display, I will not need to use a separate "outliner".The text was updated successfully, but these errors were encountered: