Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Command completion with tab key #1173

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions lua/plugins/complete-filename.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,19 @@ local complete_filename = function(expand)
range.finish = pos
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
Expand All @@ -48,4 +58,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")
13 changes: 13 additions & 0 deletions vis-cmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,19 @@ 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;
size_t len_data = strlen(data);
size_t remaining_capacity = VIS_COMMAND_BUFFER_MAX - len_data;
if (remaining_capacity >= strlen(cmd->name) + 2) /* adding 2 for \n and \0 */
snprintf((char *)data + len_data, remaining_capacity, "%s\n", cmd->name);
return true;
}

void vis_print_cmds(Vis *vis, char *cmd_list) {
map_iterate(vis->cmds, print_cmd_name, cmd_list);
}

static bool print_option(const char *key, void *value, void *txt) {
char desc[256];
const OptionDef *opt = value;
Expand Down
39 changes: 39 additions & 0 deletions vis-lua.c
Original file line number Diff line number Diff line change
Expand Up @@ -1146,6 +1146,44 @@ static int command_register(lua_State *L) {
return 1;
}

/***
* 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;
File *file = vis->win ? vis->win->file : NULL;
Filerange range = text_range_new(0, 0);

char cmd_list[VIS_COMMAND_BUFFER_MAX] = {0};
vis_print_cmds(vis, cmd_list);
char cmd[VIS_COMMAND_BUFFER_MAX + 32] = {0}; /* 32 for echo/grep/vis-menu */
sprintf(cmd, "echo '%s' | grep '^%s' | vis-menu -b", cmd_list, prefix);

int status = vis_pipe_collect(vis, file, &range, (const char*[]){ cmd, NULL }, &out, &err, false);
lua_pushinteger(L, status);
if (out)
lua_pushstring(L, out);
else
lua_pushnil(L);
free(out);
if (err)
lua_pushstring(L, err);
else
lua_pushnil(L);
free(err);
return 3;
}

/***
* Push keys to input queue and interpret them.
*
Expand Down Expand Up @@ -1531,6 +1569,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 },
Expand Down
6 changes: 6 additions & 0 deletions vis.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ typedef struct Win Win;
/* maximum bytes needed for string representation of a (pseudo) key */
#define VIS_KEY_LENGTH_MAX 64

/* maximum bytes used for list of available commands */
#define VIS_COMMAND_BUFFER_MAX 1000

/** Union used to pass arguments to key action functions. */
typedef union {
bool b;
Expand Down Expand Up @@ -838,6 +841,9 @@ bool vis_option_unregister(Vis*, const char *name);
/** Execute any kind (``:``, ``?``, ``/``) of prompt command */
bool vis_prompt_cmd(Vis*, const char *cmd);

/** Write newline separated list of available commands to ``cmd_list`` */
void vis_print_cmds(Vis*, char *cmd_list);

/**
* Pipe a given file range to an external process.
*
Expand Down
Loading