diff --git a/vimode/src/cmds/fold.c b/vimode/src/cmds/fold.c index 63b9552b8..14401e0e9 100644 --- a/vimode/src/cmds/fold.c +++ b/vimode/src/cmds/fold.c @@ -1,5 +1,5 @@ /* - * Copyright 2024 Jiri Techet + * Copyright 2024 Sylvain Cresto * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,29 +19,47 @@ #include "cmds/fold.h" #include "utils.h" -static gint prepare_fold(CmdParams *p, gboolean first_parent) +/* fold command does not depend on state of parents */ +#define FOLD_NONE 0 +/* fold command depend on state of parents */ +#define FOLD_PARENT 1 +/* fold command depend on state of contracted parent if it exists */ +#define FOLD_CONTRACTED 2 + +static gint prepare_fold(CmdParams *p, gint filter) { /* foldparent of the next line */ - gint line = -1; - if (first_parent) { - line = SSM(p->sci, SCI_GETFOLDPARENT, p->line + 1, 0); - } + gint line = SSM(p->sci, SCI_GETFOLDPARENT, p->line + 1, 0); - if (p->line == line && first_parent == TRUE) + if (p->line == line) ; /* we are already on the fold point line */ else { - gint parent = p->line; /* foldparent of the current line */ - while (1) { - line = SSM(p->sci, SCI_GETFOLDPARENT, parent, 0); - if (line == -1 || first_parent == TRUE) break; - parent = line; + line = SSM(p->sci, SCI_GETFOLDPARENT, p->line, 0); + } + + /* retreive first parent when filter != FOLD_NONE + when filter == FOLD_CONTRACTED we stop on first contracted parent if exist + */ + if (filter == FOLD_CONTRACTED && line != -1 && ! SSM(p->sci, SCI_GETFOLDEXPANDED, line, 0)) + ; /* this fold point is contracted and filter == FOLD_CONTRACTED */ + else if (filter != FOLD_NONE) + { + gint prev_line = line; + while (prev_line != -1) + { + prev_line = SSM(p->sci, SCI_GETFOLDPARENT, prev_line, 0); + if (prev_line != -1) + { + line = prev_line; + if (filter == FOLD_CONTRACTED && ! SSM(p->sci, SCI_GETFOLDEXPANDED, line, 0)) + break; + } } - if (first_parent == FALSE) - line = parent; } + if (line != -1) { /* move the cursor on the visible line before the fold */ @@ -52,9 +70,10 @@ static gint prepare_fold(CmdParams *p, gboolean first_parent) return line; } + void cmd_toggle_fold(CmdContext *c, CmdParams *p) { - gint line = prepare_fold(p, TRUE); + gint line = prepare_fold(p, FOLD_NONE); if (line != -1) SSM(p->sci, SCI_FOLDLINE, (uptr_t) line, SC_FOLDACTION_TOGGLE); } @@ -62,7 +81,7 @@ void cmd_toggle_fold(CmdContext *c, CmdParams *p) void cmd_open_fold(CmdContext *c, CmdParams *p) { - gint line = prepare_fold(p, TRUE); + gint line = prepare_fold(p, FOLD_NONE); if (line != -1) SSM(p->sci, SCI_FOLDLINE, (uptr_t) line, SC_FOLDACTION_EXPAND); } @@ -70,7 +89,7 @@ void cmd_open_fold(CmdContext *c, CmdParams *p) void cmd_close_fold(CmdContext *c, CmdParams *p) { - gint line = prepare_fold(p, TRUE); + gint line = prepare_fold(p, FOLD_NONE); if (line != -1) SSM(p->sci, SCI_FOLDLINE, (uptr_t) line, SC_FOLDACTION_CONTRACT); } @@ -78,7 +97,7 @@ void cmd_close_fold(CmdContext *c, CmdParams *p) void cmd_toggle_fold_child(CmdContext *c, CmdParams *p) { - gint line = prepare_fold(p, TRUE); + gint line = prepare_fold(p, FOLD_CONTRACTED); if (line != -1) SSM(p->sci, SCI_FOLDCHILDREN, (uptr_t) line, SC_FOLDACTION_TOGGLE); } @@ -86,14 +105,14 @@ void cmd_toggle_fold_child(CmdContext *c, CmdParams *p) void cmd_open_fold_child(CmdContext *c, CmdParams *p) { - gint line = prepare_fold(p, TRUE); + gint line = prepare_fold(p, FOLD_NONE); SSM(p->sci, SCI_FOLDCHILDREN, (uptr_t) line, SC_FOLDACTION_EXPAND); } void cmd_close_fold_child(CmdContext *c, CmdParams *p) { - gint line = prepare_fold(p, TRUE); + gint line = prepare_fold(p, FOLD_PARENT); if (line != -1) SSM(p->sci, SCI_FOLDCHILDREN, (uptr_t) line, SC_FOLDACTION_CONTRACT); } diff --git a/vimode/src/cmds/fold.h b/vimode/src/cmds/fold.h index bf732a33e..4c42b13d1 100644 --- a/vimode/src/cmds/fold.h +++ b/vimode/src/cmds/fold.h @@ -1,5 +1,5 @@ /* - * Copyright 2024 Jiri Techet + * Copyright 2024 Sylvain Cresto * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by