debugger support

This commit is contained in:
kepler155c@gmail.com
2020-05-23 21:45:05 -06:00
parent 97bfae10fb
commit 26bbb50981
6 changed files with 194 additions and 62 deletions

View File

@@ -7,41 +7,41 @@ local sub = string.sub
-- https://rosettacode.org/wiki/Jaro_distance (ported to lua)
return function(s1, s2)
local l1, l2 = #s1, #s2;
if l1 == 0 then
if l1 == 0 then
return l2 == 0 and 1.0 or 0.0
end
local match_distance = max(floor(max(l1, l2) / 2) - 1, 0)
local s1_matches = { }
local s2_matches = { }
local matches = 0
local s1_matches = { }
local s2_matches = { }
local matches = 0
for i = 1, l1 do
local _end = min(i + match_distance + 1, l2)
local _end = min(i + match_distance + 1, l2)
for k = max(1, i - match_distance), _end do
if not s2_matches[k] and sub(s1, i, i) == sub(s2, k, k) then
s1_matches[i] = true
s2_matches[k] = true
matches = matches + 1
break
if not s2_matches[k] and sub(s1, i, i) == sub(s2, k, k) then
s1_matches[i] = true
s2_matches[k] = true
matches = matches + 1
break
end
end
end
if matches == 0 then
if matches == 0 then
return 0.0
end
local t = 0.0
local k = 1
local t = 0.0
local k = 1
for i = 1, l1 do
if s1_matches[i] then
if s1_matches[i] then
while not s2_matches[k] do
k = k + 1
end
if sub(s1, i, i) ~= sub(s2, k, k) then
t = t + 0.5
end
k = k + 1
k = k + 1
end
end
@@ -51,6 +51,6 @@ return function(s1, s2)
b = b + .5
end
local m = matches
return (m / l1 + m / l2 + (m - t) / m) / 3.0 + b
local m = matches
return (m / l1 + m / l2 + (m - t) / m) / 3.0 + b
end

View File

@@ -12,6 +12,10 @@ local function traceback(x)
return x
end
if x and x:match(':%d+: 0$') then
return x
end
if debug_traceback then
-- The parens are important, as they prevent a tail call occuring, meaning
-- the stack level is preserved. This ensures the code behaves identically
@@ -65,7 +69,7 @@ local function trim_traceback(stack)
local t = { }
for _, line in pairs(trace) do
if not matchesFilter(line) then
line = line:gsub("in function", "in")
line = line:gsub("in function", "in"):gsub('%w+/', '')
table.insert(t, line)
end
end
@@ -84,9 +88,15 @@ return function (fn, ...)
if not res[1] and res[2] ~= nil then
local err, trace = trim_traceback(res[2])
_G._syslog('\n' .. err .. '\n' .. 'stack traceback:')
for _, v in ipairs(trace) do
_G._syslog(v)
if #trace > 0 then
_G._syslog('\n' .. err .. '\n' .. 'stack traceback:')
for _, v in ipairs(trace) do
_G._syslog(v)
end
end
if err:match(':%d+: 0$') then
return true
end
return res[1], err, trace

View File

@@ -0,0 +1,107 @@
local class = require('opus.class')
local fuzzy = require('opus.fuzzy')
local UI = require('opus.ui')
local fs = _G.fs
local _insert = table.insert
UI.QuickSelect = class(UI.Window)
UI.QuickSelect.defaults = {
UIElement = 'QuickSelect',
}
function UI.QuickSelect:postInit()
self.filterEntry = UI.TextEntry {
x = 2, y = 2, ex = -2,
shadowText = 'File name',
accelerators = {
[ 'enter' ] = 'accept',
[ 'up' ] = 'grid_up',
[ 'down' ] = 'grid_down',
},
}
self.grid = UI.ScrollingGrid {
x = 2, y = 3, ex = -2, ey = -4,
disableHeader = true,
columns = {
{ key = 'name' },
{ key = 'dir', textColor = 'lightGray' },
},
accelerators = {
grid_select = 'accept',
},
}
self.cancel = UI.Button {
x = -9, y = -2,
text = 'Cancel',
event = 'select_cancel',
}
end
function UI.QuickSelect:draw()
self:fillArea(1, 1, self.width, self.height, string.rep('\127', self.width), 'black', 'gray')
self:drawChildren()
end
function UI.QuickSelect:applyFilter(filter)
if filter then
filter = filter:lower()
self.grid.sortColumn = 'score'
for _,v in pairs(self.grid.values) do
v.score = -fuzzy(v.lname, filter)
end
else
self.grid.sortColumn = 'lname'
end
self.grid:update()
self.grid:setIndex(1)
end
function UI.QuickSelect:enable()
self.grid.values = { }
local function recurse(dir)
local files = fs.list(dir)
for _,f in ipairs(files) do
local fullName = fs.combine(dir, f)
if fs.native.isDir(fullName) then -- skip virtual dirs
if f ~= '.git' then recurse(fullName) end
else
_insert(self.grid.values, {
name = f,
dir = dir,
lname = f:lower(),
fullName = fullName,
})
end
end
end
recurse('')
self:applyFilter()
self.filterEntry:reset()
UI.Window.enable(self)
end
function UI.QuickSelect:eventHandler(event)
if event.type == 'grid_up' then
self.grid:emit({ type = 'scroll_up' })
return true
elseif event.type == 'grid_down' then
self.grid:emit({ type = 'scroll_down' })
return true
elseif event.type == 'accept' then
local sel = self.grid:getSelected()
if sel then
self:emit({ type = 'select_file', file = sel.fullName, element = self })
end
return true
elseif event.type == 'text_change' then
self:applyFilter(event.text)
self.grid:draw()
return true
end
end