Skip to content

Commit

Permalink
Fix motion problems with line wrapping
Browse files Browse the repository at this point in the history
  • Loading branch information
techee committed May 8, 2024
1 parent aeaaf3a commit fa7025b
Showing 1 changed file with 39 additions and 21 deletions.
60 changes: 39 additions & 21 deletions vimode/src/cmds/motion.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,39 @@ void cmd_goto_right(CmdContext *c, CmdParams *p)
}


static gint doc_line_from_visible_delta(CmdParams *p, gint line, gint delta)
static gint doc_line_from_visible_delta(CmdParams *p, gint line, gint delta, gboolean *overflow)
{
gint visible_line = SSM(p->sci, SCI_VISIBLEFROMDOCLINE, line, 0);
gint visible_lines = SSM(p->sci, SCI_VISIBLEFROMDOCLINE, p->line_num, 0);
gint new_visible_line = visible_line + delta;
gboolean oflow = FALSE;
gint new_line = line;
gint i = 0;

new_visible_line = new_visible_line < 0 ? 0 : new_visible_line;
new_visible_line = new_visible_line > visible_lines ? visible_lines : new_visible_line;
return SSM(p->sci, SCI_DOCLINEFROMVISIBLE, new_visible_line, 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 @@ -65,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 = doc_line_from_visible_delta(p, 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 @@ -82,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 = doc_line_from_visible_delta(p, 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 All @@ -109,7 +127,7 @@ void cmd_goto_up_nonempty(CmdContext *c, CmdParams *p)

static void goto_down(CmdParams *p, gint num)
{
gint one_above = doc_line_from_visible_delta(p, p->line, p->num - 1);
gint one_above = doc_line_from_visible_delta(p, p->line, p->num - 1, NULL);
gint 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 @@ -140,39 +158,39 @@ 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 = doc_line_from_visible_delta(p, p->line, -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 = doc_line_from_visible_delta(p, p->line, 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 = doc_line_from_visible_delta(p, p->line, -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 = doc_line_from_visible_delta(p, p->line, 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;
num = doc_line_from_visible_delta(p, num, -1);
num = doc_line_from_visible_delta(p, num, -1, NULL);
goto_nonempty(p->sci, num, TRUE);
}

Expand All @@ -182,7 +200,7 @@ 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;
num = doc_line_from_visible_delta(p, num, -1);
num = doc_line_from_visible_delta(p, num, -1, NULL);
goto_nonempty(p->sci, num, TRUE);
}

Expand All @@ -192,20 +210,20 @@ void cmd_goto_screen_top(CmdContext *c, CmdParams *p)
gint line;
gint top = p->line_visible_first;
gint count = p->line_visible_num;
gint max = doc_line_from_visible_delta(p, top, count);
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);
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)
{
gint num = doc_line_from_visible_delta(p, p->line_visible_first, p->line_visible_num / 2);
gint num = doc_line_from_visible_delta(p, p->line_visible_first, p->line_visible_num / 2, NULL);
goto_nonempty(p->sci, num, FALSE);
}

Expand All @@ -214,7 +232,7 @@ void cmd_goto_screen_bottom(CmdContext *c, CmdParams *p)
{
gint top = p->line_visible_first;
gint count = p->line_visible_num;
gint line = doc_line_from_visible_delta(p, 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

0 comments on commit fa7025b

Please sign in to comment.