Cleaner and better.

This commit is contained in:
Bruce Hill 2018-03-14 18:45:32 -07:00
parent b208ccb782
commit b014887266
2 changed files with 159 additions and 146 deletions

View File

@ -2,7 +2,7 @@ local C = require("curses")
local repr = require('repr')
local COLORS = { }
local run_debugger, guard, stdscr
local AUTO = -1
local AUTO = { }
local log = io.open("output.log", "w")
local callstack_range
callstack_range = function()
@ -51,10 +51,13 @@ do
return
end
self.active = active
return self._pad:attrset(active and self.colors.active_frame or self.colors.inactive_frame)
return self._frame:attrset(active and self.colors.active_frame or self.colors.inactive_frame)
end,
select = function(self, i)
if i == self.selected or #self.lines == 0 then
if #self.lines == 0 then
i = nil
end
if i == self.selected then
return self.selected
end
if i ~= nil then
@ -62,62 +65,56 @@ do
end
if self.selected then
local j = self.selected
local attr = (j % 2 == 0) and self.colors.even_row or self.colors.odd_row
local attr = self.colors.line_colors[j]
self.chstrs[j]:set_str(0, self.lines[j], attr)
self.chstrs[j]:set_str(#self.lines[j], ' ', attr, self.chstrs[j]:len() - #self.lines[j])
self._pad:mvaddchstr(j - 1 + 1, 0 + 1, self.chstrs[j])
self._pad:mvaddchstr(j - 1, 0, self.chstrs[j])
end
if i then
local attr = self.active and self.colors.active or self.colors.highlight
self.chstrs[i]:set_str(0, self.lines[i], attr)
self.chstrs[i]:set_str(#self.lines[i], ' ', attr, self.chstrs[i]:len() - #self.lines[i])
self._pad:mvaddchstr(i - 1 + 1, 0 + 1, self.chstrs[i])
self._pad:mvaddchstr(i - 1, 0, self.chstrs[i])
local scrolloff = 3
if i > self.scroll_y + (self.height - 2) - scrolloff then
self.scroll_y = i - (self.height - 2) + scrolloff
elseif i < self.scroll_y + scrolloff then
self.scroll_y = i - scrolloff
end
self.scroll_y = math.max(1, math.min(#self.lines, self.scroll_y))
end
self.selected = i
if self.selected then
if self.scroll_y + self.height - 1 < self.selected then
self.scroll_y = math.min(self.selected - (self.height - 1), #self.lines - self.height)
elseif self.scroll_y + 1 > self.selected then
self.scroll_y = self.selected - 1
end
end
self:refresh()
if self.on_select then
self:on_select(self.selected)
end
return self.selected
end,
scroll = function(self, delta)
if self.selected == nil then
return self:select(1)
scroll = function(self, dy, dx)
if self.selected ~= nil then
self:select(self.selected + (dy or 0))
else
self.scroll_y = math.max(1, math.min(self._height - self.height, self.scroll_y + (dy or 0)))
end
return self:select(self.selected + delta)
self.scroll_x = math.max(1, math.min(self._width - self.width, self.scroll_x + (dx or 0)))
return self:refresh()
end,
refresh = function(self)
self._pad:border(C.ACS_VLINE, C.ACS_VLINE, C.ACS_HLINE, C.ACS_HLINE, C.ACS_ULCORNER, C.ACS_URCORNER, C.ACS_LLCORNER, C.ACS_LRCORNER)
self._frame:border(C.ACS_VLINE, C.ACS_VLINE, C.ACS_HLINE, C.ACS_HLINE, C.ACS_ULCORNER, C.ACS_URCORNER, C.ACS_LLCORNER, C.ACS_LRCORNER)
if self.label then
self._pad:mvaddstr(0, math.floor((self.width - #self.label - 2) / 2), " " .. tostring(self.label) .. " ")
self._frame:mvaddstr(0, math.floor((self.width - #self.label - 2) / 2), " " .. tostring(self.label) .. " ")
end
return self._pad:pnoutrefresh(self.scroll_y, self.scroll_x, self.y, self.x, self.y + self.height + 1, self.x + self.width)
self._frame:refresh()
local h, w = math.min(self.height - 2, self._height), math.min(self.width - 2, self._width)
return self._pad:pnoutrefresh(self.scroll_y - 1, self.scroll_x - 1, self.y + 1, self.x + 1, self.y + h, self.x + w)
end,
erase = function(self)
self._pad:erase()
return self._pad:pnoutrefresh(self.scroll_y, self.scroll_x, self.y, self.x, self.y + self.height, self.x + self.width)
self._frame:erase()
return self._frame:refresh()
end,
clear = function(self)
self:erase()
self.lines = { }
self.chstrs = { }
self:set_internal_size(2, 2)
if self.resize_height then
self:set_size(self._height, self.width)
end
if self.resize_width then
self:set_size(self.height, self._width)
end
self.selected = nil
self.scroll_y, self.scroll_x = 0, 0
return self:refresh()
__gc = function(self)
self._frame:cancel()
return self._pad:cancel()
end
}
_base_0.__index = _base_0
@ -132,28 +129,29 @@ do
__index = default_colors
})
end
self.scroll_y, self.scroll_x = 0, 0
self.scroll_y, self.scroll_x = 1, 1
self.selected = nil
if self.width == AUTO then
self.width = 2
local _list_0 = self.lines
for _index_0 = 1, #_list_0 do
local x = _list_0[_index_0]
self.width = math.max(self.width, #x + 2)
end
end
self._width = self.width
self._height = #self.lines
if self.height == AUTO then
self.height = #self.lines + 2
self.height = self._height + 2
end
self._height = self.height
self._width = 0
local _list_0 = self.lines
for _index_0 = 1, #_list_0 do
local x = _list_0[_index_0]
self._width = math.max(self._width, #x + 2)
end
if self.width == AUTO then
self.width = self._width + 2
end
self._frame = C.newwin(self.height, self.width, self.y, self.x)
self._pad = C.newpad(self._height, self._width)
self._pad:scrollok(true)
self:set_active(false)
self.chstrs = { }
for i, line in ipairs(self.lines) do
local attr = (i % 2 == 0) and self.colors.even_row or self.colors.odd_row
local chstr = C.new_chstr(self.width - 2)
local attr = self.colors.line_colors[i]
local chstr = C.new_chstr(self._width)
self.chstrs[i] = chstr
if #line >= chstr:len() then
line = line:sub(1, chstr:len())
@ -161,7 +159,7 @@ do
line = line .. (" "):rep(chstr:len() - #line)
end
chstr:set_str(0, line, attr)
self._pad:mvaddchstr(i - 1 + 1, 0 + 1, chstr)
self._pad:mvaddchstr(i - 1, 0, chstr)
end
return self:refresh()
end,
@ -234,8 +232,11 @@ run_debugger = function(err_msg)
default_colors = {
active_frame = COLORS.BLUE,
inactive_frame = COLORS.BROWN,
odd_row = COLORS.REGULAR,
even_row = COLORS.INVERTED,
line_colors = setmetatable({ }, {
__index = function(self, i)
return (i % 2 == 0 and COLORS.INVERTED or COLORS.REGULAR)
end
}),
highlight = COLORS.WHITE_BG,
active = COLORS.YELLOW_BG
}
@ -248,8 +249,11 @@ run_debugger = function(err_msg)
err_msg_lines[i] = (" "):rep(math.floor((SCREEN_W - 2 - #line) / 2)) .. line
end
pads.err = Pad(0, 0, AUTO, SCREEN_W, err_msg_lines, "Error Message", {
even_row = COLORS.RED | C.A_BOLD,
odd_row = COLORS.RED | C.A_BOLD,
line_colors = setmetatable({ }, {
__index = function()
return COLORS.RED | C.A_BOLD
end
}),
inactive_frame = COLORS.RED | C.A_DIM
})
end
@ -303,30 +307,19 @@ run_debugger = function(err_msg)
show_src = function(filename, line_no)
local file = file_cache[filename]
local src_lines = { }
local selected = nil
local err_line = nil
if file then
local i = 0
for line in file:gmatch("[^\n]*") do
local _continue_0 = false
repeat
i = i + 1
if i < line_no - (pads.stack.height - 2) / 2 then
_continue_0 = true
break
end
table.insert(src_lines, line)
if i == line_no then
selected = #src_lines
end
if #src_lines >= pads.stack.height - 2 then
break
end
_continue_0 = true
until true
if not _continue_0 then
break
i = i + 1
table.insert(src_lines, line)
if i == line_no then
err_line = #src_lines
end
end
while #src_lines < pads.stack.height do
table.insert(src_lines, "")
end
else
table.insert(src_lines, "<no source code found>")
end
@ -334,10 +327,15 @@ run_debugger = function(err_msg)
pads.src:erase()
end
pads.src = Pad(pads.err.height, pads.stack.x + pads.stack.width, pads.stack.height, SCREEN_W - pads.stack.x - pads.stack.width - 0, src_lines, "(S)ource Code", {
highlight = COLORS.RED_BG,
inactive_frame = COLORS.GREEN | C.A_BOLD
line_colors = setmetatable({
[err_line] = COLORS.RED_BG
}, {
__index = function(self, i)
return (i % 2 == 0) and INVERTED or REGULAR
end
})
})
return pads.src:select(selected)
return pads.src:select(err_line)
end
local show_vars
show_vars = function(stack_index)
@ -401,13 +399,21 @@ run_debugger = function(err_msg)
local c = stdscr:getch()
local _exp_0 = c
if C.KEY_DOWN == _exp_0 or C.KEY_SF == _exp_0 or ("j"):byte() == _exp_0 then
selected_pad:scroll(1)
elseif C.KEY_UP == _exp_0 or C.KEY_SR == _exp_0 or ("k"):byte() == _exp_0 then
selected_pad:scroll(-1)
selected_pad:scroll(1, 0)
elseif ('J'):byte() == _exp_0 then
selected_pad:scroll(10)
selected_pad:scroll(10, 0)
elseif C.KEY_UP == _exp_0 or C.KEY_SR == _exp_0 or ("k"):byte() == _exp_0 then
selected_pad:scroll(-1, 0)
elseif ('K'):byte() == _exp_0 then
selected_pad:scroll(-10)
selected_pad:scroll(-10, 0)
elseif C.KEY_RIGHT == _exp_0 or ("l"):byte() == _exp_0 then
selected_pad:scroll(0, 1)
elseif ("L"):byte() == _exp_0 then
selected_pad:scroll(0, 10)
elseif C.KEY_LEFT == _exp_0 or ("h"):byte() == _exp_0 then
selected_pad:scroll(0, -1)
elseif ("H"):byte() == _exp_0 then
selected_pad:scroll(0, -10)
elseif ('c'):byte() == _exp_0 then
select_pad(pads.stack)
elseif ('s'):byte() == _exp_0 then

View File

@ -2,7 +2,7 @@ C = require "curses"
repr = require 'repr'
COLORS = {}
local run_debugger, guard, stdscr
AUTO = -1
AUTO = {}
log = io.open("output.log", "w")
-- Return the callstack index of the code that actually caused an error and the max index
@ -41,17 +41,19 @@ class Pad
new: (@y,@x,@height,@width,@lines,@label,@colors=default_colors)=>
if @colors and @colors != default_colors
setmetatable(@colors, __index:default_colors)
@scroll_y, @scroll_x = 0, 0
@scroll_y, @scroll_x = 1, 1
@selected = nil
if @width == AUTO
@width = 2
for x in *@lines do @width = math.max(@width, #x+2)
@_width = @width
@_height = #@lines
if @height == AUTO
@height = #@lines + 2
@_height = @height
@height = @_height + 2
@_width = 0
for x in *@lines do @_width = math.max(@_width, #x+2)
if @width == AUTO
@width = @_width + 2
@_frame = C.newwin(@height, @width, @y, @x)
@_pad = C.newpad(@_height, @_width)
@_pad\scrollok(true)
@ -59,81 +61,78 @@ class Pad
@chstrs = {}
for i, line in ipairs(@lines)
attr = (i % 2 == 0) and @colors.even_row or @colors.odd_row
chstr = C.new_chstr(@width-2)
attr = @colors.line_colors[i]
chstr = C.new_chstr(@_width)
@chstrs[i] = chstr
if #line >= chstr\len!
line = line\sub(1, chstr\len!)
else
line ..= (" ")\rep(chstr\len!-#line)
chstr\set_str(0, line, attr)
@_pad\mvaddchstr(i-1+1,0+1,chstr)
@_pad\mvaddchstr(i-1,0,chstr)
@refresh!
set_active: (active)=>
return if active == @active
@active = active
@_pad\attrset(active and @colors.active_frame or @colors.inactive_frame)
@_frame\attrset(active and @colors.active_frame or @colors.inactive_frame)
select: (i)=>
if i == @selected or #@lines == 0 then return @selected
if #@lines == 0 then i = nil
if i == @selected then return @selected
if i != nil
i = math.max(1, math.min(#@lines, i))
if @selected
j = @selected
attr = (j % 2 == 0) and @colors.even_row or @colors.odd_row
attr = @colors.line_colors[j]
@chstrs[j]\set_str(0, @lines[j], attr)
@chstrs[j]\set_str(#@lines[j], ' ', attr, @chstrs[j]\len!-#@lines[j])
@_pad\mvaddchstr(j-1+1,0+1,@chstrs[j])
@_pad\mvaddchstr(j-1,0,@chstrs[j])
if i
attr = @active and @colors.active or @colors.highlight
@chstrs[i]\set_str(0, @lines[i], attr)
@chstrs[i]\set_str(#@lines[i], ' ', attr, @chstrs[i]\len!-#@lines[i])
@_pad\mvaddchstr(i-1+1,0+1,@chstrs[i])
@_pad\mvaddchstr(i-1,0,@chstrs[i])
scrolloff = 3
if i > @scroll_y + (@height-2) - scrolloff
@scroll_y = i - (@height-2) + scrolloff
elseif i < @scroll_y + scrolloff
@scroll_y = i - scrolloff
@scroll_y = math.max(1, math.min(#@lines, @scroll_y))
@selected = i
if @selected
if @scroll_y + @height-1 < @selected
@scroll_y = math.min(@selected - (@height-1), #@lines-@height)
elseif @scroll_y + 1 > @selected
@scroll_y = @selected - 1
@refresh!
if @on_select then @on_select(@selected)
return @selected
scroll: (delta)=>
if @selected == nil
return @select 1
@select(@selected + delta)
scroll: (dy,dx)=>
if @selected != nil
@select(@selected + (dy or 0))
else
@scroll_y = math.max(1, math.min(@_height-@height, @scroll_y+(dy or 0)))
@scroll_x = math.max(1, math.min(@_width-@width, @scroll_x+(dx or 0)))
@refresh!
refresh: =>
@_pad\border(C.ACS_VLINE, C.ACS_VLINE,
@_frame\border(C.ACS_VLINE, C.ACS_VLINE,
C.ACS_HLINE, C.ACS_HLINE,
C.ACS_ULCORNER, C.ACS_URCORNER,
C.ACS_LLCORNER, C.ACS_LRCORNER)
if @label
@_pad\mvaddstr(0, math.floor((@width-#@label-2)/2), " #{@label} ")
@_pad\pnoutrefresh(@scroll_y,@scroll_x,@y,@x,@y+@height+1,@x+@width)
@_frame\mvaddstr(0, math.floor((@width-#@label-2)/2), " #{@label} ")
@_frame\refresh!
h,w = math.min(@height-2,@_height),math.min(@width-2,@_width)
@_pad\pnoutrefresh(@scroll_y-1,@scroll_x-1,@y+1,@x+1,@y+h,@x+w)
erase: =>
@_pad\erase!
@_pad\pnoutrefresh(@scroll_y,@scroll_x,@y,@x,@y+@height,@x+@width)
clear: =>
@erase!
@lines = {}
@chstrs = {}
@set_internal_size(2,2)
if @resize_height
@set_size(@_height, @width)
if @resize_width
@set_size(@height, @_width)
@selected = nil
@scroll_y, @scroll_x = 0, 0
@refresh!
@_frame\erase!
@_frame\refresh!
__gc: =>
@_frame\cancel!
@_pad\cancel!
ok, to_lua = pcall -> require('moonscript.base').to_lua
if not ok then to_lua = -> nil
@ -180,8 +179,7 @@ run_debugger = (err_msg)->
default_colors = {
active_frame: COLORS.BLUE,
inactive_frame: COLORS.BROWN,
odd_row: COLORS.REGULAR,
even_row: COLORS.INVERTED,
line_colors: setmetatable({}, __index:(i)=> (i % 2 == 0 and COLORS.INVERTED or COLORS.REGULAR))
highlight: COLORS.WHITE_BG,
active: COLORS.YELLOW_BG,
}
@ -196,7 +194,7 @@ run_debugger = (err_msg)->
for i,line in ipairs(err_msg_lines)
err_msg_lines[i] = (" ")\rep(math.floor((SCREEN_W-2-#line)/2))..line
pads.err = Pad(0,0,AUTO,SCREEN_W, err_msg_lines, "Error Message", {
even_row: COLORS.RED | C.A_BOLD, odd_row: COLORS.RED | C.A_BOLD,
line_colors: setmetatable({}, __index:->COLORS.RED | C.A_BOLD)
inactive_frame: COLORS.RED | C.A_DIM
})
@ -233,18 +231,20 @@ run_debugger = (err_msg)->
show_src = (filename, line_no)->
file = file_cache[filename]
src_lines = {}
selected = nil
err_line = nil
if file
i = 0
for line in file\gmatch("[^\n]*")
i += 1
if i < line_no-(pads.stack.height-2)/2
continue
--if i < line_no-(pads.stack.height-2)/2
-- continue
table.insert src_lines, line
if i == line_no
selected = #src_lines
if #src_lines >= pads.stack.height-2
break
err_line = #src_lines
--if #src_lines >= pads.stack.height-2
-- break
while #src_lines < pads.stack.height
table.insert(src_lines, "")
else
table.insert(src_lines, "<no source code found>")
@ -252,10 +252,9 @@ run_debugger = (err_msg)->
pads.src\erase!
pads.src = Pad(pads.err.height,pads.stack.x+pads.stack.width,
pads.stack.height,SCREEN_W-pads.stack.x-pads.stack.width-0, src_lines, "(S)ource Code", {
highlight: COLORS.RED_BG,
inactive_frame: COLORS.GREEN | C.A_BOLD,
line_colors:setmetatable({[err_line]:COLORS.RED_BG}, {__index:(i)=> (i % 2 == 0) and INVERTED or REGULAR})
})
pads.src\select(selected)
pads.src\select(err_line)
show_vars = (stack_index)->
if pads.vars
@ -313,16 +312,24 @@ run_debugger = (err_msg)->
c = stdscr\getch!
switch c
when C.KEY_DOWN, C.KEY_SF, ("j")\byte!
selected_pad\scroll(1)
selected_pad\scroll(1,0)
when ('J')\byte!
selected_pad\scroll(10,0)
when C.KEY_UP, C.KEY_SR, ("k")\byte!
selected_pad\scroll(-1)
when ('J')\byte!
selected_pad\scroll(10)
selected_pad\scroll(-1,0)
when ('K')\byte!
selected_pad\scroll(-10)
selected_pad\scroll(-10,0)
when C.KEY_RIGHT, ("l")\byte!
selected_pad\scroll(0,1)
when ("L")\byte!
selected_pad\scroll(0,10)
when C.KEY_LEFT, ("h")\byte!
selected_pad\scroll(0,-1)
when ("H")\byte!
selected_pad\scroll(0,-10)
when ('c')\byte!
select_pad(pads.stack) -- (C)allstack