aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2015-10-25 20:49:01 +0100
committerMarc André Tanner <mat@brain-dump.org>2015-10-25 22:46:43 +0100
commit34fa064edcf06d03c16c8a20dde9365d9957523e (patch)
tree91c3e4370a7121ad0b99c76528625f7ceeca3c65
parentfbb9265b95ab46824b7bc01621a01eb6a2362000 (diff)
downloadvis-34fa064edcf06d03c16c8a20dde9365d9957523e.tar.gz
vis-34fa064edcf06d03c16c8a20dde9365d9957523e.tar.xz
vis: convert changelist navigation to proper motions
-rw-r--r--config.def.h4
-rw-r--r--editor.c28
-rw-r--r--editor.h5
-rw-r--r--vis.c61
-rw-r--r--vis.h2
5 files changed, 52 insertions, 48 deletions
diff --git a/config.def.h b/config.def.h
index 84f49c5..9fa178e 100644
--- a/config.def.h
+++ b/config.def.h
@@ -479,12 +479,12 @@ static KeyAction vis_action[] = {
[VIS_ACTION_CHANGELIST_PREV] = {
"changelist-prev",
"Go to older cursor position in change list",
- changelist, { .i = -1 }
+ movement, { .i = MOVE_CHANGELIST_PREV }
},
[VIS_ACTION_CHANGELIST_NEXT] = {
"changelist-next",
"Go to newer cursor position in change list",
- changelist, { .i = +1 }
+ movement, { .i = MOVE_CHANGELIST_NEXT }
},
[VIS_ACTION_UNDO] = {
"editor-undo",
diff --git a/editor.c b/editor.c
index 3b1f104..e66d929 100644
--- a/editor.c
+++ b/editor.c
@@ -107,34 +107,6 @@ void editor_window_jumplist_invalidate(Win *win) {
ringbuf_invalidate(win->jumplist);
}
-size_t editor_window_changelist_prev(Win *win) {
- size_t pos = view_cursor_get(win->view);
- if (pos != win->changelist.pos)
- win->changelist.index = 0;
- else
- win->changelist.index++;
- size_t newpos = text_history_get(win->file->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(Win *win) {
- size_t pos = view_cursor_get(win->view);
- 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->file->text, win->changelist.index);
- if (newpos == EPOS)
- win->changelist.index++;
- else
- win->changelist.pos = newpos;
- return win->changelist.pos;
-}
-
void editor_resize(Editor *ed) {
ed->ui->resize(ed->ui);
}
diff --git a/editor.h b/editor.h
index 098b7fa..2f8b841 100644
--- a/editor.h
+++ b/editor.h
@@ -85,11 +85,13 @@ typedef struct {
} Operator;
typedef struct {
+ /* TODO: merge types / use union to save space */
size_t (*cur)(Cursor*); /* a movement based on current window content from view.h */
size_t (*txt)(Text*, size_t pos); /* a movement form text-motions.h */
size_t (*file)(Vis*, File*, size_t pos);
size_t (*vis)(Vis*, Text*, size_t pos);
size_t (*view)(Vis*, View*);
+ size_t (*win)(Vis*, Win*, size_t pos);
enum {
LINEWISE = 1 << 0,
CHARWISE = 1 << 1,
@@ -211,6 +213,7 @@ struct File {
};
typedef struct {
+ time_t state; /* state of the text, used to invalidate change list */
size_t index; /* #number of changes */
size_t pos; /* where the current change occured */
} ChangeList;
@@ -318,8 +321,6 @@ size_t editor_window_jumplist_prev(Win*);
size_t editor_window_jumplist_next(Win*);
void editor_window_jumplist_invalidate(Win*);
-size_t editor_window_changelist_prev(Win*);
-size_t editor_window_changelist_next(Win*);
/* rearrange all windows either vertically or horizontally */
void editor_windows_arrange(Editor*, enum UiLayout);
/* display a user prompt with a certain title and default text */
diff --git a/vis.c b/vis.c
index e61dd5b..4b29b87 100644
--- a/vis.c
+++ b/vis.c
@@ -110,6 +110,9 @@ static size_t view_lines_top(Vis*, View*);
static size_t view_lines_middle(Vis*, View*);
/* goto the action.count-th line from bottom of the focused window */
static size_t view_lines_bottom(Vis*, View*);
+/* navigate the change list */
+static size_t window_changelist_next(Vis*, Win*, size_t pos);
+static size_t window_changelist_prev(Vis*, Win*, size_t pos);
static Movement moves[] = {
[MOVE_LINE_UP] = { .cur = view_line_up, .type = LINEWISE },
@@ -164,6 +167,8 @@ static Movement moves[] = {
[MOVE_WINDOW_LINE_TOP] = { .view = view_lines_top, .type = LINEWISE|JUMP|IDEMPOTENT },
[MOVE_WINDOW_LINE_MIDDLE] = { .view = view_lines_middle, .type = LINEWISE|JUMP|IDEMPOTENT },
[MOVE_WINDOW_LINE_BOTTOM] = { .view = view_lines_bottom, .type = LINEWISE|JUMP|IDEMPOTENT },
+ [MOVE_CHANGELIST_NEXT] = { .win = window_changelist_next, .type = INCLUSIVE },
+ [MOVE_CHANGELIST_PREV] = { .win = window_changelist_prev, .type = INCLUSIVE },
};
static TextObject textobjs[] = {
@@ -200,8 +205,6 @@ static TextObject textobjs[] = {
static const char *nop(Vis*, const char *keys, const Arg *arg);
/* navigate jump list either in forward (arg->i>0) or backward (arg->i<0) direction */
static const char *jumplist(Vis*, const char *keys, const Arg *arg);
-/* navigate change list either in forward (arg->i>0) or backward (arg->i<0) direction */
-static const char *changelist(Vis*, const char *keys, const Arg *arg);
static const char *macro_record(Vis*, const char *keys, const Arg *arg);
static const char *macro_replay(Vis*, const char *keys, const Arg *arg);
/* temporarily suspend the editor and return to the shell, type 'fg' to get back */
@@ -665,6 +668,40 @@ static size_t view_lines_bottom(Vis *vis, View *view) {
return view_screenline_goto(vis->win->view, h - vis->action.count);
}
+static size_t window_changelist_next(Vis *vis, Win *win, size_t pos) {
+ ChangeList *cl = &win->changelist;
+ Text *txt = win->file->text;
+ time_t state = text_state(txt);
+ if (cl->state != state)
+ cl->index = 0;
+ else if (cl->index > 0 && pos == cl->pos)
+ cl->index--;
+ size_t newpos = text_history_get(txt, cl->index);
+ if (newpos == EPOS)
+ cl->index++;
+ else
+ cl->pos = newpos;
+ cl->state = state;
+ return cl->pos;
+}
+
+static size_t window_changelist_prev(Vis *vis, Win *win, size_t pos) {
+ ChangeList *cl = &win->changelist;
+ Text *txt = win->file->text;
+ time_t state = text_state(txt);
+ if (cl->state != state)
+ cl->index = 0;
+ else if (pos == cl->pos)
+ win->changelist.index++;
+ size_t newpos = text_history_get(txt, cl->index);
+ if (newpos == EPOS)
+ cl->index--;
+ else
+ cl->pos = newpos;
+ cl->state = state;
+ return cl->pos;
+}
+
/** key bindings functions */
static const char *nop(Vis *vis, const char *keys, const Arg *arg) {
@@ -682,17 +719,6 @@ static const char *jumplist(Vis *vis, const char *keys, const Arg *arg) {
return keys;
}
-static const char *changelist(Vis *vis, const char *keys, 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)
- view_cursor_to(vis->win->view, pos);
- return keys;
-}
-
static const char *key2macro(Vis *vis, const char *keys, enum VisMacro *macro) {
*macro = VIS_MACRO_INVALID;
if (keys[0] >= 'a' && keys[0] <= 'z')
@@ -1267,8 +1293,9 @@ static const char *switchmode(Vis *vis, const char *keys, const Arg *arg) {
/** action processing: execut the operator / movement / text object */
static void action_do(Vis *vis, Action *a) {
- Text *txt = vis->win->file->text;
- View *view = vis->win->view;
+ Win *win = vis->win;
+ Text *txt = win->file->text;
+ View *view = win->view;
if (a->count < 1)
a->count = 1;
bool multiple_cursors = view_cursors_count(view) > 1;
@@ -1304,8 +1331,10 @@ static void action_do(Vis *vis, Action *a) {
pos = a->movement->file(vis, vis->win->file, pos);
else if (a->movement->vis)
pos = a->movement->vis(vis, txt, pos);
- else
+ else if (a->movement->view)
pos = a->movement->view(vis, view);
+ else if (a->movement->win)
+ pos = a->movement->win(vis, win, pos);
if (pos == EPOS || a->movement->type & IDEMPOTENT)
break;
}
diff --git a/vis.h b/vis.h
index 9cd8b70..baa0190 100644
--- a/vis.h
+++ b/vis.h
@@ -99,6 +99,8 @@ enum VisMotion {
MOVE_WINDOW_LINE_TOP,
MOVE_WINDOW_LINE_MIDDLE,
MOVE_WINDOW_LINE_BOTTOM,
+ MOVE_CHANGELIST_NEXT,
+ MOVE_CHANGELIST_PREV,
/* pseudo motions: keep them at the end to save space in array definition */
MOVE_TOTILL_REPEAT,
MOVE_TOTILL_REVERSE,