Files
agenda-nvim/lua/agenda/util.lua
Jonas Kattendick 16a71cadc2 feat: add agenda plugin
Import the package from my dotfiles.
2023-11-17 02:04:30 +01:00

79 lines
1.8 KiB
Lua

local M = {}
---Parses a list of arguments **kind of** like the getopts shell builtin.
---@param args string[]
---@param optstring string
---@return function
function M.getopts(args, optstring)
local spec = {}
local last
for i = 1, #optstring do
local c = optstring:sub(i, i)
if c == ':' and last then
spec[last] = true
elseif i == #optstring then
spec[c] = false
elseif last and last ~= ':' then
spec[last] = false
end
last = c
end
-- 1. if the option takes a value either
-- a. take the rest of the slice as its values if at least one char
-- remains in the slice
-- b. take the next whole argument as its value
-- 2. find the next option name (char)
local i = 1 -- arg index
local n = 1 -- slice index
local g = 1 -- I am not very smart
return function ()
while args[i] do
local arg = args[i]
-- TODO: Maybe write some tests instead :^)
if g > 2097152 then
error 'logic error'
end
g = g + 1
if n == 1 and not vim.startswith(arg, '-') then
-- "Normal" arguments end the iterator.
return
end
n = n + 1
local c = arg:sub(n, n)
if #c > n then
n = n + 1
end
if #c == 1 then
if spec[c] then
local optval = arg:sub(n + 1, #arg)
n = 1
i = i + 1
if #optval > 0 then
return i, c, optval
end
-- Remaining argument does not contain optval, consume the next argument
-- as optval.
i = i + 1
return i, c, args[i - 1]
end
-- Do not handle nil. If the opt is invalid the caller must handle it.
return i + 1, c, nil
end
-- Stray '-' ends the iterator.
return
end
end
end
return M