summaryrefslogtreecommitdiff
path: root/command.c
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2023-03-23 13:55:50 -0400
committerpommicket <pommicket@gmail.com>2023-03-23 13:55:50 -0400
commiteb088ebd059ba00735723fb394d3bfe1b3530026 (patch)
treed7bfedce0a1f859ba89525afe1ae6a1afce427ae /command.c
parent63f54d13aa7233986f784ef857faef259a889ed6 (diff)
get rid of ARG_STRING, start macros
Diffstat (limited to 'command.c')
-rw-r--r--command.c53
1 files changed, 39 insertions, 14 deletions
diff --git a/command.c b/command.c
index a384050..59166ec 100644
--- a/command.c
+++ b/command.c
@@ -96,6 +96,9 @@ static CommandName command_names[] = {
{"split-switch", CMD_SPLIT_SWITCH},
{"split-swap", CMD_SPLIT_SWAP},
{"escape", CMD_ESCAPE},
+ {"macro-record", CMD_MACRO_RECORD},
+ {"macro-stop", CMD_MACRO_STOP},
+ {"macro-execute", CMD_MACRO_EXECUTE},
};
static_assert_if_possible(arr_count(command_names) == CMD_COUNT)
@@ -135,23 +138,36 @@ const char *command_to_str(Command c) {
return "???";
}
-// get the string corresponding to this argument; returns NULL if it's not a string argument
-static const char *arg_get_string(Ted *ted, i64 argument) {
- if (argument < 0) return NULL;
- if (argument & ARG_STRING) {
- argument -= ARG_STRING;
- if (argument < ted->nstrings)
- return ted->strings[argument];
- }
- return NULL;
+void command_execute(Ted *ted, Command c, i64 argument) {
+ CommandArgument arg = {
+ .number = argument,
+ .string = NULL,
+ };
+ command_execute_ex(ted, c, arg, (CommandContext){0});
}
-void command_execute(Ted *ted, Command c, i64 argument) {
+void command_execute_ex(Ted *ted, Command c, CommandArgument full_argument, CommandContext context) {
TextBuffer *buffer = ted->active_buffer;
Node *node = ted->active_node;
Settings *settings = ted_active_settings(ted);
-
-
+ if (ted->recording_macro)
+ macro_add(ted, c, full_argument);
+ i64 argument = full_argument.number;
+ const char *argument_str = full_argument.string;
+ /*
+ it's important that when we're playing back a macro,
+ we only execute commands specifically from the macro.
+ for example, suppose the user opens the find menu and searches for "apple".
+ this might generate the macro:
+ open_find_menu()
+ insert_text("apple")
+ newline()
+ find_next("apple") // (generated by find.c)
+ if we ran these commands as-is, we'd end up searching for "apple" twice!
+ */
+ if (ted->executing_macro && !context.from_macro)
+ return;
+
switch (c) {
case CMD_UNKNOWN:
case CMD_COUNT:
@@ -272,7 +288,7 @@ void command_execute(Ted *ted, Command c, i64 argument) {
break;
case CMD_INSERT_TEXT: {
- const char *str = arg_get_string(ted, argument);
+ const char *str = argument_str;
if (str) {
buffer_insert_utf8_at_cursor(buffer, str);
}
@@ -598,7 +614,7 @@ void command_execute(Ted *ted, Command c, i64 argument) {
build_prev_error(ted);
break;
case CMD_SHELL: {
- const char *str = arg_get_string(ted, argument);
+ const char *str = argument_str;
if (str) {
strbuf_cpy(ted->build_dir, ted->cwd);
build_start_with_command(ted, str);
@@ -629,5 +645,14 @@ void command_execute(Ted *ted, Command c, i64 argument) {
case CMD_SPLIT_SWAP:
if (node) node_split_swap(ted);
break;
+ case CMD_MACRO_RECORD:
+ macro_start_recording(ted, (u32)argument);
+ break;
+ case CMD_MACRO_STOP:
+ macro_stop_recording(ted);
+ break;
+ case CMD_MACRO_EXECUTE:
+ macro_execute(ted, (u32)argument);
+ break;
}
}