Advertisement
Stiepen

KiloShell CraftOS Port

Apr 28th, 2013
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.10 KB | None | 0 0
  1. local version = "1.2"
  2. local historyLimit = 30
  3.  
  4. local parentShell = shell
  5.  
  6. local user = {getHome = function () return "/" end}
  7.  
  8. local bExit = false
  9. local sDir = (parentShell and parentShell.dir()) or "/"
  10. local sPath = (parentShell and parentShell.path()) or ".:/bin:/usr/bin:/rom/programs"
  11. local tEnvVars = {}
  12. local tAliases = (parentShell and parentShell.aliases()) or {}
  13. local pointers = {}
  14. local tProgramStack = {}
  15.  
  16. local shell = {}
  17. local tEnv = {
  18.   shell = shell
  19. }
  20.  
  21. if not fs.exists("/lib/tweaks") then
  22.   if not fs.exists("/lib") then fs.makeDir("/lib") end
  23.   print("Downloading required libs...")
  24.   parentShell.run("pastebin get U2Bm1FK0 /lib/tweaks")
  25. end
  26.  
  27. os.loadAPI("/lib/tweaks")
  28.  
  29. local function getShell(pid)
  30.   return shell
  31. end
  32. rawset(_G, "getShell", getShell)
  33.  
  34. --local textPrompt, bgPrompt, textColour, bgColour, textComplete, bgComplete
  35. local colorcfg = {}
  36. local function setColor(name)
  37.   --pcall(function()
  38.     term.setBackgroundColor(colorcfg["bg"..name])
  39.     term.setTextColor(colorcfg["text"..name])
  40.   --end)
  41. end
  42.  
  43. if term.isColour() then
  44.     colorcfg = {
  45.       textGreeting = colors.orange,
  46.       bgGreeting = colors.black,
  47.       textPrompt = colours.blue,
  48.       bgPrompt = colors.black,
  49.       textColour = colours.white,
  50.       bgColour = colours.black,
  51.       textComplete = colors.black,
  52.       bgComplete = colors.white,
  53.       textUser = colors.green,
  54.       bgUser = colors.black,
  55.     }
  56. else
  57.     colorcfg = {
  58.       textGreeting = colors.white,
  59.       bgGreeting = colors.black,
  60.       textPrompt = colours.white,
  61.       bgPrompt = colors.black,
  62.       textColour = colours.white,
  63.       bgColour = colours.black,
  64.       textComplete = colors.black,
  65.       bgComplete = colors.white,
  66.       textUser = colors.white,
  67.       bgUser = colors.black,
  68.     }
  69. end
  70.  
  71.  
  72. local function run( _sCommand, ... )
  73.     local sPath = shell.resolveProgram( _sCommand )
  74.     if sPath ~= nil then
  75.         tProgramStack[#tProgramStack + 1] = sPath
  76.         local result = os.run( tEnv, sPath, ... )
  77.         tProgramStack[#tProgramStack] = nil
  78.         return result
  79.     else
  80.         return false, "No such program"
  81.     end
  82. end
  83.  
  84. local function runLine( _sLine )
  85.     local tWords = {}
  86.     for match in string.gmatch( _sLine, "[^ \t]+" ) do
  87.         table.insert( tWords, match )
  88.     end
  89.  
  90.     local sCommand = tWords[1]
  91.     if sCommand then
  92.         return run( sCommand, unpack( tWords, 2 ) )
  93.     end
  94.     return false
  95. end
  96.  
  97. setmetatable(tEnv, {__index = _G})
  98.  
  99. function shell.run( ... )
  100.     return runLine( table.concat( { ... }, " " ) )
  101. end
  102.  
  103. function shell.exit()
  104.     bExit = true
  105. end
  106.  
  107. function shell.dir()
  108.     return sDir
  109. end
  110.  
  111. function shell.setEnvVar(var, value)
  112.   if type(var) ~= "string" then
  113.     error("parameter #1: string expected, got "..type(var))
  114.   end
  115.   if type(value) ~= "string" then
  116.     error("parameter #2: string expected, got "..type(value))
  117.   end
  118.   tEnvVars[var] = value
  119. end
  120.  
  121. function shell.getEnvVar(var, default, set)
  122.   if not tEnvVars[var] then
  123.     if set then
  124.       shell.setEnvVar(var, default)
  125.     else
  126.       return default
  127.     end
  128.   end
  129.   return tEnvVars[var]
  130. end
  131.  
  132. function shell.saveEnvVars()
  133.   local f = fs.open("/etc/envvars", "w")
  134.   f.write(textutils.serialize(tEnvVars))
  135.   f.close()
  136. end
  137.  
  138. function shell.setDir( _sDir )
  139.     sDir = _sDir
  140.     if sDir:sub(1,1) ~= "/" then sDir = "/"..sDir end
  141. end
  142.  
  143. function shell.path()
  144.     return sPath
  145. end
  146.  
  147. function shell.setPath( _sPath )
  148.     sPath = _sPath
  149. end
  150.  
  151. function shell.resolve( _sPath )
  152.     if _sPath:sub(1,2) == "/~" then
  153.       _sPath = _sPath:sub(2)
  154.     end
  155.     local sStartChar = string.sub( _sPath, 1, 1 )
  156.     if sStartChar == "~" and _sPath:sub(2,2) == "/" then
  157.       _sPath = user.getHome().._sPath:sub(2)
  158.     end
  159.     if sStartChar == "/" or sStartChar == "\\" then
  160.         return fs.combine( "", _sPath )
  161.     else
  162.         return fs.combine( sDir, _sPath )
  163.     end
  164. end
  165.  
  166. function shell.getDisplayName (_sPath)
  167.     local home = "/"
  168.     if _sPath:sub(1,1) ~= "/" then _sPath = "/".._sPath end
  169.     if _sPath:sub(1, #home) == home then
  170.         _sPath = "~".._sPath:sub(#home + 1)
  171.     end
  172.    
  173.     return _sPath--:sub(2)
  174. end
  175.  
  176. function shell.resolveProgram( _sCommand )
  177.     -- Substitute aliases firsts
  178.     if tAliases[ _sCommand ] ~= nil then
  179.         _sCommand = tAliases[ _sCommand ]
  180.     end
  181.  
  182.     -- If the path is a global path, use it directly
  183.     local sStartChar = string.sub( _sCommand, 1, 1 )
  184.     if sStartChar == "/" or sStartChar == "\\" then
  185.         local sPath = fs.combine( "", _sCommand )
  186.         if fs.exists( sPath ) and not fs.isDir( sPath ) then
  187.             return sPath
  188.         end
  189.         sPath = sPath..".lua"
  190.         if fs.exists( sPath ) and not fs.isDir( sPath ) then
  191.                 return sPath
  192.         end
  193.         return nil
  194.     end
  195.    
  196.     -- Otherwise, look on the path variable
  197.     for sPath in string.gmatch(sPath, "[^:]+") do
  198.         sPath = fs.combine( shell.resolve( sPath ), _sCommand )
  199.         if fs.exists( sPath ) and not fs.isDir( sPath ) then
  200.             return sPath
  201.         end
  202.     sPath = sPath..".lua"
  203.         if fs.exists( sPath ) and not fs.isDir( sPath ) then
  204.                 return sPath
  205.         end
  206.     end
  207.     -- Not found
  208.     return nil
  209. end
  210.  
  211. function shell.programs( _bIncludeHidden, _bIncludeAlias )
  212.     local tItems = {}
  213.    
  214.     -- Add programs from the path
  215.     for sPath in string.gmatch(sPath, "[^:]+") do
  216.         sPath = shell.resolve( sPath )
  217.         if fs.isDir( sPath ) then
  218.             local tList = fs.list( sPath )
  219.             for n,sFile in pairs( tList ) do
  220.                 if not fs.isDir( fs.combine( sPath, sFile ) ) and
  221.                    (_bIncludeHidden or string.sub( sFile, 1, 1 ) ~= ".") then
  222.                     if #sFile > 4 and sFile:sub(-4, -1) == ".lua" then
  223.                         tItems[ sFile:sub(1, -5) ] = true
  224.                     else
  225.                         tItems[ sFile ] = true
  226.                     end
  227.                 end
  228.             end
  229.         end
  230.     end
  231.     if _bIncludeAliases then
  232.         for k, v in pairs(tAliases) do
  233.             tItems[k] = true
  234.         end
  235.     end
  236.  
  237.     -- Sort and return
  238.     local tItemList = {}
  239.     for sItem, b in pairs( tItems ) do
  240.         table.insert( tItemList, sItem )
  241.     end
  242.     table.sort( tItemList )
  243.     return tItemList
  244. end
  245.  
  246. function shell.getRunningProgram()
  247.     if #tProgramStack > 0 then
  248.         return tProgramStack[#tProgramStack]
  249.     end
  250.     return nil
  251. end
  252.  
  253. function shell.setAlias( _sCommand, _sProgram )
  254.     tAliases[ _sCommand ] = _sProgram
  255. end
  256.  
  257. function shell.clearAlias( _sCommand )
  258.     tAliases[ _sCommand ] = nil
  259. end
  260.  
  261. function shell.aliases()
  262.     -- Add aliases
  263.     local tCopy = {}
  264.     for sAlias, sCommand in pairs( tAliases ) do
  265.         tCopy[sAlias] = sCommand
  266.     end
  267.     return tCopy
  268. end
  269.  
  270. function shell.addPointer(from, to)
  271.     pointers[from] = to
  272. end
  273.  
  274. local tHistory = {}
  275. local cplstr, cx, cy = nil, nil, nil
  276. local progs = {}
  277.  
  278. local function getCompleteString(text)
  279.   if text == "" then return end
  280.   for a = 1, #progs do
  281.     if #progs[a] > #text then
  282.       if progs[a]:sub(1, text:len()) == text then
  283.         return progs[a]
  284.       end
  285.     end
  286.   end
  287. end
  288.  
  289. local function charCallBack(sEvent, param, nPos, sLine, redraw, x, y)
  290.   if sEvent == "key" then
  291.     if param == keys.tab then
  292.       --complete
  293.       if cplstr then
  294.         local pos, line
  295.         line = cplstr.." "
  296.         pos = cplstr:len() + 1
  297.         return pos, line
  298.       end
  299.     end
  300.   end
  301. end
  302.  
  303. local function redrawCallBack(cc, redraw2, nPos, sLine, x, y)
  304.   cx, cy = x, y
  305.   write((" "):rep((cplstr or ""):len()))
  306.   if sLine == "" then
  307.     cplstr = nil  
  308.     term.setCursorPos(x, y)
  309.     --write((" "):rep((cplstr or ""):len()))
  310.     redraw2(cc)
  311.     return
  312.   end
  313.   cplstr = getCompleteString(sLine:sub(1,nPos + 1))
  314.   redraw2(cc)
  315.   if not cplstr then return end
  316.   local missing = cplstr:sub(nPos + 1)
  317.   term.setCursorPos(x + nPos, y)
  318.   if not cc then
  319.     setColor("Complete")
  320.     write(missing)
  321.   else
  322.     setColor("Colour")
  323.     write(cc:rep(#missing))
  324.   end
  325.   term.setCursorPos(x + nPos, y)
  326.   setColor("Colour")
  327. end
  328.  
  329. if turtle then
  330.   sPath = sPath..":/rom/programs/turtle"
  331. end
  332. if http then
  333.   sPath = sPath..":/rom/programs/http"
  334. end
  335. if term.isColor() then
  336.   sPath = sPath..":/rom/programs/color"
  337. end
  338. if not fs.exists("/etc") then fs.makeDir("/etc") end
  339. if not fs.exists("/etc/envvars") then fs.open("/etc/envvars", "w").close() end
  340. local f = fs.open("/etc/envvars", "r")
  341. tEnvVars = (textutils.unserialize(f.readAll()) or {})
  342. f.close()
  343.  
  344. shell.setAlias( "ls", "list" )
  345. shell.setAlias( "cp", "copy" )
  346. shell.setAlias( "mv", "move" )
  347. shell.setAlias( "rn", "rename" )
  348. shell.setAlias( "rm", "delete" )
  349.  
  350. shell.addPointer("dir", "ls")
  351. shell.addPointer("del", "rm")
  352.  
  353. setColor("Greeting")
  354. print("KiloShell for CraftOS, version "..version..", running on "..os.version())
  355. print("Type \"help\" to get started")
  356. --print("KiloShell version "..version.. ", running on KilOS "..KilOS.getVersion())
  357. --print("Type \"help\" to get started")
  358.  
  359.  
  360. for sPath in shell.getEnvVar("startup", "", true):gmatch('([^:]+)') do
  361.   if fs.isDir(sPath) then
  362.     local list = fs.list(sPath)
  363.     for i=1, #list do
  364.       local s, m = shell.run(sPath..list[i])
  365.       if not s then
  366.         printError("Failed to run "..sPath..". error: "..m)
  367.       end
  368.     end
  369.   else
  370.     local s, m = shell.run(sPath)
  371.     if not s then
  372.       printError("Failed to run "..sPath..". error: "..m)
  373.     end
  374.   end
  375. end
  376.  
  377. if fs.exists("/.startup") then
  378.   local s, m = shell.run("/.startup")
  379.   if m and not s then
  380.     printError("Failed to run startup: "..m)
  381.     --printError(lang.getRepl({"shell", "failed"}, {prog = "startup", err = m}))
  382.   end
  383. end
  384.  
  385. shell.setDir("/")
  386. shell.run("/.login")
  387.  
  388. while not bExit do
  389.   progs = shell.programs(false, true)
  390.   setColor("User")
  391.   local lbl = os.getComputerLabel()
  392.   write((lbl and #lbl > 0) and lbl or "unnamed")
  393.   setColor("Prompt")
  394.   write(":")
  395.   setColor("User")
  396.   write(shell.getDisplayName(sDir))
  397.   setColor("Prompt")
  398.   write("# ")
  399.   setColor("Colour")
  400.   local line = tweaks.read(nil, tHistory, charCallBack, redrawCallBack)
  401.   if cplstr and #line < #cplstr then
  402.     local x, y = term.getCursorPos()
  403.     term.setCursorPos(cx + 1, cy)
  404.     term.write((" "):rep(#cplstr - #line))
  405.     term.setCursorPos(x, y)
  406.   end
  407.   if tHistory[1] ~= line then
  408.     table.insert(tHistory, line)
  409.   end
  410.   if #tHistory > historyLimit then
  411.     table.remove(tHistory, 1)
  412.   end
  413.   local s, m = runLine(line)
  414.   if m and not s then
  415.     local cmd = line:match("[^ ]+")
  416.     local p = pointers[cmd]
  417.     if p then
  418.       --[[print(cmd.." wasn't found. Maybe you meant "..p)
  419.       tweaks.setColor(colors.yellow)
  420.       write(cmd)
  421.       tweaks.setColor(colors.blue)
  422.       --write(" was not found. Did you mean ")
  423.       tweaks.setColor(colors.yellow)
  424.       write(p)
  425.       tweaks.setColor(colors.blue)
  426.       print(" instead?")--]]
  427.       --tweaks.writeColored("§4-", cmd, "§b- ", lang)
  428.       tweaks.printColored("Could not find §4-"..cmd.."§b-. Did you mean §4-"..p.."§b- instead?")
  429.     else
  430.       printError(m)
  431.     end
  432.   end
  433. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement