Advertisement
Selim_042

ComputerCraft Back-Ports

Jan 25th, 2016
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 19.45 KB | None | 0 0
  1. if not (fs.complete or shell.complete or textutils.complete) then
  2.     _G._NBCOMPLETE = true
  3.     --[[ Read function from 1.78 ]]--
  4.     function _G.read( _sReplaceChar, _tHistory, _fnComplete )
  5.         term.setCursorBlink( true )
  6.    
  7.         local sLine = ""
  8.         local nHistoryPos
  9.         local nPos = 0
  10.         if _sReplaceChar then
  11.             _sReplaceChar = string.sub( _sReplaceChar, 1, 1 )
  12.         end
  13.    
  14.         local tCompletions
  15.         local nCompletion
  16.         local function recomplete()
  17.             if _fnComplete and nPos == string.len(sLine) then
  18.                 tCompletions = _fnComplete( sLine )
  19.                 if tCompletions and #tCompletions > 0 then
  20.                     nCompletion = 1
  21.                 else
  22.                     nCompletion = nil
  23.                 end
  24.             else
  25.                 tCompletions = nil
  26.                 nCompletion = nil
  27.             end
  28.         end
  29.    
  30.         local function uncomplete()
  31.             tCompletions = nil
  32.             nCompletion = nil
  33.         end
  34.    
  35.         local w = term.getSize()
  36.         local sx = term.getCursorPos()
  37.    
  38.         local function redraw( _bClear )
  39.             local nScroll = 0
  40.             if sx + nPos >= w then
  41.                 nScroll = (sx + nPos) - w
  42.             end
  43.    
  44.             local cx,cy = term.getCursorPos()
  45.             term.setCursorPos( sx, cy )
  46.             local sReplace = (_bClear and " ") or _sReplaceChar
  47.             if sReplace then
  48.                 term.write( string.rep( sReplace, math.max( string.len(sLine) - nScroll, 0 ) ) )
  49.             else
  50.                 term.write( string.sub( sLine, nScroll + 1 ) )
  51.             end
  52.    
  53.             if nCompletion then
  54.                 local sCompletion = tCompletions[ nCompletion ]
  55.                 local oldText, oldBg
  56.                 if not _bClear then
  57.                     oldText = term.getTextColor()
  58.                     oldBg = term.getBackgroundColor()
  59.                     term.setTextColor( colors.white )
  60.                     term.setBackgroundColor( colors.gray )
  61.                 end
  62.                 if sReplace then
  63.                     term.write( string.rep( sReplace, string.len( sCompletion ) ) )
  64.                 else
  65.                     term.write( sCompletion )
  66.                 end
  67.                 if not _bClear then
  68.                     term.setTextColor( oldText )
  69.                     term.setBackgroundColor( oldBg )
  70.                 end
  71.             end
  72.    
  73.             term.setCursorPos( sx + nPos - nScroll, cy )
  74.         end
  75.        
  76.         local function clear()
  77.             redraw( true )
  78.         end
  79.    
  80.         recomplete()
  81.         redraw()
  82.    
  83.         local function acceptCompletion()
  84.             if nCompletion then
  85.                 -- Clear
  86.                 clear()
  87.    
  88.                 -- Find the common prefix of all the other suggestions which start with the same letter as the current one
  89.                 local sCompletion = tCompletions[ nCompletion ]
  90.                 sLine = sLine .. sCompletion
  91.                 nPos = string.len( sLine )
  92.    
  93.                 -- Redraw
  94.                 recomplete()
  95.                 redraw()
  96.             end
  97.         end
  98.         while true do
  99.             local sEvent, param = os.pullEvent()
  100.             if sEvent == "char" then
  101.                 -- Typed key
  102.                 clear()
  103.                 sLine = string.sub( sLine, 1, nPos ) .. param .. string.sub( sLine, nPos + 1 )
  104.                 nPos = nPos + 1
  105.                 recomplete()
  106.                 redraw()
  107.    
  108.             elseif sEvent == "paste" then
  109.                 -- Pasted text
  110.                 clear()
  111.                 sLine = string.sub( sLine, 1, nPos ) .. param .. string.sub( sLine, nPos + 1 )
  112.                 nPos = nPos + string.len( param )
  113.                 recomplete()
  114.                 redraw()
  115.    
  116.             elseif sEvent == "key" then
  117.                 if param == keys.enter then
  118.                     -- Enter
  119.                     if nCompletion then
  120.                         clear()
  121.                         uncomplete()
  122.                         redraw()
  123.                     end
  124.                     break
  125.                    
  126.                 elseif param == keys.left then
  127.                     -- Left
  128.                     if nPos > 0 then
  129.                         clear()
  130.                         nPos = nPos - 1
  131.                         recomplete()
  132.                         redraw()
  133.                     end
  134.                    
  135.                 elseif param == keys.right then
  136.                     -- Right                
  137.                     if nPos < string.len(sLine) then
  138.                         -- Move right
  139.                         clear()
  140.                         nPos = nPos + 1
  141.                         recomplete()
  142.                         redraw()
  143.                     else
  144.                         -- Accept autocomplete
  145.                         acceptCompletion()
  146.                     end
  147.    
  148.                 elseif param == keys.up or param == keys.down then
  149.                     -- Up or down
  150.                     if nCompletion then
  151.                         -- Cycle completions
  152.                         clear()
  153.                         if param == keys.up then
  154.                             nCompletion = nCompletion - 1
  155.                             if nCompletion < 1 then
  156.                                 nCompletion = #tCompletions
  157.                             end
  158.                         elseif param == keys.down then
  159.                             nCompletion = nCompletion + 1
  160.                             if nCompletion > #tCompletions then
  161.                                 nCompletion = 1
  162.                             end
  163.                         end
  164.                         redraw()
  165.    
  166.                     elseif _tHistory then
  167.                         -- Cycle history
  168.                         clear()
  169.                         if param == keys.up then
  170.                             -- Up
  171.                             if nHistoryPos == nil then
  172.                                 if #_tHistory > 0 then
  173.                                     nHistoryPos = #_tHistory
  174.                                 end
  175.                             elseif nHistoryPos > 1 then
  176.                                 nHistoryPos = nHistoryPos - 1
  177.                             end
  178.                         else
  179.                             -- Down
  180.                             if nHistoryPos == #_tHistory then
  181.                                 nHistoryPos = nil
  182.                             elseif nHistoryPos ~= nil then
  183.                                 nHistoryPos = nHistoryPos + 1
  184.                             end                        
  185.                         end
  186.                         if nHistoryPos then
  187.                             sLine = _tHistory[nHistoryPos]
  188.                             nPos = string.len( sLine )
  189.                         else
  190.                             sLine = ""
  191.                             nPos = 0
  192.                         end
  193.                         uncomplete()
  194.                         redraw()
  195.    
  196.                     end
  197.    
  198.                 elseif param == keys.backspace then
  199.                     -- Backspace
  200.                     if nPos > 0 then
  201.                         clear()
  202.                         sLine = string.sub( sLine, 1, nPos - 1 ) .. string.sub( sLine, nPos + 1 )
  203.                         nPos = nPos - 1
  204.                         recomplete()
  205.                         redraw()
  206.                     end
  207.    
  208.                 elseif param == keys.home then
  209.                     -- Home
  210.                     if nPos > 0 then
  211.                         clear()
  212.                         nPos = 0
  213.                         recomplete()
  214.                         redraw()
  215.                     end
  216.    
  217.                 elseif param == keys.delete then
  218.                     -- Delete
  219.                     if nPos < string.len(sLine) then
  220.                         clear()
  221.                         sLine = string.sub( sLine, 1, nPos ) .. string.sub( sLine, nPos + 2 )                
  222.                         recomplete()
  223.                         redraw()
  224.                     end
  225.    
  226.                 elseif param == keys["end"] then
  227.                     -- End
  228.                     if nPos < string.len(sLine ) then
  229.                         clear()
  230.                         nPos = string.len(sLine)
  231.                         recomplete()
  232.                         redraw()
  233.                     end
  234.    
  235.                 elseif param == keys.tab then
  236.                     -- Tab (accept autocomplete)
  237.                     acceptCompletion()
  238.    
  239.                 end
  240.    
  241.             elseif sEvent == "term_resize" then
  242.                 -- Terminal resized
  243.                 w = term.getSize()
  244.                 redraw()
  245.    
  246.             end
  247.         end
  248.    
  249.         local cx, cy = term.getCursorPos()
  250.         term.setCursorBlink( false )
  251.         term.setCursorPos( w + 1, cy )
  252.         print()
  253.        
  254.         return sLine
  255.     end
  256.    
  257.     --[[ Fs completion functions from 1.78 ]]--
  258.     local tEmpty = {}
  259.     function fs.complete( sPath, sLocation, bIncludeFiles, bIncludeDirs )
  260.         bIncludeFiles = (bIncludeFiles ~= false)
  261.         bIncludeDirs = (bIncludeDirs ~= false)
  262.         local sDir = sLocation
  263.         local nStart = 1
  264.         local nSlash = string.find( sPath, "[/\\]", nStart )
  265.         if nSlash == 1 then
  266.             sDir = ""
  267.             nStart = 2
  268.         end
  269.         local sName
  270.         while not sName do
  271.             local nSlash = string.find( sPath, "[/\\]", nStart )
  272.             if nSlash then
  273.                 local sPart = string.sub( sPath, nStart, nSlash - 1 )
  274.                 sDir = fs.combine( sDir, sPart )
  275.                 nStart = nSlash + 1
  276.             else
  277.                 sName = string.sub( sPath, nStart )
  278.             end
  279.         end
  280.    
  281.         if fs.isDir( sDir ) then
  282.             local tResults = {}
  283.             if bIncludeDirs and sPath == "" then
  284.                 table.insert( tResults, "." )
  285.             end
  286.             if sDir ~= "" then
  287.                 if sPath == "" then
  288.                     table.insert( tResults, (bIncludeDirs and "..") or "../" )
  289.                 elseif sPath == "." then
  290.                     table.insert( tResults, (bIncludeDirs and ".") or "./" )
  291.                 end
  292.             end
  293.             local tFiles = fs.list( sDir )
  294.             for n=1,#tFiles do
  295.                 local sFile = tFiles[n]
  296.                 if #sFile >= #sName and string.sub( sFile, 1, #sName ) == sName then
  297.                     local bIsDir = fs.isDir( fs.combine( sDir, sFile ) )
  298.                     local sResult = string.sub( sFile, #sName + 1 )
  299.                     if bIsDir then
  300.                         table.insert( tResults, sResult .. "/" )
  301.                         if bIncludeDirs and #sResult > 0 then
  302.                             table.insert( tResults, sResult )
  303.                         end
  304.                     else
  305.                         if bIncludeFiles and #sResult > 0 then
  306.                             table.insert( tResults, sResult )
  307.                         end
  308.                     end
  309.                 end
  310.             end
  311.             return tResults
  312.         end
  313.         return tEmpty
  314.     end
  315.    
  316.     --[[ Shell completion functions from 1.78 ]]--
  317.     local tAliases = (parentShell and parentShell.aliases()) or {}
  318.     local function tokenise( ... )
  319.         local sLine = table.concat( { ... }, " " )
  320.         local tWords = {}
  321.         local bQuoted = false
  322.         for match in string.gmatch( sLine .. "\"", "(.-)\"" ) do
  323.             if bQuoted then
  324.                 table.insert( tWords, match )
  325.             else
  326.                 for m in string.gmatch( match, "[^ \t]+" ) do
  327.                     table.insert( tWords, m )
  328.                 end
  329.             end
  330.             bQuoted = not bQuoted
  331.         end
  332.         return tWords
  333.     end
  334.     local tCompletionInfo = (parentShell and parentShell.getCompletionInfo()) or {}
  335.     local function completeProgram( sLine )
  336.         if #sLine > 0 and string.sub( sLine, 1, 1 ) == "/" then
  337.             -- Add programs from the root
  338.             return fs.complete( sLine, "", true, false )
  339.    
  340.         else
  341.             local tResults = {}
  342.             local tSeen = {}
  343.    
  344.             -- Add aliases
  345.             for sAlias, sCommand in pairs( tAliases ) do
  346.                 if #sAlias > #sLine and string.sub( sAlias, 1, #sLine ) == sLine then
  347.                     local sResult = string.sub( sAlias, #sLine + 1 )
  348.                     if not tSeen[ sResult ] then
  349.                         table.insert( tResults, sResult )
  350.                         tSeen[ sResult ] = true
  351.                     end
  352.                 end
  353.             end
  354.    
  355.             -- Add programs from the path
  356.             local tPrograms = shell.programs()
  357.             for n=1,#tPrograms do
  358.                 local sProgram = tPrograms[n]
  359.                 if #sProgram > #sLine and string.sub( sProgram, 1, #sLine ) == sLine then
  360.                     local sResult = string.sub( sProgram, #sLine + 1 )
  361.                     if not tSeen[ sResult ] then
  362.                         table.insert( tResults, sResult )
  363.                         tSeen[ sResult ] = true
  364.                     end
  365.                 end
  366.             end
  367.    
  368.             -- Sort and return
  369.             table.sort( tResults )
  370.             return tResults
  371.         end
  372.     end
  373.    
  374.     local function completeProgramArgument( sProgram, nArgument, sPart, tPreviousParts )
  375.         local tInfo = tCompletionInfo[ sProgram ]
  376.         if tInfo then
  377.             return tInfo.fnComplete( shell, nArgument, sPart, tPreviousParts )
  378.         end
  379.         return nil
  380.     end
  381.    
  382.     function shell.complete( sLine )
  383.         if #sLine > 0 then
  384.             local tWords = tokenise( sLine )
  385.             local nIndex = #tWords
  386.             if string.sub( sLine, #sLine, #sLine ) == " " then
  387.                 nIndex = nIndex + 1
  388.             end
  389.             if nIndex == 1 then
  390.                 local sBit = tWords[1] or ""
  391.                 local sPath = shell.resolveProgram( sBit )
  392.                 if tCompletionInfo[ sPath ] then
  393.                     return { " " }
  394.                 else
  395.                     local tResults = completeProgram( sBit )
  396.                     for n=1,#tResults do
  397.                         local sResult = tResults[n]
  398.                         local sPath = shell.resolveProgram( sBit .. sResult )
  399.                         if tCompletionInfo[ sPath ] then
  400.                             tResults[n] = sResult .. " "
  401.                         end
  402.                     end
  403.                     return tResults
  404.                 end
  405.    
  406.             elseif nIndex > 1 then
  407.                 local sPath = shell.resolveProgram( tWords[1] )
  408.                 local sPart = tWords[nIndex] or ""
  409.                 local tPreviousParts = tWords
  410.                 tPreviousParts[nIndex] = nil
  411.                 return completeProgramArgument( sPath , nIndex - 1, sPart, tPreviousParts )
  412.    
  413.             end
  414.         end
  415.         return nil
  416.     end
  417.    
  418.     function shell.completeProgram( sProgram )
  419.         return completeProgram( sProgram )
  420.     end
  421.    
  422.     function shell.setCompletionFunction( sProgram, fnComplete )
  423.         tCompletionInfo[ sProgram ] = {
  424.             fnComplete = fnComplete
  425.         }
  426.     end
  427.    
  428.     function shell.getCompletionInfo()
  429.         return tCompletionInfo
  430.     end
  431.    
  432.     --[[ Textutils completion functions form 1.78 ]]--
  433.     local g_tLuaKeywords = {
  434.         [ "and" ] = true,
  435.         [ "break" ] = true,
  436.         [ "do" ] = true,
  437.         [ "else" ] = true,
  438.         [ "elseif" ] = true,
  439.         [ "end" ] = true,
  440.         [ "false" ] = true,
  441.         [ "for" ] = true,
  442.         [ "function" ] = true,
  443.         [ "if" ] = true,
  444.         [ "in" ] = true,
  445.         [ "local" ] = true,
  446.         [ "nil" ] = true,
  447.         [ "not" ] = true,
  448.         [ "or" ] = true,
  449.         [ "repeat" ] = true,
  450.         [ "return" ] = true,
  451.         [ "then" ] = true,
  452.         [ "true" ] = true,
  453.         [ "until" ] = true,
  454.         [ "while" ] = true,
  455.     }
  456.     local tEmpty = {}
  457.     function textutils.complete( sSearchText, tSearchTable )
  458.         local nStart = 1
  459.         local nDot = string.find( sSearchText, ".", nStart, true )
  460.         local tTable = tSearchTable or _ENV
  461.         while nDot do
  462.             local sPart = string.sub( sSearchText, nStart, nDot - 1 )
  463.             local value = tTable[ sPart ]
  464.             if type( value ) == "table" then
  465.                 tTable = value
  466.                 nStart = nDot + 1
  467.                 nDot = string.find( sSearchText, ".", nStart, true )
  468.             else
  469.                 return tEmpty
  470.             end
  471.         end
  472.    
  473.         local sPart = string.sub( sSearchText, nStart, nDot )
  474.         local nPartLength = string.len( sPart )
  475.    
  476.         local tResults = {}
  477.         local tSeen = {}
  478.         while tTable do
  479.             for k,v in pairs( tTable ) do
  480.                 if not tSeen[k] and type(k) == "string" then
  481.                     if string.find( k, sPart, 1, true ) == 1 then
  482.                         if not g_tLuaKeywords[k] and string.match( k, "^[%a_][%a%d_]*$" ) then
  483.                             local sResult = string.sub( k, nPartLength + 1 )
  484.                             if type(v) == "function" then
  485.                                 sResult = sResult .. "("
  486.                             elseif type(v) == "table" and next(v) ~= nil then
  487.                                 sResult = sResult .. "."
  488.                             end
  489.                             table.insert( tResults, sResult )
  490.                         end
  491.                     end
  492.                 end
  493.                 tSeen[k] = true
  494.             end
  495.             local tMetatable = getmetatable( tTable )
  496.             if tMetatable and type( tMetatable.__index ) == "table" then
  497.                 tTable = tMetatable.__index
  498.             else
  499.                 tTable = nil
  500.             end
  501.         end
  502.    
  503.         table.sort( tResults )
  504.         return tResults
  505.     end
  506. end
  507.  
  508. if (_G.settings == nil) then
  509.     nbSettings = true
  510.    
  511.     local tSettings = {}
  512.    
  513.     _G.settings = {}
  514.     function _G.settings.set( sName, value )
  515.         if type(sName) ~= "string" or
  516.            (type(value) ~= "string" and type(value) ~= "number" and type(value) ~= "boolean" and type(value) ~= "table") then
  517.             error( "Expected string, value", 2 )
  518.         end
  519.         if type(value) == "table" then
  520.             -- Ensure value is serializeable
  521.             value = textutils.unserialize( textutils.serialize(value) )
  522.         end
  523.         tSettings[ sName ] = value
  524.     end
  525.    
  526.     local copy
  527.     function copy( value )
  528.         if type(v) == "table" then
  529.             local result = {}
  530.             for k,v in pairs(value) do
  531.                 result[k] = copy(v)
  532.             end
  533.             return result
  534.         else
  535.             return value
  536.         end
  537.     end
  538.    
  539.     function _G.settings.get( sName, default )
  540.         if type(sName) ~= "string" then
  541.             error( "Expected string", 2 )
  542.         end
  543.         local result = tSettings[ sName ]
  544.         if result ~= nil then
  545.             return copy(result)
  546.         else
  547.             return default
  548.         end
  549.     end
  550.    
  551.     function _G.settings.unset( sName )
  552.         if type(sName) ~= "string" then
  553.             error( "Expected string", 2 )
  554.         end
  555.         tSettings[ sName ] = nil
  556.     end
  557.    
  558.     function _G.clear()
  559.         tSettings = {}
  560.     end
  561.    
  562.     function _G.settings.getNames()
  563.         local result = {}
  564.         for k,v in pairs( tSettings ) do
  565.             result[ #result + 1 ] = k
  566.         end
  567.         return result
  568.     end
  569.    
  570.     function _G.settings.load( sPath )
  571.         if type(sPath) ~= "string" then
  572.             error( "Expected string", 2 )
  573.         end
  574.         local file = fs.open( sPath, "r" )
  575.         if file then
  576.             local sText = file.readAll()
  577.             file.close()
  578.    
  579.             local tFile = textutils.unserialize( sText )
  580.             if type(tFile) == "table" then
  581.                 for k,v in pairs(tFile) do
  582.                     if type(k) == "string" and
  583.                        (type(v) == "string" or type(v) == "number" or type(v) == "boolean" or type(v) == "table") then
  584.                         set( k, v )
  585.                     end
  586.                 end
  587.             end
  588.         end
  589.     end
  590.    
  591.     function _G.settings.save( sPath )
  592.         if type(sPath) ~= "string" then
  593.             error( "Expected string", 2 )
  594.         end
  595.         local file = fs.open( sPath, "w" )
  596.         file.write( textutils.serialize( tSettings ) )
  597.         file.close()
  598.     end
  599. else
  600.     print("Settings API is already loaded.")
  601.     print("Likely because you are running CC 1.77+")
  602. end
  603.  
  604. --[[ Load settings ]]--
  605. print("\nLoading settings")
  606. if (settings.nbSettings) then
  607.     settings.load("/.settings")
  608.     if (#settings.getNames() == 0) then
  609.         local settingsFile = fs.open("/.settings",'w')
  610.         settingsFile.write(textutils.serialise({["bios.use_multishell"]=true,["shell.autocomplete"]=true,
  611.             ["shell.allow_disk_startup"]=not command,["shell.allow_startup"]=true,["lua.autocomplete"]=true,
  612.             ["list.show_hidden"]=false,["edit.autocomplete"]=true,}))
  613.         settingsFile.close()
  614.         settings.load("/.settings")
  615.     end
  616. end
  617. if (settings.get("bios.use_multishell")) then
  618.     mulishell = nil
  619. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement