>From 057d565fdb44f9dc64553b6c4014907ee57dae91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Diego=20Aur=C3=A9lio=20Mesquita?= Date: Sun, 12 Aug 2018 11:19:17 -0300 Subject: [PATCH] new feature: function interpolation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is now possible to bind commands by name (instead of only by its shortcut) to keys using ${}. For example, consider adding the following line to .nanorc: bind M-' "before word2${cutwordleft}after. Add a dollar sign: $$" main Will make produce "before after. Add a dollar sign: $" when M-' is pressed. Signed-off-by: Marco Diego Aurélio Mesquita --- src/winio.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/winio.c b/src/winio.c index 6908ee1d..fa8eb931 100644 --- a/src/winio.c +++ b/src/winio.c @@ -59,6 +59,8 @@ 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. */ +static bool playing = FALSE; + /* Whether we are playing a pre-recorded macro. */ /* Add the given code to the macro buffer. */ void add_to_macrobuffer(int code) @@ -292,9 +294,58 @@ void implant(const char *string) { for (int i = strlen(string); i > 0; i--) put_back(string[i - 1]); + playing = TRUE; } #endif +/* Process interpolated command in a shortcut bound text. */ +struct sc *process_command() +{ + size_t pos; + char *command = NULL; + size_t command_length = 0; + + /* A $$ was found, just eat one $. */ + if (key_buffer_len >= 1 && key_buffer[0] == (int)'$') { + key_buffer_len--; + memmove(key_buffer, key_buffer + 1, key_buffer_len *sizeof(int)); + return NULL; + } + + /* What we have is neither a command nor a $$, just ignore it*/ + if (key_buffer_len < 2 || key_buffer[0] != (int)'{') + return NULL; + + for(pos = 1; pos < key_buffer_len; pos++) { + if (key_buffer[pos] == (int)'}') + break; + + command = (char*)nrealloc(command, command_length * sizeof(char)); + command[command_length] = (char)key_buffer[pos]; + command_length++; + } + + /* We found a command, let's try to execute it. */ + if (key_buffer[pos] == (int)'}') { + struct sc *shortcut; + key_buffer[pos] = (int)'\0'; + + shortcut = strtosc(command); + + /* Got an invalid command. */ + if (!shortcut) { + key_buffer[pos] = (int)'}'; + } else { + key_buffer_len -= pos + 1; + memmove(key_buffer, key_buffer + pos + 1, key_buffer_len*sizeof(int)); + return shortcut; + } + } + + free(command); + return NULL; +} + /* Try to read input_len codes from the keystroke buffer. If the * keystroke buffer is empty and win isn't NULL, try to read in more * codes from win and add them to the keystroke buffer before doing @@ -303,6 +354,9 @@ int *get_input(WINDOW *win, size_t input_len) { int *input; + if (key_buffer_len == 0) + playing = FALSE; + if (key_buffer_len == 0 && win != NULL) read_keys_from(win); @@ -1757,6 +1811,14 @@ const sc *get_shortcut(int *kbinput) *kbinput, meta_key ? "TRUE" : "FALSE"); #endif + if (playing) { + if (kbinput[0] == (int)'$') { + s = process_command(); + if(s) + return s; + } + } + /* Plain characters cannot be shortcuts, so just skip those. */ if (!meta_key && (*kbinput & 0x7F) >= 0x20 && *kbinput <= 0xFF) return NULL; -- 2.11.0