aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2014-09-08 21:58:50 +0200
committerMarc André Tanner <mat@brain-dump.org>2014-09-08 21:58:50 +0200
commitee3ded959f5486e921e45ac6753b21c2fcd63f0f (patch)
tree69bbccd4f7babce44dad355ac0dcc1573e9fa895
parente7b6ac1574ba4dad280e6a45beb52dac4e3ea2e9 (diff)
downloadvis-ee3ded959f5486e921e45ac6753b21c2fcd63f0f.tar.gz
vis-ee3ded959f5486e921e45ac6753b21c2fcd63f0f.tar.xz
Improve undo/redo
Currently a snapshot is taken whenever an operator is completed or a certain idle time in either insert or replace mode is detected.
-rw-r--r--config.def.h25
-rw-r--r--main.c8
-rw-r--r--vis.c18
-rw-r--r--vis.h3
4 files changed, 27 insertions, 27 deletions
diff --git a/config.def.h b/config.def.h
index 3b5437e..6ab2286 100644
--- a/config.def.h
+++ b/config.def.h
@@ -288,6 +288,10 @@ static void split(const Arg *arg) {
void action_do(Action *a);
void action_reset(Action *a);
+static void snapshot(void) {
+ text_snapshot(vis->win->text);
+}
+
static void repeat(const Arg *arg) {
action = action_prev;
action_do(&action);
@@ -457,6 +461,7 @@ void action_do(Action *a) {
switchmode_to(mode_prev);
else if (mode == &vis_modes[VIS_MODE_VISUAL])
switchmode(&(const Arg){ .i = VIS_MODE_NORMAL });
+ snapshot();
}
if (a != &action_prev) {
@@ -466,6 +471,16 @@ void action_do(Action *a) {
}
}
+static void undo(const Arg *arg) {
+ if (text_undo(vis->win->text))
+ vis_draw(vis);
+}
+
+static void redo(const Arg *arg) {
+ if (text_redo(vis->win->text))
+ vis_draw(vis);
+}
+
static void zero(const Arg *arg) {
if (action.count == 0)
movement(&(const Arg){ .i = MOVE_LINE_BEGIN });
@@ -698,8 +713,8 @@ static KeyBinding vis_normal[] = {
{ { NONE('i') }, switchmode, { .i = VIS_MODE_INSERT } },
{ { NONE('v') }, switchmode, { .i = VIS_MODE_VISUAL } },
{ { NONE('R') }, switchmode, { .i = VIS_MODE_REPLACE} },
- { { NONE('u') }, call, { .f = vis_undo } },
- { { CONTROL('R') }, call, { .f = vis_redo } },
+ { { NONE('u') }, undo, { NULL } },
+ { { CONTROL('R') }, redo, { NULL } },
{ { CONTROL('L') }, call, { .f = vis_draw } },
{ { NONE(':') }, prompt, { .s = ":" } },
{ /* empty last element, array terminator */ },
@@ -862,12 +877,14 @@ static Mode vis_modes[] = {
.parent = &vis_modes[VIS_MODE_READLINE],
.bindings = vis_insert_mode,
.input = vis_insert_input,
+ .idle = snapshot,
},
[VIS_MODE_REPLACE] = {
.name = "REPLACE",
.parent = &vis_modes[VIS_MODE_INSERT],
.bindings = vis_replace,
.input = vis_replace_input,
+ .idle = snapshot,
},
};
@@ -939,8 +956,8 @@ static KeyBinding nano_keys[] = {
{ { META('|') }, movement, { .i = MOVE_FILE_BEGIN } },
{ { META('/') }, movement, { .i = MOVE_FILE_END } },
{ { META('?') }, movement, { .i = MOVE_FILE_END } },
- { { META('U') }, call, { .f = vis_undo } },
- { { META('E') }, call, { .f = vis_redo } },
+ { { META('U') }, undo, { NULL } },
+ { { META('E') }, redo, { NULL } },
#if 0
{ { CONTROL('I') }, insert, { .s = "\t" } },
/* TODO: handle this in vis to insert \n\r when appriopriate */
diff --git a/main.c b/main.c
index 7078f44..28b72c5 100644
--- a/main.c
+++ b/main.c
@@ -47,6 +47,7 @@ struct Mode {
void (*leave)(Mode *new);
bool (*unknown)(Key *key0, Key *key1); /* unknown key for this mode, return value determines whether parent modes will be checked */
bool (*input)(const char *str, size_t len); /* unknown key for this an all parent modes */
+ void (*idle)(void);
};
typedef struct {
@@ -263,7 +264,8 @@ int main(int argc, char *argv[]) {
}
if (!FD_ISSET(STDIN_FILENO, &fds)) {
- vis_snapshot(vis);
+ if (mode->idle)
+ mode->idle();
timeout = NULL;
continue;
}
@@ -291,7 +293,9 @@ int main(int argc, char *argv[]) {
if (key.code)
continue;
- if (mode->input && mode->input(key.str, strlen(key.str)))
+ if (mode->input)
+ mode->input(key.str, strlen(key.str));
+ if (mode->idle)
timeout = &idle;
}
diff --git a/vis.c b/vis.c
index ec5bf6d..8af9134 100644
--- a/vis.c
+++ b/vis.c
@@ -51,24 +51,6 @@ void vis_statusbar_set(Vis *vis, vis_statusbar_t statusbar) {
vis->statusbar = statusbar;
}
-void vis_snapshot(Vis *vis) {
- text_snapshot(vis->win->text);
-}
-
-void vis_undo(Vis *vis) {
- VisWin *win = vis->win;
- // TODO window invalidation
- if (text_undo(win->text))
- window_draw(win->win);
-}
-
-void vis_redo(Vis *vis) {
- VisWin *win = vis->win;
- // TODO window invalidation
- if (text_redo(win->text))
- window_draw(win->win);
-}
-
static void vis_windows_arrange_horizontal(Vis *vis) {
int n = 0, x = 0, y = 0;
for (VisWin *win = vis->windows; win; win = win->next)
diff --git a/vis.h b/vis.h
index 3fc9dad..b7272b4 100644
--- a/vis.h
+++ b/vis.h
@@ -88,9 +88,6 @@ struct Syntax { /* a syntax definition */
Vis *vis_new(int width, int height);
void vis_free(Vis*);
void vis_resize(Vis*, int width, int height);
-void vis_snapshot(Vis*);
-void vis_undo(Vis*);
-void vis_redo(Vis*);
void vis_draw(Vis*);
void vis_update(Vis*);
void vis_insert_key(Vis*, const char *c, size_t len);