From 51457299a9aca3673f9a6f8355aa7895409a74ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Pankowski?= Date: Sun, 21 Sep 2025 21:51:19 +0200 Subject: [PATCH] vis: implement fast jump --- vis/.config/vis/fast-jump.lua | 110 ++++++++++++++++++++++++++++++++++ vis/.config/vis/visrc.lua | 1 + 2 files changed, 111 insertions(+) create mode 100644 vis/.config/vis/fast-jump.lua diff --git a/vis/.config/vis/fast-jump.lua b/vis/.config/vis/fast-jump.lua new file mode 100644 index 0000000..7834b41 --- /dev/null +++ b/vis/.config/vis/fast-jump.lua @@ -0,0 +1,110 @@ +local lpeg = vis.lpeg + +P = lpeg.P +R = lpeg.R +S = lpeg.S +Cp = lpeg.Cp +Ct = lpeg.Ct +space = S(' \t\n\r') +alnum = R('az', 'AZ', '09') + +local function search(p) + return Ct(((1 - p)^0 * Cp() * p * Cp())^0) +end + +vis:map(vis.modes.NORMAL, '\\', function(keys) + if #keys > 1 then + vis.win:draw() + end + local _, esc = keys:find('') + if esc then + return esc + end + local _, enter = keys:find('') + if enter then + keys = keys:gsub('', '') + end + keys = keys:gsub('', 'J') + keys = keys:gsub('', 'K') + vis:info(keys) + local n = 0 + keys = keys:gsub('[KJ]', function(s) + if s == 'K' then + n = n - 1 + elseif s == 'J' then + n = n + 1 + end + return '' + end) + keys = keys:gsub('.', '') + if #keys < 1 then + return -1 + end + local up = n < 0 + local v = vis.win.viewport.bytes + local data = vis.win.file:content(v) + local p = P(false) + local prefix = nil + for i = 1, #keys do + local x = keys:sub(i, i) + if x == 'A' then + prefix = alnum + elseif x == 'F' then + prefix = P(1) - space + else + local y = S(x:lower() .. x:upper()) + if i == 1 then + p = y + elseif prefix then + p = p * (prefix - y)^0 * y + elseif x == ' ' then + p = p * space^1 + else + p = p * y + end + prefix = false + end + end + p = search(p) + local lst = p:match(data) + if not lst then + vis:info('not found') + return + end + local pos = vis.win.selection.pos + local prev = 0 + local next = 0 + for i = 2, #lst, 2 do + local a = lst[i-1] + v.start - 1 + if a < pos then + prev = i + end + if a > pos then + next = i + break + end + end + local j = 0 + if up then + j = prev + 1 + 2 * n + else + j = next - 1 + 2 * n + end + if j > 0 and j < #lst then + pos = lst[j] + v.start - 1 + end + if enter then + vis.win.selection.pos = pos + return enter + end + for i = 2, #lst, 2 do + local a = lst[i-1] + v.start - 1 + local b = lst[i] + v.start - 2 + if a == pos then + vis.win:style(vis.win.STYLE_COLOR_COLUMN, a, b) + else + vis.win:style(vis.win.STYLE_SELECTION, a, b) + end + end + return -1 +end, 'colorize token') diff --git a/vis/.config/vis/visrc.lua b/vis/.config/vis/visrc.lua index ba3e35d..aa394f6 100644 --- a/vis/.config/vis/visrc.lua +++ b/vis/.config/vis/visrc.lua @@ -1,4 +1,5 @@ require('vis') +require('fast-jump') local plug = (function() if not pcall(require, 'plugins/vis-plug') then