diff options
| author | Max Schillinger <maxschillinger@web.de> | 2024-03-18 10:08:40 +0100 |
|---|---|---|
| committer | Randy Palamar <randy@rnpnr.xyz> | 2025-11-28 07:41:12 -0700 |
| commit | 3f1c3ee80e46f80d7f1642009c4f9dffa404d935 (patch) | |
| tree | 08e3ab9011bcb4396ffca5f51d20c079d44da901 | |
| parent | 12fc09a442939d0af09d700c7a8074cca9b1694e (diff) | |
| download | vis-3f1c3ee80e46f80d7f1642009c4f9dffa404d935.tar.gz vis-3f1c3ee80e46f80d7f1642009c4f9dffa404d935.tar.xz | |
Add command completion with tab key
In the command prompt, press <tab> to get a list of all available
commands and pick one (using vis-menu). This works also after typing the
first letters of a command (p.e. `:la<tab>`).
Co-authored-by: Matěj Cepl <mcepl@cepl.eu>
| -rw-r--r-- | lua/plugins/complete-filename.lua | 18 | ||||
| -rw-r--r-- | vis-cmds.c | 9 | ||||
| -rw-r--r-- | vis-lua.c | 36 | ||||
| -rw-r--r-- | vis.h | 8 |
4 files changed, 67 insertions, 4 deletions
diff --git a/lua/plugins/complete-filename.lua b/lua/plugins/complete-filename.lua index 604361c..db0f2a7 100644 --- a/lua/plugins/complete-filename.lua +++ b/lua/plugins/complete-filename.lua @@ -29,9 +29,19 @@ local complete_filename = function(expand) prefix = home .. prefix:sub(j + 1) end - local cmdfmt = "vis-complete --file '%s'" - if expand then cmdfmt = "vis-open -- '%s'*" end - local status, out, err = vis:pipe(cmdfmt:format(prefix:gsub("'", "'\\''"))) + local status, out, err + if prefix:sub(1, 1) == ":" then + status, out, err = vis:complete_command(prefix:sub(2)) + if out then + out = out:gsub("\n$", ""):sub(#prefix) .. " " + end + pos = range.start + #prefix + expand = false + else + local cmdfmt = "vis-complete --file '%s'" + if expand then cmdfmt = "vis-open -- '%s'*" end + status, out, err = vis:pipe(cmdfmt:format(prefix:gsub("'", "'\\''"))) + end if status ~= 0 or not out then if err then vis:info(err) end return @@ -55,4 +65,4 @@ end, "Complete file name") -- complete file path at primary selection location using vis-open(1) vis:map(vis.modes.INSERT, "<C-x><C-o>", function() complete_filename(true); -end, "Complete file name (expands path)") +end, "Complete file name (expands path) or command") @@ -693,6 +693,15 @@ static bool print_cmd(const char *key, void *value, void *data) { return text_appendf(data, " %-30s %s\n", usage, help ? help : ""); } +static bool print_cmd_name(const char *key, void *value, void *data) { + CommandDef *cmd = value; + return buffer_appendf(data, "%s\n", cmd->name); +} + +void vis_print_cmds(Vis *vis, Buffer *buf) { + map_iterate(vis->cmds, print_cmd_name, buf); +} + static bool print_option(const char *key, void *value, void *txt) { char desc[256]; const OptionDef *opt = value; @@ -1147,6 +1147,41 @@ static int command_register(lua_State *L) { } /*** + * Let user pick a command matching the given prefix. + * + * The editor core will be blocked while the external process is running. + * + * @function complete_command + * @tparam string prefix the prefix of the command to be completed + * @treturn int code the exit status of the executed command + * @treturn string stdout the data written to stdout + * @treturn string stderr the data written to stderr + */ +static int complete_command(lua_State *L) { + Vis *vis = obj_ref_check(L, 1, "vis"); + const char *prefix = luaL_checkstring(L, 2); + char *out = NULL, *err = NULL; + char cmd[32]; + int max_prefix_len = sizeof(cmd) - sizeof("grep '^' | vis-menu -b"); // including NUL + snprintf(cmd, sizeof(cmd), "grep '^%.*s' | vis-menu -b", max_prefix_len, prefix); + + Buffer buf = {0}; + vis_print_cmds(vis, &buf); + int status = vis_pipe_buf_collect(vis, buffer_content0(&buf), (const char*[]){cmd, NULL}, &out, &err, false); + + lua_pushinteger(L, status); + if (out) lua_pushstring(L, out); + else lua_pushnil(L); + if (err) lua_pushstring(L, err); + else lua_pushnil(L); + + free(out); + free(err); + buffer_release(&buf); + return 3; +} + +/*** * Push keys to input queue and interpret them. * * The keys are processed as if they were read from the keyboard. @@ -1559,6 +1594,7 @@ static const struct luaL_Reg vis_lua[] = { { "option_register", option_register }, { "option_unregister", option_unregister }, { "command_register", command_register }, + { "complete_command", complete_command }, { "feedkeys", feedkeys }, { "insert", insert }, { "replace", replace }, @@ -14,6 +14,7 @@ typedef struct Win Win; #include "text-regex.h" #include "libutf.h" #include "array.h" +#include "buffer.h" #ifndef CONFIG_HELP #define CONFIG_HELP 1 @@ -1230,6 +1231,13 @@ bool vis_option_unregister(Vis *vis, const char *name); bool vis_prompt_cmd(Vis *vis, const char *cmd); /** + * Write newline separated list of available commands to ``buf`` + * @param vis The editor instance. + * @param buf The buffer to write to. + */ +void vis_print_cmds(Vis*, Buffer *buf); + +/** * Pipe a given file range to an external process. * @param vis The editor instance. * @param file The file to pipe. |
