aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2016-02-25 16:25:14 +0100
committerMarc André Tanner <mat@brain-dump.org>2016-02-25 17:20:00 +0100
commit95bae46af604f1fda07c8e7b92a278e28792c427 (patch)
tree6efdeab93b78e61171c5a8289cf42659298649dd
parent08d686d991cce58a22b4841010feae0e38dbe3d0 (diff)
downloadvis-95bae46af604f1fda07c8e7b92a278e28792c427.tar.gz
vis-95bae46af604f1fda07c8e7b92a278e28792c427.tar.xz
vis: use standard registers for macro recordings
Also support upper case register to append to an existing macro.
-rw-r--r--README.md5
-rw-r--r--main.c55
-rw-r--r--vis-core.h3
-rw-r--r--vis.c24
-rw-r--r--vis.h34
5 files changed, 52 insertions, 69 deletions
diff --git a/README.md b/README.md
index 8d6a770..6f24dca 100644
--- a/README.md
+++ b/README.md
@@ -256,8 +256,9 @@ Operators can be forced to work line wise by specifying `V`.
### Macros
- `[a-z]` are recognized macro names, `q` starts a recording, `@` plays it back.
- `@@` refers to the least recently recorded macro.
+ The general purpose registers `[a-z]` can be used to record macros. Use
+ one of `[A-Z]` to append to an existing macro. `q` starts a recording,
+ `@` plays it back. `@@` refers to the least recently recorded macro.
### Command line prompt
diff --git a/main.c b/main.c
index 6cd7d18..f3bbc3f 100644
--- a/main.c
+++ b/main.c
@@ -1124,31 +1124,39 @@ static const char *nop(Vis *vis, const char *keys, const Arg *arg) {
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')
- *macro = keys[0] - 'a';
- else if (keys[0] == '@')
- *macro = VIS_MACRO_LAST_RECORDED;
- else if (keys[0] == '\0')
+static const char *key2register(Vis *vis, const char *keys, enum VisRegister *reg) {
+ *reg = VIS_REG_INVALID;
+ if (!keys[0])
return NULL;
+ if ('a' <= keys[0] && keys[0] <= 'z')
+ *reg = keys[0] - 'a';
+ else if ('A' <= keys[0] && keys[0] <= 'Z')
+ *reg = VIS_REG_A + keys[0] - 'A';
+ else if (keys[0] == '*' || keys[0] == '+')
+ *reg = VIS_REG_CLIPBOARD;
+ else if (keys[0] == '_')
+ *reg = VIS_REG_BLACKHOLE;
+ else if (keys[0] == '0')
+ *reg = VIS_REG_ZERO;
+ else if (keys[0] == '@')
+ *reg = VIS_MACRO_LAST_RECORDED;
return keys+1;
}
static const char *macro_record(Vis *vis, const char *keys, const Arg *arg) {
- if (vis_macro_record_stop(vis))
- return keys;
- enum VisMacro macro;
- keys = key2macro(vis, keys, &macro);
- vis_macro_record(vis, macro);
+ if (!vis_macro_record_stop(vis)) {
+ enum VisRegister reg;
+ keys = key2register(vis, keys, &reg);
+ vis_macro_record(vis, reg);
+ }
vis_draw(vis);
return keys;
}
static const char *macro_replay(Vis *vis, const char *keys, const Arg *arg) {
- enum VisMacro macro;
- keys = key2macro(vis, keys, &macro);
- vis_macro_replay(vis, macro);
+ enum VisRegister reg;
+ keys = key2register(vis, keys, &reg);
+ vis_macro_replay(vis, reg);
return keys;
}
@@ -1389,23 +1397,6 @@ static const char *selection_restore(Vis *vis, const char *keys, const Arg *arg)
return keys;
}
-static const char *key2register(Vis *vis, const char *keys, enum VisRegister *reg) {
- *reg = VIS_REG_INVALID;
- if (!keys[0])
- return NULL;
- if (keys[0] >= 'a' && keys[0] <= 'z')
- *reg = keys[0] - 'a';
- else if (keys[0] >= 'A' && keys[0] <= 'Z')
- *reg = VIS_REG_A + keys[0] - 'A';
- else if (keys[0] == '*' || keys[0] == '+')
- *reg = VIS_REG_CLIPBOARD;
- else if (keys[0] == '_')
- *reg = VIS_REG_BLACKHOLE;
- else if (keys[0] == '0')
- *reg = VIS_REG_ZERO;
- return keys+1;
-}
-
static const char *reg(Vis *vis, const char *keys, const Arg *arg) {
enum VisRegister reg;
keys = key2register(vis, keys, &reg);
diff --git a/vis-core.h b/vis-core.h
index 15b4167..fc42a37 100644
--- a/vis-core.h
+++ b/vis-core.h
@@ -142,8 +142,7 @@ struct Vis {
Win *windows; /* all windows currently managed by this editor instance */
Win *win; /* currently active/focused window */
Win *message_window; /* special window to display multi line messages */
- Register registers[VIS_REG_INVALID]; /* registers used for yank and put */
- Macro macros[VIS_MACRO_INVALID]; /* recorded macros */
+ Register registers[VIS_REG_INVALID]; /* registers used for text manipulations yank/put etc. and macros */
Macro *recording, *last_recording; /* currently (if non NULL) and least recently recorded macro */
Macro *macro_operator; /* special macro used to repeat certain operators */
Mode *mode_before_prompt; /* user mode which was active before entering prompt */
diff --git a/vis.c b/vis.c
index 1707dab..7bb5d6a 100644
--- a/vis.c
+++ b/vis.c
@@ -46,7 +46,7 @@
/* enable large file optimization for files larger than: */
#define LARGE_FILE (1 << 25)
-static Macro *macro_get(Vis *vis, enum VisMacro m);
+static Macro *macro_get(Vis *vis, enum VisRegister);
static void macro_replay(Vis *vis, const Macro *macro);
/** window / file handling */
@@ -367,8 +367,6 @@ void vis_free(Vis *vis) {
text_regex_free(vis->search_pattern);
for (int i = 0; i < LENGTH(vis->registers); i++)
register_release(&vis->registers[i]);
- for (int i = 0; i < LENGTH(vis->macros); i++)
- macro_release(&vis->macros[i]);
vis->ui->free(vis->ui);
map_free(vis->cmds);
map_free(vis->options);
@@ -924,11 +922,13 @@ int vis_run(Vis *vis, int argc, char *argv[]) {
return vis->exit_status;
}
-static Macro *macro_get(Vis *vis, enum VisMacro m) {
- if (m == VIS_MACRO_LAST_RECORDED)
+static Macro *macro_get(Vis *vis, enum VisRegister id) {
+ if (id == VIS_MACRO_LAST_RECORDED)
return vis->last_recording;
- if (m < LENGTH(vis->macros))
- return &vis->macros[m];
+ if (VIS_REG_A <= id && id <= VIS_REG_Z)
+ id -= VIS_REG_A;
+ if (id < LENGTH(vis->registers))
+ return &vis->registers[id].buf;
return NULL;
}
@@ -941,11 +941,12 @@ void macro_operator_stop(Vis *vis) {
vis->macro_operator = NULL;
}
-bool vis_macro_record(Vis *vis, enum VisMacro id) {
+bool vis_macro_record(Vis *vis, enum VisRegister id) {
Macro *macro = macro_get(vis, id);
if (vis->recording || !macro)
return false;
- macro_reset(macro);
+ if (!(VIS_REG_A <= id && id <= VIS_REG_Z))
+ macro_reset(macro);
vis->recording = macro;
return true;
}
@@ -972,11 +973,12 @@ static void macro_replay(Vis *vis, const Macro *macro) {
Buffer buf;
buffer_init(&buf);
buffer_put(&buf, macro->data, macro->len);
+ buffer_append(&buf, "\0", 1);
vis_keys_raw(vis, &buf, macro->data);
buffer_release(&buf);
}
-bool vis_macro_replay(Vis *vis, enum VisMacro id) {
+bool vis_macro_replay(Vis *vis, enum VisRegister id) {
Macro *macro = macro_get(vis, id);
if (!macro || macro == vis->recording)
return false;
@@ -1048,7 +1050,7 @@ void vis_register_set(Vis *vis, enum VisRegister reg) {
}
const char *vis_register_get(Vis *vis, enum VisRegister reg, size_t *len) {
- if (reg >= VIS_REG_A && reg <= VIS_REG_Z)
+ if (VIS_REG_A <= reg && reg <= VIS_REG_Z)
reg -= VIS_REG_A;
if (reg < LENGTH(vis->registers))
return register_get(vis, &vis->registers[reg], len);
diff --git a/vis.h b/vis.h
index 614d34a..fad7eca 100644
--- a/vis.h
+++ b/vis.h
@@ -322,28 +322,6 @@ bool vis_textobject(Vis*, enum VisTextObject);
int vis_textobject_register(Vis*, int type, void *data,
Filerange (*textobject)(Vis*, Win*, void*, size_t pos));
-/* macro REPEAT and INVALID should be considered as implementation details (TODO: hide them?) */
-enum VisMacro {
- VIS_MACRO_a, VIS_MACRO_b, VIS_MACRO_c, VIS_MACRO_d, VIS_MACRO_e,
- VIS_MACRO_f, VIS_MACRO_g, VIS_MACRO_h, VIS_MACRO_i, VIS_MACRO_j,
- VIS_MACRO_k, VIS_MACRO_l, VIS_MACRO_m, VIS_MACRO_n, VIS_MACRO_o,
- VIS_MACRO_p, VIS_MACRO_q, VIS_MACRO_r, VIS_MACRO_s, VIS_MACRO_t,
- VIS_MACRO_u, VIS_MACRO_v, VIS_MACRO_w, VIS_MACRO_x, VIS_MACRO_y,
- VIS_MACRO_z,
- VIS_MACRO_OPERATOR, /* records entered keys after an operator */
- VIS_MACRO_REPEAT, /* copy of the above macro once the recording is finished */
- VIS_MACRO_INVALID, /* denotes the end of "real" macros */
- VIS_MACRO_LAST_RECORDED, /* pseudo macro referring to last recorded one */
-};
-
-/* start a macro recording, fails if a recording is already on going */
-bool vis_macro_record(Vis*, enum VisMacro);
-/* stop recording, fails if there is nothing to stop */
-bool vis_macro_record_stop(Vis*);
-/* check whether a recording is currently on going */
-bool vis_macro_recording(Vis*);
-/* replay a macro. a macro currently being recorded can't be replayed */
-bool vis_macro_replay(Vis*, enum VisMacro);
enum VisMark {
VIS_MARK_a, VIS_MARK_b, VIS_MARK_c, VIS_MARK_d, VIS_MARK_e,
@@ -371,6 +349,8 @@ enum VisRegister {
VIS_REG_BLACKHOLE, /* /dev/null register */
VIS_REG_CLIPBOARD, /* system clipboard register */
VIS_REG_PROMPT, /* internal register which shadows DEFAULT in PROMPT mode */
+ VIS_MACRO_OPERATOR, /* records entered keys after an operator */
+ VIS_MACRO_REPEAT, /* copy of the above macro once the recording is finished */
VIS_REG_INVALID, /* has to be the last 'real' register */
VIS_REG_A, VIS_REG_B, VIS_REG_C, VIS_REG_D, VIS_REG_E,
VIS_REG_F, VIS_REG_G, VIS_REG_H, VIS_REG_I, VIS_REG_J,
@@ -378,6 +358,7 @@ enum VisRegister {
VIS_REG_P, VIS_REG_Q, VIS_REG_R, VIS_REG_S, VIS_REG_T,
VIS_REG_U, VIS_REG_V, VIS_REG_W, VIS_REG_X, VIS_REG_Y,
VIS_REG_Z,
+ VIS_MACRO_LAST_RECORDED, /* pseudo macro referring to last recorded one */
};
/* set the register to use, if none is given the DEFAULT register is used */
@@ -385,6 +366,15 @@ void vis_register_set(Vis*, enum VisRegister);
/* get register content */
const char *vis_register_get(Vis*, enum VisRegister, size_t *len);
+/* start a macro recording, fails if a recording is already on going */
+bool vis_macro_record(Vis*, enum VisRegister);
+/* stop recording, fails if there is nothing to stop */
+bool vis_macro_record_stop(Vis*);
+/* check whether a recording is currently on going */
+bool vis_macro_recording(Vis*);
+/* replay a macro. a macro currently being recorded can't be replayed */
+bool vis_macro_replay(Vis*, enum VisRegister);
+
/* repeat last operator, possibly with a new count if one was provided in the meantime */
void vis_repeat(Vis*);