Line data Source code
1 : #include "macro.h" 2 : #include "serialize.h" 3 : #include "util/string-view.h" 4 : 5 8 : static void merge_insert_buffer(CommandMacroState *m) 6 : { 7 8 : size_t len = m->insert_buffer.len; 8 8 : if (len == 0) { 9 6 : return; 10 : } 11 2 : String s = string_new(32 + len); 12 2 : StringView ibuf = strview_from_string(&m->insert_buffer); 13 2 : string_append_literal(&s, "insert -k "); 14 2 : if (unlikely(strview_has_prefix(&ibuf, "-"))) { 15 1 : string_append_literal(&s, "-- "); 16 : } 17 2 : string_append_escaped_arg_sv(&s, ibuf, true); 18 2 : string_clear(&m->insert_buffer); 19 2 : ptr_array_append(&m->macro, string_steal_cstring(&s)); 20 : } 21 : 22 2 : bool macro_record(CommandMacroState *m) 23 : { 24 2 : if (m->recording) { 25 : return false; 26 : } 27 2 : ptr_array_free(&m->prev_macro); 28 2 : m->prev_macro = m->macro; 29 2 : m->macro = (PointerArray) PTR_ARRAY_INIT; 30 2 : m->recording = true; 31 2 : return true; 32 : } 33 : 34 1 : bool macro_stop(CommandMacroState *m) 35 : { 36 1 : if (!m->recording) { 37 : return false; 38 : } 39 1 : merge_insert_buffer(m); 40 1 : m->recording = false; 41 1 : return true; 42 : } 43 : 44 1 : bool macro_cancel(CommandMacroState *m) 45 : { 46 1 : if (!m->recording) { 47 : return false; 48 : } 49 1 : ptr_array_free(&m->macro); 50 1 : m->macro = m->prev_macro; 51 1 : m->prev_macro = (PointerArray) PTR_ARRAY_INIT; 52 1 : m->recording = false; 53 1 : return true; 54 : } 55 : 56 5 : void macro_command_hook(CommandMacroState *m, const char *cmd_name, char **args) 57 : { 58 5 : if (!m->recording) { 59 0 : return; 60 : } 61 5 : String buf = string_new(512); 62 5 : string_append_cstring(&buf, cmd_name); 63 7 : for (size_t i = 0; args[i]; i++) { 64 2 : string_append_byte(&buf, ' '); 65 2 : string_append_escaped_arg(&buf, args[i], true); 66 : } 67 5 : merge_insert_buffer(m); 68 5 : ptr_array_append(&m->macro, string_steal_cstring(&buf)); 69 : } 70 : 71 5 : void macro_insert_char_hook(CommandMacroState *m, CodePoint c) 72 : { 73 5 : if (!m->recording) { 74 : return; 75 : } 76 5 : string_append_codepoint(&m->insert_buffer, c); 77 : } 78 : 79 2 : void macro_insert_text_hook(CommandMacroState *m, const char *text, size_t size) 80 : { 81 2 : if (!m->recording) { 82 0 : return; 83 : } 84 2 : String buf = string_new(512); 85 2 : StringView sv = string_view(text, size); 86 2 : string_append_literal(&buf, "insert -m "); 87 2 : if (unlikely(strview_has_prefix(&sv, "-"))) { 88 1 : string_append_literal(&buf, "-- "); 89 : } 90 2 : string_append_escaped_arg_sv(&buf, sv, true); 91 2 : merge_insert_buffer(m); 92 2 : ptr_array_append(&m->macro, string_steal_cstring(&buf)); 93 : } 94 : 95 1 : String dump_macro(const CommandMacroState *m) 96 : { 97 1 : String buf = string_new(4096); 98 10 : for (size_t i = 0, n = m->macro.count; i < n; i++) { 99 9 : const char *cmd_str = m->macro.ptrs[i]; 100 9 : string_append_cstring(&buf, cmd_str); 101 9 : string_append_byte(&buf, '\n'); 102 : } 103 1 : return buf; 104 : } 105 : 106 3 : void free_macro(CommandMacroState *m) 107 : { 108 3 : string_free(&m->insert_buffer); 109 3 : ptr_array_free(&m->macro); 110 3 : ptr_array_free(&m->prev_macro); 111 3 : m->recording = false; 112 3 : }