From 06fe23ba9c06c5cd88a0836a2bcd1db9ba5de31b Mon Sep 17 00:00:00 2001 From: Lignum Date: Sun, 30 Jul 2017 18:32:19 +0200 Subject: [PATCH 1/4] Add error checking to edit --- .../computercraft/lua/rom/programs/edit.lua | 123 ++++++++++++++---- 1 file changed, 101 insertions(+), 22 deletions(-) diff --git a/src/main/resources/assets/computercraft/lua/rom/programs/edit.lua b/src/main/resources/assets/computercraft/lua/rom/programs/edit.lua index 6a3b3b914c..c626f7aa9e 100644 --- a/src/main/resources/assets/computercraft/lua/rom/programs/edit.lua +++ b/src/main/resources/assets/computercraft/lua/rom/programs/edit.lua @@ -28,6 +28,13 @@ local scrollX, scrollY = 0,0 local tLines = {} local bRunning = true +local tMessages = {} +local tMessageColours = { + error = colours.red, + warning = colours.yellow, + info = colours.blue +} + -- Colours local highlightColour, keywordColour, commentColour, textColour, bgColour, stringColour if term.isColour() then @@ -66,6 +73,36 @@ if string.len( sStatus ) > w - 5 then sStatus = "Press Ctrl for menu" end +local function addMessage( nLine, sType, sContent ) + tMessages[ nLine ] = { + sType = sType, + sContent = sContent, + bExpanded = false + } +end + +local function removeMessage( nLine ) + return table.remove( tMessages, nLine ) +end + +local function clearMessages() + tMessages = {} +end + +local function checkErrors() + clearMessages() + local fLoad = _G.load + local sProgram = table.concat( tLines, "\n" ) + local _, sErr = fLoad( sProgram ) + if sErr then + local sLine, sMsg = string.match( sErr, ".+%:%d+%:%s%[.+%]%:(%d+)%:%s(.+)" ) + local nLine = tonumber( sLine ) + if nLine then + addMessage( nLine, "error", sMsg ) + end + end +end + local function load( _sPath ) tLines = {} if fs.exists( _sPath ) then @@ -77,10 +114,12 @@ local function load( _sPath ) end file:close() end - + if #tLines == 0 then table.insert( tLines, "" ) end + + return checkErrors() end local function save( _sPath ) @@ -102,11 +141,13 @@ local function save( _sPath ) error( "Failed to open ".._sPath ) end end - + local ok, err = pcall( innerSave ) - if file then + if file then file.close() end + + checkErrors() return ok, err end @@ -150,8 +191,8 @@ local function tryWrite( sLine, regex, colour ) end local function writeHighlighted( sLine ) - while string.len(sLine) > 0 do - sLine = + while string.len(sLine) > 0 do + sLine = tryWrite( sLine, "^%-%-%[%[.-%]%]", commentColour ) or tryWrite( sLine, "^%-%-.*", commentColour ) or tryWrite( sLine, "^\"\"", stringColour ) or @@ -212,18 +253,42 @@ local function writeCompletion( sLine ) end end +local function drawMessage( y, tMsg ) + local nPrevColour = term.getBackgroundColour() + local sSymbol = tMsg.bExpanded and string.char( 16 ) or string.char( 17 ) + local nColour = tMessageColours[ tMsg.sType ] or colours.black + + term.setBackgroundColour( nColour ) + + if tMsg.bExpanded then + term.clearLine() + term.setCursorPos( 1, y ) + term.write( tMsg.sContent ) + end + + term.setCursorPos( w, y ) + term.write( sSymbol ) + term.setBackgroundColour( nPrevColour ) +end + local function redrawText() local cursorX, cursorY = x, y for y=1,h-1 do term.setCursorPos( 1 - scrollX, y ) term.clearLine() - local sLine = tLines[ y + scrollY ] + local nLine = y + scrollY + local sLine = tLines[ nLine ] if sLine ~= nil then writeHighlighted( sLine ) if cursorY == y and cursorX == #sLine + 1 then writeCompletion() end + + local tMsg = tMessages[ nLine ] + if tMsg then + drawMessage( y, tMsg ) + end end end term.setCursorPos( x - scrollX, y - scrollY ) @@ -239,6 +304,11 @@ local function redrawLine(_nY) writeCompletion() end term.setCursorPos( x - scrollX, _nY - scrollY ) + + local tMsg = tMessages[_nY] + if tMsg then + drawMessage( _nY - scrollY, tMsg ) + end end end @@ -282,7 +352,7 @@ local function redrawMenu() term.setCursorPos( x - scrollX, y - scrollY ) end -local tMenuFuncs = { +local tMenuFuncs = { Save = function() if bReadOnly then sStatus = "Access denied" @@ -290,6 +360,7 @@ local tMenuFuncs = { local ok, err = save( sPath ) if ok then sStatus="Saved to "..sPath + redrawText() else sStatus="Error saving to "..sPath end @@ -322,9 +393,9 @@ local tMenuFuncs = { } printerTerminal.scroll = function() if nPage == 1 then - printer.setPageTitle( sName.." (page "..nPage..")" ) + printer.setPageTitle( sName.." (page "..nPage..")" ) end - + while not printer.newPage() do if printer.getInkLevel() < 1 then sStatus = "Printer out of ink, please refill" @@ -333,11 +404,11 @@ local tMenuFuncs = { else sStatus = "Printer output tray full, please empty" end - + term.redirect( screenTerminal ) redrawMenu() term.redirect( printerTerminal ) - + local timer = os.startTimer(0.5) sleep(0.5) end @@ -349,7 +420,7 @@ local tMenuFuncs = { printer.setPageTitle( sName.." (page "..nPage..")" ) end end - + bMenu = false term.redirect( printerTerminal ) local ok, error = pcall( function() @@ -362,14 +433,14 @@ local tMenuFuncs = { if not ok then print( error ) end - + while not printer.endPage() do sStatus = "Printer output tray full, please empty" redrawMenu() sleep( 0.5 ) end bMenu = true - + if nPage > 1 then sStatus = "Printed "..nPage.." Pages" else @@ -412,7 +483,7 @@ local function setCursor( newX, newY ) x, y = newX, newY local screenX = x - scrollX local screenY = y - scrollY - + local bRedraw = false if screenX < 1 then scrollX = x - 1 @@ -423,7 +494,7 @@ local function setCursor( newX, newY ) screenX = w bRedraw = true end - + if screenY < 1 then scrollY = y - 1 screenY = 1 @@ -690,7 +761,7 @@ while bRunning do redrawMenu() end - + elseif sEvent == "char" then if not bMenu and not bReadOnly then -- Input text @@ -721,7 +792,7 @@ while bRunning do tLines[y] = string.sub(sLine,1,x-1) .. param .. string.sub(sLine,x) setCursor( x + string.len( param ), y ) end - + elseif sEvent == "mouse_click" then if not bMenu then if param == 1 then @@ -730,11 +801,19 @@ while bRunning do if cy < h then local newY = math.min( math.max( scrollY + cy, 1 ), #tLines ) local newX = math.min( math.max( scrollX + cx, 1 ), string.len( tLines[newY] ) + 1 ) - setCursor( newX, newY ) + + local tMsg = tMessages[ newY ] + if cx == w and tMsg then + tMsg.bExpanded = not tMsg.bExpanded + redrawLine( newY ) + setCursor( x, y ) + else + setCursor( newX, newY ) + end end end end - + elseif sEvent == "mouse_scroll" then if not bMenu then if param == -1 then @@ -744,7 +823,7 @@ while bRunning do scrollY = scrollY - 1 redrawText() end - + elseif param == 1 then -- Scroll down local nMaxScroll = #tLines - (h-1) @@ -753,7 +832,7 @@ while bRunning do scrollY = scrollY + 1 redrawText() end - + end end From 9c26304ccea3927768f44838be6e1676c8a76a57 Mon Sep 17 00:00:00 2001 From: Lignum Date: Sun, 30 Jul 2017 18:54:41 +0200 Subject: [PATCH 2/4] Hide cursor under error messages ... and remove error messages when a line is removed --- .../computercraft/lua/rom/programs/edit.lua | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/main/resources/assets/computercraft/lua/rom/programs/edit.lua b/src/main/resources/assets/computercraft/lua/rom/programs/edit.lua index c626f7aa9e..d91c32c6ea 100644 --- a/src/main/resources/assets/computercraft/lua/rom/programs/edit.lua +++ b/src/main/resources/assets/computercraft/lua/rom/programs/edit.lua @@ -505,7 +505,19 @@ local function setCursor( newX, newY ) bRedraw = true end - recomplete() + local bOnExpandedMsg = false + for nY,v in pairs( tMessages ) do + if y == nY and v.bExpanded then + bOnExpandedMsg = true + break + end + end + + if not bOnExpandedMsg then + recomplete() + end + term.setCursorBlink( not bOnExpandedMsg ) + if bRedraw then redrawText() elseif y ~= oldY then @@ -540,6 +552,11 @@ local function acceptCompletion() end end +local function removeLine( nY ) + table.remove( tLines, nY ) + tMessages[ nY ] = nil +end + -- Handle input while bRunning do local sEvent, param, param2, param3 = os.pullEvent() @@ -701,7 +718,7 @@ while bRunning do redrawLine(y) elseif y<#tLines then tLines[y] = tLines[y] .. tLines[y+1] - table.remove( tLines, y+1 ) + removeLine( y+1 ) recomplete() redrawText() end @@ -724,7 +741,7 @@ while bRunning do -- Remove newline local sPrevLen = string.len( tLines[y-1] ) tLines[y-1] = tLines[y-1] .. tLines[y] - table.remove( tLines, y ) + removeLine( y ) setCursor( sPrevLen + 1, y - 1 ) redrawText() end @@ -753,11 +770,7 @@ while bRunning do elseif param == keys.leftCtrl or param == keys.rightCtrl or param == keys.rightAlt then -- Menu toggle bMenu = not bMenu - if bMenu then - term.setCursorBlink( false ) - else - term.setCursorBlink( true ) - end + term.setCursorBlink( bMenu ) redrawMenu() end From d63f3ca09780da4b5724e699307d258680388cf5 Mon Sep 17 00:00:00 2001 From: Lignum Date: Sun, 30 Jul 2017 19:13:47 +0200 Subject: [PATCH 3/4] Add warnings Including an os.loadAPI deprecation warning --- .../computercraft/lua/rom/programs/edit.lua | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/main/resources/assets/computercraft/lua/rom/programs/edit.lua b/src/main/resources/assets/computercraft/lua/rom/programs/edit.lua index d91c32c6ea..9992b94515 100644 --- a/src/main/resources/assets/computercraft/lua/rom/programs/edit.lua +++ b/src/main/resources/assets/computercraft/lua/rom/programs/edit.lua @@ -31,10 +31,19 @@ local bRunning = true local tMessages = {} local tMessageColours = { error = colours.red, - warning = colours.yellow, + warning = colours.orange, info = colours.blue } +local sLoadAPIDeprecated = "os.loadAPI is deprecated, use require instead" + +-- This is quite ugly, but we'd have to do outrageous bytecode analysis +-- otherwise, so it's good enough. +local tWarnings = { + ["os%.loadAPI%s?%(.+%)"] = sLoadAPIDeprecated, + ["os%.loadAPI%s?['\"].+['\"]"] = sLoadAPIDeprecated +} + -- Colours local highlightColour, keywordColour, commentColour, textColour, bgColour, stringColour if term.isColour() then @@ -89,10 +98,22 @@ local function clearMessages() tMessages = {} end +local function findWarnings( tLines ) + for i,v in pairs( tLines ) do + for p,m in pairs( tWarnings ) do + if string.match( v, p ) then + addMessage( i, "warning", m ) + break + end + end + end +end + local function checkErrors() clearMessages() local fLoad = _G.load local sProgram = table.concat( tLines, "\n" ) + findWarnings( tLines ) local _, sErr = fLoad( sProgram ) if sErr then local sLine, sMsg = string.match( sErr, ".+%:%d+%:%s%[.+%]%:(%d+)%:%s(.+)" ) @@ -554,7 +575,7 @@ end local function removeLine( nY ) table.remove( tLines, nY ) - tMessages[ nY ] = nil + tMessages[ nY ] = nil end -- Handle input From e65cc4c5330fdef6e5053689a648dbafcc6b80d0 Mon Sep 17 00:00:00 2001 From: Lignum Date: Sun, 30 Jul 2017 19:42:52 +0200 Subject: [PATCH 4/4] Fix mysteries related to scrolling and clicking errors --- .../resources/assets/computercraft/lua/rom/programs/edit.lua | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/resources/assets/computercraft/lua/rom/programs/edit.lua b/src/main/resources/assets/computercraft/lua/rom/programs/edit.lua index 9992b94515..cfe70ba176 100644 --- a/src/main/resources/assets/computercraft/lua/rom/programs/edit.lua +++ b/src/main/resources/assets/computercraft/lua/rom/programs/edit.lua @@ -840,10 +840,9 @@ while bRunning do if cx == w and tMsg then tMsg.bExpanded = not tMsg.bExpanded redrawLine( newY ) - setCursor( x, y ) - else - setCursor( newX, newY ) end + + setCursor( newX, newY ) end end end