summaryrefslogtreecommitdiff
path: root/macro.c
blob: d334dd57a4dde5451c55f0683e6a3f61bb828d13 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include "ted-internal.h"

typedef struct MacroAction {
	Command command;
	CommandArgument argument;
} MacroAction;

struct Macro {
	// dynamic array
	MacroAction *actions;
};

static void macro_clear(Macro *macro) {
	arr_foreach_ptr(macro->actions, MacroAction, act) {
		free((char *)act->argument.string);
	}
	arr_free(macro->actions);
	
	memset(macro, 0, sizeof *macro);
}

void macro_start_recording(Ted *ted, u32 index) {
	if (index >= TED_MACRO_MAX) return;
	if (ted->executing_macro) return;
	if (ted->recording_macro) {
		macro_stop_recording(ted);
		return;
	}
	
	command_execute(ted, CMD_CLEAR_SELECTION, 0);
	
	ted->recording_macro = &ted->macros[index];
	macro_clear(ted->recording_macro);
}

void macro_stop_recording(Ted *ted) {
	ted->recording_macro = NULL;
}

void macro_add(Ted *ted, Command command, const CommandArgument *argument) {
	if (!ted->recording_macro) return;
	if (command == CMD_MACRO_EXECUTE || command == CMD_MACRO_RECORD || command == CMD_MACRO_STOP)
		return;
	CommandArgument arg = *argument;
	if (arg.string)
		arg.string = str_dup(arg.string);
	MacroAction action = {
		.command = command,
		.argument = arg
	};
	arr_add(ted->recording_macro->actions, action);
}

void macro_execute(Ted *ted, u32 index) {
	if (index >= TED_MACRO_MAX) return;
	Macro *macro = &ted->macros[index];
	if (ted->recording_macro == macro) {
		// don't allow running a macro while it's being recorded
		return;
	}
	
	ted->executing_macro = true;
	const CommandContext context = {.running_macro = true};
	arr_foreach_ptr(macro->actions, MacroAction, act) {
		command_execute_ex(ted, act->command, &act->argument, &context);
	}
	ted->executing_macro = false;
}

void macros_init(Ted *ted) {
	ted->macros = calloc(TED_MACRO_MAX, sizeof *ted->macros);
}

void macros_free(Ted *ted) {
	for (int i = 0; i < TED_MACRO_MAX; ++i) {
		Macro *macro = &ted->macros[i];
		macro_clear(macro);
	}
	free(ted->macros);
	ted->macros = NULL;
}