234 lines
5.3 KiB
Lua
234 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.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.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.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.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
|