vis: implement fast jump
This commit is contained in:
110
vis/.config/vis/fast-jump.lua
Normal file
110
vis/.config/vis/fast-jump.lua
Normal file
@@ -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('<Escape>')
|
||||||
|
if esc then
|
||||||
|
return esc
|
||||||
|
end
|
||||||
|
local _, enter = keys:find('<Enter>')
|
||||||
|
if enter then
|
||||||
|
keys = keys:gsub('<Enter>', '')
|
||||||
|
end
|
||||||
|
keys = keys:gsub('<Tab>', 'J')
|
||||||
|
keys = keys:gsub('<S[-]Tab>', '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('.<Backspace>', '')
|
||||||
|
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')
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
require('vis')
|
require('vis')
|
||||||
|
require('fast-jump')
|
||||||
|
|
||||||
local plug = (function()
|
local plug = (function()
|
||||||
if not pcall(require, 'plugins/vis-plug') then
|
if not pcall(require, 'plugins/vis-plug') then
|
||||||
|
|||||||
Reference in New Issue
Block a user