Skip to content

Commit

Permalink
Merge pull request #1338 from techee/vimode_fold
Browse files Browse the repository at this point in the history
vimode: Handle folded lines correctly
  • Loading branch information
techee authored May 21, 2024
2 parents 6e0cb58 + 33984ab commit 23d0a58
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 18 deletions.
1 change: 1 addition & 0 deletions vimode/src/cmd-runner.c
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,7 @@ static gboolean process_cmd(CmdDef *cmds, CmdContext *ctx, gboolean ins_mode)
{
if (orig_mode == VI_MODE_COMMAND_SINGLE)
vi_set_mode(VI_MODE_INSERT);
ensure_current_line_expanded(ctx->sci);
}
else if (!consumed && ctx->kpl)
{
Expand Down
74 changes: 56 additions & 18 deletions vimode/src/cmds/motion.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
}


Expand All @@ -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);
}

Expand Down
2 changes: 2 additions & 0 deletions vimode/src/excmd-runner.c
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,7 @@ void excmd_perform(CmdContext *ctx, const gchar *cmd)
{
case ':':
perform_simple_ex_cmd(ctx, cmd + 1);
ensure_current_line_expanded(ctx->sci);
break;
case '/':
case '?':
Expand All @@ -483,6 +484,7 @@ void excmd_perform(CmdContext *ctx, const gchar *cmd)
pos = perform_search(ctx->sci, ctx->search_text, ctx->num, FALSE);
if (pos >= 0)
SET_POS(ctx->sci, pos, TRUE);
ensure_current_line_expanded(ctx->sci);
break;
}
}
Expand Down
8 changes: 8 additions & 0 deletions vimode/src/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,3 +219,11 @@ void goto_nonempty(ScintillaObject *sci, gint line, gboolean scroll)
pos = NEXT(sci, pos);
SET_POS(sci, pos, scroll);
}


void ensure_current_line_expanded(ScintillaObject *sci)
{
gint line = GET_CUR_LINE(sci);
if (!SSM(sci, SCI_GETLINEVISIBLE, line, 0))
SSM(sci, SCI_ENSUREVISIBLE, line, 0);
}
1 change: 1 addition & 0 deletions vimode/src/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@ void perform_substitute(ScintillaObject *sci, const gchar *cmd, gint from, gint
const gchar *flag_override);

gint get_line_number_rel(ScintillaObject *sci, gint shift);
void ensure_current_line_expanded(ScintillaObject *sci);

#endif

0 comments on commit 23d0a58

Please sign in to comment.