nano

nano with my custom patches
git clone git://bsandro.tech/nano
Log | Files | Refs | README | LICENSE

commit 6d111c93430690c37d102a769542841d833ea149
parent bb667beb5aa289a900c6b2a0e275dbc62203837b
Author: Benno Schulenberg <bensberg@telfort.nl>
Date:   Sat, 20 Jan 2018 13:01:43 +0100

new feature: allow binding a key to a string (in a nanorc file)

In this way a single keystroke can produce a fragment of text or a
series of commands, or a mix of the two.  It is like a prerecorded
macro.

This fulfills https://savannah.gnu.org/bugs/?52931.

Diffstat:
Msrc/global.c | 14++++++++++++++
Msrc/nano.c | 3++-
Msrc/nano.h | 2++
Msrc/prompt.c | 2+-
Msrc/proto.h | 3+++
Msrc/rcfile.c | 14++++++++++++--
6 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/src/global.c b/src/global.c @@ -318,6 +318,9 @@ void flip_newbuffer(void) void discard_buffer(void) { } +void implant(void) +{ +} /* Add a function to the function list. */ void add_to_funcs(void (*func)(void), int menus, const char *desc, const char *help, @@ -1379,6 +1382,17 @@ void set_spell_shortcuts(void) } #endif /* ENABLE_COLOR && ENABLE_SPELLER */ +/* Execute the function of the given shortcut. */ +void execute(const sc *shortcut) +{ + if (shortcut->scfunc == implant) + /* Insert the corresponding string into the keyboard buffer. */ + for (int i = strlen(shortcut->expansion); i > 0; i--) + put_back(shortcut->expansion[i - 1]); + else + shortcut->scfunc(); +} + const subnfunc *sctofunc(const sc *s) { subnfunc *f = allfuncs; diff --git a/src/nano.c b/src/nano.c @@ -1753,7 +1753,8 @@ int do_input(bool allow_funcs) } #endif /* Execute the function of the shortcut. */ - s->scfunc(); + execute(s); + #ifndef NANO_TINY /* When the marked region changes without Shift being held, * discard a soft mark. And when the marked region covers a diff --git a/src/nano.h b/src/nano.h @@ -439,6 +439,8 @@ typedef struct sc { int ordinal; /* The how-manieth toggle this is, in order to be able to * keep them in sequence. */ + char *expansion; + /* The string of keycodes to which this shortcut is expanded. */ #endif struct sc *next; /* Next in the list. */ diff --git a/src/prompt.c b/src/prompt.c @@ -180,7 +180,7 @@ int do_statusbar_input(bool *ran_func, bool *finished) *ran_func = TRUE; if (f && (!ISSET(VIEW_MODE) || f->viewok) && f->scfunc != do_gotolinecolumn_void) - f->scfunc(); + execute(s); } *finished = TRUE; } diff --git a/src/proto.h b/src/proto.h @@ -318,6 +318,7 @@ char *input_tab(char *buf, bool allow_files, size_t *place, /* Some functions in global.c. */ size_t length_of_list(int menu); +void implant(void); const sc *first_sc_for(int menu, void (*func)(void)); int the_code_for(void (*func)(void), int defaultval); functionptrtype func_from_key(int *kbinput); @@ -329,6 +330,7 @@ void shortcut_init(void); void set_lint_or_format_shortcuts(void); void set_spell_shortcuts(void); #endif +void execute(const sc *shortcut); const subnfunc *sctofunc(const sc *s); const char *flagtostr(int flag); sc *strtosc(const char *input); @@ -619,6 +621,7 @@ void dump_filestruct(const filestruct *inptr); void record_macro(void); void run_macro(void); size_t get_key_buffer_len(void); +void put_back(int keycode); void unget_kbinput(int kbinput, bool metakey); int get_kbinput(WINDOW *win, bool showcursor); int parse_kbinput(WINDOW *win); diff --git a/src/rcfile.c b/src/rcfile.c @@ -336,6 +336,7 @@ bool is_universal(void (*func)(void)) func == do_home || func == do_end || #ifndef NANO_TINY func == do_prev_word_void || func == do_next_word_void || + func == implant || #endif func == do_delete || func == do_backspace || func == do_cut_text_void || func == do_uncut_text || @@ -396,7 +397,7 @@ void parse_binding(char *ptr, bool dobind) if (dobind) { funcptr = ptr; - ptr = parse_next_word(ptr); + ptr = parse_argument(ptr); if (funcptr[0] == '\0') { rcfile_error(N_("Must specify a function to bind the key to")); @@ -414,7 +415,16 @@ void parse_binding(char *ptr, bool dobind) } if (dobind) { - newsc = strtosc(funcptr); + /* If the thing to bind starts with a double quote, it is a string, + * otherwise it is the name of a function. */ + if (*funcptr == '"') { + newsc = nmalloc(sizeof(sc)); + newsc->scfunc = implant; + newsc->expansion = mallocstrcpy(NULL, funcptr + 1); + newsc->toggle = 0; + } else + newsc = strtosc(funcptr); + if (newsc == NULL) { rcfile_error(N_("Cannot map name \"%s\" to a function"), funcptr); goto free_things;