diff options
| -rw-r--r-- | degesch.c | 101 | 
1 files changed, 66 insertions, 35 deletions
@@ -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);  | 
