diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2015-01-06 21:28:39 +0100 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2015-01-06 22:15:55 +0100 |
| commit | d3b3e218edcaa950477645a9add92c83cd0543b9 (patch) | |
| tree | 0362222761e8770b241ba4d1ced8dd144bbcfaa9 | |
| parent | 876b8f94649c9ec405375cf687b55a65e2e666ec (diff) | |
| download | vis-d3b3e218edcaa950477645a9add92c83cd0543b9.tar.gz vis-d3b3e218edcaa950477645a9add92c83cd0543b9.tar.xz | |
Rudimentary change list (accessible via g; and g,)
| -rw-r--r-- | README | 5 | ||||
| -rw-r--r-- | config.def.h | 2 | ||||
| -rw-r--r-- | editor.c | 28 | ||||
| -rw-r--r-- | editor.h | 9 | ||||
| -rw-r--r-- | text.c | 12 | ||||
| -rw-r--r-- | text.h | 3 | ||||
| -rw-r--r-- | vis.c | 14 |
7 files changed, 70 insertions, 3 deletions
@@ -480,8 +480,9 @@ and their current support in vis. Jump list and change list ------------------------- - A per window, fixed size, file local jump list is implemented. - The change list is currently not supported. + A per window, file local jump list (navigate with CTRL+O and CTRL+I) + and change list (navigate with g; and g,) is supported. The jump + list is implemented as a fixed sized ring buffer. Mouse support ------------- diff --git a/config.def.h b/config.def.h index 655671f..db41216 100644 --- a/config.def.h +++ b/config.def.h @@ -384,6 +384,8 @@ static KeyBinding vis_mode_normal[] = { { { CONTROL('Y') }, wslide, { .i = +1 } }, { { CONTROL('O') }, jumplist, { .i = -1 } }, { { CONTROL('I') }, jumplist, { .i = +1 } }, + { { NONE('g'), NONE(';') }, changelist, { .i = -1 } }, + { { NONE('g'), NONE(',') }, changelist, { .i = +1 } }, { { NONE('a') }, insertmode, { .i = MOVE_CHAR_NEXT } }, { { NONE('A') }, insertmode, { .i = MOVE_LINE_END } }, { { NONE('C') }, change, { .i = MOVE_LINE_END } }, @@ -172,6 +172,34 @@ void editor_window_jumplist_invalidate(EditorWin *win) { ringbuf_invalidate(win->jumplist); } +size_t editor_window_changelist_prev(EditorWin *win) { + size_t pos = window_cursor_get(win->win); + if (pos != win->changelist.pos) + win->changelist.index = 0; + else + win->changelist.index++; + size_t newpos = text_history_get(win->text, win->changelist.index); + if (newpos == EPOS) + win->changelist.index--; + else + win->changelist.pos = newpos; + return win->changelist.pos; +} + +size_t editor_window_changelist_next(EditorWin *win) { + size_t pos = window_cursor_get(win->win); + if (pos != win->changelist.pos) + win->changelist.index = 0; + else if (win->changelist.index > 0) + win->changelist.index--; + size_t newpos = text_history_get(win->text, win->changelist.index); + if (newpos == EPOS) + win->changelist.index++; + else + win->changelist.pos = newpos; + return win->changelist.pos; +} + void editor_resize(Editor *ed, int width, int height) { ed->width = width; ed->height = height; @@ -13,11 +13,17 @@ typedef struct Editor Editor; typedef struct EditorWin EditorWin; +typedef struct { + size_t index; /* #number of changes */ + size_t pos; /* where the current change occured */ +} ChangeList; + struct EditorWin { Editor *editor; /* editor instance to which this window belongs */ Text *text; /* underlying text management */ Win *win; /* window for the text area */ RingBuffer *jumplist; /* LRU jump management */ + ChangeList changelist; /* state for iterating through least recently changes */ WINDOW *statuswin; /* curses window for the statusbar */ int width, height; /* window size including the statusbar */ EditorWin *prev, *next; /* neighbouring windows */ @@ -158,6 +164,9 @@ void editor_window_jumplist_add(EditorWin*, size_t pos); size_t editor_window_jumplist_prev(EditorWin*); size_t editor_window_jumplist_next(EditorWin*); void editor_window_jumplist_invalidate(EditorWin*); + +size_t editor_window_changelist_prev(EditorWin*); +size_t editor_window_changelist_next(EditorWin*); /* rearrange all windows either vertically or horizontally */ void editor_windows_arrange_vertical(Editor*); void editor_windows_arrange_horizontal(Editor*); @@ -1177,6 +1177,18 @@ void text_mark_intern_clear_all(Text *txt) { text_mark_intern_clear(txt, mark); } +size_t text_history_get(Text *txt, size_t index) { + for (Action *a = txt->current_action ? txt->current_action : txt->undo; a; a = a->next) { + if (index-- == 0) { + Change *c = a->change; + while (c && c->next) + c = c->next; + return c ? c->pos : EPOS; + } + } + return EPOS; +} + int text_fd_get(Text *txt) { return txt->fd; } @@ -83,6 +83,9 @@ size_t text_mark_intern_get(Text*, MarkIntern); void text_mark_intern_clear(Text*, MarkIntern); void text_mark_intern_clear_all(Text*); +/* get position of change denoted by index, where 0 indicates the most recent */ +size_t text_history_get(Text*, size_t index); + size_t text_size(Text*); bool text_modified(Text*); /* test whether the underlying file uses UNIX style \n or Windows style \r\n newlines */ @@ -385,8 +385,10 @@ static TextObject *moves_linewise[] = { }; /** functions to be called from keybindings */ -/* navigate jumplist either in forward (arg->i>0) or backward (arg->i<0) direction */ +/* navigate jump list either in forward (arg->i>0) or backward (arg->i<0) direction */ static void jumplist(const Arg *arg); +/* navigate change list either in forward (arg->i>0) or backward (arg->i<0) direction */ +static void changelist(const Arg *arg); static void macro_record(const Arg *arg); static void macro_replay(const Arg *arg); /* temporarily suspend the editor and return to the shell, type 'fg' to get back */ @@ -810,6 +812,16 @@ static void jumplist(const Arg *arg) { window_cursor_to(vis->win->win, pos); } +static void changelist(const Arg *arg) { + size_t pos; + if (arg->i > 0) + pos = editor_window_changelist_next(vis->win); + else + pos = editor_window_changelist_prev(vis->win); + if (pos != EPOS) + window_cursor_to(vis->win->win, pos); +} + static Macro *key2macro(const Arg *arg) { if (arg->i) return &vis->macros[arg->i]; |
