degesch: clean up key binding initialization
This commit is contained in:
parent
cc505090d4
commit
0bdf76edc5
183
degesch.c
183
degesch.c
|
@ -216,6 +216,34 @@ input_erase (struct input *self)
|
|||
rl_redisplay ();
|
||||
}
|
||||
|
||||
static void
|
||||
input_bind (struct input *self, const char *seq, const char *function_name)
|
||||
{
|
||||
(void) self;
|
||||
rl_bind_keyseq (seq, rl_named_function (function_name));
|
||||
}
|
||||
|
||||
static void
|
||||
input_bind_meta (struct input *self, char key, const char *function_name)
|
||||
{
|
||||
// This one seems to actually work
|
||||
char keyseq[] = { '\\', 'e', key, 0 };
|
||||
input_bind (self, keyseq, function_name);
|
||||
#if 0
|
||||
// While this one only fucks up UTF-8
|
||||
// Tested with urxvt and xterm, on Debian Jessie/Arch, default settings
|
||||
// \M-<key> behaves exactly the same
|
||||
rl_bind_key (META (key), rl_named_function (function_name));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
input_bind_control (struct input *self, char key, const char *function_name)
|
||||
{
|
||||
char keyseq[] = { '\\', 'C', '-', key, 0 };
|
||||
input_bind (self, keyseq, function_name);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
static int app_readline_init (void);
|
||||
|
@ -437,6 +465,26 @@ input_on_terminal_resized (struct input *self)
|
|||
el_resize (self->editline);
|
||||
}
|
||||
|
||||
static void
|
||||
input_bind (struct input *self, const char *seq, const char *function_name)
|
||||
{
|
||||
el_set (self->editline, EL_BIND, seq, function_name, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
input_bind_meta (struct input *self, char key, const char *function_name)
|
||||
{
|
||||
char keyseq[] = { 'M', '-', key, 0 };
|
||||
input_bind (self, keyseq, function_name);
|
||||
}
|
||||
|
||||
static void
|
||||
input_bind_control (struct input *self, char key, const char *function_name)
|
||||
{
|
||||
char keyseq[] = { '^', key, 0 };
|
||||
input_bind (self, keyseq, function_name);
|
||||
}
|
||||
|
||||
static void
|
||||
input_redisplay (struct input *self)
|
||||
{
|
||||
|
@ -506,12 +554,8 @@ input_start (struct input *self, const char *program_name)
|
|||
el_set (self->editline, EL_UNBUFFERED, true);
|
||||
el_set (self->editline, EL_EDITOR, "emacs");
|
||||
|
||||
// No, editline, it's not supposed to kill the entire line
|
||||
el_set (self->editline, EL_BIND, "^W", "ed-delete-prev-word", NULL);
|
||||
// Just what are you doing?
|
||||
el_set (self->editline, EL_BIND, "^U", "vi-kill-line-prev", NULL);
|
||||
|
||||
app_editline_init (self);
|
||||
|
||||
self->prompt_shown = 1;
|
||||
self->active = true;
|
||||
}
|
||||
|
@ -5391,6 +5435,26 @@ redraw_screen (struct app_context *ctx)
|
|||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
bind_common_keys (struct app_context *ctx)
|
||||
{
|
||||
struct input *self = &ctx->input;
|
||||
input_bind_control (self, 'p', "previous-buffer");
|
||||
input_bind_control (self, 'n', "next-buffer");
|
||||
|
||||
// Redefine M-0 through M-9 to switch buffers
|
||||
for (int i = 0; i <= 9; i++)
|
||||
input_bind_meta (self, '0' + i, "goto-buffer");
|
||||
|
||||
if (key_f5)
|
||||
input_bind (self, key_f5, "previous-buffer");
|
||||
if (key_f6)
|
||||
input_bind (self, key_f6, "next-buffer");
|
||||
|
||||
if (clear_screen)
|
||||
input_bind_control (self, 'l', "redraw-screen");
|
||||
}
|
||||
|
||||
// --- GNU Readline user actions -----------------------------------------------
|
||||
|
||||
#ifdef HAVE_READLINE
|
||||
|
@ -5491,20 +5555,6 @@ on_readline_input (char *line)
|
|||
ctx->input.prompt_shown = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
app_readline_bind_meta (char key, rl_command_func_t cb)
|
||||
{
|
||||
// This one seems to actually work
|
||||
char keyseq[] = { '\\', 'e', key, 0 };
|
||||
rl_bind_keyseq (keyseq, cb);
|
||||
#if 0
|
||||
// While this one only fucks up UTF-8
|
||||
// Tested with urxvt and xterm, on Debian Jessie/Arch, default settings
|
||||
// \M-<key> behaves exactly the same
|
||||
rl_bind_key (META (key), cb);
|
||||
#endif
|
||||
}
|
||||
|
||||
static char **
|
||||
app_readline_completion (const char *text, int start, int end)
|
||||
{
|
||||
|
@ -5520,41 +5570,32 @@ app_readline_completion (const char *text, int start, int end)
|
|||
static int
|
||||
app_readline_init (void)
|
||||
{
|
||||
struct app_context *ctx = g_ctx;
|
||||
struct input *self = &ctx->input;
|
||||
|
||||
// XXX: maybe use rl_make_bare_keymap() and start from there;
|
||||
// our dear user could potentionally rig things up in a way that might
|
||||
// result in some funny unspecified behaviour
|
||||
|
||||
rl_add_defun ("previous-buffer", on_readline_previous_buffer, -1);
|
||||
rl_add_defun ("next-buffer", on_readline_next_buffer, -1);
|
||||
|
||||
// Redefine M-0 through M-9 to switch buffers
|
||||
for (int i = 0; i <= 9; i++)
|
||||
app_readline_bind_meta ('0' + i, on_readline_goto_buffer);
|
||||
|
||||
rl_bind_keyseq ("\\C-p", rl_named_function ("previous-buffer"));
|
||||
rl_bind_keyseq ("\\C-n", rl_named_function ("next-buffer"));
|
||||
app_readline_bind_meta ('p', rl_named_function ("previous-history"));
|
||||
app_readline_bind_meta ('n', rl_named_function ("next-history"));
|
||||
|
||||
if (key_f5)
|
||||
rl_bind_keyseq (key_f5, rl_named_function ("previous-buffer"));
|
||||
if (key_f6)
|
||||
rl_bind_keyseq (key_f6, rl_named_function ("next-buffer"));
|
||||
|
||||
if (clear_screen)
|
||||
{
|
||||
rl_add_defun ("goto-buffer", on_readline_goto_buffer, -1);
|
||||
rl_add_defun ("redraw-screen", on_readline_redraw_screen, -1);
|
||||
rl_bind_keyseq ("\\C-l", rl_named_function ("redraw-screen"));
|
||||
}
|
||||
rl_add_defun ("send-line", on_readline_return, -1);
|
||||
|
||||
// We need to hide the prompt first
|
||||
rl_bind_key (RETURN, on_readline_return);
|
||||
bind_common_keys (ctx);
|
||||
|
||||
// Move native history commands
|
||||
input_bind_meta (self, 'p', "previous-history");
|
||||
input_bind_meta (self, 'n', "next-history");
|
||||
|
||||
// We need to hide the prompt and input first
|
||||
rl_bind_key (RETURN, rl_named_function ("send-line"));
|
||||
|
||||
// Completion
|
||||
rl_variable_bind ("completion-ignore-case", "on");
|
||||
rl_bind_key (TAB, rl_named_function ("menu-complete"));
|
||||
if (key_btab)
|
||||
rl_bind_keyseq (key_btab, rl_named_function ("menu-complete-backward"));
|
||||
input_bind (self, key_btab, "menu-complete-backward");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -5707,47 +5748,37 @@ on_editline_return (EditLine *editline, int key)
|
|||
static void
|
||||
app_editline_init (struct input *self)
|
||||
{
|
||||
el_set (self->editline, EL_ADDFN, "goto-buffer",
|
||||
"Go to buffer", on_editline_goto_buffer);
|
||||
el_set (self->editline, EL_ADDFN, "previous-buffer",
|
||||
"Previous buffer", on_editline_previous_buffer);
|
||||
el_set (self->editline, EL_ADDFN, "next-buffer",
|
||||
"Next buffer", on_editline_next_buffer);
|
||||
|
||||
// Redefine M-0 through M-9 to switch buffers
|
||||
for (size_t i = 0; i < 10; i++)
|
||||
static const struct { const char *name; const char *help;
|
||||
unsigned char (*func) (EditLine *, int); } x[] =
|
||||
{
|
||||
char keyseq[] = { 'M', '-', '0' + i, 0 };
|
||||
el_set (self->editline, EL_BIND, keyseq, "goto-buffer", NULL);
|
||||
}
|
||||
{ "goto-buffer", "Go to buffer", on_editline_goto_buffer },
|
||||
{ "previous-buffer", "Previous buffer", on_editline_previous_buffer },
|
||||
{ "next-buffer", "Next buffer", on_editline_next_buffer },
|
||||
{ "redraw-screen", "Redraw screen", on_editline_redraw_screen },
|
||||
{ "send-line", "Send line", on_editline_return },
|
||||
{ "complete", "Complete word", on_editline_complete },
|
||||
};
|
||||
for (size_t i = 0; i < N_ELEMENTS (x); i++)
|
||||
el_set (self->editline, EL_ADDFN, x[i].name, x[i].help, x[i].func);
|
||||
|
||||
el_set (self->editline, EL_BIND, "M-p", "ed-prev-history", NULL);
|
||||
el_set (self->editline, EL_BIND, "M-n", "ed-next-history", NULL);
|
||||
el_set (self->editline, EL_BIND, "^P", "previous-buffer", NULL);
|
||||
el_set (self->editline, EL_BIND, "^N", "next-buffer", NULL);
|
||||
bind_common_keys (g_ctx);
|
||||
|
||||
if (key_f5)
|
||||
el_set (self->editline, EL_BIND, key_f5, "previous-buffer", NULL);
|
||||
if (key_f6)
|
||||
el_set (self->editline, EL_BIND, key_f6, "next-buffer", NULL);
|
||||
// Move native history commands
|
||||
input_bind_meta (self, 'p', "ed-prev-history");
|
||||
input_bind_meta (self, 'n', "ed-next-history");
|
||||
|
||||
if (clear_screen)
|
||||
{
|
||||
el_set (self->editline, EL_ADDFN, "redraw-screen",
|
||||
"Redraw screen", on_editline_redraw_screen);
|
||||
el_set (self->editline, EL_BIND, "^L", "redraw-screen", NULL);
|
||||
}
|
||||
// No, editline, it's not supposed to kill the entire line
|
||||
input_bind_control (self, 'w', "ed-delete-prev-word");
|
||||
// Just what are you doing?
|
||||
input_bind_control (self, 'u', "vi-kill-line-prev");
|
||||
|
||||
// We need to hide the prompt and input first
|
||||
input_bind (self, "\n", "send-line");
|
||||
|
||||
input_bind_control (self, 'i', "complete");
|
||||
|
||||
// Source the user's defaults file
|
||||
el_source (self->editline, NULL);
|
||||
|
||||
el_set (self->editline, EL_ADDFN, "send-line",
|
||||
"Send line", on_editline_return);
|
||||
el_set (self->editline, EL_BIND, "\n", "send-line", NULL);
|
||||
|
||||
el_set (self->editline, EL_ADDFN, "complete",
|
||||
"Complete word", on_editline_complete);
|
||||
el_set (self->editline, EL_BIND, "^I", "complete", NULL);
|
||||
}
|
||||
|
||||
#endif // HAVE_EDITLINE
|
||||
|
|
Loading…
Reference in New Issue