diff options
| author | Olivia Kinnear <git@superatomic.dev> | 2026-03-28 22:07:04 -0500 |
|---|---|---|
| committer | Olivia Kinnear <git@superatomic.dev> | 2026-04-10 11:08:26 -0500 |
| commit | 8715877417b5c5fee98e6cac9e4e60ca08050048 (patch) | |
| tree | c0283a005101a7507e9f78b28fd6eede384cf073 /src | |
| parent | 6bea0cdbdcb576fa9633521dbb560985e8f0076b (diff) | |
feat(ex): add `:log` command
Diffstat (limited to 'src')
| -rw-r--r-- | src/nvim/cmdexpand.c | 43 | ||||
| -rw-r--r-- | src/nvim/cmdexpand_defs.h | 1 | ||||
| -rw-r--r-- | src/nvim/ex_cmds.lua | 6 | ||||
| -rw-r--r-- | src/nvim/ex_docmd.c | 25 |
4 files changed, 75 insertions, 0 deletions
diff --git a/src/nvim/cmdexpand.c b/src/nvim/cmdexpand.c index 04fcde7ee6..6030197357 100644 --- a/src/nvim/cmdexpand.c +++ b/src/nvim/cmdexpand.c @@ -1304,6 +1304,7 @@ char *addstar(char *fname, size_t len, int context) && fname[0] == '/') || context == EXPAND_CHECKHEALTH || context == EXPAND_LSP + || context == EXPAND_LOG || context == EXPAND_LUA) { retval = xstrnsave(fname, len); } else { @@ -2316,6 +2317,10 @@ static const char *set_context_by_cmdname(const char *cmd, cmdidx_T cmdidx, expa xp->xp_context = EXPAND_CHECKHEALTH; break; + case CMD_log: + xp->xp_context = EXPAND_LOG; + break; + case CMD_lsp: xp->xp_context = EXPAND_LSP; break; @@ -2858,6 +2863,43 @@ static char *get_healthcheck_names(expand_T *xp FUNC_ATTR_UNUSED, int idx) return NULL; } +/// Completion for |:log| command. +/// +/// Given to ExpandGeneric() to obtain `:log` completion. +/// @param[in] idx Index of the item. +/// @param[in] xp Not used. +static char *get_log_arg(expand_T *xp FUNC_ATTR_UNUSED, int idx) +{ + static Object names = OBJECT_INIT; + static char *last_xp_line = NULL; + static unsigned last_gen = 0; + + if (last_xp_line == NULL || strcmp(last_xp_line, + xp->xp_line) != 0 + || last_gen != get_cmdline_last_prompt_id()) { + xfree(last_xp_line); + last_xp_line = xstrdup(xp->xp_line); + MAXSIZE_TEMP_ARRAY(args, 1); + Error err = ERROR_INIT; + + ADD_C(args, CSTR_AS_OBJ(xp->xp_line)); + // Build the current command line as a Lua string argument + Object res = NLUA_EXEC_STATIC("return require'vim._core.ex_cmd'.log_complete(...)", args, + kRetObject, NULL, + &err); + api_clear_error(&err); + api_free_object(names); + names = res; + last_gen = get_cmdline_last_prompt_id(); + } + + if (names.type == kObjectTypeArray && idx < (int)names.data.array.size + && names.data.array.items[idx].type == kObjectTypeString) { + return names.data.array.items[idx].data.string.data; + } + return NULL; +} + /// Completion for |:lsp| command. /// /// Given to ExpandGeneric() to obtain `:lsp` completion. @@ -2937,6 +2979,7 @@ static int ExpandOther(char *pat, expand_T *xp, regmatch_T *rmp, char ***matches { EXPAND_SCRIPTNAMES, get_scriptnames_arg, true, false }, { EXPAND_RETAB, get_retab_arg, true, true }, { EXPAND_CHECKHEALTH, get_healthcheck_names, true, false }, + { EXPAND_LOG, get_log_arg, true, false }, { EXPAND_LSP, get_lsp_arg, true, false }, }; int ret = FAIL; diff --git a/src/nvim/cmdexpand_defs.h b/src/nvim/cmdexpand_defs.h index 3535e216d6..532ea7fd11 100644 --- a/src/nvim/cmdexpand_defs.h +++ b/src/nvim/cmdexpand_defs.h @@ -119,6 +119,7 @@ enum { EXPAND_CHECKHEALTH, EXPAND_LUA, EXPAND_LSP, + EXPAND_LOG, }; /// Type used by ExpandGeneric() diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua index 93cc0f3bfe..679b2d25ae 100644 --- a/src/nvim/ex_cmds.lua +++ b/src/nvim/ex_cmds.lua @@ -1587,6 +1587,12 @@ M.cmds = { func = 'ex_lockvar', }, { + command = 'log', + flags = bit.bor(EXTRA, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_log', + }, + { command = 'lolder', flags = bit.bor(RANGE, COUNT, TRLBAR), addr_type = 'ADDR_UNSIGNED', diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 2f332a6e33..3971bf998b 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -8291,6 +8291,31 @@ static void ex_terminal(exarg_T *eap) do_cmdline_cmd(ex_cmd); } +/// ":log {name}" +static void ex_log(exarg_T *eap) +{ + Error err = ERROR_INIT; + MAXSIZE_TEMP_ARRAY(args, 2); + + char mods[1024]; + size_t mods_len = 0; + mods[0] = NUL; + + if (cmdmod.cmod_tab > 0 || cmdmod.cmod_split != 0) { + bool multi_mods = false; + mods_len = add_win_cmd_modifiers(mods, &cmdmod, &multi_mods); + assert(mods_len < sizeof(mods)); + } + ADD_C(args, CSTR_AS_OBJ(eap->arg)); + ADD_C(args, STRING_OBJ(((String){ .data = mods, .size = mods_len }))); + + NLUA_EXEC_STATIC("require'vim._core.ex_cmd'.ex_log(...)", args, kRetNilBool, NULL, &err); + if (ERROR_SET(&err)) { + emsg_multiline(err.msg, "lua_error", HLF_E, true); + } + api_clear_error(&err); +} + /// ":lsp {subcmd} {clients}" static void ex_lsp(exarg_T *eap) { |
