diff --git a/lua/sloth-flake/command/init.lua b/lua/sloth-flake/command/init.lua index ada16a5..e44bf1e 100644 --- a/lua/sloth-flake/command/init.lua +++ b/lua/sloth-flake/command/init.lua @@ -8,13 +8,69 @@ local commands = { version = require 'sloth-flake.command.version', } -function sloth_cmd(param) +local function parse_line(line, cursor_pos) + local raw_args = vim.split(line, ' +', { trimempty = true }) + local parse_pos = 1 + local args = vim.iter(raw_args):map(function(arg) + local start, stop = string.find(line, arg, parse_pos, { plain = true }) + parse_pos = stop + return { + arg = arg, + start = start, + stop = stop, + } + end):totable() + parse_pos = 1 + local arg_idx = 1 + vim.iter(args):find(function(arg) + if cursor_pos < arg.start then + arg_idx = arg_idx - 1 + return true + elseif cursor_pos <= arg.stop then + return true + end + arg_idx = arg_idx + 1 + return false + end) + arg_idx = arg_idx < 1 and 1 or arg_idx + if arg_idx > #args then + args[#args + 1] = { + arg = "", + start = line:len(), + stop = line:len(), + } + end + return { + line = line, + args = args, + arg_idx = arg_idx, + pos = cursor_pos, + in_arg_pos = args[arg_idx] and cursor_pos - args[arg_idx].start + 1, + } +end +-- print(vim.inspect(parse_line('Sloth ', 6))) + +local function sloth_cmd_complete(arg_lead, cmd_line, cursor_pos) + local parsed_line = parse_line(cmd_line, cursor_pos) + local arg = parsed_line.args[parsed_line.arg_idx] + if parsed_line.arg_idx == 2 then + return vim.iter(commands):map(function(name, command) + return vim.startswith(name, arg.arg) and name or nil + end):totable() + elseif parsed_line.arg_idx > 2 then + local cmd = parsed_line.args[2].arg + local command = commands[cmd] + return command and command.complete(parsed_line) + end +end + +local function sloth_cmd(param) local args = param.fargs local cmd = args[1] or "list"; table.remove(args, 1) - local fn = commands[cmd] - if fn then - fn(args) + local command = commands[cmd] + if command then + command.cmd(args) else vim.api.nvim_err_writeln(string.format([[No Sloth subcommand "%s"]], cmd)) end @@ -23,6 +79,7 @@ end function M.register() vim.api.nvim_create_user_command('Sloth', sloth_cmd, { nargs = '*', + complete = sloth_cmd_complete }) end diff --git a/lua/sloth-flake/command/list.lua b/lua/sloth-flake/command/list.lua index a1eed0e..49d4552 100644 --- a/lua/sloth-flake/command/list.lua +++ b/lua/sloth-flake/command/list.lua @@ -1,29 +1,46 @@ local Dep = require 'sloth-flake.dep' local utils = require 'sloth-flake.utils' -return function(args) - local filter = args[1] or "all" - local deps = vim.iter(Dep.all()):map(function(_, dep) - return dep.name - end) - if filter == "all" then - -- Nothing to do - elseif filter == "loaded" then - deps = deps:filter(function(dep) - return Dep.get(dep).is_loaded +local filters = { + all = {}, + loaded = {}, + notloaded = {}, +} + +return { + complete = function(line) + if line.arg_idx == 3 then + local prefix = line.args[3].arg + return vim.iter(vim.tbl_keys(filters)):filter(function(name) + return vim.startswith(name, prefix) + end):totable() + end + end, + + cmd = function(args) + local filter = args[1] or "all" + local deps = vim.iter(Dep.all()):map(function(_, dep) + return dep.name end) - elseif filter == "notloaded" then - deps = deps:filter(function(dep) - return not Dep.get(dep).is_loaded - end) - else - utils.error([[No Sloth list filter "%s".]], cmd) - utils.error("Filters are: all, loaded, notloaded") - return - end - deps = deps:totable() - table.sort(deps) - for _, dep in ipairs(deps) do - print(string.format("- %s", dep)) - end -end + if filter == "all" then + -- Nothing to do + elseif filter == "loaded" then + deps = deps:filter(function(dep) + return Dep.get(dep).is_loaded + end) + elseif filter == "notloaded" then + deps = deps:filter(function(dep) + return not Dep.get(dep).is_loaded + end) + else + utils.error([[No Sloth list filter "%s".]], cmd) + utils.error("Filters are: all, loaded, notloaded") + return + end + deps = deps:totable() + table.sort(deps) + for _, dep in ipairs(deps) do + print(string.format("- %s", dep)) + end + end, +} diff --git a/lua/sloth-flake/command/load.lua b/lua/sloth-flake/command/load.lua index cd68ddf..599575a 100644 --- a/lua/sloth-flake/command/load.lua +++ b/lua/sloth-flake/command/load.lua @@ -1,15 +1,32 @@ local Dep = require 'sloth-flake.dep' local utils = require 'sloth-flake.utils' -return function(plugins) - if #plugins == 0 then - utils.error("You should at least give a plugin to load!") - return - end - for _, plugin in ipairs(plugins) do - local dep = Dep.get(plugin) - if dep ~= nil then - dep:load() +return { + complete = function(line) + local previous_deps = vim.iter(line.args):enumerate():map(function(i, arg) + if i < 3 or i > line.arg_idx then return end + return arg.arg + end):totable() + + local prefix = line.args[line.arg_idx].arg + return vim.iter(Dep.all()):filter(function(name, dep) + return vim.startswith(name, prefix) and not dep.is_loaded + and not vim.list_contains(previous_deps, name) + end):map(function(name) + return name + end):totable() + end, + + cmd = function(plugins) + if #plugins == 0 then + utils.error("You should at least give a plugin to load!") + return end - end -end + for _, plugin in ipairs(plugins) do + local dep = Dep.get(plugin) + if dep ~= nil then + dep:load() + end + end + end, +} diff --git a/lua/sloth-flake/command/version.lua b/lua/sloth-flake/command/version.lua index f8a5689..c6f505f 100644 --- a/lua/sloth-flake/command/version.lua +++ b/lua/sloth-flake/command/version.lua @@ -1,4 +1,7 @@ -return function() - local version = require('sloth-flake.version') - print(string.format('Sloth v%s', version())) -end +return { + complete = function() end, + cmd = function() + local version = require('sloth-flake.version') + print(string.format('Sloth v%s', version())) + end, +}