-- Copyright (c) 2009 Aleksey Cheusov -- 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