Skip to content

Commit 3f64704

Browse files
committed
Speed up G motion.
It was implemented as a repeated j from the top of the file, which was slow for files with many lines.
1 parent 2eceda3 commit 3f64704

1 file changed

Lines changed: 10 additions & 7 deletions

File tree

motion.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ static struct motion motion_table[] = {
389389
{'W', next_WORD_start, EXCLUSIVE},
390390
{'e', next_word_end, INCLUSIVE},
391391
{'E', next_WORD_end, INCLUSIVE},
392-
{'G', down, LINEWISE}, // See motion_apply...
392+
{'G', NULL, LINEWISE}, // See motion_apply...
393393
{'t', till_forward_exclusive, INCLUSIVE},
394394
{'f', till_forward_inclusive, INCLUSIVE},
395395
{'T', till_backward_exclusive, INCLUSIVE},
@@ -431,18 +431,21 @@ struct motion *motion_get(struct editor *editor, struct tb_event *ev) {
431431
}
432432

433433
size_t motion_apply(struct motion *motion, struct editor *editor) {
434-
unsigned int n = editor->count ? editor->count : 1;
435-
436434
size_t cursor = window_cursor(editor->window);
437435
struct motion_context ctx = {cursor, editor->window, editor};
438436

439-
size_t nlines = gb_nlines(editor->window->buffer->text);
440-
// TODO(isbadawi): This is a hack to make G work correctly.
437+
// For G, don't repeatedly apply a motion; jump directly to the target line.
441438
if (motion->name == 'G') {
442-
n = (editor->count ? editor->count : (unsigned int) nlines) - 1;
443-
ctx.pos = buffer_top(ctx);
439+
struct gapbuf *gb = editor->window->buffer->text;
440+
int line = gb_nlines(gb) - 1;
441+
if (editor->count) {
442+
line = min((int)editor->count - 1, line);
443+
}
444+
editor->count = 0;
445+
return gb_linecol_to_pos(gb, line, 0);
444446
}
445447

448+
unsigned int n = editor->count ? editor->count : 1;
446449
for (unsigned int i = 0; i < n; ++i) {
447450
ctx.pos = motion->op(ctx);
448451
}

0 commit comments

Comments
 (0)