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; ///< All our buffers in order
|
||||||
struct buffer *buffers_tail; ///< The tail of our buffers
|
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 str_map buffers_by_name; ///< Excludes GLOBAL and SERVER
|
||||||
struct buffer *global_buffer; ///< The global buffer
|
struct buffer *global_buffer; ///< The global buffer
|
||||||
struct buffer *server_buffer; ///< The server 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);
|
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
|
// 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*
|
// history including attached data, is a pretty recent addition. *sigh*
|
||||||
#if RL_READLINE_VERSION >= 0x0603
|
#if RL_READLINE_VERSION >= 0x0603
|
||||||
@ -1524,16 +1527,107 @@ irc_process_message (const struct irc_message *msg,
|
|||||||
|
|
||||||
// --- User input handling -----------------------------------------------------
|
// --- User input handling -----------------------------------------------------
|
||||||
|
|
||||||
static void handle_command_help (struct app_context *, const char *);
|
static void handle_command_help (struct app_context *, char *);
|
||||||
|
|
||||||
static void
|
/// Cuts the longest non-whitespace portion of text and advances the pointer
|
||||||
handle_command_buffer (struct app_context *ctx, const char *arguments)
|
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
|
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)
|
if (ctx->irc_fd != -1)
|
||||||
{
|
{
|
||||||
@ -1548,7 +1642,7 @@ handle_command_quit (struct app_context *ctx, const char *arguments)
|
|||||||
static struct command_handler
|
static struct command_handler
|
||||||
{
|
{
|
||||||
char *name;
|
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
|
// TODO: probably also a usage string
|
||||||
}
|
}
|
||||||
g_command_handlers[] =
|
g_command_handlers[] =
|
||||||
@ -1586,7 +1680,7 @@ g_command_handlers[] =
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void
|
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
|
// TODO: show a list of all user commands
|
||||||
}
|
}
|
||||||
@ -1637,13 +1731,17 @@ process_user_command (struct app_context *ctx, char *command)
|
|||||||
initialized = true;
|
initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: cut a single word (strtok_r()?)
|
char *name = cut_word (&command);
|
||||||
// TODO: if it's a number, switch to the given buffer
|
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)
|
if (handler)
|
||||||
// FIXME: pass arguments correctly
|
handler->handler (ctx, command);
|
||||||
handler->handler (ctx, "");
|
else
|
||||||
|
{
|
||||||
|
// TODO: print a "no such command" error message
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Loading…
Reference in New Issue
Block a user