go.nvim/lua/go/alt_getopt.lua
2023-01-18 09:20:11 +11:00

235 lines
5.3 KiB
Lua

-- Copyright (c) 2009 Aleksey Cheusov <vle@gmx.net>
-- Copyright info:
-- https://github.com/cheusov/lua-alt-getopt/blob/f495c21d6a203ab280603aa5799e636fb5651ae7/alt_getopt.lua#L3-L20
-- updated for neovim lua JIT by ray-x
local type, pairs, ipairs, os = type, pairs, ipairs, os
local utils = require('go.utils')
local log = utils.log
local alt_getopt = {}
local function convert_short2long(opts)
local ret = {}
for short_opt, accept_arg in opts:gmatch("(%w)(:?)") do
ret[short_opt] = #accept_arg
end
return ret
end
local function err_unknown_opt(opt)
-- vim.notify("Unknown option `-" .. (#opt > 1 and "-" or "") .. opt, vim.lsp.log_levels.INFO)
end
local function canonize(options, opt)
if not options[opt] then
err_unknown_opt(opt)
end
while type(options[opt]) == "string" do
opt = options[opt]
if not options[opt] then
err_unknown_opt(opt)
end
end
return opt
end
function alt_getopt.get_ordered_opts(arg, sh_opts, long_opts)
local i = 1
local count = 1
local opts = {}
local optarg = {}
local options = convert_short2long(sh_opts)
for k, v in pairs(long_opts) do
options[k] = v
end
local unparsed = {}
while i <= #arg do
local a = arg[i]
if type(a) ~= "string" then
log('failed to decode', type(a), a)
goto continue
end
if a == "--" then
i = i + 1
break
elseif a == "-" then
break
elseif a:sub(1, 2) == "--" then
local pos = a:find("=", 1, true)
if pos then
local opt = a:sub(3, pos - 1)
opt = canonize(options, opt)
if options[opt] == 0 then
vim.notify("Bad usage of option `" .. a, vim.lsp.log_levels.ERROR)
end
optarg[count] = a:sub(pos + 1)
opts[count] = opt
else
local opt = a:sub(3)
opt = canonize(options, opt)
if options[opt] == 0 then
opts[count] = opt
else
if i == #arg then
vim.notify("Missed value for option `" .. a, vim.lsp.log_levels.ERROR)
return
end
optarg[count] = arg[i + 1]
opts[count] = opt
i = i + 1
end
end
count = count + 1
elseif a:sub(1, 1) == "-" then
for j = 2, a:len() do
local opt = canonize(options, a:sub(j, j))
if options[opt] == 0 then
opts[count] = opt
count = count + 1
elseif a:len() == j then
if i == #arg then
vim.notify("Missed value for option `-" .. opt, vim.lsp.log_levels.ERROR)
end
optarg[count] = arg[i + 1]
opts[count] = opt
i = i + 1
count = count + 1
break
else
optarg[count] = a:sub(j + 1)
opts[count] = opt
count = count + 1
break
end
end
else
table.insert(unparsed, a)
end
i = i + 1
::continue::
end
return opts, i, optarg, unparsed
end
function alt_getopt.get_opts(arg, sh_opts, long_opts)
local ret = {}
local opts, optind, optarg, unparsed = alt_getopt.get_ordered_opts(arg, sh_opts, long_opts)
for i, v in ipairs(opts) do
if optarg and optarg[i] then
ret[v] = optarg[i]
else
ret[v] = (optarg ~= nil)
end
end
return ret, optind, unparsed
end
function alt_getopt.rebuid_args(opts, reminder)
local ret = {}
for i, v in pairs(opts) do
if opts[i] == true then
table.insert(ret, "-" .. i)
else
table.insert(ret, "-" .. i)
table.insert(ret, v)
end
end
if not vim.tbl_isempty(reminder) then
vim.list_extend(ret, reminder)
end
if next(ret) == nil then
return nil
end
return ret
end
function test_arg(arg)
local long_opts = {
verbose = "v",
help = "h",
test = "t",
stop = "s",
restart = "r",
-- fake = 0,
-- len = 1,
tags = "g",
output = "o",
set_value = "S",
["set-output"] = "o",
}
local opts
local optarg, unparsed
local optind
arg = arg or { "-t", "-r", "-c", "path1", "-g", "unit,integration", "path" }
-- arg = arg or { "-t", "-r", "-c", "-g", "unit,integration" }
opts, optind, optarg, unparsed = alt_getopt.get_ordered_opts(arg, "cg:hvo:n:rS:st", long_opts)
print("ordered opts")
print(vim.inspect(opts))
print(vim.inspect(optind))
print(vim.inspect(optarg))
print(vim.inspect(unparsed))
print("ordered opts end")
for i, v in ipairs(opts) do
if optarg[i] then
print("option opts[i] " .. v .. ": " .. vim.inspect(optarg[i]))
else
print("option " .. v)
end
end
print("get_opts ")
optarg, optind, unparsed = alt_getopt.get_opts(arg, "cg:hVvo:n:rS:st", long_opts)
print("opts " .. vim.inspect(optarg))
print("optind " .. vim.inspect(optind))
print(vim.inspect(unparsed))
local fin_options = {}
for k, v in pairs(optarg) do
table.insert(fin_options, "fin-option " .. k .. ": " .. vim.inspect(v) .. "\n")
end
table.sort(fin_options)
print(table.concat(fin_options))
--
for i = optind, #arg do
print(string.format("ARGV [%s] = %s\n", i, arg[i]))
end
end
-- test_arg()
--
-- print("test 2")
--
-- test_arg({ "-tr", "-c", "-g", "unit,integration" })
-- test_arg({ "--tags", "unit,integration", "--restart" })
-- test_arg({ "run", "restart" })
-- test_arg({ "--tags", "unit,integration", "-c", "--restart" })
return alt_getopt