Branch: refs/heads/master Author: Jiří Techet techet@gmail.com Committer: Jiří Techet techet@gmail.com Date: Tue, 21 May 2024 21:41:42 UTC Commit: 522b79dc7b1f25576e4bf44277f5e49bfa46cd9d https://github.com/geany/geany-plugins/commit/522b79dc7b1f25576e4bf44277f5e4...
Log Message: ----------- vimode: Take into account folded lines when moving cursor
We need to perform the moves based on visible lines and not plain document lines as the latter may be folded and then the moves are made incorrectly.
Modified Paths: -------------- vimode/src/cmds/motion.c
Modified: vimode/src/cmds/motion.c 74 lines changed, 56 insertions(+), 18 deletions(-) =================================================================== @@ -41,9 +41,39 @@ void cmd_goto_right(CmdContext *c, CmdParams *p) }
+static gint doc_line_from_visible_delta(CmdParams *p, gint line, gint delta, gboolean *overflow) +{ + gboolean oflow = FALSE; + gint new_line = line; + gint i = 0; + + while (i < ABS(delta)) + { + gint inc = delta > 0 ? 1 : -1; + gint tmp = new_line + inc; + + if (tmp < 0 || tmp >= p->line_num) + { + oflow = TRUE; + break; + } + new_line = tmp; + + if (SSM(p->sci, SCI_GETLINEVISIBLE, new_line, 0)) + i++; + } + + if (overflow) + *overflow = oflow; + + return new_line; +} + + void cmd_goto_up(CmdContext *c, CmdParams *p) { gint one_above, pos; + gboolean line_underflow;
if (p->line == 0) return; @@ -53,8 +83,8 @@ void cmd_goto_up(CmdContext *c, CmdParams *p) * SCI_CHOOSECARETX which we cannot read directly from Scintilla and which * we want to keep - perform jump to previous/following line and add * one final SCI_LINEUP/SCI_LINEDOWN which recovers SCI_CHOOSECARETX for us. */ - one_above = p->line - p->num - 1; - if (one_above >= 0) + one_above = doc_line_from_visible_delta(p, p->line, -p->num - 1, &line_underflow); + if (!line_underflow) { /* Every case except for the first line - go one line above and perform * SCI_LINEDOWN. This ensures that even with wrapping on, we get the @@ -70,7 +100,7 @@ void cmd_goto_up(CmdContext *c, CmdParams *p) * on, we need to repeat SCI_LINEUP to get to the first line of wrapping. * This may lead to visible slow scrolling which is why there's the * fast case above for anything else but the first line. */ - gint one_below = p->line - p->num + 1; + gint one_below = doc_line_from_visible_delta(p, p->line, -p->num + 1, NULL); gint wrap_count;
one_below = one_below > 0 ? one_below : 1; @@ -98,15 +128,13 @@ void cmd_goto_up_nonempty(CmdContext *c, CmdParams *p) static void goto_down(CmdParams *p, gint num) { gint one_above, pos; - gint last_line = p->line_num - 1;
- if (p->line == last_line) + if (p->line >= p->line_num - 1) return;
- /* see cmd_goto_up() for explanation */ - one_above = p->line + num - 1; - one_above = one_above < last_line ? one_above : last_line - 1; + one_above = doc_line_from_visible_delta(p, p->line, p->num - 1, NULL); pos = SSM(p->sci, SCI_GETLINEENDPOSITION, one_above, 0); + SET_POS_NOX(p->sci, pos, FALSE); SSM(p->sci, SCI_LINEDOWN, 0, 0); } @@ -136,39 +164,40 @@ void cmd_goto_down_one_less_nonempty(CmdContext *c, CmdParams *p) void cmd_goto_page_up(CmdContext *c, CmdParams *p) { gint shift = p->line_visible_num * p->num; - gint new_line = get_line_number_rel(p->sci, -shift); + gint new_line = doc_line_from_visible_delta(p, p->line, -shift, NULL); goto_nonempty(p->sci, new_line, TRUE); }
void cmd_goto_page_down(CmdContext *c, CmdParams *p) { gint shift = p->line_visible_num * p->num; - gint new_line = get_line_number_rel(p->sci, shift); + gint new_line = doc_line_from_visible_delta(p, p->line, shift, NULL); goto_nonempty(p->sci, new_line, TRUE); }
void cmd_goto_halfpage_up(CmdContext *c, CmdParams *p) { gint shift = p->num_present ? p->num : p->line_visible_num / 2; - gint new_line = get_line_number_rel(p->sci, -shift); + gint new_line = doc_line_from_visible_delta(p, p->line, -shift, NULL); goto_nonempty(p->sci, new_line, TRUE); }
void cmd_goto_halfpage_down(CmdContext *c, CmdParams *p) { gint shift = p->num_present ? p->num : p->line_visible_num / 2; - gint new_line = get_line_number_rel(p->sci, shift); + gint new_line = doc_line_from_visible_delta(p, p->line, shift, NULL); goto_nonempty(p->sci, new_line, TRUE); }
void cmd_goto_line(CmdContext *c, CmdParams *p) { gint num = p->num > p->line_num ? p->line_num : p->num; - goto_nonempty(p->sci, num - 1, TRUE); + num = doc_line_from_visible_delta(p, num, -1, NULL); + goto_nonempty(p->sci, num, TRUE); }
@@ -177,30 +206,39 @@ void cmd_goto_line_last(CmdContext *c, CmdParams *p) gint num = p->num > p->line_num ? p->line_num : p->num; if (!p->num_present) num = p->line_num; - goto_nonempty(p->sci, num - 1, TRUE); + num = doc_line_from_visible_delta(p, num, -1, NULL); + goto_nonempty(p->sci, num, TRUE); }
void cmd_goto_screen_top(CmdContext *c, CmdParams *p) { + gint line; gint top = p->line_visible_first; gint count = p->line_visible_num; - gint line = top + p->num; - goto_nonempty(p->sci, line > top + count ? top + count : line, FALSE); + gint max = doc_line_from_visible_delta(p, top, count, NULL); + gint num = p->num; + + if (!p->num_present) + num = 0; + + line = doc_line_from_visible_delta(p, top, num, NULL); + goto_nonempty(p->sci, line > max ? max : line, FALSE); }
void cmd_goto_screen_middle(CmdContext *c, CmdParams *p) { - goto_nonempty(p->sci, p->line_visible_first + p->line_visible_num/2, FALSE); + gint num = doc_line_from_visible_delta(p, p->line_visible_first, p->line_visible_num / 2, NULL); + goto_nonempty(p->sci, num, FALSE); }
void cmd_goto_screen_bottom(CmdContext *c, CmdParams *p) { gint top = p->line_visible_first; gint count = p->line_visible_num; - gint line = top + count - p->num; + gint line = doc_line_from_visible_delta(p, top, count - p->num, NULL); goto_nonempty(p->sci, line < top ? top : line, FALSE); }
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).