degesch: allow multiple commands in aliases
Separated by ;, which can be escaped as $;
This commit is contained in:
parent
1b56b4ee72
commit
403dbc83ab
116
degesch.c
116
degesch.c
@ -8034,59 +8034,75 @@ process_user_command
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static const char *
|
||||||
expand_alias_definition (const struct str *definition, const char *arguments)
|
expand_alias_escape (const char *p, const char *arguments, struct str *output)
|
||||||
{
|
{
|
||||||
struct str_vector v;
|
struct str_vector words;
|
||||||
str_vector_init (&v);
|
str_vector_init (&words);
|
||||||
cstr_split_ignore_empty (arguments, ' ', &v);
|
cstr_split_ignore_empty (arguments, ' ', &words);
|
||||||
|
|
||||||
|
// TODO: eventually also add support for argument ranges
|
||||||
|
int as_number = *p - '0';
|
||||||
|
if (as_number > 0 && as_number <= 9
|
||||||
|
&& (size_t) as_number <= words.len)
|
||||||
|
str_append (output, words.vector[as_number - 1]);
|
||||||
|
else if (*p == '*')
|
||||||
|
str_append (output, arguments);
|
||||||
|
else if (strchr ("$;", *p))
|
||||||
|
str_append_c (output, *p);
|
||||||
|
else
|
||||||
|
str_append_printf (output, "$%c", *p);
|
||||||
|
|
||||||
|
str_vector_free (&words);
|
||||||
|
return ++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
expand_alias_definition (const struct str *definition, const char *arguments,
|
||||||
|
struct str_vector *commands)
|
||||||
|
{
|
||||||
struct str expanded;
|
struct str expanded;
|
||||||
str_init (&expanded);
|
str_init (&expanded);
|
||||||
|
|
||||||
// TODO: eventually also support argument ranges
|
|
||||||
bool escape = false;
|
bool escape = false;
|
||||||
for (const char *p = definition->str; *p; p++)
|
for (const char *p = definition->str; *p; p++)
|
||||||
{
|
{
|
||||||
if (!escape)
|
if (escape)
|
||||||
{
|
{
|
||||||
if (*p == '$' && p[1])
|
p = expand_alias_escape (p, arguments, &expanded);
|
||||||
|
escape = false;
|
||||||
|
}
|
||||||
|
else if (*p == ';')
|
||||||
|
{
|
||||||
|
str_vector_add_owned (commands, str_steal (&expanded));
|
||||||
|
str_init (&expanded);
|
||||||
|
}
|
||||||
|
else if (*p == '$' && p[1])
|
||||||
escape = true;
|
escape = true;
|
||||||
else
|
else
|
||||||
str_append_c (&expanded, *p);
|
str_append_c (&expanded, *p);
|
||||||
continue;
|
}
|
||||||
|
str_vector_add_owned (commands, str_steal (&expanded));
|
||||||
}
|
}
|
||||||
|
|
||||||
int as_number = *p - '0';
|
static bool
|
||||||
if (as_number > 0 && as_number <= 9
|
expand_alias (struct app_context *ctx,
|
||||||
&& (size_t) as_number <= v.len)
|
const char *alias_name, char *input, struct str_vector *commands)
|
||||||
str_append (&expanded, v.vector[as_number - 1]);
|
|
||||||
else if (*p == '*')
|
|
||||||
str_append (&expanded, arguments);
|
|
||||||
else if (*p == '$')
|
|
||||||
str_append_c (&expanded, '$');
|
|
||||||
else
|
|
||||||
str_append_printf (&expanded, "$%c", *p);
|
|
||||||
escape = false;
|
|
||||||
}
|
|
||||||
str_vector_free (&v);
|
|
||||||
return str_steal (&expanded);
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *
|
|
||||||
expand_alias (struct app_context *ctx, const char *alias_name, char *input)
|
|
||||||
{
|
{
|
||||||
struct config_item_ *entry =
|
struct config_item_ *entry =
|
||||||
str_map_find (get_aliases_config (ctx), alias_name);
|
str_map_find (get_aliases_config (ctx), alias_name);
|
||||||
if (!entry)
|
if (!entry)
|
||||||
return NULL;
|
return false;
|
||||||
|
|
||||||
if (config_item_type_is_string (entry->type))
|
|
||||||
return expand_alias_definition (&entry->value.string, input);
|
|
||||||
|
|
||||||
|
if (!config_item_type_is_string (entry->type))
|
||||||
|
{
|
||||||
log_global_error (ctx, "Error executing `/%s': %s",
|
log_global_error (ctx, "Error executing `/%s': %s",
|
||||||
alias_name, "alias definition is not a string");
|
alias_name, "alias definition is not a string");
|
||||||
return NULL;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
expand_alias_definition (&entry->value.string, input, commands);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
@ -8123,30 +8139,46 @@ send_message_to_current_buffer (struct app_context *ctx, char *message)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static bool process_input_utf8 (struct app_context *, char *, int);
|
||||||
|
|
||||||
|
static bool
|
||||||
|
process_alias (struct app_context *ctx, struct str_vector *commands, int level)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < commands->len; i++)
|
||||||
|
log_global_debug (ctx, "Alias expanded to: ###d: \"#s\"",
|
||||||
|
(int) i, commands->vector[i]);
|
||||||
|
for (size_t i = 0; i < commands->len; i++)
|
||||||
|
if (!process_input_utf8 (ctx, commands->vector[i], ++level))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
process_input_utf8 (struct app_context *ctx, char *input, int alias_level)
|
process_input_utf8 (struct app_context *ctx, char *input, int alias_level)
|
||||||
{
|
{
|
||||||
if (*input != '/' || *++input == '/')
|
if (*input != '/' || *++input == '/')
|
||||||
{
|
{
|
||||||
send_message_to_current_buffer (ctx, input);
|
send_message_to_current_buffer (ctx, input);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *name = cut_word (&input);
|
char *name = cut_word (&input);
|
||||||
if (process_user_command (ctx, name, input))
|
if (process_user_command (ctx, name, input))
|
||||||
return;
|
return true;
|
||||||
|
|
||||||
char *expanded = expand_alias (ctx, name, input);
|
struct str_vector commands;
|
||||||
if (expanded)
|
str_vector_init (&commands);
|
||||||
log_global_debug (ctx, "Alias expanded to \"#s\"", expanded);
|
|
||||||
|
|
||||||
if (!expanded)
|
bool result = false;
|
||||||
|
if (!expand_alias (ctx, name, input, &commands))
|
||||||
log_global_error (ctx, "#s: /#s", "No such command or alias", name);
|
log_global_error (ctx, "#s: /#s", "No such command or alias", name);
|
||||||
else if (alias_level != 0)
|
else if (alias_level != 0)
|
||||||
log_global_error (ctx, "#s: /#s", "Aliases can't nest", name);
|
log_global_error (ctx, "#s: /#s", "Aliases can't nest", name);
|
||||||
else
|
else
|
||||||
process_input_utf8 (ctx, expanded, ++alias_level);
|
result = process_alias (ctx, &commands, alias_level);
|
||||||
free (expanded);
|
|
||||||
|
str_vector_free (&commands);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -8156,7 +8188,7 @@ process_input (struct app_context *ctx, char *user_input)
|
|||||||
if (!(input = iconv_xstrdup (ctx->term_to_utf8, user_input, -1, NULL)))
|
if (!(input = iconv_xstrdup (ctx->term_to_utf8, user_input, -1, NULL)))
|
||||||
print_error ("character conversion failed for `%s'", "user input");
|
print_error ("character conversion failed for `%s'", "user input");
|
||||||
else
|
else
|
||||||
process_input_utf8 (ctx, input, 0);
|
(void) process_input_utf8 (ctx, input, 0);
|
||||||
free (input);
|
free (input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user