Much cleaner and prettier

This commit is contained in:
Bruce Hill 2018-04-05 14:25:56 -07:00
parent 987337d289
commit 9e090da0b9
2 changed files with 386 additions and 109 deletions

310
ldt.lua
View File

@ -374,6 +374,9 @@ local TOP_LOCATION = { }
local locations = { }
local Location
Location = function(old_loc, kind, key)
if old_loc == nil then
return TOP_LOCATION
end
if not (locations[old_loc]) then
locations[old_loc] = { }
end
@ -381,7 +384,11 @@ Location = function(old_loc, kind, key)
locations[old_loc][kind] = { }
end
if not (locations[old_loc][kind][key]) then
locations[old_loc][kind][key] = { }
locations[old_loc][kind][key] = {
old_loc = old_loc,
kind = kind,
key = key
}
end
return locations[old_loc][kind][key]
end
@ -401,23 +408,134 @@ local is_value_expanded
is_value_expanded = function(location, key)
return expansions[Location(location, VALUE, key)]
end
local TYPE_COLORS = setmetatable({ }, {
__index = 0
})
local colored_repr
colored_repr = function(x, width, depth)
if depth == nil then
depth = 2
end
depth = depth - 1
local x_type = type(x)
if x_type == 'table' then
if next(x) == nil then
return {
"{}",
TYPE_COLORS.table
}
end
if depth == 0 then
return {
"{",
TYPE_COLORS.table,
"...",
Color('white'),
"}",
TYPE_COLORS.table
}
end
local ret = {
"{",
TYPE_COLORS.table
}
local i = 1
for k, v in pairs(x) do
if k == i then
local _list_0 = colored_repr(x[i], width, depth)
for _index_0 = 1, #_list_0 do
local s = _list_0[_index_0]
ret[#ret + 1] = s
end
i = i + 1
else
local _list_0 = colored_repr(k, width, depth)
for _index_0 = 1, #_list_0 do
local s = _list_0[_index_0]
ret[#ret + 1] = s
end
ret[#ret + 1] = ' = '
ret[#ret + 1] = Color('white')
local _list_1 = colored_repr(v, width, depth)
for _index_0 = 1, #_list_1 do
local s = _list_1[_index_0]
ret[#ret + 1] = s
end
end
ret[#ret + 1] = ', '
ret[#ret + 1] = Color('white')
end
if #ret > 2 then
ret[#ret] = nil
ret[#ret] = nil
end
local len = 0
for i = 1, #ret - 1, 2 do
len = len + #ret[i]
end
for i = #ret - 1, 3, -2 do
if len <= width - 1 then
break
end
if ret[i + 2] then
ret[i + 2], ret[i + 3] = nil, nil
end
ret[i] = '...'
ret[i + 1] = Color('white')
end
ret[#ret + 1] = '}'
ret[#ret + 1] = TYPE_COLORS.table
return ret
elseif x_type == 'string' then
local ret = {
(x:match('^[^\n]*')),
TYPE_COLORS.string
}
for line in x:gmatch('\n([^\n]*)') do
ret[#ret + 1] = '\\n'
ret[#ret + 1] = Color('white on black')
ret[#ret + 1] = line
ret[#ret + 1] = TYPE_COLORS.string
end
local len = 0
for i = 1, #ret - 1, 2 do
len = len + #ret[i]
end
for i = #ret - 1, 1, -2 do
if len <= width then
break
end
if ret[i + 2] then
ret[i + 2], ret[i + 3] = nil, nil
end
len = len - #ret[i]
if len <= width then
ret[i] = ret[i]:sub(1, width - len - 3)
ret[i + 2] = '...'
ret[i + 3] = Color('blue')
break
end
end
return ret
else
local s = tostring(x)
if #s > width then
return {
s:sub(1, width - 3),
TYPE_COLORS[type(x)],
'...',
Color('blue')
}
else
return {
s,
TYPE_COLORS[type(x)]
}
end
end
end
local make_lines
make_lines = function(location, x, width)
local type_colors = {
string = Color('blue on black'),
number = Color('magenta'),
boolean = Color('yellow'),
["nil"] = Color('cyan'),
table = Color('white bold'),
["function"] = Color('green'),
userdata = Color('cyan bold'),
thread = Color('blue')
}
setmetatable(type_colors, {
__index = function()
return Color('red bold')
end
})
local _exp_0 = type(x)
if 'string' == _exp_0 then
local lines = { }
@ -438,6 +556,13 @@ make_lines = function(location, x, width)
table.insert(lines, _line)
end
end
if #lines == 0 then
table.insert(lines, {
location = location,
"''",
Color('blue')
})
end
return lines
elseif 'table' == _exp_0 then
local prepend
@ -463,87 +588,81 @@ make_lines = function(location, x, width)
local key_lines = make_lines(Location(location, KEY, k), k, width - 1)
for i, key_line in ipairs(key_lines) do
if i == 1 then
prepend(key_line, C.ACS_DIAMOND, Color('green bold'), ' ', Color())
prepend(key_line, ' ', Color(), C.ACS_DIAMOND, Color('green bold'), ' ', Color())
else
prepend(key_line, ' ', Color())
prepend(key_line, ' ', Color())
end
table.insert(lines, key_line)
end
table.insert(lines, {
location = Location(location, KEY, k)
})
local value_lines = make_lines(Location(location, VALUE, k), v, width - 2)
for i, value_line in ipairs(value_lines) do
if i == 1 then
prepend(value_line, C.ACS_DIAMOND, Color('blue bold'), ' ', Color())
prepend(value_line, ' ', Color(), C.ACS_DIAMOND, Color('blue bold'), ' ', Color())
else
prepend(value_line, ' ', Color())
prepend(value_line, ' ', Color())
end
table.insert(lines, value_line)
end
table.insert(lines, {
location = Location(location, VALUE, k)
})
elseif is_value_expanded(location, k) then
local k_str = type(k) == 'string' and k:gsub('\n', '\\n') or repr(k, 2)
if #k_str > width then
k_str = k_str:sub(1, width - 3) .. '...'
end
local k_str = colored_repr(k, width - 1)
table.insert(lines, {
location = Location(location, KEY, k),
k_str,
type_colors[type(k)] | C.A_REVERSE
'-',
Color('red'),
unpack(k_str)
})
local v_lines = make_lines(Location(location, VALUE, k), v, width - 1)
prepend(v_lines[1], C.ACS_LLCORNER, Color())
prepend(v_lines[1], ' ', Color())
for i = 2, #v_lines do
prepend(v_lines[i], ' ', Color())
prepend(v_lines[i], ' ', Color())
end
for _index_0 = 1, #v_lines do
local v_line = v_lines[_index_0]
table.insert(lines, v_line)
end
elseif is_key_expanded(location, k) then
local k_lines = make_lines(Location(location, KEY, k), k, width - 1)
for i = 1, #k_lines - 1 do
prepend(k_lines[i], ' ', Color())
local k_lines = make_lines(Location(location, KEY, k), k, width - 4)
for i = 1, #k_lines do
prepend(k_lines[i], ' ', Color())
end
prepend(k_lines[#k_lines], C.ACS_ULCORNER, Color())
for _index_0 = 1, #k_lines do
local k_line = k_lines[_index_0]
table.insert(lines, k_line)
end
local v_str = type(v) == 'string' and v:gsub('\n', '\\n') or repr(v, 2)
if #v_str > width then
v_str = v_str:sub(1, width - 3) .. '...'
end
local v_str = colored_repr(v, width - 2)
table.insert(lines, {
location = Location(location, VALUE, k),
v_str,
type_colors[type(v)]
' ',
Color(),
unpack(v_str)
})
else
local k_space = math.floor((width - 3) / 3)
local k_str = type(k) == 'string' and k:gsub('\n', '\\n') or repr(k, 2)
if #k_str > k_space then
k_str = k_str:sub(1, k_space - 3) .. '...'
end
local v_space = (width - 3) - #k_str
local v_str = type(v) == 'string' and v:gsub('\n', '\\n') or repr(v, 2)
if #v_str > v_space then
v_str = v_str:sub(1, v_space - 3) .. '...'
end
table.insert(lines, {
local k_space = math.floor((width - 4) / 3)
local k_str = colored_repr(k, k_space)
local v_space = (width - 4) - #k_str
local v_str = colored_repr(v, v_space)
local line = {
location = Location(location, VALUE, k),
k_str,
type_colors[type(k)] | C.A_REVERSE,
' = ',
Color(),
v_str,
type_colors[type(v)]
})
'+',
Color('green'),
unpack(k_str)
}
table.insert(line, ' = ')
table.insert(line, Color('white'))
for _index_0 = 1, #v_str do
local s = v_str[_index_0]
table.insert(line, s)
end
table.insert(lines, line)
end
end
if #lines == 0 then
table.insert(lines, {
location = location,
'{}',
TYPE_COLORS.table
})
end
return lines
else
local str = repr(x, 2)
@ -554,7 +673,7 @@ make_lines = function(location, x, width)
{
location = location,
str,
type_colors[type(x)]
TYPE_COLORS[type(x)]
}
}
end
@ -583,11 +702,11 @@ do
local old_selected
old_selected, self.selected = self.selected, i
if old_selected and self.chstrs[old_selected] then
self.chstrs[old_selected]:set_str(0, ' ')
self.chstrs[old_selected]:set_str(0, ' ', Color('yellow bold'))
self._pad:mvaddchstr(old_selected - 1, 0, self.chstrs[old_selected])
end
if self.selected then
self.chstrs[self.selected]:set_ch(0, C.ACS_RARROW, Color('green bold'))
self.chstrs[self.selected]:set_ch(0, C.ACS_RARROW, Color('yellow bold'))
self._pad:mvaddchstr(self.selected - 1, 0, self.chstrs[self.selected])
local scrolloff = 3
if self.selected > self.scroll_y + (self.height - 2) - scrolloff then
@ -630,11 +749,49 @@ do
expansions[self.chstr_locations[self.selected]] = true
return self:full_refresh()
elseif C.KEY_LEFT == _exp_0 or ("h"):byte() == _exp_0 then
expansions[self.chstr_locations[self.selected]] = nil
return self:full_refresh()
local loc = self.chstr_locations[self.selected]
if expansions[loc] == nil then
loc = Location(loc.old_loc, (loc.kind == KEY and VALUE or KEY), loc.key)
end
while loc and expansions[loc] == nil do
loc = loc.old_loc
end
if loc then
expansions[loc] = nil
end
self:full_refresh()
if loc and self.chstr_locations[self.selected] ~= loc then
for i, chstr_loc in ipairs(self.chstr_locations) do
if chstr_loc == loc then
self:select(i)
break
end
end
elseif not loc then
return self:select(1)
end
elseif ("H"):byte() == _exp_0 then
expansions[self.chstr_locations[self.selected]] = nil
return self:full_refresh()
local loc = self.chstr_locations[self.selected]
if expansions[loc] == nil then
loc = Location(loc.old_loc, (loc.kind == KEY and VALUE or KEY), loc.key)
end
while loc and expansions[loc] == nil do
loc = loc.old_loc
end
if loc then
expansions[loc] = nil
end
self:full_refresh()
if loc and self.chstr_locations[self.selected] ~= loc then
for i, chstr_loc in ipairs(self.chstr_locations) do
if chstr_loc == loc then
self:select(i)
break
end
end
elseif not loc then
return self:select(1)
end
end
end
}
@ -656,6 +813,11 @@ do
local lines = make_lines(TOP_LOCATION, self.data, W)
for i, line in ipairs(lines) do
local chstr = C.new_chstr(W)
if i == self.selected then
chstr:set_ch(0, C.ACS_RARROW, Color('yellow bold'))
else
chstr:set_str(0, ' ', Color('yellow bold'))
end
local offset = 1
for j = 1, #line - 1, 2 do
local chunk, attrs = line[j], line[j + 1]
@ -775,6 +937,16 @@ ldb = {
C.curs_set(0)
C.start_color()
C.use_default_colors()
do
TYPE_COLORS.string = Color('blue on black')
TYPE_COLORS.number = Color('magenta')
TYPE_COLORS.boolean = Color('cyan')
TYPE_COLORS["nil"] = Color('cyan')
TYPE_COLORS.table = Color('yellow')
TYPE_COLORS["function"] = Color('green')
TYPE_COLORS.userdata = Color('cyan bold')
TYPE_COLORS.thread = Color('blue')
end
do
stdscr:wbkgd(Color("yellow on red bold"))
stdscr:clear()

185
ldt.moon
View File

@ -253,12 +253,14 @@ VALUE = {}
TOP_LOCATION = {}
locations = {}
Location = (old_loc, kind, key)->
if old_loc == nil
return TOP_LOCATION
unless locations[old_loc]
locations[old_loc] = {}
unless locations[old_loc][kind]
locations[old_loc][kind] = {}
unless locations[old_loc][kind][key]
locations[old_loc][kind][key] = {}
locations[old_loc][kind][key] = {:old_loc, :kind, :key}
return locations[old_loc][kind][key]
expand = (kind, key, location)->
@ -270,12 +272,73 @@ is_key_expanded = (location, key)->
is_value_expanded = (location, key)->
expansions[Location(location, VALUE, key)]
TYPE_COLORS = setmetatable({}, {__index: 0})
colored_repr = (x, width, depth=2)->
depth -= 1
x_type = type(x)
if x_type == 'table' then
if next(x) == nil
return {"{}", TYPE_COLORS.table}
if depth == 0
return {"{", TYPE_COLORS.table, "...", Color('white'), "}", TYPE_COLORS.table}
ret = {"{", TYPE_COLORS.table}
i = 1
for k, v in pairs(x)
if k == i
for s in *colored_repr(x[i], width, depth) do ret[#ret+1] = s
i = i + 1
else
for s in *colored_repr(k, width, depth) do ret[#ret+1] = s
ret[#ret+1] = ' = '
ret[#ret+1] = Color('white')
for s in *colored_repr(v, width, depth) do ret[#ret+1] = s
ret[#ret+1] = ', '
ret[#ret+1] = Color('white')
if #ret > 2
ret[#ret] = nil
ret[#ret] = nil
len = 0
for i=1,#ret-1,2 do len += #ret[i]
for i=#ret-1,3,-2
if len <= width-1
break
if ret[i+2]
ret[i+2], ret[i+3] = nil, nil
ret[i] = '...'
ret[i+1] = Color('white')
ret[#ret+1] = '}'
ret[#ret+1] = TYPE_COLORS.table
return ret
elseif x_type == 'string'
ret = {(x\match('^[^\n]*')), TYPE_COLORS.string}
for line in x\gmatch('\n([^\n]*)')
ret[#ret+1] = '\\n'
ret[#ret+1] = Color('white on black')
ret[#ret+1] = line
ret[#ret+1] = TYPE_COLORS.string
len = 0
for i=1,#ret-1,2 do len += #ret[i]
for i=#ret-1,1,-2
if len <= width then break
if ret[i+2]
ret[i+2], ret[i+3] = nil, nil
len -= #ret[i]
if len <= width
ret[i] = ret[i]\sub(1, width-len-3)
ret[i+2] = '...'
ret[i+3] = Color('blue')
break
return ret
else
s = tostring(x)
return if #s > width
{s\sub(1,width-3), TYPE_COLORS[type(x)], '...', Color('blue')}
else
{s, TYPE_COLORS[type(x)]}
make_lines = (location, x, width)->
-- Return a list of {location=location, text1, color1, text2, color2, ...}
type_colors = {string:Color('blue on black'), number:Color('magenta'), boolean:Color('yellow'),
nil:Color('cyan'), table:Color('white bold'), function:Color('green'),
userdata:Color('cyan bold'), thread:Color('blue')}
setmetatable(type_colors, {__index: -> Color('red bold')})
switch type(x)
when 'string'
lines = {}
@ -289,6 +352,8 @@ make_lines = (location, x, width)->
table.insert(_line, subline)
table.insert(_line, Color('blue on black'))
table.insert(lines, _line)
if #lines == 0
table.insert lines, {:location, "''", Color('blue')}
return lines
when 'table'
prepend = (line, ...)->
@ -303,58 +368,59 @@ make_lines = (location, x, width)->
key_lines = make_lines(Location(location, KEY, k), k, width-1)
for i,key_line in ipairs(key_lines)
if i == 1
prepend(key_line, C.ACS_DIAMOND, Color('green bold'), ' ', Color!)
prepend(key_line, ' ', Color!, C.ACS_DIAMOND, Color('green bold'), ' ', Color!)
else
prepend(key_line, ' ', Color!)
prepend(key_line, ' ', Color!)
table.insert(lines, key_line)
table.insert(lines, {location:Location(location, KEY, k)})
value_lines = make_lines(Location(location, VALUE, k), v, width-2)
for i,value_line in ipairs(value_lines)
if i == 1
prepend(value_line, C.ACS_DIAMOND, Color('blue bold'), ' ', Color!)
prepend(value_line, ' ', Color!, C.ACS_DIAMOND, Color('blue bold'), ' ', Color!)
else
prepend(value_line, ' ', Color!)
prepend(value_line, ' ', Color!)
table.insert(lines, value_line)
table.insert(lines, {location:Location(location, VALUE, k)})
elseif is_value_expanded(location, k)
k_str = type(k) == 'string' and k\gsub('\n','\\n') or repr(k,2)
if #k_str > width then k_str = k_str\sub(1,width-3)..'...'
table.insert(lines, {location:Location(location, KEY, k), k_str, type_colors[type(k)] | C.A_REVERSE})
k_str = colored_repr(k,width-1)
table.insert lines, {
location:Location(location, KEY, k),
'-', Color('red'), unpack(k_str)
}
v_lines = make_lines(Location(location, VALUE, k), v, width-1)
prepend(v_lines[1], C.ACS_LLCORNER, Color!)
prepend(v_lines[1], ' ', Color!)
for i=2,#v_lines
prepend(v_lines[i], ' ', Color!)
prepend(v_lines[i], ' ', Color!)
for v_line in *v_lines do table.insert(lines, v_line)
elseif is_key_expanded(location, k)
k_lines = make_lines(Location(location, KEY, k), k, width-1)
for i=1,#k_lines-1
prepend(k_lines[i], ' ', Color!)
-- TODO: make this less ugly
prepend(k_lines[#k_lines], C.ACS_ULCORNER, Color!)
k_lines = make_lines(Location(location, KEY, k), k, width-4)
for i=1,#k_lines
prepend(k_lines[i], ' ', Color!)
for k_line in *k_lines do table.insert(lines, k_line)
v_str = type(v) == 'string' and v\gsub('\n','\\n') or repr(v,2)
if #v_str > width then v_str = v_str\sub(1,width-3)..'...'
table.insert(lines, {location:Location(location, VALUE, k), v_str, type_colors[type(v)]})
v_str = colored_repr(v,width-2)
table.insert(lines, {location:Location(location, VALUE, k), ' ', Color!, unpack(v_str)})
else
k_space = math.floor((width-3)/3)
k_str = type(k) == 'string' and k\gsub('\n','\\n') or repr(k,2)
if #k_str > k_space then k_str = k_str\sub(1,k_space-3)..'...'
v_space = (width-3)-#k_str
v_str = type(v) == 'string' and v\gsub('\n','\\n') or repr(v,2)
if #v_str > v_space then v_str = v_str\sub(1,v_space-3)..'...'
table.insert(lines, {
k_space = math.floor((width-4)/3)
k_str = colored_repr(k,k_space)
v_space = (width-4)-#k_str
v_str = colored_repr(v,v_space)
line = {
location:Location(location, VALUE, k),
k_str, type_colors[type(k)] | C.A_REVERSE,
' = ', Color!,
v_str, type_colors[type(v)]})
'+', Color('green'),
unpack(k_str)
}
table.insert line, ' = '
table.insert line, Color('white')
for s in *v_str do table.insert(line, s)
table.insert(lines, line)
if #lines == 0
table.insert lines, {:location, '{}', TYPE_COLORS.table}
return lines
else
str = repr(x,2)
if #str > width
str = str\sub(1,width-3)..'...'
return {{:location, str, type_colors[type(x)]}}
return {{:location, str, TYPE_COLORS[type(x)]}}
class DataViewer extends Pad
@ -374,6 +440,10 @@ class DataViewer extends Pad
lines = make_lines(TOP_LOCATION, @data, W)
for i,line in ipairs(lines)
chstr = C.new_chstr(W)
if i == @selected
chstr\set_ch(0, C.ACS_RARROW, Color('yellow bold'))
else
chstr\set_str(0, ' ', Color('yellow bold'))
offset = 1
for j=1,#line-1,2
chunk, attrs = line[j], line[j+1]
@ -424,11 +494,11 @@ class DataViewer extends Pad
old_selected,@selected = @selected,i
if old_selected and @chstrs[old_selected]
@chstrs[old_selected]\set_str(0, ' ')
@chstrs[old_selected]\set_str(0, ' ', Color('yellow bold'))
@_pad\mvaddchstr(old_selected-1,0,@chstrs[old_selected])
if @selected
@chstrs[@selected]\set_ch(0, C.ACS_RARROW, Color('green bold'))
@chstrs[@selected]\set_ch(0, C.ACS_RARROW, Color('yellow bold'))
@_pad\mvaddchstr(@selected-1,0,@chstrs[@selected])
scrolloff = 3
@ -470,11 +540,38 @@ class DataViewer extends Pad
@full_refresh!
when C.KEY_LEFT, ("h")\byte!
expansions[@chstr_locations[@selected]] = nil
loc = @chstr_locations[@selected]
if expansions[loc] == nil
loc = Location(loc.old_loc, (loc.kind == KEY and VALUE or KEY), loc.key)
while loc and expansions[loc] == nil
loc = loc.old_loc
if loc
expansions[loc] = nil
@full_refresh!
if loc and @chstr_locations[@selected] != loc
for i,chstr_loc in ipairs(@chstr_locations)
if chstr_loc == loc
@select(i)
break
elseif not loc
@select(1)
when ("H")\byte!
expansions[@chstr_locations[@selected]] = nil
loc = @chstr_locations[@selected]
if expansions[loc] == nil
loc = Location(loc.old_loc, (loc.kind == KEY and VALUE or KEY), loc.key)
while loc and expansions[loc] == nil
loc = loc.old_loc
if loc
expansions[loc] = nil
@full_refresh!
if loc and @chstr_locations[@selected] != loc
for i,chstr_loc in ipairs(@chstr_locations)
if chstr_loc == loc
@select(i)
break
elseif not loc
@select(1)
ok, to_lua = pcall -> require('moonscript.base').to_lua
if not ok then to_lua = -> nil
@ -508,13 +605,21 @@ ldb = {
err_msg or= ''
stdscr = C.initscr!
SCREEN_H, SCREEN_W = stdscr\getmaxyx!
C.cbreak!
C.echo(false)
C.nl(false)
C.curs_set(0)
C.start_color!
C.use_default_colors!
with TYPE_COLORS
.string = Color('blue on black')
.number = Color('magenta')
.boolean = Color('cyan')
.nil = Color('cyan')
.table = Color('yellow')
.function = Color('green')
.userdata = Color('cyan bold')
.thread = Color('blue')
do -- Fullscreen flash
stdscr\wbkgd(Color"yellow on red bold")