summaryrefslogtreecommitdiff
path: root/command.c
diff options
context:
space:
mode:
Diffstat (limited to 'command.c')
-rw-r--r--command.c60
1 files changed, 45 insertions, 15 deletions
diff --git a/command.c b/command.c
index 0bad2a6..168597a 100644
--- a/command.c
+++ b/command.c
@@ -37,6 +37,7 @@ static CommandName command_names[] = {
{"select-all", CMD_SELECT_ALL},
{"select-up-blank-line", CMD_SELECT_UP_BLANK_LINE},
{"select-down-blank-line", CMD_SELECT_DOWN_BLANK_LINE},
+ {"clear-selection", CMD_CLEAR_SELECTION},
{"page-up", CMD_PAGE_UP},
{"page-down", CMD_PAGE_DOWN},
{"previous-position", CMD_PREVIOUS_POSITION},
@@ -96,6 +97,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 +139,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:
@@ -194,6 +211,9 @@ void command_execute(Ted *ted, Command c, i64 argument) {
if (buffer) buffer_select_left(buffer, argument);
autocomplete_close(ted);
break;
+ case CMD_CLEAR_SELECTION:
+ if (buffer) buffer_deselect(buffer);
+ break;
case CMD_SELECT_RIGHT:
if (buffer) buffer_select_right(buffer, argument);
autocomplete_close(ted);
@@ -267,11 +287,12 @@ void command_execute(Ted *ted, Command c, i64 argument) {
autocomplete_close(ted);
break;
case CMD_PREVIOUS_POSITION:
- buffer_cursor_move_to_prev_pos(buffer);
+ if (buffer)
+ buffer_cursor_move_to_prev_pos(buffer);
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);
}
@@ -597,7 +618,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);
@@ -628,5 +649,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;
}
}