degesch: make it work to some extent
GNU Readline still ignores our Meta keyseqs.
This commit is contained in:
parent
583262ae67
commit
869781c33a
101
degesch.c
101
degesch.c
@ -788,9 +788,9 @@ buffer_send (struct app_context *ctx, struct buffer *buffer,
|
||||
line->type = type;
|
||||
line->flags = flags;
|
||||
line->when = time (NULL);
|
||||
line->who = origin ? xstrdup (origin) : NULL;
|
||||
line->who = xstrdup (origin ? origin : "");
|
||||
line->object = str_steal (&text);
|
||||
line->reason = reason ? xstrdup (reason) : NULL;
|
||||
line->reason = xstrdup (reason ? reason : "");
|
||||
|
||||
LIST_APPEND_WITH_TAIL (buffer->lines, buffer->lines_tail, line);
|
||||
buffer->lines_count++;
|
||||
@ -910,9 +910,6 @@ buffer_activate (struct app_context *ctx, struct buffer *buffer)
|
||||
clear_history ();
|
||||
#endif // RL_READLINE_VERSION < 0x0603
|
||||
|
||||
// Now at last we can switch the pointers
|
||||
ctx->current_buffer = buffer;
|
||||
|
||||
// Restore the target buffer's history
|
||||
if (buffer->history)
|
||||
{
|
||||
@ -946,6 +943,9 @@ buffer_activate (struct app_context *ctx, struct buffer *buffer)
|
||||
rl_redisplay ();
|
||||
}
|
||||
|
||||
// Now at last we can switch the pointers
|
||||
ctx->current_buffer = buffer;
|
||||
|
||||
refresh_prompt (ctx);
|
||||
}
|
||||
|
||||
@ -1043,7 +1043,15 @@ try_finish_quit (struct app_context *ctx)
|
||||
static void
|
||||
initiate_quit (struct app_context *ctx)
|
||||
{
|
||||
print_status ("shutting down");
|
||||
// First get rid of readline
|
||||
if (ctx->readline_prompt_shown)
|
||||
rl_crlf ();
|
||||
|
||||
rl_callback_handler_remove ();
|
||||
ctx->readline_prompt_shown = false;
|
||||
|
||||
// Initiate a connection close
|
||||
buffer_send_status (ctx, ctx->global_buffer, "shutting down");
|
||||
if (ctx->irc_fd != -1)
|
||||
irc_shutdown (ctx);
|
||||
|
||||
@ -1273,8 +1281,8 @@ irc_establish_connection (struct app_context *ctx,
|
||||
real_host = buf;
|
||||
|
||||
char *address = format_host_port_pair (real_host, port);
|
||||
// FIXME: print to the server buffer
|
||||
print_status ("connecting to %s...", address);
|
||||
buffer_send_status (ctx, ctx->server_buffer,
|
||||
"connecting to %s...", address);
|
||||
free (address);
|
||||
|
||||
if (!connect (sockfd, gai_iter->ai_addr, gai_iter->ai_addrlen))
|
||||
@ -1386,7 +1394,11 @@ refresh_prompt (struct app_context *ctx)
|
||||
}
|
||||
str_free (&prompt);
|
||||
|
||||
// We need to be somehow able to initialize it
|
||||
// First reset the prompt to work around a bug in readline
|
||||
rl_set_prompt ("");
|
||||
if (ctx->readline_prompt_shown)
|
||||
rl_redisplay ();
|
||||
|
||||
rl_set_prompt (ctx->readline_prompt);
|
||||
if (ctx->readline_prompt_shown)
|
||||
rl_redisplay ();
|
||||
@ -1397,9 +1409,6 @@ on_readline_goto_buffer (int count, int key)
|
||||
{
|
||||
(void) count;
|
||||
|
||||
if (!(key & 0x80))
|
||||
return 0;
|
||||
|
||||
int n = (key & 0x7F) - '0';
|
||||
if (n < 0 || n > 9)
|
||||
return 0;
|
||||
@ -1443,14 +1452,17 @@ init_readline (void)
|
||||
rl_add_defun ("next-buffer", on_readline_next_buffer, -1);
|
||||
|
||||
// Redefine M-0 through M-9 to switch buffers
|
||||
char keyseq[] = "\\M-0";
|
||||
for (int i = 0; i <= 9; i++)
|
||||
rl_bind_key (0x80 /* this is the Meta modifier for Readline */
|
||||
| ('0' + i), on_readline_goto_buffer);
|
||||
{
|
||||
keyseq[3] = '0' + i;
|
||||
rl_bind_keyseq (keyseq, on_readline_goto_buffer);
|
||||
}
|
||||
|
||||
rl_bind_keyseq ("C-p", rl_named_function ("previous-buffer"));
|
||||
rl_bind_keyseq ("C-n", rl_named_function ("next-buffer"));
|
||||
rl_bind_keyseq ("M-p", rl_named_function ("previous-history"));
|
||||
rl_bind_keyseq ("M-n", rl_named_function ("next-history"));
|
||||
rl_bind_keyseq ("\\C-p", rl_named_function ("previous-buffer"));
|
||||
rl_bind_keyseq ("\\C-n", rl_named_function ("next-buffer"));
|
||||
rl_bind_keyseq ("\\M-p", rl_named_function ("previous-history"));
|
||||
rl_bind_keyseq ("\\M-n", rl_named_function ("next-history"));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1594,6 +1606,7 @@ irc_process_message (const struct irc_message *msg,
|
||||
// XXX: should we really print this?
|
||||
buffer_send_status (ctx, ctx->server_buffer, "successfully connected");
|
||||
ctx->irc_ready = true;
|
||||
refresh_prompt (ctx);
|
||||
|
||||
const char *autojoin = str_map_find (&ctx->config, "autojoin");
|
||||
if (autojoin)
|
||||
@ -1613,7 +1626,11 @@ irc_process_message (const struct irc_message *msg,
|
||||
unsigned long dummy;
|
||||
if (xstrtoul (&dummy, msg->command, 10))
|
||||
{
|
||||
char *reconstructed = join_str_vector (&msg->params, ' ');
|
||||
struct str_vector copy;
|
||||
str_vector_init (©);
|
||||
str_vector_add_vector (©, msg->params.vector + !!msg->params.len);
|
||||
char *reconstructed = join_str_vector (©, ' ');
|
||||
str_vector_free (©);
|
||||
char *utf8 = irc_to_utf8 (ctx, reconstructed);
|
||||
free (reconstructed);
|
||||
buffer_send_status (ctx, ctx->server_buffer, "%s", utf8);
|
||||
@ -1834,7 +1851,7 @@ static void
|
||||
process_user_command (struct app_context *ctx, char *command)
|
||||
{
|
||||
static bool initialized = false;
|
||||
struct str_map partial;
|
||||
static struct str_map partial;
|
||||
if (!initialized)
|
||||
{
|
||||
init_partial_matching_user_command_map (&partial);
|
||||
@ -2127,12 +2144,6 @@ irc_connect (struct app_context *ctx, struct error **e)
|
||||
|
||||
// TODO: again, get rid of `struct error' in here. The question is: how
|
||||
// do we tell our caller that he should not try to reconnect?
|
||||
if (!irc_host)
|
||||
{
|
||||
error_set (e, "no hostname specified in configuration");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool use_ssl;
|
||||
if (!irc_get_boolean_from_config (ctx, "ssl", &use_ssl, e))
|
||||
return false;
|
||||
@ -2233,8 +2244,13 @@ on_readline_input (char *line)
|
||||
process_input (g_ctx, line);
|
||||
free (line);
|
||||
}
|
||||
else
|
||||
// Anything better to do?
|
||||
rl_crlf ();
|
||||
|
||||
g_ctx->readline_prompt_shown = true;
|
||||
// initiate_quit() disables readline; we just wait then
|
||||
if (!g_ctx->quitting)
|
||||
g_ctx->readline_prompt_shown = true;
|
||||
}
|
||||
|
||||
// --- Configuration loading ---------------------------------------------------
|
||||
@ -2372,7 +2388,7 @@ autofill_user_info (struct app_context *ctx, struct error **e)
|
||||
if (comma)
|
||||
*comma = '\0';
|
||||
|
||||
str_map_set (&ctx->config, "username", xstrdup (gecos));
|
||||
str_map_set (&ctx->config, "realname", xstrdup (gecos));
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -2418,6 +2434,13 @@ load_config (struct app_context *ctx, struct error **e)
|
||||
if (!success)
|
||||
return false;
|
||||
|
||||
const char *irc_host = str_map_find (&ctx->config, "irc_host");
|
||||
if (!irc_host)
|
||||
{
|
||||
error_set (e, "no hostname specified in configuration");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!irc_get_boolean_from_config (ctx,
|
||||
"reconnect", &ctx->reconnect, e)
|
||||
|| !irc_get_boolean_from_config (ctx,
|
||||
@ -2454,7 +2477,7 @@ init_poller_events (struct app_context *ctx)
|
||||
|
||||
poller_fd_init (&ctx->signal_event, &ctx->poller, g_signal_pipe[0]);
|
||||
ctx->signal_event.dispatcher = (poller_fd_fn) on_signal_pipe_readable;
|
||||
ctx->signal_event.user_data = &ctx;
|
||||
ctx->signal_event.user_data = ctx;
|
||||
poller_fd_set (&ctx->signal_event, POLLIN);
|
||||
|
||||
poller_fd_init (&ctx->tty_event, &ctx->poller, STDIN_FILENO);
|
||||
@ -2523,6 +2546,14 @@ main (int argc, char *argv[])
|
||||
|
||||
setup_signal_handlers ();
|
||||
|
||||
struct error *e = NULL;
|
||||
if (!load_config (&ctx, &e))
|
||||
{
|
||||
print_error ("%s", e->message);
|
||||
error_free (e);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
init_colors (&ctx);
|
||||
init_poller_events (&ctx);
|
||||
init_buffers (&ctx);
|
||||
@ -2530,17 +2561,17 @@ main (int argc, char *argv[])
|
||||
refresh_prompt (&ctx);
|
||||
|
||||
// TODO: connect asynchronously (first step towards multiple servers)
|
||||
// TODO: print load_config() errors to the global buffer,
|
||||
// switch buffers and print irc_connect() errors to the server buffer?
|
||||
struct error *e = NULL;
|
||||
if (!load_config (&ctx, &e)
|
||||
|| !irc_connect (&ctx, &e))
|
||||
if (!irc_connect (&ctx, &e))
|
||||
{
|
||||
buffer_send_error (&ctx, ctx.global_buffer, "%s", e->message);
|
||||
buffer_send_error (&ctx, ctx.server_buffer, "%s", e->message);
|
||||
error_free (e);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// TODO
|
||||
ctx.irc_nickname = xstrdup ("TODO");
|
||||
ctx.irc_user_mode = xstrdup ("");
|
||||
|
||||
rl_startup_hook = init_readline;
|
||||
rl_catch_sigwinch = false;
|
||||
rl_callback_handler_install (ctx.readline_prompt, on_readline_input);
|
||||
|
Loading…
Reference in New Issue
Block a user