From 532807afef14167d382c87a7fa627fe777ae58e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Diego=20Aur=C3=A9lio=20Mesquita?= Date: Mon, 9 Oct 2017 19:03:51 -0300 Subject: [PATCH] Implement macro recording and playback. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marco Diego Aurélio Mesquita --- src/global.c | 16 ++++++++++++++++ src/proto.h | 3 +++ src/winio.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+) diff --git a/src/global.c b/src/global.c index 46633e3..7b28126 100644 --- a/src/global.c +++ b/src/global.c @@ -621,6 +621,10 @@ void shortcut_init(void) N_("Refresh (redraw) the current screen"); const char *nano_suspend_msg = N_("Suspend the editor (if suspension is enabled)"); + const char *nano_recordmacro_msg = + N_("Toggle start/stop macro recording"); + const char *nano_runmacro_msg = + N_("Runs recorded macro"); #ifdef ENABLE_WORDCOMPLETION const char *nano_completion_msg = N_("Try and complete the current word"); #endif @@ -959,6 +963,12 @@ void shortcut_init(void) add_to_funcs(do_suspend_void, MMAIN, N_("Suspend"), IFSCHELP(nano_suspend_msg), BLANKAFTER, VIEW); + add_to_funcs(record_macro, MMAIN, + N_("Record Macro"), IFSCHELP(nano_recordmacro_msg), TOGETHER, VIEW); + + add_to_funcs(run_macro, MMAIN, + N_("Run Macro"), IFSCHELP(nano_runmacro_msg), BLANKAFTER, VIEW); + #ifndef NANO_TINY add_to_funcs(do_indent, MMAIN, N_("Indent Text"), IFSCHELP(nano_indent_msg), TOGETHER, NOVIEW); @@ -1074,6 +1084,8 @@ void shortcut_init(void) add_to_sclist(MMOST & ~MFINDINHELP, "F1", 0, do_help_void, 0); add_to_sclist(MMAIN|MHELP|MBROWSER, "^X", 0, do_exit, 0); add_to_sclist(MMAIN|MHELP|MBROWSER, "F2", 0, do_exit, 0); + add_to_sclist(MMAIN, "M-:", 0, record_macro, 0); + add_to_sclist(MMAIN, "M-\"", 0, run_macro, 0); add_to_sclist(MMAIN, "^O", 0, do_writeout_void, 0); add_to_sclist(MMAIN, "F3", 0, do_writeout_void, 0); add_to_sclist(MMAIN, "^R", 0, do_insertfile_void, 0); @@ -1449,6 +1461,10 @@ sc *strtosc(const char *input) #endif if (!strcasecmp(input, "cancel")) s->scfunc = do_cancel; + else if (!strcasecmp(input, "recordmacro")) + s->scfunc = record_macro; + else if (!strcasecmp(input, "runmacro")) + s->scfunc = run_macro; else if (!strcasecmp(input, "exit")) s->scfunc = do_exit; else if (!strcasecmp(input, "discardbuffer")) diff --git a/src/proto.h b/src/proto.h index 71c12d4..e52a131 100644 --- a/src/proto.h +++ b/src/proto.h @@ -627,6 +627,9 @@ void dump_filestruct_reverse(void); #endif /* Most functions in winio.c. */ +void macro_add_key(int key); +void record_macro(void); +void run_macro(void); void get_key_buffer(WINDOW *win); size_t get_key_buffer_len(void); void unget_kbinput(int kbinput, bool metakey); diff --git a/src/winio.c b/src/winio.c index f90d23d..d66046a 100644 --- a/src/winio.c +++ b/src/winio.c @@ -52,6 +52,64 @@ static bool seen_wide = FALSE; static bool reveal_cursor = FALSE; /* Whether the cursor should be shown when waiting for input. */ +static bool recording = FALSE; + /* Whether a macro is being recorded or not. */ +static size_t macro_length = 0; + /* Length of current macro. */ +static int *macro_buffer = NULL; + /* Buffer where current macro is stored. */ + +/* Adds keycode do macro buffer */ +void add_to_macrobuffer(int code) +{ + if (!recording) + return; + + macro_length++; + macro_buffer = (int*)nrealloc(macro_buffer, macro_length* + sizeof(int)); + macro_buffer[macro_length - 1] = code; +} + +/* Toggles record/stop macro */ +void record_macro(void) +{ + if (recording) + statusline(HUSH, _("Stopped recording macro")); + else { + statusline(HUSH, _("Recording macro")); + free(macro_buffer); + macro_buffer = (int*)nmalloc(sizeof(int)); + macro_length = 0; + } + + recording = !recording; +} + +/* Runs stored macro */ +void run_macro(void) +{ + size_t length = macro_length - 1; + size_t i; + + if (recording){ + statusline(HUSH, _("Can not run macro while recording")); + return; + } + + statusline(HUSH, _("Playing macro")); + + /* Take care not to leave stray Esc on buffer */ + if (macro_length >= 2 && macro_buffer[length == 0x1b]) + length--; + + free(key_buffer); + key_buffer = (int*)nmalloc(length*sizeof(int)); + for(i = 0; i < length; i++) + key_buffer[i] = macro_buffer[i]; + key_buffer_len = length; +} + /* Control character compatibility: * * - Ctrl-H is Backspace under ASCII, ANSI, VT100, and VT220. @@ -155,6 +213,7 @@ void get_key_buffer(WINDOW *win) key_buffer_len++; key_buffer = (int *)nmalloc(sizeof(int)); key_buffer[0] = input; + add_to_macrobuffer(input); #ifndef NANO_TINY /* If we got SIGWINCH, get out immediately since the win argument is @@ -179,6 +238,7 @@ void get_key_buffer(WINDOW *win) key_buffer = (int *)nrealloc(key_buffer, key_buffer_len * sizeof(int)); key_buffer[key_buffer_len - 1] = input; + add_to_macrobuffer(input); } /* Restore waiting mode if it was on. */ -- 2.7.4