Fix Python folding collapse isuue

Fix Python folding collapse isuue by using a fold level stack.

Fix #1898, close #5131
This commit is contained in:
zufuliu 2019-02-25 14:39:32 +08:00 committed by Don HO
parent 690fd45f07
commit 17628b7dd9
No known key found for this signature in database
GPG Key ID: 6C429F1D8D84F46E
2 changed files with 75 additions and 0 deletions

View File

@ -1949,8 +1949,80 @@ void ScintillaEditView::bufferUpdated(Buffer * buffer, int mask)
} }
} }
bool ScintillaEditView::isFoldIndentationBased() const
{
const auto lexer = execute(SCI_GETLEXER);
// search IndentAmount in scintilla\lexers folder
return lexer == SCLEX_PYTHON
|| lexer == SCLEX_COFFEESCRIPT
|| lexer == SCLEX_HASKELL
|| lexer == SCLEX_NIMROD
|| lexer == SCLEX_VB
|| lexer == SCLEX_YAML
;
}
namespace {
struct FoldLevelStack
{
int levelCount = 0; // 1-based level number
int levelStack[MAX_FOLD_COLLAPSE_LEVEL]{};
void push(int level)
{
while (levelCount != 0 && level <= levelStack[levelCount - 1])
{
--levelCount;
}
levelStack[levelCount++] = level;
}
};
}
void ScintillaEditView::collapseFoldIndentationBased(int level2Collapse, bool mode)
{
execute(SCI_COLOURISE, 0, -1);
FoldLevelStack levelStack;
++level2Collapse; // 1-based level number
const int maxLine = static_cast<int32_t>(execute(SCI_GETLINECOUNT));
int line = 0;
while (line < maxLine)
{
int level = static_cast<int32_t>(execute(SCI_GETFOLDLEVEL, line));
if (level & SC_FOLDLEVELHEADERFLAG)
{
level &= SC_FOLDLEVELNUMBERMASK;
// don't need the actually level number, only the relationship.
levelStack.push(level);
if (level2Collapse == levelStack.levelCount)
{
if (isFolded(line) != mode)
{
fold(line, mode);
}
// skip all children lines, required to avoid buffer overrun.
line = static_cast<int32_t>(execute(SCI_GETLASTCHILD, line, -1));
}
}
++line;
}
runMarkers(true, 0, true, false);
}
void ScintillaEditView::collapse(int level2Collapse, bool mode) void ScintillaEditView::collapse(int level2Collapse, bool mode)
{ {
if (isFoldIndentationBased())
{
collapseFoldIndentationBased(level2Collapse, mode);
return;
}
execute(SCI_COLOURISE, 0, -1); execute(SCI_COLOURISE, 0, -1);
int maxLine = static_cast<int32_t>(execute(SCI_GETLINECOUNT)); int maxLine = static_cast<int32_t>(execute(SCI_GETLINECOUNT));

View File

@ -98,6 +98,7 @@ const int CP_GREEK = 1253;
const bool fold_uncollapse = true; const bool fold_uncollapse = true;
const bool fold_collapse = false; const bool fold_collapse = false;
#define MAX_FOLD_COLLAPSE_LEVEL 8
enum TextCase : UCHAR enum TextCase : UCHAR
{ {
@ -559,6 +560,8 @@ public:
::MessageBox(_hSelf, TEXT("This function needs a newer OS version."), TEXT("Change Case Error"), MB_OK | MB_ICONHAND); ::MessageBox(_hSelf, TEXT("This function needs a newer OS version."), TEXT("Change Case Error"), MB_OK | MB_ICONHAND);
}; };
bool isFoldIndentationBased() const;
void collapseFoldIndentationBased(int level2Collapse, bool mode);
void collapse(int level2Collapse, bool mode); void collapse(int level2Collapse, bool mode);
void foldAll(bool mode); void foldAll(bool mode);
void fold(size_t line, bool mode); void fold(size_t line, bool mode);