diff options
| -rw-r--r-- | README.md | 5 | ||||
| -rw-r--r-- | main.c | 55 | ||||
| -rw-r--r-- | vis-core.h | 3 | ||||
| -rw-r--r-- | vis.c | 24 | ||||
| -rw-r--r-- | vis.h | 34 |
5 files changed, 52 insertions, 69 deletions
@@ -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 @@ -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, ¯o); - vis_macro_record(vis, macro); + if (!vis_macro_record_stop(vis)) { + enum VisRegister reg; + keys = key2register(vis, keys, ®); + 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, ¯o); - vis_macro_replay(vis, macro); + enum VisRegister reg; + keys = key2register(vis, keys, ®); + 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, ®); @@ -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 */ @@ -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); @@ -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*); |
