-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path4coder_dynamic_bindings.cpp
More file actions
143 lines (115 loc) · 6.25 KB
/
4coder_dynamic_bindings.cpp
File metadata and controls
143 lines (115 loc) · 6.25 KB
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*
4coder_dynamic_bindings.cpp - Dynamic Bindings
*/
// TOP
function Key_Code
dynamic_binding_key_code_from_string(String_Const_u8 key_string){
Key_Code result = 0;
for (i32 i = 1; i < KeyCode_COUNT; i += 1){
String_Const_u8 str = SCu8(key_code_name[i]);
if (string_match(str, key_string)){
result = i;
break;
}
}
return result;
}
function b32
dynamic_binding_load_from_file(Application_Links *app, Mapping *mapping, String_Const_u8 filename){
b32 result = false;
Scratch_Block scratch(app);
String_Const_u8 filename_copied = push_string_copy(scratch, filename);
String8List search_list = {};
def_search_normal_load_list(scratch, &search_list);
String_Const_u8 full_path = def_search_get_full_path(scratch, &search_list, filename_copied);
{
String8 message = push_stringf(scratch, "loading bindings: %.*s\n",
string_expand(full_path));
print_message(app, message);
}
FILE *file = 0;
if (full_path.size > 0){
file = fopen((char*)full_path.str, "rb");
}
if (file != 0){
String_Const_u8 data = dump_file_handle(scratch, file);
Config *parsed = def_config_from_text(app, scratch, filename, data);
fclose(file);
if (parsed != 0){
result = true;
Thread_Context* tctx = get_thread_context(app);
mapping_release(tctx, mapping);
mapping_init(tctx, mapping);
MappingScope();
SelectMapping(mapping);
for (Config_Assignment *assignment = parsed->first;
assignment != 0;
assignment = assignment->next){
Config_LValue *l = assignment->l;
if (l != 0 && l->index == 0){
Config_Get_Result rvalue = config_evaluate_rvalue(parsed, assignment, assignment->r);
if (rvalue.type == ConfigRValueType_Compound){
String_Const_u8 map_name = l->identifier;
String_ID map_name_id = vars_save_string(map_name);
SelectMap(map_name_id);
Config_Compound *compound = rvalue.compound;
Config_Get_Result_List list = typed_compound_array_reference_list(scratch, parsed, compound);
for (Config_Get_Result_Node *node = list.first; node != 0; node = node->next){
Config_Compound *src = node->result.compound;
String_Const_u8 cmd_string = {0};
String_Const_u8 key_string = {0};
String_Const_u8 mod_string[9] = {0};
if (!config_compound_string_member(parsed, src, "cmd", 0, &cmd_string)){
def_config_push_error(scratch, parsed, node->result.pos, "Command string is required in binding");
goto finish_map;
}
if (!config_compound_string_member(parsed, src, "key", 1, &key_string)){
def_config_push_error(scratch, parsed, node->result.pos, "Key string is required in binding");
goto finish_map;
}
for (i32 mod_idx = 0; mod_idx < ArrayCount(mod_string); mod_idx += 1){
String_Const_u8 str = push_stringf(scratch, "mod_%i", mod_idx);
if (config_compound_string_member(parsed, src, str, 2 + mod_idx, &mod_string[mod_idx])){
// NOTE(rjf): No-Op
}
}
// NOTE(rjf): Map read in successfully.
{
// NOTE(rjf): Find command.
Command_Metadata *command = get_command_metadata_from_name(cmd_string);
// NOTE(rjf): Find keycode.
Key_Code keycode = dynamic_binding_key_code_from_string(key_string);
// NOTE(rjf): Find mods.
i32 mod_count = 0;
Key_Code mods[ArrayCount(mod_string)] = {0};
for (i32 i = 0; i < ArrayCount(mod_string); i += 1){
if (mod_string[i].str){
mods[mod_count] = dynamic_binding_key_code_from_string(mod_string[i]);
mod_count += 1;
}
}
if (keycode != 0 && command != 0){
Input_Modifier_Set mods_set = { mods, mod_count, };
map_set_binding(mapping, map, command->proc, InputEventKind_KeyStroke, keycode, &mods_set);
}
else{
def_config_push_error(scratch, parsed, node->result.pos,
(keycode != 0) ? (char*)"Invalid command" :
(command != 0) ? (char*)"Invalid key":
(char*)"Invalid command and key");
}
}
finish_map:;
}
if (parsed->errors.first != 0){
String_Const_u8 error_text = config_stringize_errors(app, scratch, parsed);
print_message(app, error_text);
}
}
}
}
}
}
return(result);
}
// BOTTOM