summaryrefslogtreecommitdiff
path: root/degesch.c
diff options
context:
space:
mode:
authorPřemysl Janouch <p.janouch@gmail.com>2016-03-06 17:59:45 +0100
committerPřemysl Janouch <p.janouch@gmail.com>2016-03-06 18:12:12 +0100
commit584d2f0295df01cff4ac24c336af40f4c2a762e2 (patch)
tree41b59d84fb0c82bfa119c02f78bbc845c9d1c776 /degesch.c
parent3304b718aac98103b5fb3c2855bb661887c62aa1 (diff)
downloadxK-584d2f0295df01cff4ac24c336af40f4c2a762e2.tar.gz
xK-584d2f0295df01cff4ac24c336af40f4c2a762e2.tar.xz
xK-584d2f0295df01cff4ac24c336af40f4c2a762e2.zip
degesch: use libffi to unify input callbacks
And fuck you both, Readline and Editline.
Diffstat (limited to 'degesch.c')
-rw-r--r--degesch.c610
1 files changed, 284 insertions, 326 deletions
diff --git a/degesch.c b/degesch.c
index 57b1bf7..3d0130a 100644
--- a/degesch.c
+++ b/degesch.c
@@ -68,6 +68,8 @@ enum
#undef lines
#undef columns
+#include <ffi.h>
+
#ifdef HAVE_READLINE
#include <readline/readline.h>
#include <readline/history.h>
@@ -134,6 +136,22 @@ input_buffer_destroy (struct input_buffer *self)
free (self);
}
+typedef bool (*input_fn) (int count, int key, void *user_data);
+
+struct input_fn_data
+{
+ ffi_closure closure; ///< Closure
+
+ LIST_HEADER (struct input_fn_data)
+ input_fn callback; ///< Real callback
+ void *user_data; ///< Real callback user data
+
+#ifdef HAVE_EDITLINE
+ wchar_t *name; ///< Function name
+ wchar_t *help; ///< Function help
+#endif // HAVE_EDITLINE
+};
+
struct input
{
bool active; ///< Are we a thing?
@@ -145,6 +163,7 @@ struct input
#elif defined HAVE_EDITLINE
EditLine *editline; ///< The EditLine object
#endif // HAVE_EDITLINE
+ struct input_fn_data *fns; ///< Functions
char *prompt; ///< The prompt we use
int prompt_shown; ///< Whether the prompt is shown now
@@ -164,6 +183,14 @@ input_free (struct input *self)
#ifdef HAVE_READLINE
free (self->saved_line);
#endif // HAVE_READLINE
+ LIST_FOR_EACH (struct input_fn_data, iter, self->fns)
+ {
+#ifdef HAVE_EDITLINE
+ free (iter->name);
+ free (iter->help);
+#endif // HAVE_EDITLINE
+ ffi_closure_free (iter);
+ }
free (self->prompt);
}
@@ -279,6 +306,45 @@ input_get_content (struct input *self)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+static void
+input_closure_forwarder (ffi_cif *cif, void *ret, void **args, void *user_data)
+{
+ (void) cif;
+
+ struct input_fn_data *data = user_data;
+ if (!data->callback
+ (*(int *) args[0], UNMETA (*(int *) args[1]), data->user_data))
+ rl_ding ();
+ *(int *) ret = 0;
+}
+
+static void
+input_add_fn (struct input *self,
+ const char *name, const char *help, input_fn callback, void *user_data)
+{
+ (void) help;
+
+ void *bound_fn = NULL;
+ struct input_fn_data *data = ffi_closure_alloc (sizeof *data, &bound_fn);
+ hard_assert (data);
+
+ static ffi_cif cif;
+ static ffi_type *args[2] = { &ffi_type_sint, &ffi_type_sint };
+ hard_assert (ffi_prep_cif
+ (&cif, FFI_DEFAULT_ABI, 2, &ffi_type_sint, args) == FFI_OK);
+
+ data->prev = data->next = NULL;
+ data->callback = callback;
+ data->user_data = user_data;
+ hard_assert (ffi_prep_closure_loc (&data->closure,
+ &cif, input_closure_forwarder, data, bound_fn) == FFI_OK);
+
+ rl_add_defun (name, (rl_command_func_t *) bound_fn, -1);
+ LIST_PREPEND (self->fns, data);
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
static int app_readline_init (void);
static void on_readline_input (char *line);
static char **app_readline_completion (const char *text, int start, int end);
@@ -604,6 +670,52 @@ input_get_content (struct input *self)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
static void
+input_closure_forwarder (ffi_cif *cif, void *ret, void **args, void *user_data)
+{
+ (void) cif;
+
+ struct input_fn_data *data = user_data;
+ *(unsigned char *) ret = data->callback
+ (1, *(int *) args[1], data->user_data) ? CC_NORM : CC_ERROR;
+}
+
+static wchar_t *
+ascii_to_wide (const char *ascii)
+{
+ size_t len = strlen (ascii) + 1;
+ wchar_t *wide = xcalloc (sizeof *wide, len);
+ while (len--)
+ hard_assert ((wide[len] = (unsigned char) ascii[len]) < 0x80);
+ return wide;
+}
+
+static void
+input_add_fn (struct input *self,
+ const char *name, const char *help, input_fn callback, void *user_data)
+{
+ void *bound_fn = NULL;
+ struct input_fn_data *data = ffi_closure_alloc (sizeof *data, &bound_fn);
+ hard_assert (data);
+
+ static ffi_cif cif;
+ static ffi_type *args[2] = { &ffi_type_pointer, &ffi_type_sint };
+ hard_assert (ffi_prep_cif
+ (&cif, FFI_DEFAULT_ABI, 2, &ffi_type_uchar, args) == FFI_OK);
+
+ data->user_data = user_data;
+ data->callback = callback;
+ data->name = ascii_to_wide (name);
+ data->help = ascii_to_wide (help);
+ hard_assert (ffi_prep_closure_loc (&data->closure,
+ &cif, input_closure_forwarder, data, bound_fn) == FFI_OK);
+
+ el_wset (self->editline, EL_ADDFN, data->name, data->help, bound_fn);
+ LIST_PREPEND (self->fns, data);
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+static void
input_start (struct input *self, const char *program_name)
{
self->editline = el_init (program_name, stdin, stdout, stderr);
@@ -11161,40 +11273,6 @@ resume_terminal (struct app_context *ctx)
input_show (&ctx->input);
}
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-static void
-redraw_screen (struct app_context *ctx)
-{
- input_hide (&ctx->input);
-
- // If by some circumstance we had the wrong idea
- input_on_terminal_resized (&ctx->input);
- update_screen_size ();
-
- buffer_print_backlog (ctx, ctx->current_buffer);
-
- input_show (&ctx->input);
-}
-
-static bool
-jump_to_buffer (struct app_context *ctx, int n)
-{
- if (n < 0 || n > 9)
- return false;
-
- // There's no buffer zero
- if (n == 0)
- n = 10;
-
- if (ctx->last_buffer && buffer_get_index (ctx, ctx->current_buffer) == n)
- // Fast switching between two buffers
- buffer_activate (ctx, ctx->last_buffer);
- else if (!buffer_goto (ctx, n))
- return false;
- return true;
-}
-
static pid_t
spawn_helper_child (struct app_context *ctx)
{
@@ -11222,69 +11300,20 @@ spawn_helper_child (struct app_context *ctx)
}
static void
-launch_backlog_helper (struct app_context *ctx, int backlog_fd)
+redraw_screen (struct app_context *ctx)
{
- hard_assert (!ctx->running_backlog_helper);
- switch (spawn_helper_child (ctx))
- {
- case 0:
- dup2 (backlog_fd, STDIN_FILENO);
- execl ("/bin/sh", "/bin/sh", "-c", get_config_string
- (ctx->config.root, "behaviour.backlog_helper"), NULL);
- print_error ("%s: %s",
- "Failed to launch backlog helper", strerror (errno));
- _exit (EXIT_FAILURE);
- case -1:
- log_global_error (ctx, "#s: #l",
- "Failed to launch backlog helper", strerror (errno));
- break;
- default:
- ctx->running_backlog_helper = true;
- }
-}
+ input_hide (&ctx->input);
-static void
-display_backlog (struct app_context *ctx)
-{
- FILE *backlog = tmpfile ();
- if (!backlog)
- {
- log_global_error (ctx, "#s: #l",
- "Failed to create a temporary file", strerror (errno));
- return;
- }
+ // If by some circumstance we had the wrong idea
+ input_on_terminal_resized (&ctx->input);
+ update_screen_size ();
- for (struct buffer_line *line = ctx->current_buffer->lines;
- line; line = line->next)
- buffer_line_write_to_backlog (ctx, line, backlog);
+ buffer_print_backlog (ctx, ctx->current_buffer);
- rewind (backlog);
- set_cloexec (fileno (backlog));
- launch_backlog_helper (ctx, fileno (backlog));
- fclose (backlog);
+ input_show (&ctx->input);
}
-static void
-display_full_log (struct app_context *ctx)
-{
- char *path = buffer_get_log_path (ctx->current_buffer);
- FILE *full_log = fopen (path, "rb");
- free (path);
-
- if (!full_log)
- {
- log_global_error (ctx, "Failed to open log file for #s: #l",
- ctx->current_buffer->name, strerror (errno));
- return;
- }
-
- if (ctx->current_buffer->log_file)
- fflush (ctx->current_buffer->log_file);
-
- set_cloexec (fileno (full_log));
- launch_backlog_helper (ctx, fileno (full_log));
- fclose (full_log);
-}
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
static bool
dump_input_to_file (struct app_context *ctx, char *template, struct error **e)
@@ -11324,12 +11353,16 @@ try_dump_input_to_file (struct app_context *ctx)
return NULL;
}
-static void
-launch_input_editor (struct app_context *ctx)
+static bool
+on_edit_input (int count, int key, void *user_data)
{
+ (void) count;
+ (void) key;
+ struct app_context *ctx = user_data;
+
char *filename;
if (!(filename = try_dump_input_to_file (ctx)))
- return;
+ return false;
const char *command;
if (!(command = getenv ("VISUAL"))
@@ -11353,6 +11386,7 @@ launch_input_editor (struct app_context *ctx)
ctx->running_editor = true;
ctx->editor_filename = filename;
}
+ return true;
}
static void
@@ -11390,162 +11424,222 @@ input_editor_cleanup (struct app_context *ctx)
ctx->running_editor = false;
}
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
static void
-bind_common_keys (struct app_context *ctx)
+launch_backlog_helper (struct app_context *ctx, int backlog_fd)
{
- 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");
-
- input_bind_meta (self, '\t', "switch-buffer");
- input_bind_meta (self, 'm', "insert-attribute");
- input_bind_meta (self, 'h', "display-full-log");
- input_bind_meta (self, 'e', "edit-input");
-
- if (key_f5)
- input_bind (self, key_f5, "previous-buffer");
- if (key_f6)
- input_bind (self, key_f6, "next-buffer");
- if (key_ppage)
- input_bind (self, key_ppage, "display-backlog");
-
- if (clear_screen)
- input_bind_control (self, 'l', "redraw-screen");
-
- input_bind (self, "\x1b[200~", "start-paste-mode");
+ hard_assert (!ctx->running_backlog_helper);
+ switch (spawn_helper_child (ctx))
+ {
+ case 0:
+ dup2 (backlog_fd, STDIN_FILENO);
+ execl ("/bin/sh", "/bin/sh", "-c", get_config_string
+ (ctx->config.root, "behaviour.backlog_helper"), NULL);
+ print_error ("%s: %s",
+ "Failed to launch backlog helper", strerror (errno));
+ _exit (EXIT_FAILURE);
+ case -1:
+ log_global_error (ctx, "#s: #l",
+ "Failed to launch backlog helper", strerror (errno));
+ break;
+ default:
+ ctx->running_backlog_helper = true;
+ }
}
-// --- GNU Readline user actions -----------------------------------------------
-
-#ifdef HAVE_READLINE
-
-static int
-on_readline_goto_buffer (int count, int key)
+static bool
+on_display_backlog (int count, int key, void *user_data)
{
(void) count;
+ (void) key;
+ struct app_context *ctx = user_data;
- struct app_context *ctx = g_ctx;
- if (!jump_to_buffer (ctx, UNMETA (key) - '0'))
- input_ding (&ctx->input);
- return 0;
-}
+ FILE *backlog = tmpfile ();
+ if (!backlog)
+ {
+ log_global_error (ctx, "#s: #l",
+ "Failed to create a temporary file", strerror (errno));
+ return false;
+ }
-static int
-on_readline_previous_buffer (int count, int key)
-{
- (void) key;
+ for (struct buffer_line *line = ctx->current_buffer->lines;
+ line; line = line->next)
+ buffer_line_write_to_backlog (ctx, line, backlog);
- struct app_context *ctx = g_ctx;
- buffer_activate (ctx, buffer_previous (ctx, count));
- return 0;
+ rewind (backlog);
+ set_cloexec (fileno (backlog));
+ launch_backlog_helper (ctx, fileno (backlog));
+ fclose (backlog);
+ return true;
}
-static int
-on_readline_next_buffer (int count, int key)
+static bool
+on_display_full_log (int count, int key, void *user_data)
{
+ (void) count;
(void) key;
+ struct app_context *ctx = user_data;
- struct app_context *ctx = g_ctx;
- buffer_activate (ctx, buffer_next (ctx, count));
- return 0;
+ char *path = buffer_get_log_path (ctx->current_buffer);
+ FILE *full_log = fopen (path, "rb");
+ free (path);
+
+ if (!full_log)
+ {
+ log_global_error (ctx, "Failed to open log file for #s: #l",
+ ctx->current_buffer->name, strerror (errno));
+ return false;
+ }
+
+ if (ctx->current_buffer->log_file)
+ fflush (ctx->current_buffer->log_file);
+
+ set_cloexec (fileno (full_log));
+ launch_backlog_helper (ctx, fileno (full_log));
+ fclose (full_log);
+ return true;
}
-static int
-on_readline_switch_buffer (int count, int key)
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+static bool
+on_goto_buffer (int count, int key, void *user_data)
{
(void) count;
- (void) key;
+ struct app_context *ctx = user_data;
- struct app_context *ctx = g_ctx;
- if (ctx->last_buffer)
- buffer_activate (ctx, ctx->last_buffer);
- else
- input_ding (&ctx->input);
- return 0;
+ int n = key - '0';
+ if (n < 0 || n > 9)
+ return false;
+
+ // There's no buffer zero
+ if (n == 0)
+ n = 10;
+
+ if (!ctx->last_buffer || buffer_get_index (ctx, ctx->current_buffer) != n)
+ return buffer_goto (ctx, n);
+
+ // Fast switching between two buffers
+ buffer_activate (ctx, ctx->last_buffer);
+ return true;
}
-static int
-on_readline_display_backlog (int count, int key)
+static bool
+on_previous_buffer (int count, int key, void *user_data)
{
- (void) count;
(void) key;
-
- struct app_context *ctx = g_ctx;
- display_backlog (ctx);
- return 0;
+ buffer_activate (user_data, buffer_previous (user_data, count));
+ return true;
}
-static int
-on_readline_display_full_log (int count, int key)
+static bool
+on_next_buffer (int count, int key, void *user_data)
{
- (void) count;
(void) key;
-
- struct app_context *ctx = g_ctx;
- display_full_log (ctx);
- return 0;
+ buffer_activate (user_data, buffer_next (user_data, count));
+ return true;
}
-static int
-on_readline_edit_input (int count, int key)
+static bool
+on_switch_buffer (int count, int key, void *user_data)
{
(void) count;
(void) key;
+ struct app_context *ctx = user_data;
- struct app_context *ctx = g_ctx;
- launch_input_editor (ctx);
- return 0;
+ if (!ctx->last_buffer)
+ return false;
+ buffer_activate (ctx, ctx->last_buffer);
+ return true;
}
-static int
-on_readline_redraw_screen (int count, int key)
+static bool
+on_redraw_screen (int count, int key, void *user_data)
{
(void) count;
(void) key;
- struct app_context *ctx = g_ctx;
- redraw_screen (ctx);
- return 0;
+ redraw_screen (user_data);
+ return true;
}
-static int
-on_readline_insert_attribute (int count, int key)
+static bool
+on_insert_attribute (int count, int key, void *user_data)
{
(void) count;
(void) key;
- struct app_context *ctx = g_ctx;
+ struct app_context *ctx = user_data;
ctx->awaiting_mirc_escape = true;
- return 0;
+ return true;
}
-static int
-on_readline_start_paste_mode (int count, int key)
+static bool
+on_start_paste_mode (int count, int key, void *user_data)
{
(void) count;
(void) key;
- struct app_context *ctx = g_ctx;
+ struct app_context *ctx = user_data;
ctx->in_bracketed_paste = true;
- return 0;
+ return true;
}
+static void
+bind_common_keys (struct app_context *ctx)
+{
+ struct input *self = &ctx->input;
+#define XX(...) input_add_fn (self, __VA_ARGS__, ctx);
+ XX ("previous-buffer", "Previous buffer", on_previous_buffer)
+ XX ("next-buffer", "Next buffer", on_next_buffer)
+ XX ("goto-buffer", "Go to buffer", on_goto_buffer)
+ XX ("switch-buffer", "Switch buffer", on_switch_buffer)
+ XX ("display-backlog", "Show backlog", on_display_backlog)
+ XX ("display-full-log", "Show full log", on_display_full_log)
+ XX ("edit-input", "Edit input", on_edit_input)
+ XX ("redraw-screen", "Redraw screen", on_redraw_screen)
+ XX ("insert-attribute", "mIRC formatting", on_insert_attribute)
+ XX ("start-paste-mode", "Bracketed paste", on_start_paste_mode)
+#undef XX
+
+ 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");
+
+ input_bind_meta (self, '\t', "switch-buffer");
+ input_bind_meta (self, 'm', "insert-attribute");
+ input_bind_meta (self, 'h', "display-full-log");
+ input_bind_meta (self, 'e', "edit-input");
+
+ if (key_f5) input_bind (self, key_f5, "previous-buffer");
+ if (key_f6) input_bind (self, key_f6, "next-buffer");
+ if (key_ppage) input_bind (self, key_ppage, "display-backlog");
+
+ if (clear_screen)
+ input_bind_control (self, 'l', "redraw-screen");
+
+ input_bind (self, "\x1b[200~", "start-paste-mode");
+}
+
+// --- GNU Readline user actions -----------------------------------------------
+
+#ifdef HAVE_READLINE
+
static int
on_readline_return (int count, int key)
{
(void) count;
(void) key;
- struct app_context *ctx = g_ctx;
-
// Let readline pass the line to our input handler
rl_done = 1;
// Hide the line, don't redisplay it
+ struct app_context *ctx = g_ctx;
input_hide (&ctx->input);
input_restore (&ctx->input);
return 0;
@@ -11602,18 +11696,7 @@ app_readline_init (void)
// 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);
- rl_add_defun ("goto-buffer", on_readline_goto_buffer, -1);
- rl_add_defun ("switch-buffer", on_readline_switch_buffer, -1);
- rl_add_defun ("display-backlog", on_readline_display_backlog, -1);
- rl_add_defun ("display-full-log", on_readline_display_full_log, -1);
- rl_add_defun ("edit-input", on_readline_edit_input, -1);
- rl_add_defun ("redraw-screen", on_readline_redraw_screen, -1);
- rl_add_defun ("insert-attribute", on_readline_insert_attribute, -1);
- rl_add_defun ("start-paste-mode", on_readline_start_paste_mode, -1);
- rl_add_defun ("send-line", on_readline_return, -1);
-
+ rl_add_defun ("send-line", on_readline_return, -1);
bind_common_keys (ctx);
// Move native history commands
@@ -11637,113 +11720,6 @@ app_readline_init (void)
#ifdef HAVE_EDITLINE
static unsigned char
-on_editline_goto_buffer (EditLine *editline, int key)
-{
- (void) editline;
-
- struct app_context *ctx = g_ctx;
- if (!jump_to_buffer (ctx, key - '0'))
- return CC_ERROR;
- return CC_NORM;
-}
-
-static unsigned char
-on_editline_previous_buffer (EditLine *editline, int key)
-{
- (void) editline;
- (void) key;
-
- struct app_context *ctx = g_ctx;
- buffer_activate (ctx, buffer_previous (ctx, 1));
- return CC_NORM;
-}
-
-static unsigned char
-on_editline_next_buffer (EditLine *editline, int key)
-{
- (void) editline;
- (void) key;
-
- struct app_context *ctx = g_ctx;
- buffer_activate (ctx, buffer_next (ctx, 1));
- return CC_NORM;
-}
-
-static unsigned char
-on_editline_switch_buffer (EditLine *editline, int key)
-{
- (void) editline;
- (void) key;
-
- struct app_context *ctx = g_ctx;
- if (ctx->last_buffer)
- buffer_activate (ctx, ctx->last_buffer);
- else
- input_ding (&ctx->input);
- return CC_NORM;
-}
-
-static unsigned char
-on_editline_display_backlog (EditLine *editline, int key)
-{
- (void) editline;
- (void) key;
-
- display_backlog (g_ctx);
- return CC_NORM;
-}
-
-static unsigned char
-on_editline_display_full_log (EditLine *editline, int key)
-{
- (void) editline;
- (void) key;
-
- display_full_log (g_ctx);
- return CC_NORM;
-}
-
-static unsigned char
-on_editline_edit_input (EditLine *editline, int key)
-{
- (void) editline;
- (void) key;
-
- launch_input_editor (g_ctx);
- return CC_NORM;
-}
-
-static unsigned char
-on_editline_redraw_screen (EditLine *editline, int key)
-{
- (void) editline;
- (void) key;
-
- redraw_screen (g_ctx);
- return CC_NORM;
-}
-
-static unsigned char
-on_editline_insert_attribute (EditLine *editline, int key)
-{
- (void) editline;
- (void) key;
-
- g_ctx->awaiting_mirc_escape = true;
- return CC_NORM;
-}
-
-static unsigned char
-on_editline_start_paste_mode (EditLine *editline, int key)
-{
- (void) editline;
- (void) key;
-
- g_ctx->in_bracketed_paste = true;
- return CC_NORM;
-}
-
-static unsigned char
on_editline_complete (EditLine *editline, int key)
{
(void) key;
@@ -11831,29 +11807,11 @@ on_editline_return (EditLine *editline, int key)
static void
app_editline_init (struct input *self)
{
-#define XX(name, help, fn) { name, help, on_editline_ ## fn },
-
// el_set() leaks memory in 20150325 and other versions, we need wchar_t
- static const struct { const wchar_t *name; const wchar_t *help;
- unsigned char (*func) (EditLine *, int); } x[] =
- {
- XX( L"goto-buffer", L"Go to buffer", goto_buffer )
- XX( L"previous-buffer", L"Previous buffer", previous_buffer )
- XX( L"next-buffer", L"Next buffer", next_buffer )
- XX( L"switch-buffer", L"Switch buffer", switch_buffer )
- XX( L"display-backlog", L"Show backlog", display_backlog )
- XX( L"display-full-log", L"Show full log", display_full_log )
- XX( L"edit-input", L"Edit input", edit_input )
- XX( L"redraw-screen", L"Redraw screen", redraw_screen )
- XX( L"insert-attribute", L"mIRC formatting", insert_attribute )
- XX( L"start-paste-mode", L"Bracketed paste", start_paste_mode )
- XX( L"send-line", L"Send line", return )
- XX( L"complete", L"Complete word", complete )
- };
- for (size_t i = 0; i < N_ELEMENTS (x); i++)
- el_wset (self->editline, EL_ADDFN, x[i].name, x[i].help, x[i].func);
-
-#undef XX
+ el_wset (self->editline, EL_ADDFN,
+ L"send-line", L"Send line", on_editline_return);
+ el_wset (self->editline, EL_ADDFN,
+ L"complete", L"Complete word", on_editline_complete);
bind_common_keys (g_ctx);