From 0bdf76edc591524ec133a728e37b05a25d00c9d9 Mon Sep 17 00:00:00 2001
From: Přemysl Janouch
Date: Fri, 8 May 2015 06:23:38 +0200
Subject: degesch: clean up key binding initialization
---
degesch.c | 183 ++++++++++++++++++++++++++++++++++++--------------------------
1 file changed, 107 insertions(+), 76 deletions(-)
diff --git a/degesch.c b/degesch.c
index e60f1ad..18ad689 100644
--- a/degesch.c
+++ b/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- 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- 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_add_defun ("next-buffer", on_readline_next_buffer, -1);
+ rl_add_defun ("goto-buffer", on_readline_goto_buffer, -1);
+ rl_add_defun ("redraw-screen", on_readline_redraw_screen, -1);
+ rl_add_defun ("send-line", on_readline_return, -1);
- 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"));
+ bind_common_keys (ctx);
- 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 ("redraw-screen", on_readline_redraw_screen, -1);
- rl_bind_keyseq ("\\C-l", rl_named_function ("redraw-screen"));
- }
+ // Move native history commands
+ input_bind_meta (self, 'p', "previous-history");
+ input_bind_meta (self, 'n', "next-history");
- // We need to hide the prompt first
- rl_bind_key (RETURN, on_readline_return);
+ // 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");
- // Source the user's defaults file
- el_source (self->editline, NULL);
+ // We need to hide the prompt and input first
+ input_bind (self, "\n", "send-line");
- el_set (self->editline, EL_ADDFN, "send-line",
- "Send line", on_editline_return);
- el_set (self->editline, EL_BIND, "\n", "send-line", NULL);
+ input_bind_control (self, 'i', "complete");
- el_set (self->editline, EL_ADDFN, "complete",
- "Complete word", on_editline_complete);
- el_set (self->editline, EL_BIND, "^I", "complete", NULL);
+ // Source the user's defaults file
+ el_source (self->editline, NULL);
}
#endif // HAVE_EDITLINE
--
cgit v1.2.3-70-g09d2