Author Topic: Feature Request: Code Folding by Level Shortcuts  (Read 9748 times)

Offline javmss

  • Single posting newcomer
  • *
  • Posts: 7
Feature Request: Code Folding by Level Shortcuts
« on: November 17, 2009, 02:10:34 pm »
on
In November 06, 2009 I have previously posted this topic:
  Code::Blocks > User forums > Using Code::Blocks > Feature Request: Code Folding by Level Shortcuts

Since I got no answer, I thing it might be in the wrong place, so I am reposting it here.
I apologise if I'm being inconvenient.
--------------------------------------------------------------------------------

Notepad++ (http://notepad-plus.sourceforge.net/) has a very usefull feature that allows me to selectively fold all given levels by the respective keyboard shortcut.

If I want to fold all "level 3" blocks in a file (C, C++, XML, whatever), I just need to "ALT+3". To unfold, "SHIFT+ALT+3".
I can do this to anything between level 0 to level 9 (the number in my keyboard end on 9, unfortunately).

In Code::Blocks all I have (at least from what I know) is "fold/unfold current block" or "fold/unfold absolutely all existing blocks in my file".

Is there any chance to have a similar feature in Code::Blocks please???

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5217
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Feature Request: Code Folding by Level Shortcuts
« Reply #1 on: November 17, 2009, 04:48:14 pm »
hi, javmss.

Currently, I don't have much time to help you, but I can give you the direction: the source code of cbeditor.cpp, which is located in:
svn\src\sdk\cbeditor.cpp
the related code was located from line 1924-2024. So, you can simply add some modification to these code, and do the folding function as you wanted.

Code: [Select]
void cbEditor::DoFoldAll(int fold)
{
    cbAssert(m_pControl);
    if (m_SplitType != stNoSplit)
        cbAssert(m_pControl2);
    cbStyledTextCtrl* ctrl = GetControl();
    ctrl->Colourise(0, -1); // the *most* important part!
    int count = ctrl->GetLineCount();
    for (int i = 0; i <= count; ++i)
        DoFoldLine(i, fold);
}

void cbEditor::DoFoldBlockFromLine(int line, int fold)
{
    cbAssert(m_pControl);
    if (m_SplitType != stNoSplit)
        cbAssert(m_pControl2);
    cbStyledTextCtrl* ctrl = GetControl();
    ctrl->Colourise(0, -1); // the *most* important part!
    int i, parent, maxLine, level, UnfoldUpto = line;
    bool FoldedInside = false;

    parent = ctrl->GetFoldParent(line);
    level = ctrl->GetFoldLevel(parent);
    /* The following code will check if the child is hidden
    *  under parent before unfolding it
    */
    if (fold == 0)
    {
        do
        {
            if (!ctrl->GetFoldExpanded(parent))
            {
                FoldedInside = true;
                UnfoldUpto = parent;
            }
            if (wxSCI_FOLDLEVELBASE == (level & wxSCI_FOLDLEVELNUMBERMASK))
                break;
            parent = ctrl->GetFoldParent(parent);
            level = ctrl->GetFoldLevel(parent);
        }
        while (parent != -1);
    }

    maxLine = ctrl->GetLastChild(line, -1);

    for (i = UnfoldUpto; i <= maxLine; ++i)
        DoFoldLine(i, fold);
}

bool cbEditor::DoFoldLine(int line, int fold)
{
    cbAssert(m_pControl);
    if (m_SplitType != stNoSplit)
        cbAssert(m_pControl2);
    cbStyledTextCtrl* ctrl = GetControl();
    int level = ctrl->GetFoldLevel(line);

    // The fold parameter is the type of folding action requested
    // 0 = Unfold; 1 = Fold; 2 = Toggle folding.

    // Check if the line is a header (fold point).
    if (level & wxSCI_FOLDLEVELHEADERFLAG)
    {
        bool IsExpanded = ctrl->GetFoldExpanded(line);

        // If a fold/unfold request is issued when the block is already
        // folded/unfolded, ignore the request.
        if (fold == 0 && IsExpanded) return true;
        if (fold == 1 && !IsExpanded) return true;

        // Apply the folding level limit only if the current block will be
        // folded (that means it's currently expanded), folding level limiter
        // must be enabled of course. Unfolding will not be affected.
        if (m_pData->mFoldingLimit && IsExpanded)
        {
            if ((level & wxSCI_FOLDLEVELNUMBERMASK) > (wxSCI_FOLDLEVELBASE + m_pData->mFoldingLimitLevel-1))
                return false;
        }

        ctrl->ToggleFold(line);
        return true;
    }
    return false;
}

void cbEditor::FoldAll()
{
    DoFoldAll(1);
}

void cbEditor::UnfoldAll()
{
    DoFoldAll(0);
}

void cbEditor::ToggleAllFolds()
{
    DoFoldAll(2);
}
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline javmss

  • Single posting newcomer
  • *
  • Posts: 7
Re: Feature Request: Code Folding by Level Shortcuts
« Reply #2 on: December 16, 2009, 07:18:58 pm »
I don't have much knowledge about the C::B SDK, so I took a look to the code where you told me and realised I'd do something like this:

Code: [Select]
/** Fold/Unfold/Toggle all folds in the givel level.
\param level Level number of folding, starting from 0.
\param fold Type of folding action requested: \n
- 0 = Unfold.
- 1 = Fold.
- 2 = Toggle folding. */
void cbEditor::DoFoldAllAtLevel(int level, int fold)
{
    cbAssert(m_pControl);
    if (m_SplitType != stNoSplit)
        cbAssert(m_pControl2);

    cbStyledTextCtrl* ctrl = GetControl();
    ctrl->Colourise(0, -1); // the *most* important part!

// Scan all file lines searching for the specified folding level.
    int count = ctrl->GetLineCount();
    for (int line = 0; line <= count; ++line)
    {
int parent = ctrl->GetFoldParent(line);

if ( level == ctrl->GetFoldLevel(parent) ) // Found on fold in "level".
{
int maxLine = ctrl->GetLastChild(line, -1);

for (i = line; i <= maxLine; ++i)
DoFoldLine(i, fold);
}
    }
}

Now I wonder how can I bind this to different shortcuts.
I can suppose that I should create several "FoldAt#( )" methods, but I can't catch how to bind it to the "ALT+#" keys...

I will be looking for it, but I'd be very glad for a clue.

Tanks!

Offline dmoore

  • Developer
  • Lives here!
  • *****
  • Posts: 1576
Re: Feature Request: Code Folding by Level Shortcuts
« Reply #3 on: December 16, 2009, 07:40:28 pm »
maybe I can incorporate this into my editor tweaks plugin. http://forums.codeblocks.org/index.php/topic,11660.0.html

Quote
Now I wonder how can I bind this to different shortcuts.

once you have added menu entries, the keybinder plugin will let you set shortcuts for it

Offline dmoore

  • Developer
  • Lives here!
  • *****
  • Posts: 1576
Re: Feature Request: Code Folding by Level Shortcuts
« Reply #4 on: December 16, 2009, 10:15:26 pm »
btw, your code doesn't do what you think it does (GetFoldLevel returns a more complicated result). Also, I've no idea why you have the nested loop.

In addition I'm not even sure what you are trying to achieve. I assume you want options to fold all code above a certain fold level? If so, I propose:

Code: [Select]
//fold: 0 = unfold, 1 = fold
void EditorTweaks::DoFoldAboveLevel(int level, int fold)
{
    cbEditor* ed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
    if(!ed || !ed->GetControl())
        return;

    level+=wxSCI_FOLDLEVELBASE;

    ed->GetControl()->Colourise(0, -1); // the *most* important part!

    int count = ed->GetControl()->GetLineCount();
    for (int line = 0; line <= count; ++line)
    {
        int line_level_data = ed->GetControl()->GetFoldLevel(line);
        if (!(line_level_data & wxSCI_FOLDLEVELHEADERFLAG))
            continue;
        int line_level = line_level_data & wxSCI_FOLDLEVELNUMBERMASK;

        bool IsExpanded = ed->GetControl()->GetFoldExpanded(line);

        // If a fold/unfold request is issued when the block is already
        // folded/unfolded, ignore the request.
        if(line_level<=level)
            if(IsExpanded)
                continue;
        else
            if(fold==0 && IsExpanded || fold ==1 && !IsExpanded)
                continue;
        ed->GetControl()->ToggleFold(line);
    }
}

this code is now part of editor tweaks:

Code: [Select]
svn checkout http://svn.berlios.de/svnroot/repos/cbilplugin/branches/EditorTweaks
« Last Edit: December 16, 2009, 10:43:16 pm by dmoore »

Offline MortenMacFly

  • Administrator
  • Lives here!
  • *****
  • Posts: 9488
Re: Feature Request: Code Folding by Level Shortcuts
« Reply #5 on: December 17, 2009, 07:57:12 am »
Just for the record: I think the idea behind the aligner plugin would fit very well into this plugin, too. How about that?

See here: http://forums.codeblocks.org/index.php/topic,11274.msg79225.html#msg79225
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: http://www.codeblocks.org/docs/main_codeblocks_en.html
C::B FAQ: http://wiki.codeblocks.org/index.php?title=FAQ