[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Nano-devel] [PATCH v5] new feature: the ability to record and play back
From: |
Benno Schulenberg |
Subject: |
[Nano-devel] [PATCH v5] new feature: the ability to record and play back a series of keystrokes |
Date: |
Tue, 10 Oct 2017 20:46:55 +0200 |
From: Marco Diego Aurélio Mesquita <address@hidden>
Allow the user to record and run a single macro. The default binding
for starting and stopping the recording is M-' (Alt + single quote)
and for running the macro M-; (Alt + semicolon).
This fulfills https://savannah.gnu.org/bugs/?50314.
Requested-by: Peter Passchier <address@hidden>
Signed-off-by: Marco Diego Aurélio Mesquita <address@hidden>
Signed-off-by: Benno Schulenberg <address@hidden>
---
src/global.c | 13 ++++++++++++
src/proto.h | 2 ++
src/winio.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 80 insertions(+)
diff --git a/src/global.c b/src/global.c
index 46633e38..a854aa23 100644
--- a/src/global.c
+++ b/src/global.c
@@ -632,6 +632,8 @@ void shortcut_init(void)
const char *nano_savefile_msg = N_("Save file without prompting");
const char *nano_findprev_msg = N_("Search next occurrence backward");
const char *nano_findnext_msg = N_("Search next occurrence forward");
+ const char *nano_recordmacro_msg = N_("Start/stop recording a macro");
+ const char *nano_runmacro_msg = N_("Run the last recorded macro");
#endif
const char *nano_case_msg =
N_("Toggle the case sensitivity of the search");
@@ -960,6 +962,11 @@ void shortcut_init(void)
N_("Suspend"), IFSCHELP(nano_suspend_msg), BLANKAFTER, VIEW);
#ifndef NANO_TINY
+ add_to_funcs(record_macro, MMAIN,
+ N_("Record"), IFSCHELP(nano_recordmacro_msg), TOGETHER, VIEW);
+ add_to_funcs(run_macro, MMAIN,
+ N_("Run Macro"), IFSCHELP(nano_runmacro_msg), BLANKAFTER, VIEW);
+
add_to_funcs(do_indent, MMAIN,
N_("Indent Text"), IFSCHELP(nano_indent_msg), TOGETHER, NOVIEW);
add_to_funcs(do_unindent, MMAIN,
@@ -1131,6 +1138,8 @@ void shortcut_init(void)
add_to_sclist(MMAIN, "M-^", 0, do_copy_text, 0);
add_to_sclist(MMAIN, "M-}", 0, do_indent, 0);
add_to_sclist(MMAIN, "M-{", 0, do_unindent, 0);
+ add_to_sclist(MMAIN, "M-'", 0, record_macro, 0);
+ add_to_sclist(MMAIN, "M-;", 0, run_macro, 0);
add_to_sclist(MMAIN, "M-U", 0, do_undo, 0);
add_to_sclist(MMAIN, "M-E", 0, do_redo, 0);
#endif
@@ -1535,6 +1544,10 @@ sc *strtosc(const char *input)
s->scfunc = do_find_bracket;
else if (!strcasecmp(input, "wordcount"))
s->scfunc = do_wordlinechar_count;
+ else if (!strcasecmp(input, "recordmacro"))
+ s->scfunc = record_macro;
+ else if (!strcasecmp(input, "runmacro"))
+ s->scfunc = run_macro;
else if (!strcasecmp(input, "undo"))
s->scfunc = do_undo;
else if (!strcasecmp(input, "redo"))
diff --git a/src/proto.h b/src/proto.h
index 71c12d40..7f9463f4 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -627,6 +627,8 @@ void dump_filestruct_reverse(void);
#endif
/* Most functions in winio.c. */
+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 f90d23dc..ae37123c 100644
--- a/src/winio.c
+++ b/src/winio.c
@@ -51,6 +51,67 @@ static bool seen_wide = FALSE;
#endif
static bool reveal_cursor = FALSE;
/* Whether the cursor should be shown when waiting for input. */
+#ifndef NANO_TINY
+static bool recording = FALSE;
+ /* Whether we are in the process of recording a macro. */
+static int *macro_buffer = NULL;
+ /* A buffer where the recorded key codes are stored. */
+static size_t macro_length = 0;
+ /* The current length of the macro. */
+
+/* Start or stop the recording of keystrokes. */
+void record_macro(void)
+{
+ recording = !recording;
+
+ if (recording) {
+ free(macro_buffer);
+ macro_buffer = (int *)nmalloc(sizeof(int));
+ macro_length = 0;
+ statusbar(_("Recording a macro..."));
+ } else {
+ macro_length--;
+ /* Trim any trailing Esc codes. */
+ while (macro_buffer[macro_length - 1] == '\x1b')
+ macro_length--;
+ statusbar(_("Stopped recording"));
+ }
+}
+
+/* Add the given code to the macro buffer. */
+void add_to_macrobuffer(int code)
+{
+ macro_length++;
+ macro_buffer = (int*)nrealloc(macro_buffer, macro_length * sizeof(int));
+ macro_buffer[macro_length - 1] = code;
+}
+
+/* Copy the stored sequence of codes into the key buffer, so they will
+ * be "executed" again. */
+void run_macro(void)
+{
+ size_t i;
+
+ if (recording) {
+ statusline(HUSH, _("Cannot run macro while recording"));
+ /* Remove the runmacro keystroke from the macro buffer. */
+ macro_length--;
+ while (macro_buffer[macro_length - 1] == '\x1b')
+ macro_length--;
+ return;
+ }
+
+ if (macro_length == 0)
+ return;
+
+ free(key_buffer);
+ key_buffer = (int *)nmalloc(macro_length * sizeof(int));
+
+ for (i = 0; i < macro_length; i++)
+ key_buffer[i] = macro_buffer[i];
+ key_buffer_len = macro_length;
+}
+#endif /* !NANO_TINY */
/* Control character compatibility:
*
@@ -167,6 +228,10 @@ void get_key_buffer(WINDOW *win)
nodelay(win, TRUE);
while (TRUE) {
+#ifndef NANO_TINY
+ if (recording)
+ add_to_macrobuffer(input);
+#endif
input = wgetch(win);
/* If there aren't any more characters, stop reading. */
--
2.14.1
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Nano-devel] [PATCH v5] new feature: the ability to record and play back a series of keystrokes,
Benno Schulenberg <=