From 869781c33a0269ab6038fd5d2fdc89e8b317feb3 Mon Sep 17 00:00:00 2001
From: Přemysl Janouch
Date: Sat, 18 Apr 2015 03:25:10 +0200
Subject: degesch: make it work to some extent
GNU Readline still ignores our Meta keyseqs.
---
degesch.c | 101 ++++++++++++++++++++++++++++++++++++++++----------------------
1 file changed, 66 insertions(+), 35 deletions(-)
diff --git a/degesch.c b/degesch.c
index 839b9e8..e09f4cb 100644
--- a/degesch.c
+++ b/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);
--
cgit v1.2.3-70-g09d2