aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/api/command.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/api/command.c')
-rw-r--r--src/nvim/api/command.c32
1 files changed, 13 insertions, 19 deletions
diff --git a/src/nvim/api/command.c b/src/nvim/api/command.c
index 0ac3d42231..a21c9e70a7 100644
--- a/src/nvim/api/command.c
+++ b/src/nvim/api/command.c
@@ -305,7 +305,7 @@ end:
/// - output: (boolean, default false) Whether to return command output.
/// @param[out] err Error details, if any.
/// @return Command output (non-error, non-shell |:!|) if `output` is true, else empty string.
-String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Error *err)
+String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Arena *arena, Error *err)
FUNC_API_SINCE(10)
{
exarg_T ea;
@@ -343,7 +343,7 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Error
goto end;
});
- cmdname = string_to_cstr(cmd->cmd);
+ cmdname = arena_string(arena, cmd->cmd).data;
ea.cmd = cmdname;
char *p = find_ex_command(&ea, NULL);
@@ -352,9 +352,8 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Error
// autocommands defined, trigger the matching autocommands.
if (p != NULL && ea.cmdidx == CMD_SIZE && ASCII_ISUPPER(*ea.cmd)
&& has_event(EVENT_CMDUNDEFINED)) {
- p = xstrdup(cmdname);
+ p = arena_string(arena, cmd->cmd).data;
int ret = apply_autocmds(EVENT_CMDUNDEFINED, p, p, true, NULL);
- xfree(p);
// If the autocommands did something and didn't cause an error, try
// finding the command again.
p = (ret && !aborting()) ? find_ex_command(&ea, NULL) : ea.cmd;
@@ -383,28 +382,31 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Error
if (HAS_KEY(cmd, cmd, args)) {
// Process all arguments. Convert non-String arguments to String and check if String arguments
// have non-whitespace characters.
+ args = arena_array(arena, cmd->args.size);
for (size_t i = 0; i < cmd->args.size; i++) {
Object elem = cmd->args.items[i];
char *data_str;
switch (elem.type) {
case kObjectTypeBoolean:
- data_str = xcalloc(2, sizeof(char));
+ data_str = arena_alloc(arena, 2, false);
data_str[0] = elem.data.boolean ? '1' : '0';
data_str[1] = '\0';
+ ADD_C(args, CSTR_AS_OBJ(data_str));
break;
case kObjectTypeBuffer:
case kObjectTypeWindow:
case kObjectTypeTabpage:
case kObjectTypeInteger:
- data_str = xcalloc(NUMBUFLEN, sizeof(char));
+ data_str = arena_alloc(arena, NUMBUFLEN, false);
snprintf(data_str, NUMBUFLEN, "%" PRId64, elem.data.integer);
+ ADD_C(args, CSTR_AS_OBJ(data_str));
break;
case kObjectTypeString:
VALIDATE_EXP(!string_iswhite(elem.data.string), "command arg", "non-whitespace", NULL, {
goto end;
});
- data_str = string_to_cstr(elem.data.string);
+ ADD_C(args, elem);
break;
default:
VALIDATE_EXP(false, "command arg", "valid type", api_typename(elem.type), {
@@ -412,8 +414,6 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Error
});
break;
}
-
- ADD(args, CSTR_AS_OBJ(data_str));
}
bool argc_valid;
@@ -666,26 +666,20 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Error
}
if (opts->output && capture_local.ga_len > 1) {
- retv = (String){
- .data = capture_local.ga_data,
- .size = (size_t)capture_local.ga_len,
- };
+ // TODO(bfredl): if there are more cases like this we might want custom xfree-list in arena
+ retv = CBUF_TO_ARENA_STR(arena, capture_local.ga_data, (size_t)capture_local.ga_len);
// redir usually (except :echon) prepends a newline.
if (retv.data[0] == '\n') {
- memmove(retv.data, retv.data + 1, retv.size - 1);
- retv.data[retv.size - 1] = '\0';
- retv.size = retv.size - 1;
+ retv.data++;
+ retv.size--;
}
- goto end;
}
clear_ga:
if (opts->output) {
ga_clear(&capture_local);
}
end:
- api_free_array(args);
xfree(cmdline);
- xfree(cmdname);
xfree(ea.args);
xfree(ea.arglens);