yazi/yazi-plugin/preset/plugins/code.lua

104 lines
2.5 KiB
Lua

local M = {}
local function get_search_occurrences(url)
if not url.is_search then
return
end
-- Shoud we encode ~ too?
local subject_len, occurrences = tostring(url):match("^search://([^~]+)~(.-)//")
local lines = {}
for occurrence in occurrences:gmatch("[^,]+") do
local line, col = occurrence:match("(%d+)-(%d+)")
table.insert(lines, { tonumber(line), tonumber(col) })
end
if #lines == 0 then
return
end
return tonumber(subject_len), lines
end
local function get_next_occurrence_idx(search_idx, direction, occurrences_len)
local index
if direction == "up" then
index = (search_idx or 1) - 1
if index < 1 then
index = occurrences_len
end
else
index = (search_idx or 1) + 1
if index > occurrences_len then
index = 1
end
end
return index
end
function M:peek(job)
local subject_len, search_occurrences = get_search_occurrences(job.file.url)
local search_idx = job.search_idx
if search_idx == nil and search_occurrences then
local occurrence = search_occurrences[1]
local line = occurrence[1]
ya.emit("peek", {
math.max(0, line - 1),
only_if = job.file.url,
search_idx = 1,
})
return
end
local occurrence
if search_occurrences and search_idx then
occurrence = search_occurrences[search_idx]
job.position = {
line = occurrence[1],
col = occurrence[2],
length = subject_len,
}
end
local err, bound = ya.preview_code(job)
if bound then
ya.emit("peek", { bound, only_if = job.file.url, upper_bound = true, search_idx = search_idx })
elseif err and not err:find("cancelled", 1, true) then
require("empty").msg(job, err)
end
end
function M:seek(job)
local direction = job.units > 0 and "down" or "up"
local search_idx = cx.active.preview.search_idx
local h = cx.active.current.hovered
if not h or h.url ~= job.file.url then
return
end
local _, search_occurrences = get_search_occurrences(job.file.url)
if search_occurrences then
local next_occurrence_idx = get_next_occurrence_idx(search_idx, direction, #search_occurrences)
local occurrence = search_occurrences[next_occurrence_idx]
local line = occurrence[1]
ya.emit("peek", { math.max(0, line - 1), only_if = job.file.url, search_idx = next_occurrence_idx })
return
end
local step = math.floor(job.units * job.area.h / 10)
step = step == 0 and ya.clamp(-1, job.units, 1) or step
ya.emit("peek", {
math.max(0, cx.active.preview.skip + step),
only_if = job.file.url,
search_idx = search_idx,
})
end
function M:spot(job) require("file"):spot(job) end
return M