On Thu, 12 Nov 2009 20:16:53 +0900
Hyoung-Ryul Kang <[email protected]> wrote:
> Thank you for the answer. I understand that the way Geany find a
> folding point is to parse the syntax.
>
> I wonder if Geany had an option to make a folding point *according to
> the indentation*. This will enable .txt files to be folded in a very
> sensible way. I also think this would not be technically challenging
> too much, since Geany already detects indentation fairly well.
>
> Some editors like EditPlus (proprietary, www.editplus.com) have that
> option, and it is great to get a neat folded view, not only of the
> code, but also of the results of a program, which often have an
> arbitrary structure.
>
> Furthermore, you don't even need a syntax file to fold a file of a
> new type, if you only indented it appropriately.
>
> Maybe I should suggest this as a feature request.
>
> HR Kang.
Hi. One day I wrote some code to achieve this. I don't think the
attached patch will be accepted (as it's dirty and ugly :-) ), but it
may be useful to someone. The patch is for r4409.
Best regards,
Eugene.
diff --git a/scintilla/LexOthers.cxx b/scintilla/LexOthers.cxx
index 1869014..5103ece 100644
--- a/scintilla/LexOthers.cxx
+++ b/scintilla/LexOthers.cxx
@@ -1271,6 +1271,90 @@ static void ColouriseNullDoc(unsigned int startPos, int length, int, WordList *[
}
}
+static void FoldHierarchicalDoc(unsigned int startPos, int length, int /*initStyle - unused*/,
+ WordList *[], Accessor &styler) {
+ const int maxPos = startPos + length;
+ const int maxLines = styler.GetLine(maxPos - 1); // Requested last line
+ const int docLines = styler.GetLine(styler.Length() - 1); // Available last line
+
+ const bool foldCompact = styler.GetPropertyInt("fold.compact") != 0;
+
+ int spaceFlags = 0;
+
+ // Backtrack to previous non-blank line
+
+ int lineCurrent = styler.GetLine(startPos);
+ int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL);
+ while (lineCurrent > 0) {
+ lineCurrent--;
+ indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL);
+ if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG))
+ break;
+ }
+ int indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
+
+ // Process all characters to end of requested range or end of any triple quote
+ // or comment that hangs over the end of the range. Cap processing in all cases
+ // to end of document (in case of unclosed quote or comment at end).
+ while (lineCurrent <= maxLines) {
+
+ // Gather info
+ int lev = indentCurrent;
+ int lineNext = lineCurrent + 1;
+ int indentNext = indentCurrent;
+ int quote = false;
+ if (lineNext <= docLines) {
+ // Information about next line is only available if not at end of document
+ indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
+ }
+ indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
+ if (indentNext & SC_FOLDLEVELWHITEFLAG)
+ indentNext = SC_FOLDLEVELWHITEFLAG | indentCurrentLevel;
+
+ // Skip past any blank lines for next indent level info; we skip also
+ // comments (all comments, not just those starting in column 0)
+ // which effectively folds them into surrounding code rather
+ // than screwing up folding.
+
+ while (lineNext < docLines && indentNext & SC_FOLDLEVELWHITEFLAG) {
+ lineNext++;
+ indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
+ }
+
+ const int levelAfter = indentNext & SC_FOLDLEVELNUMBERMASK;
+ const int levelBefore = Platform::Maximum(indentCurrentLevel, levelAfter);
+
+ // Now set all the indent levels on the lines we skipped
+ // Do this from end to start. Once we encounter one line
+ // which is indented more than the line after the end of
+ // the comment-block, use the level of the block before
+
+ int skipLine = lineNext;
+ int skipLevel = levelAfter;
+
+ while (--skipLine > lineCurrent) {
+ int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, NULL);
+
+ if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfter &&
+ !(skipLineIndent & SC_FOLDLEVELWHITEFLAG))
+ skipLevel = levelBefore;
+
+ styler.SetLevel(skipLine, skipLevel);
+ }
+
+ // Set fold header on non-quote/non-comment line
+ if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
+ if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ }
+
+ // Set fold level for this line and move to next line
+ styler.SetLevel(lineCurrent, lev);
+ indentCurrent = indentNext;
+ lineCurrent = lineNext;
+ }
+}
+
LexerModule lmBatch(SCLEX_BATCH, ColouriseBatchDoc, "batch", 0, batchWordListDesc);
LexerModule lmDiff(SCLEX_DIFF, ColouriseDiffDoc, "diff", FoldDiffDoc, emptyWordListDesc);
LexerModule lmPo(SCLEX_PO, ColourisePoDoc, "po", 0, emptyWordListDesc);
@@ -1279,3 +1363,4 @@ LexerModule lmMake(SCLEX_MAKEFILE, ColouriseMakeDoc, "makefile", 0, emptyWordLis
LexerModule lmErrorList(SCLEX_ERRORLIST, ColouriseErrorListDoc, "errorlist", 0, emptyWordListDesc);
LexerModule lmLatex(SCLEX_LATEX, ColouriseLatexDoc, "latex", 0, emptyWordListDesc);
LexerModule lmNull(SCLEX_NULL, ColouriseNullDoc, "null");
+LexerModule lmHierarchical(SCLEX_HIERARCHICAL, ColouriseNullDoc, "hierarchical", FoldHierarchicalDoc);
diff --git a/scintilla/include/SciLexer.h b/scintilla/include/SciLexer.h
index 3f68908..1801832 100644
--- a/scintilla/include/SciLexer.h
+++ b/scintilla/include/SciLexer.h
@@ -111,6 +111,7 @@
#define SCLEX_NIMROD 96
#define SCLEX_SML 97
#define SCLEX_MARKDOWN 98
+#define SCLEX_HIERARCHICAL 99
#define SCLEX_AUTOMATIC 1000
#define SCE_P_DEFAULT 0
#define SCE_P_COMMENTLINE 1
diff --git a/src/editor.c b/src/editor.c
index c6ec83a..b400062 100644
--- a/src/editor.c
+++ b/src/editor.c
@@ -4842,6 +4842,7 @@ void editor_set_indentation_guides(GeanyEditor *editor)
case SCLEX_PROPERTIES:
case SCLEX_FORTRAN: /* Is this the best option for Fortran? */
case SCLEX_CAML:
+ case SCLEX_HIERARCHICAL:
mode = SC_IV_LOOKFORWARD;
break;
diff --git a/src/filetypes.c b/src/filetypes.c
index 4842697..3dcc0a8 100644
--- a/src/filetypes.c
+++ b/src/filetypes.c
@@ -638,6 +638,17 @@ static void init_builtin_filetypes(void)
ft->comment_open = g_strdup("--");
ft->comment_close = NULL;
ft->group = GEANY_FILETYPE_GROUP_COMPILED;
+
+#define HIERARCHICAL
+ ft = filetypes[GEANY_FILETYPES_HIERARCHICAL];
+ ft->lang = -2;
+ ft->name = g_strdup(_("Hierarchical"));
+ ft->title = g_strdup(_("Hierarchical"));
+ ft->extension = NULL;
+ ft->pattern = utils_strv_new("*", NULL);
+ ft->comment_open = NULL;
+ ft->comment_close = NULL;
+ ft->group = GEANY_FILETYPE_GROUP_MISC;
}
@@ -1621,5 +1632,3 @@ void filetypes_reload(void)
foreach_document(i)
document_reload_config(documents[i]);
}
-
-
diff --git a/src/filetypes.h b/src/filetypes.h
index 9d17605..0bb5a59 100644
--- a/src/filetypes.h
+++ b/src/filetypes.h
@@ -83,6 +83,7 @@ typedef enum
GEANY_FILETYPES_MARKDOWN,
GEANY_FILETYPES_TXT2TAGS,
GEANY_FILETYPES_ABC,
+ GEANY_FILETYPES_HIERARCHICAL,
/* ^ append items here */
GEANY_MAX_BUILT_IN_FILETYPES /* Don't use this, use filetypes_array->len instead */
}
diff --git a/src/highlighting.c b/src/highlighting.c
index ecf2ae1..a115dd2 100644
--- a/src/highlighting.c
+++ b/src/highlighting.c
@@ -2039,6 +2039,23 @@ static void styleset_default(ScintillaObject *sci, gint ft_id)
}
+static void styleset_hierarchical_init(gint ft_id, GKeyFile *config, GKeyFile *config_home)
+{
+ new_styleset(GEANY_FILETYPES_HIERARCHICAL, 0);
+
+ style_sets[GEANY_FILETYPES_ADA].keywords = g_new(gchar*, 1);
+ style_sets[GEANY_FILETYPES_ADA].keywords[0] = NULL;
+}
+
+
+static void styleset_hierarchical(ScintillaObject *sci)
+{
+ const filetype_id ft_id = GEANY_FILETYPES_HIERARCHICAL;
+
+ apply_filetype_properties(sci, SCLEX_HIERARCHICAL, ft_id);
+}
+
+
static void styleset_css_init(gint ft_id, GKeyFile *config, GKeyFile *config_home)
{
new_styleset(GEANY_FILETYPES_CSS, 22);
@@ -3270,6 +3287,7 @@ void highlighting_init_styles(gint filetype_idx, GKeyFile *config, GKeyFile *con
init_styleset_case(GEANY_FILETYPES_VHDL, styleset_vhdl_init);
init_styleset_case(GEANY_FILETYPES_XML, styleset_markup_init);
init_styleset_case(GEANY_FILETYPES_YAML, styleset_yaml_init);
+ init_styleset_case(GEANY_FILETYPES_HIERARCHICAL, styleset_hierarchical_init);
}
/* should be done in filetypes.c really: */
if (filetype_idx != GEANY_FILETYPES_NONE)
@@ -3342,6 +3360,7 @@ void highlighting_set_styles(ScintillaObject *sci, GeanyFiletype *ft)
styleset_case(GEANY_FILETYPES_VHDL, styleset_vhdl);
styleset_case(GEANY_FILETYPES_XML, styleset_xml);
styleset_case(GEANY_FILETYPES_YAML, styleset_yaml);
+ styleset_case(GEANY_FILETYPES_HIERARCHICAL, styleset_hierarchical);
case GEANY_FILETYPES_NONE:
default:
styleset_default(sci, ft->id);
_______________________________________________
Geany mailing list
[email protected]
http://lists.uvena.de/cgi-bin/mailman/listinfo/geany