2018-09-12 15:31:59 -07:00
require ( " containers " )
local string2 = require ( ' string2 ' )
local box
box = function ( text )
local max_line = 0
for line in text : gmatch ( " [^ \n ]+ " ) do
max_line = math.max ( max_line , # ( line : gsub ( " \027 %[[0-9;]*m " , " " ) ) )
end
local ret = ( " \n " .. text ) : gsub ( " \n ([^ \n ]*) " , function ( line )
local line_len = # ( line : gsub ( " \027 %[[0-9;]*m " , " " ) )
return " \n " .. tostring ( line ) .. tostring ( ( " " ) : rep ( max_line - line_len ) ) .. " \027 [0m "
end )
return ret : sub ( 2 , - 1 ) , max_line
end
local format_error
format_error = function ( err )
local context = err.context or 2
local err_line , err_linenum , err_linepos = string2.line_at ( err.source , err.start )
local err_size = math.min ( ( err.stop - err.start ) , ( # err_line - err_linepos ) + 1 )
local nl_indicator = ( err_linepos > # err_line ) and " " or " "
local fmt_str = " % " .. tostring ( # tostring ( err_linenum + context ) ) .. " d| "
local pointer
if err_size >= 2 then
pointer = ( " " ) : rep ( err_linepos + # fmt_str : format ( 0 ) - 1 ) .. " ╚ " .. tostring ( ( " ═ " ) : rep ( err_size - 2 ) ) .. " ╝ "
else
pointer = ( " " ) : rep ( err_linepos + # fmt_str : format ( 0 ) - 1 ) .. " ⬆ "
end
2019-01-19 19:38:12 -08:00
local err_msg = " \027 [33;41;1m " .. tostring ( err.title or " Error " ) .. " at " .. tostring ( err.filename or ' ??? ' ) .. " : " .. tostring ( err_linenum ) .. " , " .. tostring ( err_linepos ) .. " \027 [0m "
2018-09-12 15:31:59 -07:00
for i = err_linenum - context , err_linenum - 1 do
do
local line = string2.line ( err.source , i )
if line then
err_msg = err_msg .. " \n \027 [2m " .. tostring ( fmt_str : format ( i ) ) .. " \027 [0m " .. tostring ( line ) .. " \027 [0m "
end
end
end
if err_line then
local before = err_line : sub ( 1 , err_linepos - 1 )
local during = err_line : sub ( err_linepos , err_linepos + err_size - 1 )
local after = err_line : sub ( err_linepos + err_size , - 1 )
err_line = " \027 [0m " .. tostring ( before ) .. " \027 [41;30m " .. tostring ( during ) .. tostring ( nl_indicator ) .. " \027 [0m " .. tostring ( after )
2018-09-13 16:01:57 -07:00
err_msg = err_msg .. " \n \027 [2m " .. tostring ( fmt_str : format ( err_linenum ) ) .. tostring ( err_line ) .. " \027 [0m "
end
local _ , err_linenum_end , err_linepos_end = string2.line_at ( err.source , err.stop )
2018-09-14 14:00:48 -07:00
err_linenum_end = err_linenum_end or err_linenum
2018-09-13 16:01:57 -07:00
if err_linenum_end == err_linenum then
err_msg = err_msg .. " \n " .. tostring ( pointer )
else
for i = err_linenum + 1 , err_linenum_end do
do
local line = string2.line ( err.source , i )
if line then
if i == err_linenum_end then
local during , after = line : sub ( 1 , err_linepos_end - 1 ) , line : sub ( err_linepos_end , - 1 )
err_msg = err_msg .. " \n \027 [2m " .. tostring ( fmt_str : format ( i ) ) .. " \027 [0;41;30m " .. tostring ( during ) .. " \027 [0m " .. tostring ( after )
else
2018-09-15 15:39:38 -07:00
err_msg = err_msg .. " \n \027 [2m " .. tostring ( fmt_str : format ( i ) ) .. " \027 [0;41;30m " .. tostring ( line ) .. " \027 [0m "
2018-09-13 16:01:57 -07:00
end
end
end
2018-12-15 15:15:03 -08:00
if i > err_linenum + 1 + 5 then
err_msg = err_msg .. " \n ... \n "
break
end
2018-09-12 15:31:59 -07:00
end
end
2018-09-13 16:01:57 -07:00
local box_width = 70
2018-09-16 17:38:19 -07:00
local err_text = " \027 [47;31;1m " .. tostring ( string2.wrap ( " " .. err.error , box_width , 16 ) : gsub ( " \n " , " \n \027 [47;31;1m " ) )
2018-09-13 16:01:57 -07:00
if err.hint then
2018-09-16 17:38:19 -07:00
err_text = err_text .. " \n \027 [47;30m " .. tostring ( string2.wrap ( " Suggestion: " .. tostring ( err.hint ) , box_width , 16 ) : gsub ( " \n " , " \n \027 [47;30m " ) )
2018-09-13 16:01:57 -07:00
end
err_msg = err_msg .. ( " \n \027 [33;1m " .. box ( err_text ) : gsub ( " \n " , " \n " ) )
for i = err_linenum_end + 1 , err_linenum_end + context do
2018-09-12 15:31:59 -07:00
do
local line = string2.line ( err.source , i )
if line then
err_msg = err_msg .. " \n \027 [2m " .. tostring ( fmt_str : format ( i ) ) .. " \027 [0m " .. tostring ( line ) .. " \027 [0m "
end
end
end
return err_msg
end
return format_error