diff --git a/4ed.cpp b/4ed.cpp index c54e5b88..58d23a7a 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -264,6 +264,7 @@ App_Init_Sig(app_init){ models->keep_playing = true; models->config_api = api; + models->virtual_event_arena = reserve_arena(tctx); profile_init(&models->profile_list); @@ -351,9 +352,10 @@ App_Init_Sig(app_init){ // NOTE(allen): init baked in buffers File_Init init_files[] = { - { string_u8_litinit("*messages*"), &models->message_buffer, true , }, - { string_u8_litinit("*scratch*") , &models->scratch_buffer, false, }, - { string_u8_litinit("*log*") , &models->log_buffer , true , }, + { string_u8_litinit("*messages*"), &models->message_buffer , true , }, + { string_u8_litinit("*scratch*") , &models->scratch_buffer , false, }, + { string_u8_litinit("*log*") , &models->log_buffer , true , }, + { string_u8_litinit("*keyboard*"), &models->keyboard_buffer, true , }, }; Heap *heap = &models->heap; @@ -608,17 +610,35 @@ App_Step_Sig(app_step){ } } + Temp_Memory_Block temp(scratch); + Input_Event *simulated_input = 0; + Input_Event virtual_event = models_pop_virtual_event(scratch, models); + if (virtual_event.kind != InputEventKind_None){ + simulated_input = &virtual_event; + } + else{ if (input_node == 0){ break; } - input_node_next = input_node->next; + input_node_next = input_node->next; + simulated_input = &input_node->event; + + if (simulated_input->kind == InputEventKind_TextInsert && simulated_input->text.blocked){ + continue; + } + + // NOTE(allen): record to keyboard history + if (simulated_input->kind == InputEventKind_KeyStroke || + simulated_input->kind == InputEventKind_KeyRelease || + simulated_input->kind == InputEventKind_TextInsert){ + Temp_Memory_Block temp_key_line(scratch); + String_Const_u8 key_line = stringize_keyboard_event(scratch, simulated_input); + output_file_append(tctx, models, models->keyboard_buffer, key_line); + } + } b32 event_was_handled = false; - Input_Event *event = &input_node->event; - - if (event->kind == InputEventKind_TextInsert && event->text.blocked){ - continue; - } + Input_Event *event = simulated_input; Panel *active_panel = layout_get_active_panel(layout); View *view = active_panel->view; @@ -707,6 +727,11 @@ App_Step_Sig(app_step){ } } + linalloc_clear(models->virtual_event_arena); + models->free_virtual_event = 0; + models->first_virtual_event = 0; + models->last_virtual_event = 0; + // NOTE(allen): send panel size update if (models->layout.panel_state_dirty){ models->layout.panel_state_dirty = false; diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp index 255b587f..7774a320 100644 --- a/4ed_api_implementation.cpp +++ b/4ed_api_implementation.cpp @@ -60,6 +60,31 @@ models_pop_view_command_function(Models *models){ return(result); } +function void +models_push_virtual_event(Models *models, Input_Event *event){ + Model_Input_Event_Node *node = models->free_virtual_event; + if (node == 0){ + node = push_array(models->virtual_event_arena, Model_Input_Event_Node, 1); + } + else{ + sll_stack_pop(models->free_virtual_event); + } + sll_queue_push(models->first_virtual_event, models->last_virtual_event, node); + node->event = copy_input_event(models->virtual_event_arena, event); +} + +function Input_Event +models_pop_virtual_event(Arena *arena, Models *models){ + Input_Event result = {}; + if (models->first_virtual_event != 0){ + Model_Input_Event_Node *node = models->first_virtual_event; + result = copy_input_event(arena, &node->event); + sll_queue_pop(models->first_virtual_event, models->last_virtual_event); + sll_stack_push(models->free_virtual_event, node); + } + return(result); +} + //////////////////////////////// function b32 @@ -206,6 +231,16 @@ push_clipboard_index(Application_Links *app, Arena *arena, i32 clipboard_id, i32 return(result); } +api(custom) function b32 +enqueue_virtual_event(Application_Links *app, Input_Event *event){ + Models *models = (Models*)app->cmd_context; + b32 result = false; + if (InputEventKind_None < event->kind && event->kind < InputEventKind_COUNT){ + models_push_virtual_event(models, event); + } + return(result); +} + api(custom) function i32 get_buffer_count(Application_Links *app) { diff --git a/4ed_app_models.h b/4ed_app_models.h index fe6e497b..dbc239a1 100644 --- a/4ed_app_models.h +++ b/4ed_app_models.h @@ -40,6 +40,11 @@ struct Model_View_Command_Function{ View_ID view_id; }; +struct Model_Input_Event_Node{ + Model_Input_Event_Node *next; + Input_Event event; +}; + struct Models{ Arena arena_; Arena *arena; @@ -78,6 +83,11 @@ struct Models{ Model_View_Command_Function *first_view_cmd_func; Model_View_Command_Function *last_view_cmd_func; + Arena *virtual_event_arena; + Model_Input_Event_Node *free_virtual_event; + Model_Input_Event_Node *first_virtual_event; + Model_Input_Event_Node *last_virtual_event; + Layout layout; Working_Set working_set; Live_Views view_set; @@ -92,6 +102,7 @@ struct Models{ Editing_File *message_buffer; Editing_File *scratch_buffer; Editing_File *log_buffer; + Editing_File *keyboard_buffer; Hot_Directory hot_directory; diff --git a/4ed_app_target.cpp b/4ed_app_target.cpp index 538547f3..09c60b4c 100644 --- a/4ed_app_target.cpp +++ b/4ed_app_target.cpp @@ -62,9 +62,9 @@ #include "4coder_base_types.cpp" #include "4coder_layout.cpp" -#include "4coder_events.cpp" #include "4coder_string_match.cpp" #include "4coder_stringf.cpp" +#include "4coder_events.cpp" #include "4coder_system_helpers.cpp" #include "4coder_app_links_allocator.cpp" #include "4coder_system_allocator.cpp" diff --git a/custom/4coder_base_types.cpp b/custom/4coder_base_types.cpp index 72be5f71..7edb08a5 100644 --- a/custom/4coder_base_types.cpp +++ b/custom/4coder_base_types.cpp @@ -5299,6 +5299,17 @@ push_string_copy(Arena *arena, umem size, String_Const_Any src){ return(string); } + function String_Const_u8_Array +push_string_array_copy(Arena *arena, String_Const_u8_Array src){ + String_Const_u8_Array result = {}; + result.vals = push_array(arena, String_Const_u8, src.count); + result.count = src.count; + for (i32 i = 0; i < src.count; i += 1){ + result.vals[i] = push_string_copy(arena, src.vals[i]); + } + return(result); +} + function void string_list_push(List_String_Const_char *list, Node_String_Const_char *node){ sll_queue_push(list->first, list->last, node); diff --git a/custom/4coder_clipboard.cpp b/custom/4coder_clipboard.cpp index 0a05cee9..6013937f 100644 --- a/custom/4coder_clipboard.cpp +++ b/custom/4coder_clipboard.cpp @@ -4,7 +4,7 @@ // TOP -static b32 + function b32 clipboard_post_buffer_range(Application_Links *app, i32 clipboard_index, Buffer_ID buffer, Range_i64 range){ b32 success = false; Scratch_Block scratch(app); diff --git a/custom/4coder_default_include.cpp b/custom/4coder_default_include.cpp index a2158c74..90362a5c 100644 --- a/custom/4coder_default_include.cpp +++ b/custom/4coder_default_include.cpp @@ -20,15 +20,9 @@ #include "generated/system_api.h" #include "generated/command_metadata.h" -#include "4coder_base_types.cpp" -#include "4coder_stringf.cpp" -#include "4coder_app_links_allocator.cpp" -#include "4coder_system_allocator.cpp" - #include "4coder_profile.h" #include "4coder_async_tasks.h" #include "4coder_token.h" -#include "generated/lexer_cpp.h" #include "4coder_string_match.h" #include "4coder_helper.h" #include "4coder_delta_rule.h" @@ -55,6 +49,12 @@ //////////////////////////////// +#include "4coder_base_types.cpp" +#include "4coder_stringf.cpp" +#include "4coder_app_links_allocator.cpp" +#include "4coder_system_allocator.cpp" +#include "generated/lexer_cpp.h" + #define DYNAMIC_LINK_API #include "generated/custom_api.cpp" #define DYNAMIC_LINK_API @@ -98,6 +98,7 @@ #include "4coder_jump_lister.cpp" #include "4coder_log_parser.cpp" #include "4coder_clipboard.cpp" +#include "4coder_keyboard_macro.cpp" #include "4coder_cli_command.cpp" #include "4coder_build_commands.cpp" #include "4coder_project_commands.cpp" diff --git a/custom/4coder_events.cpp b/custom/4coder_events.cpp index 343be407..5e17ef29 100644 --- a/custom/4coder_events.cpp +++ b/custom/4coder_events.cpp @@ -36,6 +36,13 @@ copy_modifier_set(Arena *arena, Input_Modifier_Set_Fixed *set){ return(result); } +function void +copy_modifier_set(Input_Modifier_Set_Fixed *dst, Input_Modifier_Set *set){ + i32 count = clamp_top(set->count, ArrayCount(dst->mods)); + dst->count = count; + block_copy(dst->mods, set->mods, count*sizeof(*set->mods)); +} + function void add_modifier(Input_Modifier_Set_Fixed *set, Key_Code mod){ if (!has_modifier(set, mod)){ @@ -267,4 +274,170 @@ push_input_event(Arena *arena, Input_List *list, Input_Event *event){ return(&node->event); } +function Input_Event +copy_input_event(Arena *arena, Input_Event *event){ + Input_Event result = *event; + switch (result.kind){ + case InputEventKind_TextInsert: + { + result.text.string = push_string_copy(arena, event->text.string); + }break; + + case InputEventKind_KeyStroke: + case InputEventKind_KeyRelease: + { + result.key.modifiers = copy_modifier_set(arena, &event->key.modifiers); + }break; + + case InputEventKind_MouseButton: + case InputEventKind_MouseButtonRelease: + { + result.mouse.modifiers = copy_modifier_set(arena, &event->mouse.modifiers); + }break; + + case InputEventKind_MouseWheel: + { + result.mouse_wheel.modifiers = copy_modifier_set(arena, &event->mouse_wheel.modifiers); + }break; + + case InputEventKind_MouseMove: + { + result.mouse_move.modifiers = copy_modifier_set(arena, &event->mouse_move.modifiers); + }break; + + case InputEventKind_Core: + { + switch (result.core.code){ + case CoreCode_Startup: + { + result.core.flag_strings = push_string_array_copy(arena, event->core.flag_strings); + result.core.file_names = push_string_array_copy(arena, event->core.file_names); + }break; + + case CoreCode_FileExternallyModified: + case CoreCode_NewClipboardContents: + { + result.core.string = push_string_copy(arena, event->core.string); + }break; + } + }break; + } + return(result); +} + +//////////////////////////////// + +function String_Const_u8 +stringize_keyboard_event(Arena *arena, Input_Event *event){ + List_String_Const_u8 list = {}; + + switch (event->kind){ + case InputEventKind_TextInsert: + { + string_list_push(arena, &list, string_u8_litexpr("t")); + umem size = event->text.string.size; + u8 *ptr = event->text.string.str; + for (umem i = 0; i < size; i += 1, ptr += 1){ + string_list_pushf(arena, &list, "%02X", (i32)(*ptr)); + } + string_list_push(arena, &list, string_u8_litexpr("\n")); + }break; + + case InputEventKind_KeyStroke: + case InputEventKind_KeyRelease: + { + string_list_pushf(arena, &list, "k%X ", event->key.code); + if (event->kind == InputEventKind_KeyRelease){ + string_list_push(arena, &list, string_u8_litexpr("^")); + } + i32 count = event->key.modifiers.count; + if (count > 0){ + Key_Code *m = event->key.modifiers.mods; + string_list_push(arena, &list, string_u8_litexpr("m{")); + for (i32 i = 0; i < count; i += 1, m += 1){ + string_list_pushf(arena, &list, "%X ", *m); + } + string_list_push(arena, &list, string_u8_litexpr("}")); + } + string_list_push(arena, &list, string_u8_litexpr("\n")); + }break; + } + + return(string_list_flatten(arena, list)); +} + +function Input_Event +parse_keyboard_event(Arena *arena, String_Const_u8 text){ + Input_Event result = {}; + umem pos = 0; + Range_i64 range = {}; + + if (pos < text.size && text.str[pos] == 't'){ + pos += 1; + result.kind = InputEventKind_TextInsert; + + umem max_size = text.size/2; + result.text.string.str = push_array(arena, u8, max_size); + for (; pos + 1 < text.size; pos += 2){ + if (character_is_base16(text.str[pos]) && + character_is_base16(text.str[pos + 1])){ + String_Const_u8 byte_str = {text.str + pos, 2}; + result.text.string.str[result.text.string.size] = (u8)string_to_integer(byte_str, 16); + result.text.string.size += 1; + } + } + } + else if (pos < text.size && text.str[pos] == 'k'){ + pos += 1; + result.kind = InputEventKind_KeyStroke; + + range.first = pos; + for (;pos < text.size && character_is_base16(text.str[pos]); pos += 1); + range.one_past_last = pos; + + if (range.first == range.one_past_last){ + result.kind = InputEventKind_None; + } + else{ + String_Const_u8 code_str = string_substring(text, range); + result.key.code = (u32)string_to_integer(code_str, 16); + + for (;pos < text.size && character_is_whitespace(text.str[pos]); pos += 1); + + if (pos < text.size && text.str[pos] == '^'){ + result.kind = InputEventKind_KeyRelease; + pos += 1; + for (;pos < text.size && character_is_whitespace(text.str[pos]); pos += 1); + } + + if (pos < text.size && text.str[pos] == 'm'){ + pos += 1; + if (pos < text.size && text.str[pos] == '{'){ + pos += 1; + + Input_Modifier_Set_Fixed mods = {}; + for (;mods.count < ArrayCount(mods.mods);){ + for (;pos < text.size && character_is_whitespace(text.str[pos]); pos += 1); + range.first = pos; + for (;pos < text.size && character_is_base16(text.str[pos]); pos += 1); + range.one_past_last = pos; + + if (range.first == range.one_past_last){ + break; + } + + code_str = string_substring(text, range); + mods.mods[mods.count] = (u32)string_to_integer(code_str, 16); + mods.count += 1; + } + + result.key.modifiers = copy_modifier_set(arena, &mods); + } + } + } + } + + return(result); +} + // BOTTOM diff --git a/custom/4coder_events.h b/custom/4coder_events.h index 5c067d01..f18dedeb 100644 --- a/custom/4coder_events.h +++ b/custom/4coder_events.h @@ -16,6 +16,7 @@ typedef u32 Core_Code; typedef u32 Input_Event_Kind; enum{ + InputEventKind_None, InputEventKind_TextInsert, InputEventKind_KeyStroke, InputEventKind_KeyRelease, @@ -25,6 +26,8 @@ enum{ InputEventKind_MouseMove, InputEventKind_Core, InputEventKind_CustomFunction, + + InputEventKind_COUNT, }; global_const i32 Input_MaxModifierCount = 8; diff --git a/custom/4coder_keyboard_macro.cpp b/custom/4coder_keyboard_macro.cpp new file mode 100644 index 00000000..177e43fa --- /dev/null +++ b/custom/4coder_keyboard_macro.cpp @@ -0,0 +1,80 @@ +/* +4coder_keyboard_macro.cpp - Keyboard macro recording and replaying commands. +*/ + +// TOP + +global b32 global_keyboard_macro_is_recording = false; +global Range_i64 global_keyboard_macro_range = {}; + +function Buffer_ID +get_keyboard_log_buffer(Application_Links *app){ + return(get_buffer_by_name(app, string_u8_litexpr("*keyboard*"), Access_Always)); +} + +function void +keyboard_macro_play_single_line(Application_Links *app, String_Const_u8 macro_line){ + Scratch_Block scratch(app); + Input_Event event = parse_keyboard_event(scratch, macro_line); + if (event.kind != InputEventKind_None){ + enqueue_virtual_event(app, &event); + } +} + +function void +keyboard_macro_play(Application_Links *app, String_Const_u8 macro){ + Scratch_Block scratch(app, Scratch_Share); + List_String_Const_u8 lines = string_split(scratch, macro, (u8*)"\n", 1); + for (Node_String_Const_u8 *node = lines.first; + node != 0; + node = node->next){ + String_Const_u8 line = string_skip_chop_whitespace(node->string); + keyboard_macro_play_single_line(app, line); + } +} + +//////////////////////////////// + +CUSTOM_COMMAND_SIG(keyboard_macro_record) +CUSTOM_DOC("Start macro recording or end macro recording if recording is in progress") +{ + Buffer_ID buffer = get_keyboard_log_buffer(app); + if (!global_keyboard_macro_is_recording){ + global_keyboard_macro_is_recording = true; + global_keyboard_macro_range.first = buffer_get_size(app, buffer); + } + else{ + global_keyboard_macro_is_recording = false; + i64 end = buffer_get_size(app, buffer); + Buffer_Cursor cursor = buffer_compute_cursor(app, buffer, seek_pos(end)); + Buffer_Cursor back_cursor = buffer_compute_cursor(app, buffer, seek_line_col(cursor.line - 1, 1)); + global_keyboard_macro_range.one_past_last = back_cursor.pos; + +#if 0 + Scratch_Block scratch(app); + String_Const_u8 macro = push_buffer_range(app, scratch, buffer, global_keyboard_macro_range); + print_message(app, string_u8_litexpr("recorded:\n")); + print_message(app, macro); +#endif + } +} + +CUSTOM_COMMAND_SIG(keyboard_macro_replay) +CUSTOM_DOC("Replay the most recently recorded keyboard macro") +{ + if (global_keyboard_macro_is_recording){ + return; + } + + Buffer_ID buffer = get_keyboard_log_buffer(app); + Scratch_Block scratch(app, Scratch_Share); + String_Const_u8 macro = push_buffer_range(app, scratch, buffer, global_keyboard_macro_range); +#if 0 + print_message(app, string_u8_litexpr("replaying:\n")); + print_message(app, macro); +#endif + keyboard_macro_play(app, macro); +} + +// BOTTOM + diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index c9500260..8bfb4578 100644 --- a/custom/generated/command_metadata.h +++ b/custom/generated/command_metadata.h @@ -2,7 +2,7 @@ #define command_id(c) (fcoder_metacmd_ID_##c) #define command_metadata(c) (&fcoder_metacmd_table[command_id(c)]) #define command_metadata_by_id(id) (&fcoder_metacmd_table[id]) -#define command_one_past_last_id 219 +#define command_one_past_last_id 221 #if defined(CUSTOM_COMMAND_SIG) #define PROC_LINKS(x,y) x #else @@ -173,6 +173,8 @@ CUSTOM_COMMAND_SIG(paste); CUSTOM_COMMAND_SIG(paste_next); CUSTOM_COMMAND_SIG(paste_and_indent); CUSTOM_COMMAND_SIG(paste_next_and_indent); +CUSTOM_COMMAND_SIG(keyboard_macro_record); +CUSTOM_COMMAND_SIG(keyboard_macro_replay); CUSTOM_COMMAND_SIG(execute_previous_cli); CUSTOM_COMMAND_SIG(execute_any_cli); CUSTOM_COMMAND_SIG(build_search); @@ -240,7 +242,7 @@ char *source_name; i32 source_name_len; i32 line_number; }; -static Command_Metadata fcoder_metacmd_table[219] = { +static Command_Metadata fcoder_metacmd_table[221] = { { PROC_LINKS(default_view_input_handler, 0), false, "default_view_input_handler", 26, "Input consumption loop for default view behavior", 48, "w:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 56 }, { PROC_LINKS(profile_enable, 0), false, "profile_enable", 14, "Allow 4coder's self profiler to gather new profiling information.", 65, "w:\\4ed\\code\\custom\\4coder_profile.cpp", 37, 211 }, { PROC_LINKS(profile_disable, 0), false, "profile_disable", 15, "Prevent 4coder's self profiler from gathering new profiling information.", 72, "w:\\4ed\\code\\custom\\4coder_profile.cpp", 37, 218 }, @@ -405,6 +407,8 @@ static Command_Metadata fcoder_metacmd_table[219] = { { PROC_LINKS(paste_next, 0), false, "paste_next", 10, "If the previous command was paste or paste_next, replaces the paste range with the next text down on the clipboard, otherwise operates as the paste command.", 156, "w:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 70 }, { PROC_LINKS(paste_and_indent, 0), false, "paste_and_indent", 16, "Paste from the top of clipboard and run auto-indent on the newly pasted text.", 77, "w:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 108 }, { PROC_LINKS(paste_next_and_indent, 0), false, "paste_next_and_indent", 21, "Paste the next item on the clipboard and run auto-indent on the newly pasted text.", 82, "w:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 115 }, +{ PROC_LINKS(keyboard_macro_record, 0), false, "keyboard_macro_record", 21, "Start macro recording or end macro recording if recording is in progress", 72, "w:\\4ed\\code\\custom\\4coder_keyboard_macro.cpp", 44, 38 }, +{ PROC_LINKS(keyboard_macro_replay, 0), false, "keyboard_macro_replay", 21, "Replay the most recently recorded keyboard macro", 48, "w:\\4ed\\code\\custom\\4coder_keyboard_macro.cpp", 44, 62 }, { PROC_LINKS(execute_previous_cli, 0), false, "execute_previous_cli", 20, "If the command execute_any_cli has already been used, this will execute a CLI reusing the most recent buffer name and command.", 126, "w:\\4ed\\code\\custom\\4coder_cli_command.cpp", 41, 7 }, { PROC_LINKS(execute_any_cli, 0), false, "execute_any_cli", 15, "Queries for an output buffer name and system command, runs the system command as a CLI and prints the output to the specified buffer.", 133, "w:\\4ed\\code\\custom\\4coder_cli_command.cpp", 41, 22 }, { PROC_LINKS(build_search, 0), false, "build_search", 12, "Looks for a build.bat, build.sh, or makefile in the current and parent directories. Runs the first that it finds and prints the output to *compilation*.", 153, "w:\\4ed\\code\\custom\\4coder_build_commands.cpp", 44, 128 }, @@ -625,59 +629,61 @@ static i32 fcoder_metacmd_ID_paste = 160; static i32 fcoder_metacmd_ID_paste_next = 161; static i32 fcoder_metacmd_ID_paste_and_indent = 162; static i32 fcoder_metacmd_ID_paste_next_and_indent = 163; -static i32 fcoder_metacmd_ID_execute_previous_cli = 164; -static i32 fcoder_metacmd_ID_execute_any_cli = 165; -static i32 fcoder_metacmd_ID_build_search = 166; -static i32 fcoder_metacmd_ID_build_in_build_panel = 167; -static i32 fcoder_metacmd_ID_close_build_panel = 168; -static i32 fcoder_metacmd_ID_change_to_build_panel = 169; -static i32 fcoder_metacmd_ID_close_all_code = 170; -static i32 fcoder_metacmd_ID_open_all_code = 171; -static i32 fcoder_metacmd_ID_open_all_code_recursive = 172; -static i32 fcoder_metacmd_ID_load_project = 173; -static i32 fcoder_metacmd_ID_project_fkey_command = 174; -static i32 fcoder_metacmd_ID_project_go_to_root_directory = 175; -static i32 fcoder_metacmd_ID_setup_new_project = 176; -static i32 fcoder_metacmd_ID_setup_build_bat = 177; -static i32 fcoder_metacmd_ID_setup_build_sh = 178; -static i32 fcoder_metacmd_ID_setup_build_bat_and_sh = 179; -static i32 fcoder_metacmd_ID_project_command_lister = 180; -static i32 fcoder_metacmd_ID_list_all_functions_current_buffer = 181; -static i32 fcoder_metacmd_ID_list_all_functions_current_buffer_lister = 182; -static i32 fcoder_metacmd_ID_list_all_functions_all_buffers = 183; -static i32 fcoder_metacmd_ID_list_all_functions_all_buffers_lister = 184; -static i32 fcoder_metacmd_ID_select_surrounding_scope = 185; -static i32 fcoder_metacmd_ID_select_surrounding_scope_maximal = 186; -static i32 fcoder_metacmd_ID_select_next_scope_absolute = 187; -static i32 fcoder_metacmd_ID_select_next_scope_after_current = 188; -static i32 fcoder_metacmd_ID_select_prev_scope_absolute = 189; -static i32 fcoder_metacmd_ID_select_prev_top_most_scope = 190; -static i32 fcoder_metacmd_ID_place_in_scope = 191; -static i32 fcoder_metacmd_ID_delete_current_scope = 192; -static i32 fcoder_metacmd_ID_open_long_braces = 193; -static i32 fcoder_metacmd_ID_open_long_braces_semicolon = 194; -static i32 fcoder_metacmd_ID_open_long_braces_break = 195; -static i32 fcoder_metacmd_ID_if0_off = 196; -static i32 fcoder_metacmd_ID_write_todo = 197; -static i32 fcoder_metacmd_ID_write_hack = 198; -static i32 fcoder_metacmd_ID_write_note = 199; -static i32 fcoder_metacmd_ID_write_block = 200; -static i32 fcoder_metacmd_ID_write_zero_struct = 201; -static i32 fcoder_metacmd_ID_comment_line = 202; -static i32 fcoder_metacmd_ID_uncomment_line = 203; -static i32 fcoder_metacmd_ID_comment_line_toggle = 204; -static i32 fcoder_metacmd_ID_snippet_lister = 205; -static i32 fcoder_metacmd_ID_miblo_increment_basic = 206; -static i32 fcoder_metacmd_ID_miblo_decrement_basic = 207; -static i32 fcoder_metacmd_ID_miblo_increment_time_stamp = 208; -static i32 fcoder_metacmd_ID_miblo_decrement_time_stamp = 209; -static i32 fcoder_metacmd_ID_miblo_increment_time_stamp_minute = 210; -static i32 fcoder_metacmd_ID_miblo_decrement_time_stamp_minute = 211; -static i32 fcoder_metacmd_ID_profile_inspect = 212; -static i32 fcoder_metacmd_ID_kill_tutorial = 213; -static i32 fcoder_metacmd_ID_tutorial_maximize = 214; -static i32 fcoder_metacmd_ID_tutorial_minimize = 215; -static i32 fcoder_metacmd_ID_hms_demo_tutorial = 216; -static i32 fcoder_metacmd_ID_default_startup = 217; -static i32 fcoder_metacmd_ID_default_try_exit = 218; +static i32 fcoder_metacmd_ID_keyboard_macro_record = 164; +static i32 fcoder_metacmd_ID_keyboard_macro_replay = 165; +static i32 fcoder_metacmd_ID_execute_previous_cli = 166; +static i32 fcoder_metacmd_ID_execute_any_cli = 167; +static i32 fcoder_metacmd_ID_build_search = 168; +static i32 fcoder_metacmd_ID_build_in_build_panel = 169; +static i32 fcoder_metacmd_ID_close_build_panel = 170; +static i32 fcoder_metacmd_ID_change_to_build_panel = 171; +static i32 fcoder_metacmd_ID_close_all_code = 172; +static i32 fcoder_metacmd_ID_open_all_code = 173; +static i32 fcoder_metacmd_ID_open_all_code_recursive = 174; +static i32 fcoder_metacmd_ID_load_project = 175; +static i32 fcoder_metacmd_ID_project_fkey_command = 176; +static i32 fcoder_metacmd_ID_project_go_to_root_directory = 177; +static i32 fcoder_metacmd_ID_setup_new_project = 178; +static i32 fcoder_metacmd_ID_setup_build_bat = 179; +static i32 fcoder_metacmd_ID_setup_build_sh = 180; +static i32 fcoder_metacmd_ID_setup_build_bat_and_sh = 181; +static i32 fcoder_metacmd_ID_project_command_lister = 182; +static i32 fcoder_metacmd_ID_list_all_functions_current_buffer = 183; +static i32 fcoder_metacmd_ID_list_all_functions_current_buffer_lister = 184; +static i32 fcoder_metacmd_ID_list_all_functions_all_buffers = 185; +static i32 fcoder_metacmd_ID_list_all_functions_all_buffers_lister = 186; +static i32 fcoder_metacmd_ID_select_surrounding_scope = 187; +static i32 fcoder_metacmd_ID_select_surrounding_scope_maximal = 188; +static i32 fcoder_metacmd_ID_select_next_scope_absolute = 189; +static i32 fcoder_metacmd_ID_select_next_scope_after_current = 190; +static i32 fcoder_metacmd_ID_select_prev_scope_absolute = 191; +static i32 fcoder_metacmd_ID_select_prev_top_most_scope = 192; +static i32 fcoder_metacmd_ID_place_in_scope = 193; +static i32 fcoder_metacmd_ID_delete_current_scope = 194; +static i32 fcoder_metacmd_ID_open_long_braces = 195; +static i32 fcoder_metacmd_ID_open_long_braces_semicolon = 196; +static i32 fcoder_metacmd_ID_open_long_braces_break = 197; +static i32 fcoder_metacmd_ID_if0_off = 198; +static i32 fcoder_metacmd_ID_write_todo = 199; +static i32 fcoder_metacmd_ID_write_hack = 200; +static i32 fcoder_metacmd_ID_write_note = 201; +static i32 fcoder_metacmd_ID_write_block = 202; +static i32 fcoder_metacmd_ID_write_zero_struct = 203; +static i32 fcoder_metacmd_ID_comment_line = 204; +static i32 fcoder_metacmd_ID_uncomment_line = 205; +static i32 fcoder_metacmd_ID_comment_line_toggle = 206; +static i32 fcoder_metacmd_ID_snippet_lister = 207; +static i32 fcoder_metacmd_ID_miblo_increment_basic = 208; +static i32 fcoder_metacmd_ID_miblo_decrement_basic = 209; +static i32 fcoder_metacmd_ID_miblo_increment_time_stamp = 210; +static i32 fcoder_metacmd_ID_miblo_decrement_time_stamp = 211; +static i32 fcoder_metacmd_ID_miblo_increment_time_stamp_minute = 212; +static i32 fcoder_metacmd_ID_miblo_decrement_time_stamp_minute = 213; +static i32 fcoder_metacmd_ID_profile_inspect = 214; +static i32 fcoder_metacmd_ID_kill_tutorial = 215; +static i32 fcoder_metacmd_ID_tutorial_maximize = 216; +static i32 fcoder_metacmd_ID_tutorial_minimize = 217; +static i32 fcoder_metacmd_ID_hms_demo_tutorial = 218; +static i32 fcoder_metacmd_ID_default_startup = 219; +static i32 fcoder_metacmd_ID_default_try_exit = 220; #endif diff --git a/custom/generated/custom_api.cpp b/custom/generated/custom_api.cpp index 6eaa5205..9f2d4720 100644 --- a/custom/generated/custom_api.cpp +++ b/custom/generated/custom_api.cpp @@ -11,6 +11,7 @@ vtable->child_process_get_state = child_process_get_state; vtable->clipboard_post = clipboard_post; vtable->clipboard_count = clipboard_count; vtable->push_clipboard_index = push_clipboard_index; +vtable->enqueue_virtual_event = enqueue_virtual_event; vtable->get_buffer_count = get_buffer_count; vtable->get_buffer_next = get_buffer_next; vtable->get_buffer_by_name = get_buffer_by_name; @@ -194,6 +195,7 @@ child_process_get_state = vtable->child_process_get_state; clipboard_post = vtable->clipboard_post; clipboard_count = vtable->clipboard_count; push_clipboard_index = vtable->push_clipboard_index; +enqueue_virtual_event = vtable->enqueue_virtual_event; get_buffer_count = vtable->get_buffer_count; get_buffer_next = vtable->get_buffer_next; get_buffer_by_name = vtable->get_buffer_by_name; diff --git a/custom/generated/custom_api.h b/custom/generated/custom_api.h index 48265760..fb040bd8 100644 --- a/custom/generated/custom_api.h +++ b/custom/generated/custom_api.h @@ -9,6 +9,7 @@ #define custom_clipboard_post_sig() b32 custom_clipboard_post(Application_Links* app, i32 clipboard_id, String_Const_u8 string) #define custom_clipboard_count_sig() i32 custom_clipboard_count(Application_Links* app, i32 clipboard_id) #define custom_push_clipboard_index_sig() String_Const_u8 custom_push_clipboard_index(Application_Links* app, Arena* arena, i32 clipboard_id, i32 item_index) +#define custom_enqueue_virtual_event_sig() b32 custom_enqueue_virtual_event(Application_Links* app, Input_Event* event) #define custom_get_buffer_count_sig() i32 custom_get_buffer_count(Application_Links* app) #define custom_get_buffer_next_sig() Buffer_ID custom_get_buffer_next(Application_Links* app, Buffer_ID buffer_id, Access_Flag access) #define custom_get_buffer_by_name_sig() Buffer_ID custom_get_buffer_by_name(Application_Links* app, String_Const_u8 name, Access_Flag access) @@ -188,6 +189,7 @@ typedef Process_State custom_child_process_get_state_type(Application_Links* app typedef b32 custom_clipboard_post_type(Application_Links* app, i32 clipboard_id, String_Const_u8 string); typedef i32 custom_clipboard_count_type(Application_Links* app, i32 clipboard_id); typedef String_Const_u8 custom_push_clipboard_index_type(Application_Links* app, Arena* arena, i32 clipboard_id, i32 item_index); +typedef b32 custom_enqueue_virtual_event_type(Application_Links* app, Input_Event* event); typedef i32 custom_get_buffer_count_type(Application_Links* app); typedef Buffer_ID custom_get_buffer_next_type(Application_Links* app, Buffer_ID buffer_id, Access_Flag access); typedef Buffer_ID custom_get_buffer_by_name_type(Application_Links* app, String_Const_u8 name, Access_Flag access); @@ -368,6 +370,7 @@ custom_child_process_get_state_type *child_process_get_state; custom_clipboard_post_type *clipboard_post; custom_clipboard_count_type *clipboard_count; custom_push_clipboard_index_type *push_clipboard_index; +custom_enqueue_virtual_event_type *enqueue_virtual_event; custom_get_buffer_count_type *get_buffer_count; custom_get_buffer_next_type *get_buffer_next; custom_get_buffer_by_name_type *get_buffer_by_name; @@ -549,6 +552,7 @@ internal Process_State child_process_get_state(Application_Links* app, Child_Pro internal b32 clipboard_post(Application_Links* app, i32 clipboard_id, String_Const_u8 string); internal i32 clipboard_count(Application_Links* app, i32 clipboard_id); internal String_Const_u8 push_clipboard_index(Application_Links* app, Arena* arena, i32 clipboard_id, i32 item_index); +internal b32 enqueue_virtual_event(Application_Links* app, Input_Event* event); internal i32 get_buffer_count(Application_Links* app); internal Buffer_ID get_buffer_next(Application_Links* app, Buffer_ID buffer_id, Access_Flag access); internal Buffer_ID get_buffer_by_name(Application_Links* app, String_Const_u8 name, Access_Flag access); @@ -730,6 +734,7 @@ global custom_child_process_get_state_type *child_process_get_state = 0; global custom_clipboard_post_type *clipboard_post = 0; global custom_clipboard_count_type *clipboard_count = 0; global custom_push_clipboard_index_type *push_clipboard_index = 0; +global custom_enqueue_virtual_event_type *enqueue_virtual_event = 0; global custom_get_buffer_count_type *get_buffer_count = 0; global custom_get_buffer_next_type *get_buffer_next = 0; global custom_get_buffer_by_name_type *get_buffer_by_name = 0; diff --git a/custom/generated/custom_api_master_list.h b/custom/generated/custom_api_master_list.h index fb6ab146..17b0d636 100644 --- a/custom/generated/custom_api_master_list.h +++ b/custom/generated/custom_api_master_list.h @@ -9,6 +9,7 @@ api(custom) function Process_State child_process_get_state(Application_Links* ap api(custom) function b32 clipboard_post(Application_Links* app, i32 clipboard_id, String_Const_u8 string); api(custom) function i32 clipboard_count(Application_Links* app, i32 clipboard_id); api(custom) function String_Const_u8 push_clipboard_index(Application_Links* app, Arena* arena, i32 clipboard_id, i32 item_index); +api(custom) function b32 enqueue_virtual_event(Application_Links* app, Input_Event* event); api(custom) function i32 get_buffer_count(Application_Links* app); api(custom) function Buffer_ID get_buffer_next(Application_Links* app, Buffer_ID buffer_id, Access_Flag access); api(custom) function Buffer_ID get_buffer_by_name(Application_Links* app, String_Const_u8 name, Access_Flag access); diff --git a/custom/generated/remapping.h b/custom/generated/remapping.h index b4a40d21..2200da15 100644 --- a/custom/generated/remapping.h +++ b/custom/generated/remapping.h @@ -12,6 +12,8 @@ setup_default_mapping(Mapping *mapping){ SelectMap(mapid_global); BindCore(default_startup , CoreCode_Startup); BindCore(default_try_exit, CoreCode_TryExit); + Bind(keyboard_macro_record, KeyCode_U, KeyCode_Control); + Bind(keyboard_macro_replay, KeyCode_U, KeyCode_Alt); Bind(change_active_panel, KeyCode_Comma, KeyCode_Control); Bind(change_active_panel_backwards, KeyCode_Comma, KeyCode_Control, KeyCode_Shift); Bind(interactive_new, KeyCode_N, KeyCode_Control);