Advertisement
Wojbie

Shell Extended 2.1 by Wojbie

Nov 4th, 2013
1,337
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 24.43 KB | None | 0 0
  1. local parentShell = shell
  2.  
  3. local bExit = false
  4. local sDir = (parentShell and parentShell.dir and parentShell.dir()) or ""
  5. local sPath = (parentShell and parentShell.path and parentShell.path()) or ".:/rom/programs"
  6. local tAliases = (parentShell and parentShell.aliases and parentShell.aliases()) or {}
  7. local tProgramStack = {}
  8.  
  9. local bClock = true
  10.  
  11. local saveDir= (parentShell and parentShell.getRunningProgram and parentShell.getRunningProgram()) or "/"
  12. saveDir=string.sub(saveDir,1,#saveDir-#fs.getName(saveDir))
  13. if fs.isReadOnly(saveDir) then saveDir="/" end
  14.  
  15.  
  16. local shell = {}
  17. local tEnv = {
  18.     ["shell"] = shell
  19. }
  20.  
  21. --[[ Colours  --]]
  22. local promptColour, textColour, bgColour
  23. if term.isColour() then
  24.     promptColour = colours.yellow
  25.     textColour = colours.white
  26.     bgColour = colours.black
  27. else
  28.     promptColour = colours.white
  29.     textColour = colours.white
  30.     bgColour = colours.black
  31. end
  32.  
  33. --[[ Standard Shell Functions --]]
  34.  
  35. local function run( _sCommand, ... )
  36.     local sPath = shell.resolveProgram( _sCommand )
  37.     if sPath ~= nil then
  38.         tProgramStack[#tProgramStack + 1] = sPath
  39.         local result = os.run( tEnv, sPath, ... )
  40.         tProgramStack[#tProgramStack] = nil
  41.         return result
  42.     else
  43.         printError( "No such program" )
  44.         return false
  45.     end
  46. end
  47.  
  48. local function runLine( _sLine )
  49.     local tWords = {}
  50.     for match in string.gmatch( _sLine, "[^ \t]+" ) do
  51.         table.insert( tWords, match )
  52.     end
  53.     local sCommand = tWords[1]
  54.     if sCommand then
  55.         return run( sCommand, unpack( tWords, 2 ) )
  56.     end
  57.     return false
  58. end
  59.  
  60. --[[ Install shell API  --]]
  61. function shell.run( ... )
  62.     return runLine(table.concat( { ... }, " " ))
  63. end
  64.  
  65. function shell.exit()
  66.     bExit = true
  67. end
  68.  
  69. function shell.dir()
  70.     return sDir
  71. end
  72.  
  73. function shell.setDir( _sDir )
  74.     sDir = _sDir
  75. end
  76.  
  77. function shell.path()
  78.     return sPath
  79. end
  80.  
  81. function shell.setPath( _sPath )
  82.     sPath = _sPath
  83. end
  84.  
  85. function shell.resolve( _sPath )
  86.     local sStartChar = string.sub( _sPath, 1, 1 )
  87.     if sStartChar == "/" or sStartChar == "\\" then
  88.         return fs.combine( "", _sPath )
  89.     else
  90.         return fs.combine( sDir, _sPath )
  91.     end
  92. end
  93.  
  94. function shell.resolveProgram( _sCommand )
  95.     --[[ Substitute aliases firsts  --]]
  96.     if tAliases[ _sCommand ] ~= nil then
  97.         _sCommand = tAliases[ _sCommand ]
  98.     end
  99.  
  100.     --[[ If the path is a global path, use it directly  --]]
  101.     local sStartChar = string.sub( _sCommand, 1, 1 )
  102.     if sStartChar == "/" or sStartChar == "\\" then
  103.         local sPath = fs.combine( "", _sCommand )
  104.         if fs.exists( sPath ) and not fs.isDir( sPath ) then
  105.             return sPath
  106.         end
  107.         return nil
  108.     end
  109.    
  110.     --[[  Otherwise, look on the path variable  --]]
  111.     for sPath in string.gmatch(sPath, "[^:]+") do
  112.         sPath = fs.combine( shell.resolve( sPath ), _sCommand )
  113.         if fs.exists( sPath ) and not fs.isDir( sPath ) then
  114.             return sPath
  115.         end
  116.     end
  117.    
  118.     --[[ Not found  --]]
  119.     return nil
  120. end
  121.  
  122. function shell.programs( _bIncludeHidden )
  123.     local tItems = {}
  124.    
  125.     --[[ Add programs from the path  --]]
  126.     for sPath in string.gmatch(sPath, "[^:]+") do
  127.         sPath = shell.resolve( sPath )
  128.         if fs.isDir( sPath ) then
  129.             local tList = fs.list( sPath )
  130.             for n,sFile in pairs( tList ) do
  131.                 if not fs.isDir( fs.combine( sPath, sFile ) ) and
  132.                    (_bIncludeHidden or string.sub( sFile, 1, 1 ) ~= ".") then
  133.                     tItems[ sFile ] = true
  134.                 end
  135.             end
  136.         end
  137.     end
  138.  
  139.     --[[ Sort and return  --]]
  140.     local tItemList = {}
  141.     for sItem, b in pairs( tItems ) do
  142.         table.insert( tItemList, sItem )
  143.     end
  144.     table.sort( tItemList )
  145.     return tItemList
  146. end
  147.  
  148. function shell.getRunningProgram()
  149.     if #tProgramStack > 0 then
  150.         return tProgramStack[#tProgramStack]
  151.     end
  152.     return nil
  153. end
  154.  
  155. function shell.setAlias( _sCommand, _sProgram )
  156.     tAliases[ _sCommand ] = _sProgram
  157. end
  158.  
  159. function shell.clearAlias( _sCommand )
  160.     tAliases[ _sCommand ] = nil
  161. end
  162.  
  163. function shell.aliases()
  164.     --[[ Add aliases  --]]
  165.     local tCopy = {}
  166.     for sAlias, sCommand in pairs( tAliases ) do
  167.         tCopy[sAlias] = sCommand
  168.     end
  169.     return tCopy
  170. end
  171.  
  172.  
  173. --[[ My Functions --]] --[[ My Functions --]] --[[ My Functions --]]
  174.  
  175. --[[ File Useage --]]
  176. local function save(A,B) local file = fs.open(tostring(A),"w") file.write(B) file.close() end
  177. local function saveT(A,B) save(A,textutils.serialize(B)) end
  178. local function saveTH(A,B) save(A,string.gsub(textutils.serialize(B),"},","},\r\n")) end
  179. 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
  180. local function getT(A) local data = get(A) if data then data = textutils.unserialize(data) end if data then return data end end
  181.  
  182. -- pastebin code
  183.  
  184. local pastebin={}
  185. pastebin={
  186. api_user_key = false,
  187. api_dev_key="6ee24782806f592dc9b3be30960fe117",
  188. login=function(api_user_name,api_user_password)
  189.     handle=http.post("http://pastebin.com/api/api_login.php","api_user_name="..textutils.urlEncode(api_user_name).."&api_user_password="..textutils.urlEncode(api_user_password).."&api_dev_key="..textutils.urlEncode(pastebin.api_dev_key))
  190.     local out=handle.readAll()
  191.     handle.close()
  192.     return out
  193. end,
  194. listall=function()
  195.     handle=http.post("http://pastebin.com/api/api_post.php","api_user_key="..textutils.urlEncode(pastebin.api_user_key).."&api_results_limit="..textutils.urlEncode(tostring(1000)).."&api_dev_key="..textutils.urlEncode(pastebin.api_dev_key).."&api_option=list")
  196.     local out=handle.readAll()
  197.     handle.close()
  198.     return out
  199. end,
  200. user=function()
  201.     handle=http.post("http://pastebin.com/api/api_post.php","api_user_key="..textutils.urlEncode(pastebin.api_user_key).."&api_dev_key="..textutils.urlEncode(pastebin.api_dev_key).."&api_option=userdetails")
  202.     local out=handle.readAll()
  203.     handle.close()
  204.     return out
  205. end,
  206. tabulate=function(A)
  207.     local out = {}
  208.     for i, k in string.gmatch(A, "<(.-)>(.-)</%1>") do
  209.         local temp = {}
  210.         for j, l in string.gmatch(k, "<"..i.."_(.-)>(.-)</"..i.."_%1>") do
  211.             temp[j] = l
  212.         end
  213.         table.insert(out,temp)
  214.     end
  215.     return out
  216. end,
  217. getone=function(code)
  218.     handle=http.get("http://pastebin.com/raw.php?i="..code)
  219.     if not handle then return nil end
  220.     local out=handle.readAll()
  221.     handle.close()
  222.     return out
  223. end
  224. }
  225.  
  226. --[[ Read without any writes() - visually conceals leanght of password from wiever --]]
  227. local function saferead()
  228.     term.setCursorBlink( true )
  229.     local sLine = ""
  230.     local nPos = 0
  231.     local w, h = term.getSize()
  232.     local sx, sy = term.getCursorPos()     
  233.     while true do
  234.         local sEvent, param = os.pullEvent()
  235.         if sEvent == "char" then
  236.             sLine = string.sub( sLine, 1, nPos ) .. param .. string.sub( sLine, nPos + 1 )
  237.             nPos = nPos + 1
  238.         elseif sEvent == "key" then
  239.             if param == keys.enter then
  240.                 --[[ Enter --]]
  241.                 break
  242.             elseif param == keys.backspace then
  243.                 --[[ Backspace --]]
  244.                 if nPos > 0 then
  245.                     sLine = string.sub( sLine, 1, nPos - 1 ) .. string.sub( sLine, nPos + 1 )
  246.                     nPos = nPos - 1    
  247.                 end
  248.             end
  249.         end
  250.     end
  251.     term.setCursorBlink( false )
  252.     term.setCursorPos( w + 1, sy )
  253.     print()
  254.     return sLine
  255. end
  256.  
  257. local function pastelogin()
  258.     if not http then print("Http Api is offline - this will not work. Sorry") return end
  259.     pcall( function()
  260.         if not pastebin.api_user_key then
  261.             write("Username: ")
  262.             local a=read()
  263.             write("Password: ")
  264.             --[[ Passowrd is not stored - is used and forgotten --]]
  265.             local response=pastebin.login(a,saferead())
  266.             if string.find(string.lower(response), "bad api request" , 1 , true) then print("Login Unsuccessful") pastebin.api_user_key = false
  267.             else print("Login Successful") pastebin.api_user_key = response end
  268.         else
  269.             print("Already Logged in as "..pastebin.tabulate(pastebin.user())[1]["name"]..". Use plogout< to logout if you want to change users.")
  270.         end
  271.     end)
  272. end
  273.  
  274. local function pastelogout()
  275.     pastebin.api_user_key = false print("Logout Successful")
  276. end
  277.  
  278. local function pastewho()
  279.     if not http then print("Http Api is offline - this will not work. Sorry") return end
  280.     if not pastebin.api_user_key then print(" No user logged in - Please use plogin< to login") return end
  281.     pcall( function()
  282.         print("User logged in - displaying data:")
  283.         local user=pastebin.tabulate(pastebin.user())[1]
  284.         for i,k in pairs(user) do
  285.         print(i," : ",k)
  286.         end
  287.     end)
  288. end
  289.  
  290. local function pasteget(_Where)
  291.     if not http then print("Http Api is offline - this will not work. Sorry") return end
  292.     if not pastebin.api_user_key then print(" No user logged in - Please use plogin< to login") return end
  293.    
  294.     pcall( function()
  295.         local dir=fs.combine(saveDir,"Pastes")
  296.         if not _Where and not fs.exists(dir) then fs.makeDir(dir) end
  297.        
  298.         print("Downloading Filelist")
  299.         local pastes=pastebin.tabulate(pastebin.listall())
  300.        
  301.         for i=#pastes,1,-1 do --[[Removing private Pastes - no way to download them--]]
  302.             if pastes[i].private==2 then table.remove(pastes,i) end
  303.         end
  304.        
  305.         local offset=0
  306.         local selected=1
  307.         local All=false
  308.        
  309.         local function List()
  310.             local x,y=term.getSize()
  311.             term.clear()
  312.             if #pastes > y-1 then offset=math.max(0,math.min(#pastes-(y-1),selected-math.floor((y-1)/2))) else offset=0 end
  313.             for i=1,math.min(y-1,#pastes) do
  314.                 term.setCursorPos(1,i)
  315.                 if i+offset==selected then
  316.                 term.setTextColour(colours.black)
  317.                 term.setBackgroundColor(colours.white)
  318.                 else
  319.                 term.setTextColour(colours.white)
  320.                 term.setBackgroundColor(colours.black)
  321.                 end
  322.                 local temp=pastes[i+offset]
  323.                 term.write((temp.private=="1" and "." or "")..(temp.selected and "> " or "")..temp["title"]..(temp.selected and " <" or ""))
  324.             end
  325.             term.setTextColour(colours.white)
  326.             term.setBackgroundColor(colours.black)
  327.             term.setCursorPos(1,y)
  328.             if _Where then
  329.             term.write("Up/Down,D-Download")
  330.             else
  331.             term.write("Up/Down,Enter-Sel,D-Download,Tab-D-All")
  332.             end
  333.         end
  334.  
  335.         List()
  336.        
  337.         while true do
  338.             event= {os.pullEvent()}
  339.             if event[1]=="key" then
  340.                 if event[2]==keys.down then
  341.                     selected=math.min(selected+1,#pastes)
  342.                     List()
  343.                 elseif event[2]==keys.up then
  344.                     selected=math.max(selected-1,1)
  345.                     List()
  346.                 elseif event[2]==keys.d then
  347.                     if _Where then pastes[selected]["selected"]=true end
  348.                     print()
  349.                     print("Downloading Selected")  
  350.                     break
  351.                 elseif not _Where and (event[2]==keys.numPadEnter or event[2]==keys.enter)then
  352.                     pastes[selected]["selected"]=not pastes[selected]["selected"]
  353.                     List()
  354.                 elseif not _Where and  event[2]==keys.tab then
  355.                     print()
  356.                     print("Downloading All")
  357.                     All=true
  358.                     break
  359.                 end
  360.             end --if event
  361.         end
  362.        
  363.         term.setTextColour(colours.white)
  364.         term.setBackgroundColor(colours.black)
  365.        
  366.         for _,k in pairs(pastes) do
  367.             if k.selected or All then
  368.                 local name=string.gsub(k["title"]," ","_")
  369.                 print("Downloading "..name)
  370.                 local file =nil
  371.                 while true do
  372.                     file = pastebin.getone(k["key"])
  373.                     if file then break end
  374.                     print("Failed - Retrying in 5 sec")
  375.                     sleep(5)
  376.                     print("Downloading "..name)
  377.                 end
  378.                 if _Where then save(_Where,file)
  379.                 else save(fs.combine(dir,name),file) end
  380.                 print("Finished")
  381.             end
  382.         end
  383.        
  384.         print("Downloaded to ",_Where or dir )
  385.     end)
  386. end
  387.  
  388. local function pasteput()
  389.     if not http then print("Http Api is offline - this will not work. Sorry") return end
  390.     --[[To be added at later date--]]
  391. end
  392.  
  393. -- lua code
  394.  
  395. local LuatEnv = {}
  396. setmetatable( LuatEnv, { __index = getfenv() } )
  397.  
  398. local function runlua( _sCommand )
  399.     if not _sCommand then return false end
  400.  
  401.  
  402.     local nForcePrint = 0
  403.     local func, e = loadstring( _sCommand, "lua" )
  404.     local func2, e2 = loadstring( "return ".._sCommand, "lua" )
  405.     if not func then
  406.         if func2 then
  407.             func = func2
  408.             e = nil
  409.             nForcePrint = 1
  410.         end
  411.     else
  412.         if func2 then
  413.             func = func2
  414.         end
  415.     end
  416.    
  417.     if func then
  418.         setfenv( func, LuatEnv )
  419.         local tResults = { pcall( function() return func() end ) }
  420.         if tResults[1] then
  421.             local n = 1
  422.             while (tResults[n + 1] ~= nil) or (n <= nForcePrint) do
  423.                 print( tostring( tResults[n + 1] ) )
  424.                 n = n + 1
  425.             end
  426.         else
  427.             printError( tResults[2] )
  428.         end
  429.     else
  430.         printError( e )
  431.     end
  432.    
  433. end
  434.  
  435. -- cat code
  436.  
  437. local function cat(_Tfiles)
  438.     _,y=term.getSize()
  439.     local out={}
  440.    
  441.     pcall( function()
  442.         for i,k in ipairs(_Tfiles) do
  443.             local path=shell.resolve(k)
  444.             if not fs.exists(path) then print("File "..k.." don't exists") return end
  445.             if fs.isDir(path) then print(k.." is a directory") return end
  446.             local file = fs.open(path, "r")
  447.             table.insert(out,file.readAll())
  448.             file.close()
  449.         end
  450.         textutils.pagedPrint(table.concat(out))
  451.     end)
  452. end
  453.  
  454. -- find code
  455.  
  456. local function findfile(target,patt)
  457.     if target=="" then print("No target specified") return end
  458.     local matches={}
  459.     target=string.lower(target)
  460.    
  461.     local function process(path)
  462.         local T=fs.list(path)
  463.         for _,k in ipairs(T) do
  464.             local cpath=path.."/"..k
  465.             if string.find(string.lower(k), target , 1 , not patt) then table.insert(matches,cpath) end
  466.             if fs.isDir(cpath) then process(cpath) end
  467.         end
  468.     end
  469.    
  470.     local function list(_Tlist)
  471.         local tFiles = {}
  472.         local tVFiles = {}
  473.         local tDirs = {}
  474.         local tVDirs = {}
  475.         for n, sItem in pairs(_Tlist) do
  476.             if fs.isDir( sItem ) then
  477.                 table.insert( tDirs, sItem )
  478.             else
  479.                 table.insert( tFiles, sItem )
  480.             end
  481.         end
  482.         table.sort( tDirs ) table.sort( tVDirs ) table.sort( tFiles ) table.sort( tVFiles )
  483.         if term.isColour() then
  484.             textutils.pagedTabulate(colors.green , tDirs , colors.white, tFiles)
  485.         else
  486.             textutils.pagedTabulate(tDirs , tFiles)
  487.         end
  488.     end
  489.    
  490.     pcall( function()
  491.         process("")
  492.         list(matches)
  493.     end)
  494. end
  495.  
  496. -- read with tab-completition code
  497.  
  498. local function readtab( _sReplaceChar, _tHistory , _sPrefix)
  499.     term.setCursorBlink( true )
  500.  
  501.     local sLine = _sPrefix or ""
  502.     local nHistoryPos = nil
  503.     local nPos = string.len(sLine)
  504.     if _sReplaceChar then
  505.         _sReplaceChar = string.sub( _sReplaceChar, 1, 1 )
  506.     end
  507.    
  508.     local w, h = term.getSize()
  509.     local sx, sy = term.getCursorPos() 
  510.     local clocvis
  511.    
  512.     local function shellclock(_clear)
  513.         if  bClock and not _clear and sx+#sLine <= w-7 then
  514.             clocvis=true
  515.             term.setCursorBlink( false )
  516.             local state=textutils.formatTime(os.time(),true)
  517.             while #state<5 do state=" "..state end
  518.             local x=term.getCursorPos()
  519.             term.setCursorPos( w-5, sy )
  520.             term.setTextColour( promptColour )
  521.             write(state)
  522.             term.setTextColour( textColour )
  523.             term.setCursorPos( x, sy )
  524.             term.setCursorBlink( true )
  525.         else
  526.             if clocvis then
  527.                 local x=term.getCursorPos()
  528.                 term.setCursorBlink( false )
  529.                 term.setCursorPos( w-5, sy )
  530.                 write("     ")
  531.                 term.setCursorPos( x, sy )
  532.                 term.setCursorBlink( true )
  533.                 clocvis=false          
  534.             end
  535.         end    
  536.     end
  537.    
  538.     local function redraw( _sCustomReplaceChar )
  539.         local nScroll = 0
  540.         if sx + nPos >= w then
  541.             nScroll = (sx + nPos) - w
  542.         end
  543.         shellclock()
  544.         term.setCursorPos( sx, sy )
  545.         local sReplace = _sCustomReplaceChar or _sReplaceChar
  546.         if sReplace then
  547.             term.write( string.rep( sReplace, string.len(sLine) - nScroll ) )
  548.         else
  549.             term.write( string.sub( sLine, nScroll + 1 ) )
  550.         end
  551.         term.setCursorPos( sx + nPos - nScroll, sy )
  552.     end
  553.  
  554.     local function list(_Tlist,_Spath,_Bhide)
  555.         shellclock(true)
  556.         local tFiles = {}
  557.         local tVFiles = {}
  558.         local tDirs = {}
  559.         local tVDirs = {}
  560.         for n, sItem in pairs(_Tlist) do
  561.             if not (_Bhide and string.sub( sItem, 1, 1 )==".") then
  562.                 local sPath = fs.combine( _Spath, sItem )
  563.                 if fs.isDir( sPath ) then
  564.                     table.insert( tDirs, sItem )
  565.                 else
  566.                     table.insert( tFiles, sItem )
  567.                 end
  568.             end
  569.         end
  570.         table.sort( tDirs ) table.sort( tVDirs ) table.sort( tFiles ) table.sort( tVFiles )
  571.         print()
  572.         if term.isColour() then
  573.             pcall( function()
  574.             textutils.pagedTabulate( colors.green , tDirs , colors.white, tFiles)
  575.             end)
  576.         else
  577.             pcall( function()
  578.             textutils.pagedTabulate( tDirs , tFiles)
  579.             end)
  580.         end
  581.         term.setTextColour( promptColour )
  582.         write( shell.dir() .. "> " )
  583.         term.setTextColour( textColour )
  584.         sx, sy = term.getCursorPos()
  585.     end
  586.    
  587.     local function common(_String,_Min,_Cur)
  588.         if not _Cur then return _String end
  589.         local long=_Cur
  590.         for i=math.min(#_String,#_Cur),_Min,-1 do
  591.             local a,b=string.sub (_String,1,i),string.sub(_Cur,1,i)
  592.             if a==b then return a end      
  593.         end
  594.         return string.sub (_Cur,1,_Min)
  595.     end
  596.    
  597.     local tick
  598.     if bClock then tick=os.startTimer(1) end
  599.     redraw()
  600.     while true do
  601.         local sEvent, param = os.pullEvent()
  602.         if sEvent =="timer" and param==tick then shellclock() tick=os.startTimer(1)
  603.         elseif sEvent == "char" then
  604.             sLine = string.sub( sLine, 1, nPos ) .. param .. string.sub( sLine, nPos + 1 )
  605.             nPos = nPos + 1
  606.             redraw()
  607.            
  608.         elseif sEvent == "key" then
  609.             if param == keys.enter then
  610.                 --[[ Enter --]]
  611.                 shellclock(true)
  612.                 break
  613.                
  614.             elseif param == keys.left then
  615.                 --[[ Left --]]
  616.                 if nPos > 0 then
  617.                     redraw(" ")
  618.                     nPos = nPos - 1
  619.                     redraw()
  620.                 end
  621.                
  622.             elseif param == keys.right then
  623.                 --[[ Right --]]            
  624.                 if nPos < string.len(sLine) then
  625.                     redraw(" ")
  626.                     nPos = nPos + 1
  627.                     redraw()
  628.                 end
  629.            
  630.             elseif param == keys.up or param == keys.down then
  631.                 --[[ Up or down --]]
  632.                 if _tHistory then
  633.                     redraw(" ")
  634.                     if param == keys.up then
  635.                         --[[ Up --]]
  636.                         if nHistoryPos == nil then
  637.                             if #_tHistory > 0 then
  638.                                 nHistoryPos = #_tHistory
  639.                             end
  640.                         elseif nHistoryPos > 1 then
  641.                             nHistoryPos = nHistoryPos - 1
  642.                         end
  643.                     else
  644.                         --[[ Down --]]
  645.                         if nHistoryPos == #_tHistory then
  646.                             nHistoryPos = nil
  647.                         elseif nHistoryPos ~= nil then
  648.                             nHistoryPos = nHistoryPos + 1
  649.                         end                    
  650.                     end
  651.                     if nHistoryPos then
  652.                         sLine = _tHistory[nHistoryPos]
  653.                         nPos = string.len( sLine )
  654.                     else
  655.                         sLine = ""
  656.                         nPos = 0
  657.                     end
  658.                     redraw()
  659.                 end
  660.             elseif param == keys.backspace then
  661.                 --[[ Backspace --]]
  662.                 if nPos > 0 then
  663.                     redraw(" ")
  664.                     sLine = string.sub( sLine, 1, nPos - 1 ) .. string.sub( sLine, nPos + 1 )
  665.                     nPos = nPos - 1                
  666.                     redraw()
  667.                 end
  668.             elseif param == keys.home then
  669.                 --[[ Home --]]
  670.                 redraw(" ")
  671.                 nPos = 0
  672.                 redraw()       
  673.             elseif param == keys.delete then
  674.                 if nPos < string.len(sLine) then
  675.                     redraw(" ")
  676.                     sLine = string.sub( sLine, 1, nPos ) .. string.sub( sLine, nPos + 2 )              
  677.                     redraw()
  678.                 end
  679.             elseif param == keys["end"] then
  680.                 --[[ End --]]
  681.                 redraw(" ")
  682.                 nPos = string.len(sLine)
  683.                 redraw()
  684.             elseif param == keys.tab and (string.sub( sLine, nPos+1 ,nPos+1)==" " or nPos==string.len(sLine)) then
  685.                 --[[ Tab  --]]
  686.                 local need=string.match(string.sub(sLine,1,nPos),"[ ]?([^ ]-)$")
  687.                 if need=="" or string.match(need,"[\\/]$") then
  688.  
  689.                     --[[looking at root or /,\ at end mean folder --]]
  690.                     local path=shell.resolve(need or "")
  691.                     if fs.exists(path) and fs.isDir(path) then list(fs.list(path),path,true) end
  692.                    
  693.                 else
  694.                     --[[have part of name --]]                 
  695.                     --[[get absolute path and target name --]]
  696.                     local path=""
  697.                     local targ=""
  698.                     if need=="." or string.match(need,"[\\/]%.$") then --[[lokking for hidden in folder --]]
  699.                         path=shell.resolve(need).."/"
  700.                         targ="."
  701.                     else --[[lokking for normal file --]]
  702.                         path=shell.resolve(need)
  703.                         targ=fs.getName(path)
  704.                     end
  705.                    
  706.                     --[[get path without name and see it iteven exists --]]
  707.                     path=string.sub(path,1,#path-#targ) or ""
  708.                     if fs.exists(path) and fs.isDir(path) then
  709.                        
  710.                         --[[find files in path matching part --]]
  711.                         --[[at same time look for longest common leading substing --]]
  712.                         local out={}
  713.                         local long=nil
  714.                         local lim=#targ
  715.                          --[[Sanitizing magic for pattern needs ^$()%.[]*+-?--]]
  716.                         local pattern="^"..string.gsub(string.lower(targ),"[%^%$%(%)%%%.%[%]%*%+%-%?]",function(A) return "%"..A end)
  717.                         for i,k in pairs(fs.list(path)) do
  718.                             local tempS=string.lower(k)
  719.                             if string.match(tempS,pattern) then
  720.                                 table.insert(out,k)
  721.                                 long=common(tempS,lim,long)
  722.                             end
  723.                         end
  724.                         if #out==1 then
  725.                             if fs.isDir(fs.combine(path,out[1])) then out[1]=out[1].."/" end
  726.                             sLine=string.sub(sLine,1,nPos-#targ)..out[1]..string.sub( sLine, nPos + 1 )
  727.                             nPos = nPos-#targ+#out[1]
  728.                         elseif #out>1 then
  729.                             sLine=string.sub( sLine, 1, nPos-#targ )..long..string.sub( sLine, nPos + 1 )
  730.                             nPos = nPos-#targ+#long
  731.                             list(out,path)                         
  732.                         end
  733.                     end
  734.                 end
  735.                 redraw()
  736.             end
  737.         end
  738.     end
  739.    
  740.     term.setCursorBlink( false )
  741.     term.setCursorPos( w + 1, sy )
  742.     print()
  743.    
  744.     return sLine
  745. end
  746.  
  747. --[[ Back to standard shell with extended modyfications  --]]
  748.    
  749. term.setBackgroundColor( bgColour )
  750. term.setTextColour( promptColour )
  751. print( os.version(), " Extended v 2.1" )
  752. term.setTextColour( textColour )
  753.  
  754. --[[ If this is the toplevel shell, run the startup programs  --]]
  755. if parentShell == nil then
  756.     --[[ Run the startup from the ROM first  --]]
  757.     local sRomStartup = shell.resolveProgram( "/rom/startup" )
  758.     if sRomStartup then
  759.         shell.run( sRomStartup )
  760.     end
  761.    
  762.     --[[ Then run the user created startup, from the disks or the root  --]]
  763.     local sUserStartup = shell.resolveProgram( "/startup" )
  764.     for n,sSide in pairs( peripheral.getNames() ) do
  765.         if disk.isPresent( sSide ) and disk.hasData( sSide ) then
  766.             local sDiskStartup = shell.resolveProgram( fs.combine(disk.getMountPath( sSide ), "startup") )
  767.             if sDiskStartup then
  768.                 sUserStartup = sDiskStartup
  769.                 break
  770.             end
  771.         end
  772.     end
  773.    
  774.     if sUserStartup then
  775.         shell.run( sUserStartup )
  776.     end
  777. end
  778.  
  779. --[[ Run any programs passed in as arguments  --]]
  780. local tArgs = { ... }
  781. if #tArgs > 0 then
  782.     shell.run( ... )
  783. end
  784.  
  785. --[[ Read commands and execute them -- Most of modyfications happend here  --]]
  786. local tCommandHistoryfile=fs.combine(saveDir,".shellhistory.log")
  787. local tCommandHistory = {}
  788. if fs.exists(tCommandHistoryfile) then tCommandHistory = getT(tCommandHistoryfile) or {} end
  789. local nextprefix = ""
  790. while not bExit do
  791.     local a=term.getCursorPos() --making sure it will not go out of screen
  792.     if a>1 then print() end
  793.    
  794.     term.setBackgroundColor( bgColour )
  795.     term.setTextColour( promptColour )
  796.     write( shell.dir() .. "> " )
  797.     term.setTextColour( textColour )
  798.    
  799.     local sLine = readtab( nil, tCommandHistory ,nextprefix)
  800.     nextprefix = ""
  801.     if sLine~="" then
  802.    
  803.         if sLine ~= tCommandHistory[#tCommandHistory] then
  804.             table.insert( tCommandHistory, sLine )
  805.             if tCommandHistory[101] then table.remove(tCommandHistory,1) end
  806.             saveT(tCommandHistoryfile,tCommandHistory)
  807.         end
  808.        
  809.         local tWords = {}
  810.             for match in string.gmatch( sLine, "[^ \t]+" ) do
  811.             table.insert( tWords, match )
  812.         end
  813.         local sCommand = table.remove(tWords,1)
  814.        
  815.         if sCommand == "lua<" then --[[ Lua Execution --]]
  816.             runlua( string.sub( sLine, 6) )
  817.             nextprefix = "lua< "
  818.         elseif sCommand == "lua#" then --[[ Lua Clear --]]
  819.             LuatEnv = {} setmetatable( LuatEnv, { __index = getfenv() } ) print("Shell Lua Enviroment Cleared")
  820.         elseif sCommand == "cat<" then  --[[ Cat Execution --]]
  821.             cat(tWords)
  822.         elseif sCommand == "clock<" then    --[[ Clock Toggle --]]
  823.             bClock=not bClock print("Clock ",(bClock and "On")or"Off")
  824.         elseif sCommand == "find<" then --[[ Find Execution --]]
  825.             findfile(string.sub( sLine, 7))
  826.         elseif sCommand == "findpattern<" then  --[[ Find with pattern Execution --]]
  827.             findfile(string.sub( sLine, 14),true)
  828.         elseif sCommand == "plogin<" then   --[[ pastebin login --]]
  829.             pastelogin()
  830.         elseif sCommand == "plogout<" then  --[[ pastebin plogout --]]
  831.             pastelogout()
  832.         elseif sCommand == "pget<" then --[[  pastebin get one file --]]
  833.             local tar=string.sub( sLine, 7)
  834.             pasteget(shell.resolve(tar))
  835.         elseif sCommand == "plist<" then    --[[  pastebin get x files--]]
  836.             pasteget()
  837.         elseif sCommand == "pwho<" then --[[ pastebin get user info --]]
  838.             pastewho()
  839.         elseif sCommand == "help<" or sCommand == "?<"  then    --[[ Help Execution --]]
  840.             print("List of extra shell commands: lua<,lua#,cat<,clock<,find<,findpattern<,help<",(http and ",plogin<,plogout<,pget<,plist<" or ""))
  841.         elseif sCommand then --[[ Standard Execution --]]
  842.             run( sCommand, unpack( tWords ) )
  843.         end
  844.     end
  845. end
  846.  
  847. --[[ If this is the toplevel shell, run the shutdown program  --]]
  848. if parentShell == nil then
  849.     if shell.resolveProgram( "shutdown" ) then
  850.         shell.run( "shutdown" )
  851.     end
  852.     os.shutdown() --[[ just in case  --]]
  853. end
  854.  
  855. term.setTextColour( promptColour )
  856. print("Extended Shell Terminated.")
  857. print("Have a Nice Day!")
  858. term.setTextColour( textColour )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement