degesch: more user command handling
It's become obvious that I really, really need to finish printing to buffer first, as I keep adding new TODO comments.
This commit is contained in:
		
							parent
							
								
									2d91a27714
								
							
						
					
					
						commit
						954a9e127a
					
				
							
								
								
									
										122
									
								
								degesch.c
									
									
									
									
									
								
							
							
						
						
									
										122
									
								
								degesch.c
									
									
									
									
									
								
							| @ -282,6 +282,7 @@ struct app_context | ||||
| 	struct buffer *buffers;             ///< All our buffers in order
 | ||||
| 	struct buffer *buffers_tail;        ///< The tail of our buffers
 | ||||
| 
 | ||||
| 	// XXX: when we go multiserver, there will be collisions
 | ||||
| 	struct str_map buffers_by_name;     ///< Excludes GLOBAL and SERVER
 | ||||
| 	struct buffer *global_buffer;       ///< The global buffer
 | ||||
| 	struct buffer *server_buffer;       ///< The server buffer
 | ||||
| @ -822,6 +823,8 @@ buffer_remove (struct app_context *ctx, struct buffer *buffer) | ||||
| { | ||||
| 	hard_assert (buffer != ctx->current_buffer); | ||||
| 
 | ||||
| 	// TODO: part from the channel if needed
 | ||||
| 
 | ||||
| 	// rl_clear_history, being the only way I know of to get rid of the complete
 | ||||
| 	// history including attached data, is a pretty recent addition.  *sigh*
 | ||||
| #if RL_READLINE_VERSION >= 0x0603 | ||||
| @ -1524,16 +1527,107 @@ irc_process_message (const struct irc_message *msg, | ||||
| 
 | ||||
| // --- User input handling -----------------------------------------------------
 | ||||
| 
 | ||||
| static void handle_command_help (struct app_context *, const char *); | ||||
| static void handle_command_help (struct app_context *, char *); | ||||
| 
 | ||||
| static void | ||||
| handle_command_buffer (struct app_context *ctx, const char *arguments) | ||||
| /// Cuts the longest non-whitespace portion of text and advances the pointer
 | ||||
| static char * | ||||
| cut_word (char **s) | ||||
| { | ||||
| 	// TODO: parse the arguments
 | ||||
| 	char *start = *s; | ||||
| 	size_t word_len = strcspn (*s, " \t"); | ||||
| 	char *end = start + word_len; | ||||
| 	*s = end + strspn (end, " \t"); | ||||
| 	*end = '\0'; | ||||
| 	return start; | ||||
| } | ||||
| 
 | ||||
| static bool | ||||
| try_handle_buffer_goto (struct app_context *ctx, const char *word) | ||||
| { | ||||
| 	unsigned long n; | ||||
| 	if (!xstrtoul (&n, word, 10)) | ||||
| 		return false; | ||||
| 
 | ||||
| 	if (n > INT_MAX || !buffer_goto (ctx, n)) | ||||
| 	{ | ||||
| 		// TODO: print a "no such buffer" error message
 | ||||
| 	} | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| static struct buffer * | ||||
| try_decode_buffer (struct app_context *ctx, const char *word) | ||||
| { | ||||
| 	unsigned long n; | ||||
| 	struct buffer *buffer = NULL; | ||||
| 	if (xstrtoul (&n, word, 10) && n <= INT_MAX) | ||||
| 		buffer = buffer_at_index (ctx, n); | ||||
| 	if (!buffer) | ||||
| 		buffer = str_map_find (&ctx->buffers_by_name, word); | ||||
| 	// TODO: decode the global and server buffers, partial matches
 | ||||
| 	return buffer; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| handle_command_quit (struct app_context *ctx, const char *arguments) | ||||
| handle_command_buffer (struct app_context *ctx, char *arguments) | ||||
| { | ||||
| 	char *action = cut_word (&arguments); | ||||
| 	if (try_handle_buffer_goto (ctx, action)) | ||||
| 		return; | ||||
| 
 | ||||
| 	struct buffer *buffer = NULL; | ||||
| 
 | ||||
| 	// XXX: also build a prefix map?
 | ||||
| 	// TODO: some subcommand to print N last lines from the buffer
 | ||||
| 	if (!strcasecmp_ascii (action, "list")) | ||||
| 	{ | ||||
| 		// TODO: print a list of "%d: %s", index, name
 | ||||
| 	} | ||||
| 	else if (!strcasecmp_ascii (action, "clear")) | ||||
| 	{ | ||||
| 		// TODO
 | ||||
| 	} | ||||
| 	else if (!strcasecmp_ascii (action, "move")) | ||||
| 	{ | ||||
| 		// TODO: unlink the buffer and link it back at index;
 | ||||
| 		//   we will probably need to extend liberty for this
 | ||||
| 	} | ||||
| 	else if (!strcasecmp_ascii (action, "close")) | ||||
| 	{ | ||||
| 		const char *which = NULL; | ||||
| 		if (!*arguments) | ||||
| 			buffer = ctx->current_buffer; | ||||
| 		else | ||||
| 			buffer = try_decode_buffer (ctx, (which = cut_word (&arguments))); | ||||
| 
 | ||||
| 		if (!buffer) | ||||
| 		{ | ||||
| 			// TODO: print a "no such buffer: %s" message
 | ||||
| 			return; | ||||
| 		} | ||||
| 		if (buffer == ctx->global_buffer) | ||||
| 		{ | ||||
| 			// TODO: print a "can't close the global buffer" message
 | ||||
| 			return; | ||||
| 		} | ||||
| 		if (buffer == ctx->server_buffer) | ||||
| 		{ | ||||
| 			// TODO: print a "can't close the server buffer" message
 | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		if (buffer == ctx->current_buffer) | ||||
| 			buffer_activate (ctx, buffer_next (ctx, 1)); | ||||
| 		buffer_remove (ctx, buffer); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		// TODO: show usage (or do something else?)
 | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| handle_command_quit (struct app_context *ctx, char *arguments) | ||||
| { | ||||
| 	if (ctx->irc_fd != -1) | ||||
| 	{ | ||||
| @ -1548,7 +1642,7 @@ handle_command_quit (struct app_context *ctx, const char *arguments) | ||||
| static struct command_handler | ||||
| { | ||||
| 	char *name; | ||||
| 	void (*handler) (struct app_context *ctx, const char *arguments); | ||||
| 	void (*handler) (struct app_context *ctx, char *arguments); | ||||
| 	// TODO: probably also a usage string
 | ||||
| } | ||||
| g_command_handlers[] = | ||||
| @ -1586,7 +1680,7 @@ g_command_handlers[] = | ||||
| }; | ||||
| 
 | ||||
| static void | ||||
| handle_command_help (struct app_context *ctx, const char *arguments) | ||||
| handle_command_help (struct app_context *ctx, char *arguments) | ||||
| { | ||||
| 	// TODO: show a list of all user commands
 | ||||
| } | ||||
| @ -1637,13 +1731,17 @@ process_user_command (struct app_context *ctx, char *command) | ||||
| 		initialized = true; | ||||
| 	} | ||||
| 
 | ||||
| 	// TODO: cut a single word (strtok_r()?)
 | ||||
| 	// TODO: if it's a number, switch to the given buffer
 | ||||
| 	char *name = cut_word (&command); | ||||
| 	if (try_handle_buffer_goto (ctx, name)) | ||||
| 		return; | ||||
| 
 | ||||
| 	struct command_handler *handler = str_map_find (&partial, command); | ||||
| 	struct command_handler *handler = str_map_find (&partial, name); | ||||
| 	if (handler) | ||||
| 		// FIXME: pass arguments correctly
 | ||||
| 		handler->handler (ctx, ""); | ||||
| 		handler->handler (ctx, command); | ||||
| 	else | ||||
| 	{ | ||||
| 		// TODO: print a "no such command" error message
 | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user