vis
a vi-like editor based on Plan 9's structural regular expressions
git clone https://9o.is/git/vis.git
commit 8d39575e466df80b3af14b8386b8f233bf2c089a parent 2d5aaccb6034492f04a96e510ad16ba90be9f66a Author: Marc André Tanner <mat@brain-dump.org> Date: Thu, 28 Jan 2016 16:30:44 +0100 vis: implement nn% Moves to the given percentage of the file in bytes (not lines). This is useful when dealing with huge files because it is a constant time operation. Performance could still be improved by adapting the display code not to rely on line numbers at all. Diffstat:
| M | config.def.h | | | 2 | +- |
| M | main.c | | | 20 | +++++++++++++++----- |
| M | vis-motions.c | | | 8 | ++++++++ |
| M | vis.h | | | 1 | + |
4 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/config.def.h b/config.def.h @@ -39,7 +39,7 @@ static const KeyBinding bindings_motions[] = { { "^", ACTION(CURSOR_LINE_START) }, { "g_", ACTION(CURSOR_LINE_FINISH) }, { "$", ACTION(CURSOR_LINE_LASTCHAR) }, - { "%", ACTION(CURSOR_BRACKET_MATCH) }, + { "%", ACTION(CURSOR_PERCENT) }, { "b", ACTION(CURSOR_WORD_START_PREV) }, { "B", ACTION(CURSOR_LONGWORD_START_PREV) }, { "w", ACTION(CURSOR_WORD_START_NEXT) }, diff --git a/main.c b/main.c @@ -107,6 +107,8 @@ static const char *call(Vis*, const char *keys, const Arg *arg); static const char *window(Vis*, const char *keys, const Arg *arg); /* show info about Unicode character at cursor position */ static const char *unicode_info(Vis*, const char *keys, const Arg *arg); +/* either go to count % of ile or to matching item */ +static const char *percent(Vis*, const char *keys, const Arg *arg); enum { VIS_ACTION_EDITOR_SUSPEND, @@ -132,7 +134,7 @@ enum { VIS_ACTION_CURSOR_SCREEN_LINE_BEGIN, VIS_ACTION_CURSOR_SCREEN_LINE_MIDDLE, VIS_ACTION_CURSOR_SCREEN_LINE_END, - VIS_ACTION_CURSOR_BRACKET_MATCH, + VIS_ACTION_CURSOR_PERCENT, VIS_ACTION_CURSOR_PARAGRAPH_PREV, VIS_ACTION_CURSOR_PARAGRAPH_NEXT, VIS_ACTION_CURSOR_SENTENCE_PREV, @@ -385,10 +387,10 @@ static KeyAction vis_action[] = { "Move cursor to end of screen/display line", movement, { .i = VIS_MOVE_SCREEN_LINE_END } }, - [VIS_ACTION_CURSOR_BRACKET_MATCH] = { - "cursor-match-bracket", - "Match corresponding symbol if cursor is on a bracket character", - movement, { .i = VIS_MOVE_BRACKET_MATCH } + [VIS_ACTION_CURSOR_PERCENT] = { + "cursor-percent", + "Move to count % of file or matching item", + percent }, [VIS_ACTION_CURSOR_PARAGRAPH_PREV] = { "cursor-paragraph-prev", @@ -1602,6 +1604,14 @@ static const char *unicode_info(Vis *vis, const char *keys, const Arg *arg) { return keys; } +static const char *percent(Vis *vis, const char *keys, const Arg *arg) { + if (vis_count_get(vis) == VIS_COUNT_UNKNOWN) + vis_motion(vis, VIS_MOVE_BRACKET_MATCH); + else + vis_motion(vis, VIS_MOVE_PERCENT); + return keys; +} + static Vis *vis; static void signal_handler(int signum, siginfo_t *siginfo, void *context) { diff --git a/vis-motions.c b/vis-motions.c @@ -194,6 +194,13 @@ static size_t bracket_match(Text *txt, size_t pos) { return pos; } +static size_t percent(Vis *vis, Text *txt, size_t pos) { + int ratio = vis_count_get_default(vis, 0); + if (ratio > 100) + ratio = 100; + return text_size(txt) * ratio / 100; +} + void vis_motion_type(Vis *vis, enum VisMotionType type) { vis->action.type = type; } @@ -342,5 +349,6 @@ Movement vis_motions[] = { [VIS_MOVE_JUMPLIST_NEXT] = { .win = window_jumplist_next, .type = INCLUSIVE }, [VIS_MOVE_JUMPLIST_PREV] = { .win = window_jumplist_prev, .type = INCLUSIVE }, [VIS_MOVE_NOP] = { .win = window_nop, .type = IDEMPOTENT }, + [VIS_MOVE_PERCENT] = { .vis = percent, .type = IDEMPOTENT }, }; diff --git a/vis.h b/vis.h @@ -228,6 +228,7 @@ enum VisMotion { VIS_MOVE_JUMPLIST_NEXT, VIS_MOVE_JUMPLIST_PREV, VIS_MOVE_NOP, + VIS_MOVE_PERCENT, VIS_MOVE_INVALID, /* denotes the end of the "real" motions */ /* pseudo motions: keep them at the end to save space in array definition */ VIS_MOVE_TOTILL_REPEAT,