Skip to content

Commit bd777c7

Browse files
committed
add cmd_print_macro intended for saving macros
1 parent 58f29e4 commit bd777c7

File tree

4 files changed

+61
-17
lines changed

4 files changed

+61
-17
lines changed

cmd.c

+22-1
Original file line numberDiff line numberDiff line change
@@ -1024,7 +1024,7 @@ int cmd_apply_macro(cmd_context_t *ctx) {
10241024
return MLE_OK;
10251025
}
10261026

1027-
// Apply a macro
1027+
// Apply the last applied macro
10281028
int cmd_apply_macro_last(cmd_context_t *ctx) {
10291029
kmacro_t *macro;
10301030
if (!ctx->editor->macro_last) return MLE_OK;
@@ -1034,6 +1034,27 @@ int cmd_apply_macro_last(cmd_context_t *ctx) {
10341034
return MLE_OK;
10351035
}
10361036

1037+
// Apply the last applied macro
1038+
int cmd_print_macro(cmd_context_t *ctx) {
1039+
char *name;
1040+
kmacro_t *macro;
1041+
size_t i;
1042+
char key[MLE_MAX_KEYNAME_LEN + 1];
1043+
editor_prompt(ctx->editor, "print_macro: Name?", NULL, &name);
1044+
if (!name) return MLE_OK;
1045+
HASH_FIND_STR(ctx->editor->macro_map, name, macro);
1046+
free(name);
1047+
if (!macro) MLE_RETURN_ERR(ctx->editor, "Macro not found%s", "");
1048+
for (i = 0; i < macro->inputs_len; i++) {
1049+
editor_input_to_key(&macro->inputs[i], key);
1050+
MLE_FOREACH_CURSOR(ctx->cursor) {
1051+
mark_insert_before(cursor->mark, key, strlen(key));
1052+
mark_insert_before(cursor->mark, " ", 1);
1053+
}
1054+
}
1055+
return MLE_OK;
1056+
}
1057+
10371058
// No-op
10381059
int cmd_noop(cmd_context_t *ctx) {
10391060
(void)ctx;

editor.c

+29-15
Original file line numberDiff line numberDiff line change
@@ -1090,6 +1090,18 @@ int editor_force_redraw(editor_t *editor) {
10901090
return MLE_OK;
10911091
}
10921092

1093+
// Return a key name given a kinput. `keyname` must be allocated to at least
1094+
// `MLE_MAX_KEYNAME_LEN + 1`. Return `MLE_ERR` if `input` doesn't represent a
1095+
// valid input.
1096+
int editor_input_to_key(kinput_t *input, char *keyname) {
1097+
struct tb_event ev;
1098+
memset(&ev, 0, sizeof(ev));
1099+
ev.mod = input->mod;
1100+
ev.ch = input->ch;
1101+
ev.key = input->key;
1102+
return _editor_event_to_key(&ev, keyname);
1103+
}
1104+
10931105
// If input == editor->macro_toggle_key, toggle macro mode and return 1. Else
10941106
// return 0.
10951107
static int _editor_maybe_toggle_macro(editor_t *editor, kinput_t *input) {
@@ -1595,34 +1607,34 @@ static int _editor_key_to_input(char *key, kinput_t *ret_input) {
15951607
// Return a key name given a key event
15961608
static int _editor_event_to_key(struct tb_event *ev, char *ret_keyname) {
15971609
char key[MLE_MAX_KEYNAME_LEN + 1];
1610+
memset(key, 0, sizeof(key));
1611+
15981612
#define MLE_KEY_DEF(pkname, pmodmin, pmodadd, pch, pkey) \
15991613
} else if ( \
16001614
(((pch) && ev->ch == (pch)) \
16011615
|| (!(pch) && ev->key == (pkey))) \
16021616
&& (((pmodmin) & ev->mod) == (pmodmin)) \
16031617
) { \
1604-
if ((pmodadd)) ev->mod &= ~(pmodadd); \
1605-
sprintf(key, (pkname));
1618+
snprintf(key, sizeof(key), (pkname));
16061619
if (0) {
16071620
return MLE_ERR;
16081621
#include "keys.h"
1609-
} else {
1610-
memset(key, 0, sizeof(key));
1622+
} else if (ev->ch <= 0x10ffff && !(ev->ch >= 0xd800 && ev->ch <= 0xdfff)) {
1623+
if (ev->ch == 0) return MLE_ERR; // TODO: Support null-char input?
16111624
tb_utf8_unicode_to_char(key, ev->ch);
1625+
} else {
1626+
return MLE_ERR; // No match for key and ch is not a valid codepoint
16121627
}
16131628
#undef MLE_KEY_DEF
1614-
if (ev->mod & TB_MOD_CTRL) {
1615-
*ret_keyname++ = 'C';
1616-
}
1617-
if (ev->mod & TB_MOD_ALT) {
1618-
*ret_keyname++ = 'M';
1619-
}
1620-
if (ev->mod & TB_MOD_SHIFT) {
1621-
*ret_keyname++ = 'S';
1622-
}
1623-
if (ev->mod & TB_MOD_CTRL || ev->mod & TB_MOD_ALT || ev->mod & TB_MOD_SHIFT) {
1629+
1630+
if (ev->mod & TB_MOD_CTRL) *ret_keyname++ = 'C';
1631+
if (ev->mod & TB_MOD_ALT) *ret_keyname++ = 'M';
1632+
if (ev->mod & TB_MOD_SHIFT) *ret_keyname++ = 'S';
1633+
1634+
if (ev->mod & (TB_MOD_CTRL | TB_MOD_ALT | TB_MOD_SHIFT)) {
16241635
*ret_keyname++ = '-';
16251636
}
1637+
16261638
sprintf(ret_keyname, "%s", key);
16271639
return MLE_OK;
16281640
}
@@ -1736,15 +1748,16 @@ static void _editor_register_cmds(editor_t *editor) {
17361748
_editor_register_cmd_fn(editor, "cmd_perl", cmd_perl);
17371749
_editor_register_cmd_fn(editor, "cmd_pop_kmap", cmd_pop_kmap);
17381750
_editor_register_cmd_fn(editor, "cmd_prev", cmd_prev);
1751+
_editor_register_cmd_fn(editor, "cmd_print_macro", cmd_print_macro);
17391752
_editor_register_cmd_fn(editor, "cmd_push_kmap", cmd_push_kmap);
17401753
_editor_register_cmd_fn(editor, "cmd_quit", cmd_quit);
17411754
_editor_register_cmd_fn(editor, "cmd_quit_without_saving", cmd_quit_without_saving);
17421755
_editor_register_cmd_fn(editor, "cmd_redo", cmd_redo);
17431756
_editor_register_cmd_fn(editor, "cmd_redraw", cmd_redraw);
17441757
_editor_register_cmd_fn(editor, "cmd_remove_extra_cursors", cmd_remove_extra_cursors);
17451758
_editor_register_cmd_fn(editor, "cmd_repeat", cmd_repeat);
1746-
_editor_register_cmd_fn(editor, "cmd_replace", cmd_replace);
17471759
_editor_register_cmd_fn(editor, "cmd_replace_all", cmd_replace_all);
1760+
_editor_register_cmd_fn(editor, "cmd_replace", cmd_replace);
17481761
_editor_register_cmd_fn(editor, "cmd_rfind_word", cmd_rfind_word);
17491762
_editor_register_cmd_fn(editor, "cmd_rsearch", cmd_rsearch);
17501763
_editor_register_cmd_fn(editor, "cmd_save_as", cmd_save_as);
@@ -1896,6 +1909,7 @@ static void _editor_init_kmaps(editor_t *editor) {
18961909
MLE_KBINDING_DEF("cmd_apply_macro", "M-Z"),
18971910
MLE_KBINDING_DEF("cmd_apply_macro_by", "M-M **"),
18981911
MLE_KBINDING_DEF("cmd_apply_macro_last", "f6"),
1912+
MLE_KBINDING_DEF("cmd_print_macro", "M-<"),
18991913
MLE_KBINDING_DEF("cmd_next", "M-n"),
19001914
MLE_KBINDING_DEF("cmd_prev", "M-p"),
19011915
MLE_KBINDING_DEF("cmd_last", "M-0"),

mle.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,7 @@ int editor_display(editor_t *editor);
439439
int editor_debug_dump(editor_t *editor, FILE *fp);
440440
int editor_force_redraw(editor_t *editor);
441441
int editor_set_input_mode(editor_t *editor);
442+
int editor_input_to_key(kinput_t *input, char *keyname);
442443

443444
// bview functions
444445
bview_t *bview_get_split_root(bview_t *self);
@@ -558,15 +559,16 @@ int cmd_outdent(cmd_context_t *ctx);
558559
int cmd_perl(cmd_context_t *ctx);
559560
int cmd_pop_kmap(cmd_context_t *ctx);
560561
int cmd_prev(cmd_context_t *ctx);
562+
int cmd_print_macro(cmd_context_t *ctx);
561563
int cmd_push_kmap(cmd_context_t *ctx);
562564
int cmd_quit(cmd_context_t *ctx);
563565
int cmd_quit_without_saving(cmd_context_t *ctx);
564566
int cmd_redo(cmd_context_t *ctx);
565567
int cmd_redraw(cmd_context_t *ctx);
566568
int cmd_remove_extra_cursors(cmd_context_t *ctx);
567569
int cmd_repeat(cmd_context_t *ctx);
568-
int cmd_replace(cmd_context_t *ctx);
569570
int cmd_replace_all(cmd_context_t *ctx);
571+
int cmd_replace(cmd_context_t *ctx);
570572
int cmd_rfind_word(cmd_context_t *ctx);
571573
int cmd_rsearch(cmd_context_t *ctx);
572574
int cmd_save_as(cmd_context_t *ctx);

tests/func/test_macro.sh

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/usr/bin/env bash
2+
3+
extra_opts=(-M 'printable a A S-a M-a M-A MS-a C-a CS-a CM-a CMS-a enter comma tab f1' )
4+
macro='M-< p r i n t a b l e enter'
5+
declare -A expected
6+
expected[printed_macro]='^a A S-a M-a M-A MS-a C-a CS-a CM-a CMS-a C-enter comma C-tab f1 $'
7+
source 'test.sh'

0 commit comments

Comments
 (0)