diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2014-09-28 11:11:07 +0200 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2014-09-28 11:11:07 +0200 |
| commit | ddf8647a5393e049f514a39764aebd8893ce00b9 (patch) | |
| tree | 0539941bd5ce776f89af000e8579ae833b90f8c5 | |
| parent | d954d51a4ce4d6fa13e9312fb72afa0f666a3378 (diff) | |
| download | vis-ddf8647a5393e049f514a39764aebd8893ce00b9.tar.gz vis-ddf8647a5393e049f514a39764aebd8893ce00b9.tar.xz | |
Make '.' repeat last insertion
| -rw-r--r-- | config.def.h | 3 | ||||
| -rw-r--r-- | text.c | 13 | ||||
| -rw-r--r-- | text.h | 2 | ||||
| -rw-r--r-- | vis.c | 10 |
4 files changed, 28 insertions, 0 deletions
diff --git a/config.def.h b/config.def.h index e203446..a10b2ad 100644 --- a/config.def.h +++ b/config.def.h @@ -545,6 +545,9 @@ static void vis_mode_insert_idle(void) { static void vis_mode_insert_input(const char *str, size_t len) { editor_insert_key(vis, str, len); + /* make sure we can repeat the last insert */ + action_reset(&action_prev); + action_prev.op = &ops[OP_REPEAT_INSERT]; } static KeyBinding vis_mode_replace[] = { @@ -110,6 +110,7 @@ struct Text { Buffer *buffers; /* all buffers which have been allocated to hold insertion data */ Piece *pieces; /* all pieces which have been allocated, used to free them */ Piece *cache; /* most recently modified piece */ + Piece *last_insertion; /* most recently inserted piece */ int piece_count; /* number of pieces allocated, only used for debuging purposes */ Piece begin, end; /* sentinel nodes which always exists but don't hold any data */ Action *redo, *undo; /* two stacks holding all actions performed to the file */ @@ -395,6 +396,8 @@ static void piece_free(Piece *p) { p->text->pieces = p->global_next; if (p->text->cache == p) p->text->cache = NULL; + if (p->text->last_insertion == p) + p->text->last_insertion = NULL; free(p); } @@ -555,6 +558,7 @@ bool text_insert(Text *txt, size_t pos, const char *data, size_t len) { span_init(&c->old, p, p); } + txt->last_insertion = new; cache_piece(txt, new); span_swap(txt, &c->old, &c->new); return true; @@ -802,6 +806,15 @@ void text_snapshot(Text *txt) { txt->cache = NULL; } +size_t text_last_insertion(Text *txt, const char **content) { + if (!txt->last_insertion) { + *content = NULL; + return 0; + } + *content = txt->last_insertion->data; + return txt->last_insertion->len; +} + void text_free(Text *txt) { if (!txt) return; @@ -45,6 +45,8 @@ void text_snapshot(Text*); size_t text_undo(Text*); size_t text_redo(Text*); +size_t text_last_insertion(Text*, const char **content); + size_t text_pos_by_lineno(Text*, size_t lineno); size_t text_lineno_by_pos(Text*, size_t pos); @@ -160,6 +160,7 @@ static void op_delete(OperatorContext *c); static void op_shift_right(OperatorContext *c); static void op_shift_left(OperatorContext *c); static void op_case_change(OperatorContext *c); +static void op_repeat_insert(OperatorContext *c); /* these can be passed as int argument to operator(&(const Arg){ .i = OP_*}) */ enum { @@ -170,6 +171,7 @@ enum { OP_SHIFT_RIGHT, OP_SHIFT_LEFT, OP_CASE_CHANGE, + OP_REPEAT_INSERT, }; static Operator ops[] = { @@ -180,6 +182,7 @@ static Operator ops[] = { [OP_SHIFT_RIGHT] = { op_shift_right }, [OP_SHIFT_LEFT] = { op_shift_left }, [OP_CASE_CHANGE] = { op_case_change }, + [OP_REPEAT_INSERT] = { op_repeat_insert }, }; #define PAGE INT_MAX @@ -620,6 +623,13 @@ static void op_case_change(OperatorContext *c) { free(buf); } +static void op_repeat_insert(OperatorContext *c) { + const char *content; + size_t len = text_last_insertion(vis->win->text, &content); + editor_insert(vis, c->pos, content, len); + window_cursor_to(vis->win->win, c->pos + len); +} + /** movement implementations of type: size_t (*move)(const Arg*) */ static char *get_word_under_cursor() { |
