From eded38c7b59447cff7598d6cd0d9ff89b501aaa6 Mon Sep 17 00:00:00 2001 From: sammyette Date: Sat, 2 Dec 2023 12:35:12 -0400 Subject: [PATCH] feat: add completions for sudo --- .../{completions.lua => completions/init.lua} | 20 +++++++ nature/completions/sudo.lua | 53 +++++++++++++++++++ 2 files changed, 73 insertions(+) rename nature/{completions.lua => completions/init.lua} (60%) create mode 100644 nature/completions/sudo.lua diff --git a/nature/completions.lua b/nature/completions/init.lua similarity index 60% rename from nature/completions.lua rename to nature/completions/init.lua index f8127a1..a77a264 100644 --- a/nature/completions.lua +++ b/nature/completions/init.lua @@ -1,3 +1,23 @@ +local fs = require 'fs' + +-- explanation: this specific function gives to us info about +-- the currently running source. this includes a path to the +-- source file (info.source) +-- we will use that to automatically load all commands by reading +-- all the files in this dir and just requiring it. +local info = debug.getinfo(1) +local commandDir = fs.dir(info.source) +if commandDir == '.' then return end + +local commands = fs.readdir(commandDir) +for _, command in ipairs(commands) do + local name = command:gsub('%.lua', '') -- chop off extension + if name ~= 'init' then + -- skip this file (for obvious reasons) + require('nature.completions.' .. name) + end +end + function hilbish.completion.handler(line, pos) if type(line) ~= 'string' then error '#1 must be a string' end if type(pos) ~= 'number' then error '#2 must be a number' end diff --git a/nature/completions/sudo.lua b/nature/completions/sudo.lua new file mode 100644 index 0000000..5ca31e4 --- /dev/null +++ b/nature/completions/sudo.lua @@ -0,0 +1,53 @@ +local function curry(f) + return function (x) return function (y) return f(x,y) end end +end + +local flags = {} +local function flag(f, description) + flags[f] = {description} +end + +local addflag = curry(flag) + +addflag '-A' 'Ask for password via askpass or $SUDO_ASKPASS' +addflag '-B' 'Ring the bell as part of the password prompt.' + +hilbish.complete('command.sudo', function(query, ctx, fields) + table.remove(fields, 1) + local nonflags = table.filter(fields, function(v) + if v == '' then + return false + end + return v:match '^%-' == nil + end) + + if #fields == 1 or #nonflags == 0 then + -- complete commands or sudo flags + if query:match ('^%-') then + local compFlags = {} + for flg, flgstuff in pairs(flags) do + if flg:match('^' .. query) then + compFlags[flg] = flgstuff + end + end + + local compGroup = { + items = compFlags, + type = 'list' + } + + return {compGroup}, query + end + + local comps, pfx = hilbish.completion.bins(query, ctx, fields) + local compGroup = { + items = comps, + type = 'grid' + } + + return {compGroup}, pfx + end + + -- otherwise, get command flags + return hilbish.completion.call('command.' .. fields[2], query, ctx, fields) +end)