diff --git a/src/global.c b/src/global.c index 20eeb62c6c82f123aaf99c85d127f57af07e433b..d6af4e7d0fc417f880d2261f91a99888e8882535 100644 --- 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 index 12543dd41bfc4c190b88425720ff0845c1c70ba7..c57b457d2e9a4a02f208a214ce487af07e3b2a91 100644 --- 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 index 92f8e296e4c2120d23877d4f7c548f582a04bbb7..44d719492d02a1f72fdca9845a8ec79ce95b148d 100644 --- 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 index c067a3fb07523fbd9ae83cbe070b18e7135d99dd..0b73c40bfcc8b6c62016d30d350d54716192af06 100644 --- 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 index c4f6f074f39bbacc678c618c7eded679f1a5c016..18995490cc184b1f07234401043d4e0d096b9353 100644 --- 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 index ddfbd003c54a513f72bd64b11660e43fb50f1083..84dc57aac1e704c78306155b40c749013f9e9581 100644 --- 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;