darkrc/vim/plugin/matcha.lua

97 lines
2.1 KiB
Lua

local function nextcol(state)
local from, to = state.str:find(state.pattern, state.last)
if from then
state.last = to+1
return from, to
end
end
local function isfile(path)
return vim.fn.isdirectory(path) == 0
end
local function colmatch(str, pattern)
return nextcol, {str=str,pattern=pattern,last=0}
end
local function findLocations(pattern, first_glob, ...)
local paths if first_glob then
paths = vim.fn.glob(first_glob, false, true)
if ... then
for _, glob in ipairs { ... } do
for _, path in ipairs(vim.fn.glob(glob, false, true)) do
-- Assume overhead of table.insert is outweighed by all the file ops anyway
table.insert(paths, path)
end
end
end
else
paths = vim.fn.argv()
end
local locations = {}
for _, path in ipairs(paths) do
local lnum = 0
if isfile(path) then
for line in io.lines(path) do
lnum = lnum + 1
for from, to in colmatch(line, pattern) do
table.insert(locations, {
filename = path;
lnum = lnum;
col = from;
end_col = to;
text = line:sub(from, to)
})
end
end
end
end
return locations
end
local parse_args do
if pcall(require, "arrr") then
local arrr = require "arrr"
parse_args = arrr {
{ "Use location list instead of quickfix list", "--location-list", "-l" };
{ "Appends to the current quicklist", "--append", "-a" };
{ "Replaces the current quicklist", "--replace", "-r" };
}
else
function parse_args(args)
return args
end
end
end
vim.api.nvim_create_user_command("Matcha", function(params)
local args = parse_args(params.fargs)
local locations = findLocations(unpack(args))
if not locations[1] then return print("Nothing found") end
local action if args.append then
action = "a"
elseif args.replace then
action = "u"
else
action = " "
end
local what = { title = string.format("Matcha: `%s`", args[1]), items = locations }
if args.locationlist then
vim.fn.setloclist(0, {}, action, what)
vim.cmd("lopen")
vim.cmd("lrewind")
else
vim.fn.setqflist({}, action, what)
vim.cmd("copen")
vim.cmd("crewind")
end
end, {nargs="+"})