Compare commits

..

2 Commits

2 changed files with 100 additions and 85 deletions

View File

@@ -1,81 +1,75 @@
require('vis')
local lpeg = vis.lpeg local lpeg = vis.lpeg
P = lpeg.P local P = lpeg.P
R = lpeg.R local Cp = lpeg.Cp
S = lpeg.S local Ct = lpeg.Ct
Cp = lpeg.Cp
Ct = lpeg.Ct
space = S(' \t\n\r')
alnum = R('az', 'AZ', '09')
local function search(p) local function search(p)
return Ct(((1 - p)^0 * Cp() * p * Cp())^0) return Ct(((1 - p)^0 * Cp() * p)^0)
end end
vis:map(vis.modes.NORMAL, '\\', function(keys) local up = {
if #keys > 1 then 'a', 's', 'd', 'f' ,
vis.win:draw() 'q', 'w', 'e', 'r', 't', 'g',
end 'z', 'x', 'c', 'v', 'b',
'1', '2', '3', '4', '5',
'A', 'S', 'D', 'F' ,
'Q', 'W', 'E', 'R', 'T', 'G',
'Z', 'X', 'C', 'V', 'B',
'!', '@', '#', '$', '%',
'`', '~',
}
local down = {
'j', 'k', 'l', ';',
'y', 'u', 'i', 'o', 'p',
'n', 'm', ',', '.', '/',
'6', '7', '8', '9', '0',
'J', 'K', 'L', ':',
'Y', 'U', 'I', 'O', 'P',
'N', 'M', '<', '>', '?',
'^', '&', '*', '(', ')',
"'", '"', '\\', '|',
}
local jumps = {}
local function jump(keys)
local _, esc = keys:find('<Escape>') local _, esc = keys:find('<Escape>')
if esc then if esc then
return esc return esc
end end
local _, enter = keys:find('<Enter>') local ret = #keys
if enter then keys = keys:gsub('<Enter>', '\n')
keys = keys:gsub('<Enter>', '') if #keys < 2 then
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 return -1
end end
local up = n < 0 if #keys > 2 then
vis:info('not found')
return ret
end
local v = vis.win.viewport.bytes local v = vis.win.viewport.bytes
local data = vis.win.file:content(v) local data = vis.win.file:content(v)
local p = P(false)
local prefix = nil local p = search(P(keys))
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) local lst = p:match(data)
if not lst then if not lst or #lst == 0 then
vis:info('not found') vis:info('not found')
return return ret
end end
local pos = vis.win.selection.pos if #lst == 1 then
vis.win.selection.pos = v.start + lst[1] - 1
return ret
end
local pos = vis.win.selection.pos - v.start
local prev = 0 local prev = 0
local next = 0 local next = #lst + 1
for i = 2, #lst, 2 do local t = {}
local a = lst[i-1] + v.start - 1 jumps = {}
for i = 1, #lst do
local a = lst[i]
if a < pos then if a < pos then
prev = i prev = i
end end
@@ -84,27 +78,53 @@ vis:map(vis.modes.NORMAL, '\\', function(keys)
break break
end end
end end
local j = 0 local j = 1
if up then for i = prev, 1, -1 do
j = prev + 1 + 2 * n if not up[j] then
break
end
t[i] = up[j]
jumps[t[i]] = v.start + lst[i] - 1
j = j + 1
end
j = 1
for i = next, #lst do
if not down[j] then
break
end
t[i] = down[j]
jumps[t[i]] = v.start + lst[i] - 1
j = j + 1
end
local input = ''
local k = 1
for i = 1, #lst do
input = input .. data:sub(k, lst[i] - 1)
if t[i] then
input = input .. '\x1b[1;37;44m' .. keys .. '\x1b[42m' .. t[i] .. '\x1b[0m'
k = lst[i] + 3
if data:sub(k - 1, k - 1) == '\n' then
k = k - 1
end
else else
j = next - 1 + 2 * n input = input .. '\x1b[1;37;44m' .. keys .. '\x1b[0m'
k = lst[i] + 2
end end
if j > 0 and j < #lst then
pos = lst[j] + v.start - 1
end end
if enter then input = input .. data:sub(k)
vis.win.selection.pos = pos
return enter local code, out, err = vis:pipe(input, 'fzf --ansi --layout=reverse-list --no-info --no-separator --color gutter:-1 --marker="" --padding 0,0,0,3 --print-query --bind change:accept')
end if code ~= 0 then
for i = 2, #lst, 2 do vis:info(err or ('fzf exit code ' .. code))
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 else
vis.win:style(vis.win.STYLE_SELECTION, a, b) local p = jumps[out:sub(1, 1)]
if p then
vis.win.selection.pos = p
else
vis:info('not found')
end end
end end
return -1 return ret
end, 'colorize token') end
vis:map(vis.modes.NORMAL, '\\', jump)

View File

@@ -262,12 +262,7 @@ local function add_note()
local lines = vis.win.file.lines local lines = vis.win.file.lines
lines[#lines + 1] = '## ' lines[#lines + 1] = '## '
local pos = vis.win.file.size - 1 local pos = vis.win.file.size - 1
local code, date, err = vis:pipe("date '+%F %T'") lines[#lines + 1] = '* time: ' .. os.date('%Y-%m-%d %X')
if code ~= 0 then
vis:message(err)
else
lines[#lines + 1] = '* time: ' .. date:gsub('%s+$', '')
end
if line then if line then
lines[#lines + 1] = '* line: ' .. line lines[#lines + 1] = '* line: ' .. line
end end