Wojbie

Shell Utility Extended

Mar 31st, 2015 (edited)
683
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 13.64 KB | None | 0 0
  1. --# Shell Utility Extended v1.1 - Program to extend/modify Computercraft autocompletion system.
  2. --# Made By Wojbie
  3. --# http://pastebin.com/iAisZ9VA
  4.  
  5. --   Copyright (c) 2015-2021 Wojbie (wojbie@wojbie.net)
  6. --   Redistribution and use in source and binary forms, with or without modification, are permitted (subject to the limitations in the disclaimer below) provided that the following conditions are met:
  7. --   1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  8. --   2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  9. --   3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
  10. --   4. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
  11. --   5. The origin of this software must not be misrepresented; you must not claim that you wrote the original software.
  12. --   NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. YOU ACKNOWLEDGE THAT THIS SOFTWARE IS NOT DESIGNED, LICENSED OR INTENDED FOR USE IN THE DESIGN, CONSTRUCTION, OPERATION OR MAINTENANCE OF ANY NUCLEAR FACILITY.
  13.  
  14. --#Global Settings
  15.  
  16. --Add fix to type program
  17.  
  18. --Chat suggested usernames. Place all usernames you want suggested in here.
  19. --example: local tChatNames = {"Wojbie","Ninja","Spy"}
  20. local tChatNames = {}
  21. --Pastebin usernames for pastes suggestions. Place all usernames you want suggested in here.
  22. --example: local tPastebinNames = {"Wojbie","Ninja","Spy"}
  23. local tPastebinNames = {}
  24.  
  25.  
  26. -- #Support functions
  27. local function save(A,B) local file = fs.open(tostring(A),"w") file.write(B) file.close() end
  28. local function saveT(A,B) save(A,textutils.serialize(B)) end
  29. local function saveTL(A,B) save(A,string.gsub(textutils.serialize(B),"\n%s*","")) end
  30.  
  31. local function get(A) local file = fs.open(tostring(A),"r") if not file then return false end local data = file.readAll() file.close() if data then return data end end
  32. local function getT(A) local data = get(A) if data then data = textutils.unserialize(data) end if data then return data end end
  33. local function getHttp(A) if not http.checkURL(A) then return false end local file = http.get(A) if not file then return false end local data = file.readAll() file.close() if data then return data end end
  34.  
  35. local function completeMultipleChoice( sText, tOptions, bAddSpaces )
  36.     local tResults = {}
  37.     for n=1,#tOptions do
  38.         local sOption = tOptions[n]
  39.         if #sOption + (bAddSpaces and 1 or 0) > #sText and string.sub( sOption, 1, #sText ) == sText then
  40.             local sResult = string.sub( sOption, #sText + 1 )
  41.             if bAddSpaces then
  42.                 table.insert( tResults, sResult .. " " )
  43.             else
  44.                 table.insert( tResults, sResult )
  45.             end
  46.         end
  47.     end
  48.     return tResults
  49. end
  50.  
  51. local function quoteGuard(sText,tOptions)
  52.     --detects spaces in autocompleted stuff and adds quotes as needed.
  53.     --kinda wonky
  54.     --not gonna use it
  55.     for i=1,#tOptions do
  56.         if tOptions[i]:match("%s") then --space detected activate quote-man
  57.             if sText == "" then tOptions[i]='"'..tOptions[i] end
  58.             tOptions[i]=tOptions[i]..'"'
  59.         end
  60.     end
  61.     return tOptions
  62. end
  63.  
  64.  
  65. local function peripherallook(sType,fTest)
  66.     local result={}
  67.     peripheral.find(sType,function(sName,tObject) if ( not fTest ) or fTest(sName,tObject) then table.insert(result,sName) end return false end)
  68.     return result
  69. end
  70.  
  71. local function hostnameslook(sProtocol)
  72.     -- Build list of host IDs
  73.     local tResults = {}
  74.     local close=false
  75.    
  76.     if not rednet.isOpen() then
  77.         for i,k in pairs(rs.getSides()) do
  78.             if peripheral.getType( k ) == "modem" then
  79.                 rednet.open(k)
  80.                 close=k
  81.                 break
  82.             end
  83.         end
  84.         if not close then return tResults end
  85.     end
  86.  
  87.     -- Broadcast a lookup packet
  88.     rednet.broadcast( {
  89.         sType = "lookup",
  90.         sProtocol = sProtocol,
  91.         sHostname = sHostname,
  92.     }, "dns" )
  93.  
  94.     -- Start a timer
  95.     local timer = os.startTimer( 0.5 )
  96.  
  97.     -- Wait for events
  98.     while true do
  99.         local event, p1, p2, p3 = os.pullEvent()
  100.         if event == "rednet_message" then
  101.             -- Got a rednet message, check if it's the response to our request
  102.             local nSenderID, tMessage, sMessageProtocol = p1, p2, p3
  103.             if sMessageProtocol == "dns" and tMessage.sType == "lookup response" then
  104.                 if tMessage.sProtocol == sProtocol then
  105.                         table.insert( tResults, tMessage.sHostname )
  106.                 end
  107.             end
  108.         else
  109.             -- Got a timer event, check it's the end of our timeout
  110.             if p1 == timer then
  111.                 break
  112.             end
  113.         end
  114.     end
  115.  
  116.     if close then
  117.         rednet.close(close)
  118.     end
  119.    
  120.     return tResults
  121. end
  122.  
  123. --#Disable autocompletition of rarely used parts/phrases that mess with the lives like xpcall and dofile
  124.  
  125. if textutils.complete("do")[1] == "file(" then --test if not disabled already
  126.  
  127.     local limited = {["do"]="file(",["x"]="pcall("}
  128.    
  129.     local textutils_complete = textutils.complete
  130.     textutils.complete = function(sName,tEnv)
  131.         if not limited[sName] then
  132.             return textutils_complete(sName,tEnv)
  133.         else
  134.             local ret = textutils_complete(sName,tEnv)
  135.             for i=#ret,1,-1 do
  136.                 if ret[i] == limited[sName] then table.remove(ret,i) end
  137.             end
  138.             return ret
  139.         end
  140.     end
  141.    
  142. end
  143.  
  144. --#Shell Completition
  145.  
  146. --Eject implementation --list only disk drives
  147.  
  148. local function completeEject( shell, nIndex, sText, tPreviousText )
  149.     if nIndex == 1 then
  150.         return completeMultipleChoice(sText,peripherallook("drive"))
  151.     end
  152. end
  153. shell.setCompletionFunction( "rom/programs/eject", completeEject )
  154.  
  155. --Label implementation --list only disk drives
  156.  
  157. local tLabelOptions = { "get", "get ", "set ", "clear", "clear " }
  158. local function completeLabel( shell, nIndex, sText, tPreviousText )
  159.     if nIndex == 1 then
  160.         return completeMultipleChoice( sText, tLabelOptions )
  161.     elseif nIndex == 2 then
  162.         return completeMultipleChoice(sText,peripherallook("drive"))
  163.     end
  164. end
  165. shell.setCompletionFunction( "rom/programs/label", completeLabel )
  166.  
  167. --Monitor implementation --list only monitors
  168.  
  169. local function completeMonitor( shell, nIndex, sText, tPreviousText )
  170.     if nIndex == 1 then
  171.         return completeMultipleChoice(sText,peripherallook("monitor"), true )
  172.     elseif nIndex == 2 then
  173.         return shell.completeProgram( sText )
  174.     end
  175. end
  176. shell.setCompletionFunction( "rom/programs/monitor", completeMonitor )
  177.  
  178. --DJ implementation --list only drives with songs inside. Show song name at that side in []
  179.  
  180. local tDJOptions = { "play", "play ", "stop" }
  181. local function Audiotest(sName,tObject)
  182.     return tObject.hasAudio()
  183. end
  184. local function AddSongName(tList,sText)
  185. tOutput = {}
  186. for _,k in pairs(tList) do
  187.     if sText ~= k then
  188.         table.insert(tOutput,k.." ["..disk.getAudioTitle(k).."]")
  189.     end
  190. end
  191. for _,k in pairs(tList) do
  192.     table.insert(tOutput,k)
  193. end
  194. return tOutput
  195. end
  196. local function completeDJ( shell, nIndex, sText, tPreviousText )
  197.     if nIndex == 1 then
  198.         return completeMultipleChoice( sText, tDJOptions )
  199.     elseif nIndex == 2 and tPreviousText[2] == "play" then
  200.         return completeMultipleChoice(sText,AddSongName(peripherallook("drive",Audiotest),sText))
  201.     end
  202. end
  203. shell.setCompletionFunction( "rom/programs/fun/dj", completeDJ )
  204.  
  205. --Pastebin implementation -- get website http://pastebin.com/u/..name
  206.  
  207. --<td><img src="/i/t.gif" class="i_p0" title="Public paste, everybody can see this paste." alt="" border="0" /> <a href="/DW3LCC3L">Monitor Mirror v2.1</a></td>
  208. --local tPastes={"DW3LCC3L"}
  209. --local tNames={["DW3LCC3L"] = "DW3LCC3L [Monitor Mirror v2.1]"}
  210. --local tFlatNames = {["DW3LCC3L"] = "Monitor_Mirror_v2.1}
  211.  
  212. --Code to get all the public pastes on Ext-util load.
  213. local tPastes = {}
  214. local tNames = {}
  215. local tFlatNames = {}
  216. for _,name in pairs(tPastebinNames) do
  217.     local site = "http://pastebin.com/u/"..textutils.urlEncode( name )
  218.     if http.checkURL(site) then
  219.         local data = getHttp(site)
  220.         if data then
  221.             --get pastes from data here.
  222.             for i,k in string.gmatch (data, '<td><img src="/i/t.gif" class="i_p0" title="Public paste, everybody can see this paste." alt="" border="0" /> <a href="/(%w+)">(.-)</a></td>') do
  223.                 table.insert(tPastes,i)
  224.                 tNames[i] = i.." ["..k.."]"
  225.                 tFlatNames[i] = string.gsub(k,"%s","_")
  226.             end
  227.         end
  228.     end
  229. end
  230.  
  231. --Auto Completition Part
  232. local function AddPasteName(tList,sText)
  233. tOutput = {}
  234. for _,k in pairs(tList) do
  235.     if sText ~= k then
  236.         table.insert(tOutput,tNames[k] or k)
  237.     end
  238. end
  239. for _,k in pairs(tList) do
  240.     table.insert(tOutput,tNames[k] and k)
  241. end
  242. return tOutput
  243. end
  244.  
  245. local tPastebinOptions = { "get ", "run ", "put" }
  246. local function completePastebin( shell, nIndex, sText, tPreviousText )
  247.     if nIndex == 1 then
  248.         return completeMultipleChoice( sText, tPastebinOptions )
  249.     elseif nIndex == 2 then
  250.         if tPreviousText[2] == "put" then
  251.             return fs.complete( sText, shell.dir(), true, false )
  252.         elseif tPreviousText[2] == "get" then
  253.             return completeMultipleChoice( sText, AddPasteName(tPastes,sText), true)
  254.         elseif tPreviousText[2] == "run" then
  255.             return completeMultipleChoice( sText, AddPasteName(tPastes,sText) )
  256.         end
  257.     elseif nIndex == 3 then
  258.         if tPreviousText[2] == "get" and tFlatNames[tPreviousText[3]]  then
  259.             return completeMultipleChoice( sText, {tFlatNames[tPreviousText[3]]} )
  260.         end
  261.     end
  262. end
  263. shell.setCompletionFunction( "rom/programs/http/pastebin", completePastebin )
  264.  
  265. --Chat implementation -- On join allow for duble tap of Tab to scan area for chat servers. Automaticly suggest names from tChatNames table
  266.  
  267. local tChatOptions = {"join ", "host "}
  268. --local tChatNames = {"Wojbie"}
  269. local tServers = {}
  270. local nLasttab = 0
  271. local function completeChat( shell, nIndex, sText, tPreviousText )
  272.     if nIndex == 1 then
  273.         return completeMultipleChoice( sText, tChatOptions )
  274.     elseif nIndex == 2 and tPreviousText[2] == "join" then
  275.         if sText =="" then
  276.             local nTime=os.clock()
  277.             if (nTime-nLasttab) < 0 then
  278.                 --do nothing           
  279.             elseif (nTime-nLasttab) < 0.5 then
  280.                 tServers = hostnameslook("chat") --on 2 empty inputs in 0.5 sec range do a rednet scan, if not empty dont re-scan.
  281.                 if #tServers == 0 then
  282.                     tServers =  {" [No Servers Found. Re-Tap to Re-Scan]"," "}
  283.                     nLasttab = os.clock()
  284.                 else
  285.                     --tServers = quoteGuard(sText,tServers) --not used cause wonky
  286.                     nLasttab = os.clock() + 30 --30 sec lock time after scan. So it won't scan in row.
  287.                 end
  288.             else
  289.                 tServers =  {" [Double-Tap Tab to Scan]"," "}
  290.                 nLasttab = os.clock()
  291.             end
  292.         end
  293.         return completeMultipleChoice( sText, tServers , true )
  294.     elseif nIndex == 3 and tPreviousText[2] == "join" then
  295.         return completeMultipleChoice( sText, tChatNames)
  296.     end
  297. end
  298. shell.setCompletionFunction( "rom/programs/rednet/chat", completeChat )
  299.  
  300. --GPS implementation -- move order of options so locate is first.
  301.  
  302. local tGPSOptions = {"locate" , "host", "host "}
  303. local function completeGPS( shell, nIndex, sText, tPreviousText )
  304.     if nIndex == 1 then
  305.         return completeMultipleChoice( sText, tGPSOptions )
  306.     end
  307. end
  308. shell.setCompletionFunction( "rom/programs/gps", completeGPS )
  309.  
  310. --Type implementation - error removal
  311. shell.setCompletionFunction( "rom/programs/type", shell.getCompletionInfo()["rom/programs/delete"].fnComplete ) --take correct one from delete program.
  312.  
  313. --#Turtle Additions implementation
  314.  
  315. if turtle then
  316. --#Premade Tables
  317.  
  318.     local ArgLists = {
  319.             ['slots']={},
  320.             ['equip']={'left', 'right'},
  321.             ['direction']={'left', 'right', 'forward', 'back', 'down', 'up'},
  322.             ['turn']={'left', 'right'},
  323.     }
  324.     for i=1,16 do
  325.         ArgLists['slots'][i]=tostring(i).." "
  326.     end
  327.  
  328.     local function completeGo( shell, nIndex, sText )
  329.         if nIndex == 1 then
  330.             return completeMultipleChoice(sText,ArgLists.direction)
  331.         end
  332.     end
  333.     shell.setCompletionFunction( "rom/programs/turtle/go", completeGo )
  334.  
  335.     local function completeTurn( shell, nIndex, sText )
  336.         if nIndex == 1 then
  337.             return completeMultipleChoice(sText,ArgLists.turn)
  338.         end
  339.     end
  340.     shell.setCompletionFunction( "rom/programs/turtle/turn", completeTurn )
  341.  
  342.     local function completeEquip( shell, nIndex, sText )
  343.         if nIndex == 1 then
  344.             return completeMultipleChoice(sText,ArgLists.slots,true)
  345.         elseif nIndex == 2 then
  346.             return completeMultipleChoice(sText,ArgLists.equip)
  347.         end
  348.     end
  349.     shell.setCompletionFunction( "rom/programs/turtle/equip", completeEquip )
  350.  
  351.     local function completeUnequip( shell, nIndex, sText )
  352.         if nIndex == 1 then
  353.             return completeMultipleChoice(sText,ArgLists.equip)
  354.         end
  355.     end
  356.     shell.setCompletionFunction( "rom/programs/turtle/unequip", completeUnequip )
  357.  
  358. end
Add Comment
Please, Sign In to add comment