Advertisement
pepeknamornik

commander P7

Jun 20th, 2019 (edited)
1,130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 13.80 KB | None | 0 0
  1. verze = "21.0703.R1"
  2. term.setBackgroundColor(colors.blue)
  3. term.clear()
  4. term.setCursorPos(1,1)
  5. local w,h = term.getSize()
  6.  
  7. local expect = dofile("rom/modules/main/cc/expect.lua").expect
  8.  
  9. local multishell = multishell
  10. local parentShell = shell
  11. local parentTerm = term.current()
  12.  
  13. if multishell then
  14.     multishell.setTitle(multishell.getCurrent(), "shell")
  15. end
  16.  
  17. local bExit = false
  18. local sDir = parentShell and parentShell.dir() or ""
  19. local sPath = parentShell and parentShell.path() or ".:/rom/programs"
  20. local tAliases = parentShell and parentShell.aliases() or {}
  21. local tCompletionInfo = parentShell and parentShell.getCompletionInfo() or {}
  22. local tProgramStack = {}
  23.  
  24. local shell = {} --- @export
  25. local function createShellEnv(sDir)
  26.     local tEnv = {}
  27.     tEnv.shell = shell
  28.     tEnv.multishell = multishell
  29.  
  30.     local package = {}
  31.     package.loaded = {
  32.         _G = _G,
  33.         bit32 = bit32,
  34.         coroutine = coroutine,
  35.         math = math,
  36.         package = package,
  37.         string = string,
  38.         table = table,
  39.     }
  40.     package.path = "?;?.lua;?/init.lua;/rom/modules/main/?;/rom/modules/main/?.lua;/rom/modules/main/?/init.lua"
  41.     if turtle then
  42.         package.path = package.path .. ";/rom/modules/turtle/?;/rom/modules/turtle/?.lua;/rom/modules/turtle/?/init.lua"
  43.     elseif command then
  44.         package.path = package.path .. ";/rom/modules/command/?;/rom/modules/command/?.lua;/rom/modules/command/?/init.lua"
  45.     end
  46.     package.config = "/\n;\n?\n!\n-"
  47.     package.preload = {}
  48.     package.loaders = {
  49.         function(name)
  50.             if package.preload[name] then
  51.                 return package.preload[name]
  52.             else
  53.                 return nil, "no field package.preload['" .. name .. "']"
  54.             end
  55.         end,
  56.         function(name)
  57.             local fname = string.gsub(name, "%.", "/")
  58.             local sError = ""
  59.             for pattern in string.gmatch(package.path, "[^;]+") do
  60.                 local sPath = string.gsub(pattern, "%?", fname)
  61.                 if sPath:sub(1, 1) ~= "/" then
  62.                     sPath = fs.combine(sDir, sPath)
  63.                 end
  64.                 if fs.exists(sPath) and not fs.isDir(sPath) then
  65.                     local fnFile, sError = loadfile(sPath, nil, tEnv)
  66.                     if fnFile then
  67.                         return fnFile, sPath
  68.                     else
  69.                         return nil, sError
  70.                     end
  71.                 else
  72.                     if #sError > 0 then
  73.                         sError = sError .. "tu  "
  74.                     end
  75.                     sError = sError .. "no file '" .. sPath .. "'"
  76.                 end
  77.             end
  78.             return nil, sError
  79.         end,
  80.     }
  81.  
  82.     local sentinel = {}
  83.     local function require(name)
  84.         expect(1, name, "string")
  85.         if package.loaded[name] == sentinel then
  86.             error("loop or previous error loading module '" .. name .. "'", 0)
  87.         end
  88.         if package.loaded[name] then
  89.             return package.loaded[name]
  90.         end
  91.  
  92.         local sError = "module '" .. name .. "' not found:"
  93.         for _, searcher in ipairs(package.loaders) do
  94.             local loader = table.pack(searcher(name))
  95.             if loader[1] then
  96.                 package.loaded[name] = sentinel
  97.                 local result = loader[1](name, table.unpack(loader, 2, loader.n))
  98.                 if result == nil then result = true end
  99.  
  100.                 package.loaded[name] = result
  101.                 return result
  102.             else
  103.                 sError = sError .. "\n  " .. loader[2]
  104.             end
  105.         end
  106.         error(sError, 2)
  107.     end
  108.  
  109.     tEnv.package = package
  110.     tEnv.require = require
  111.  
  112.     return tEnv
  113. end
  114.  
  115. local promptColour, textColour, bgColour
  116. if term.isColour() then
  117.     promptColour = colours.yellow
  118.     textColour = colours.white
  119.     bgColour = 2048
  120. else
  121.     promptColour = colours.white
  122.     textColour = colours.white
  123.     bgColour = colours.black
  124. end
  125.  
  126. local function run(_sCommand, ...)
  127.     local sPath = shell.resolveProgram(_sCommand)
  128.     if sPath ~= nil then
  129.         tProgramStack[#tProgramStack + 1] = sPath
  130.  
  131.         local sDir = fs.getDir(sPath)
  132.         local env = createShellEnv(sDir)
  133.         env.arg = { [0] = _sCommand, ... }
  134.         local result = os.run(env, sPath, ...)
  135.         tProgramStack[#tProgramStack] = nil
  136.         if multishell then
  137.             if #tProgramStack > 0 then
  138.                 local sTitle = fs.getName(tProgramStack[#tProgramStack])
  139.                 if sTitle:sub(-4) == ".lua" then
  140.                     sTitle = sTitle:sub(1, -5)
  141.                 end
  142.                 multishell.setTitle(multishell.getCurrent(), sTitle)
  143.             else
  144.                 multishell.setTitle(multishell.getCurrent(), "shell")
  145.             end
  146.         end
  147.        
  148.         return result
  149.        else
  150.         printError("No such program")
  151.         return false
  152.     end
  153. end
  154.  
  155. local function tokenise(...)
  156.     local sLine = table.concat({ ... }, " ")
  157.     local tWords = {}
  158.     local bQuoted = false
  159.     for match in string.gmatch(sLine .. "\"", "(.-)\"") do
  160.         if bQuoted then
  161.             table.insert(tWords, match)
  162.         else
  163.             for m in string.gmatch(match, "[^ \t]+") do
  164.                 table.insert(tWords, m)
  165.             end
  166.         end
  167.         bQuoted = not bQuoted
  168.     end
  169.     return tWords
  170. end
  171.  
  172. function shell.run(...)
  173.     local tWords = tokenise(...)
  174.     local sCommand = tWords[1]
  175.     if sCommand then
  176.         return run(sCommand, table.unpack(tWords, 2))
  177.     end
  178.     return false
  179. end
  180.  
  181. function shell.exit()
  182.     bExit = true
  183. end
  184.  
  185. function shell.dir()
  186.     return sDir
  187. end
  188.  
  189. function shell.setDir(dir)
  190.     expect(1, dir, "string")
  191.     if not fs.isDir(dir) then
  192.         error("Not a directory", 2)
  193.     end
  194.     sDir = fs.combine(dir, "")
  195. end
  196.  
  197. function shell.path()
  198.     return sPath
  199. end
  200.  
  201. function shell.setPath(path)
  202.     expect(1, path, "string")
  203.     sPath = path
  204. end
  205.  
  206. function shell.resolve(path)
  207.     expect(1, path, "string")
  208.     local sStartChar = string.sub(path, 1, 1)
  209.     if sStartChar == "/" or sStartChar == "\\" then
  210.         return fs.combine("", path)
  211.     else
  212.         return fs.combine(sDir, path)
  213.     end
  214. end
  215.  
  216. local function pathWithExtension(_sPath, _sExt)
  217.     local nLen = #sPath
  218.     local sEndChar = string.sub(_sPath, nLen, nLen)
  219.     if sEndChar == "/" or sEndChar == "\\" then
  220.         _sPath = string.sub(_sPath, 1, nLen - 1)
  221.     end
  222.     return _sPath .. "." .. _sExt
  223. end
  224.  
  225. function shell.resolveProgram(command)
  226.     expect(1, command, "string")
  227.  
  228.     if tAliases[command] ~= nil then
  229.         command = tAliases[command]
  230.     end
  231.  
  232.     if command:find("/") or command:find("\\") then
  233.         local sPath = shell.resolve(command)
  234.         if fs.exists(sPath) and not fs.isDir(sPath) then
  235.             return sPath
  236.         else
  237.             local sPathLua = pathWithExtension(sPath, "lua")
  238.             if fs.exists(sPathLua) and not fs.isDir(sPathLua) then
  239.                 return sPathLua
  240.             end
  241.         end
  242.         return nil
  243.     end
  244.  
  245.     for sPath in string.gmatch(sPath, "[^:]+") do
  246.         sPath = fs.combine(shell.resolve(sPath), command)
  247.         if fs.exists(sPath) and not fs.isDir(sPath) then
  248.             return sPath
  249.         else
  250.             local sPathLua = pathWithExtension(sPath, "lua")
  251.             if fs.exists(sPathLua) and not fs.isDir(sPathLua) then
  252.                 return sPathLua
  253.             end
  254.         end
  255.     end
  256.  
  257.     return nil
  258. end
  259.  
  260. function shell.programs(include_hidden)
  261.     expect(1, include_hidden, "boolean", "nil")
  262.  
  263.     local tItems = {}
  264.  
  265.     for sPath in string.gmatch(sPath, "[^:]+") do
  266.         sPath = shell.resolve(sPath)
  267.         if fs.isDir(sPath) then
  268.             local tList = fs.list(sPath)
  269.             for n = 1, #tList do
  270.                 local sFile = tList[n]
  271.                 if not fs.isDir(fs.combine(sPath, sFile)) and
  272.                    (include_hidden or string.sub(sFile, 1, 1) ~= ".") then
  273.                     if #sFile > 4 and sFile:sub(-4) == ".lua" then
  274.                         sFile = sFile:sub(1, -5)
  275.                     end
  276.                     tItems[sFile] = true
  277.                 end
  278.             end
  279.         end
  280.     end
  281.  
  282.     local tItemList = {}
  283.     for sItem in pairs(tItems) do
  284.         table.insert(tItemList, sItem)
  285.     end
  286.     table.sort(tItemList)
  287.     return tItemList
  288. end
  289.  
  290. local function completeProgram(sLine)
  291.     if #sLine > 0 and (sLine:find("/") or sLine:find("\\")) then
  292.         return fs.complete(sLine, sDir, true, false)
  293.  
  294.     else
  295.         local tResults = {}
  296.         local tSeen = {}
  297.  
  298.         for sAlias in pairs(tAliases) do
  299.             if #sAlias > #sLine and string.sub(sAlias, 1, #sLine) == sLine then
  300.                 local sResult = string.sub(sAlias, #sLine + 1)
  301.                 if not tSeen[sResult] then
  302.                     table.insert(tResults, sResult)
  303.                     tSeen[sResult] = true
  304.                 end
  305.             end
  306.         end
  307.  
  308.         local tDirs = fs.complete(sLine, sDir, false, false)
  309.         for i = 1, #tDirs do
  310.             local sResult = tDirs[i]
  311.             if not tSeen[sResult] then
  312.                 table.insert (tResults, sResult)
  313.                 tSeen [sResult] = true
  314.             end
  315.         end
  316.  
  317.         local tPrograms = shell.programs()
  318.         for n = 1, #tPrograms do
  319.             local sProgram = tPrograms[n]
  320.             if #sProgram > #sLine and string.sub(sProgram, 1, #sLine) == sLine then
  321.                 local sResult = string.sub(sProgram, #sLine + 1)
  322.                 if not tSeen[sResult] then
  323.                     table.insert(tResults, sResult)
  324.                     tSeen[sResult] = true
  325.                 end
  326.             end
  327.         end
  328.  
  329.         table.sort(tResults)
  330.         return tResults
  331.     end
  332. end
  333.  
  334. local function completeProgramArgument(sProgram, nArgument, sPart, tPreviousParts)
  335.     local tInfo = tCompletionInfo[sProgram]
  336.     if tInfo then
  337.         return tInfo.fnComplete(shell, nArgument, sPart, tPreviousParts)
  338.     end
  339.     return nil
  340. end
  341.  
  342. function shell.complete(sLine)
  343.     expect(1, sLine, "string")
  344.     if #sLine > 0 then
  345.         local tWords = tokenise(sLine)
  346.         local nIndex = #tWords
  347.         if string.sub(sLine, #sLine, #sLine) == " " then
  348.             nIndex = nIndex + 1
  349.         end
  350.         if nIndex == 1 then
  351.             local sBit = tWords[1] or ""
  352.             local sPath = shell.resolveProgram(sBit)
  353.             if tCompletionInfo[sPath] then
  354.                 return { " " }
  355.             else
  356.                 local tResults = completeProgram(sBit)
  357.                 for n = 1, #tResults do
  358.                     local sResult = tResults[n]
  359.                     local sPath = shell.resolveProgram(sBit .. sResult)
  360.                     if tCompletionInfo[sPath] then
  361.                         tResults[n] = sResult .. " "
  362.                     end
  363.                 end
  364.                 return tResults
  365.             end
  366.  
  367.         elseif nIndex > 1 then
  368.             local sPath = shell.resolveProgram(tWords[1])
  369.             local sPart = tWords[nIndex] or ""
  370.             local tPreviousParts = tWords
  371.             tPreviousParts[nIndex] = nil
  372.             return completeProgramArgument(sPath , nIndex - 1, sPart, tPreviousParts)
  373.  
  374.         end
  375.     end
  376.     return nil
  377. end
  378.  
  379. function shell.completeProgram(program)
  380.     expect(1, program, "string")
  381.     return completeProgram(program)
  382. end
  383.  
  384. function shell.setCompletionFunction(program, complete)
  385.     expect(1, program, "string")
  386.     expect(2, complete, "function")
  387.     tCompletionInfo[program] = {
  388.         fnComplete = complete,
  389.     }
  390. end
  391.  
  392. function shell.getRunningProgram()
  393.     if #tProgramStack > 0 then
  394.         return tProgramStack[#tProgramStack]
  395.     end
  396.     return nil
  397. end
  398.  
  399. if multishell then
  400.     function shell.openTab(...)
  401.         local tWords = tokenise(...)
  402.         local sCommand = tWords[1]
  403.         if sCommand then
  404.             local sPath = shell.resolveProgram(sCommand)
  405.             if sPath == "rom/programs/shell.lua" then
  406.                 return multishell.launch(createShellEnv("rom/programs"), sPath, table.unpack(tWords, 2))
  407.             elseif sPath ~= nil then
  408.                 return multishell.launch(createShellEnv("rom/programs"), "rom/programs/shell.lua", sCommand, table.unpack(tWords, 2))
  409.             else
  410.                 printError("No such program")
  411.             end
  412.         end
  413.     end
  414.  
  415.     function shell.switchTab(id)
  416.         expect(1, id, "number")
  417.         multishell.setFocus(id)
  418.     end
  419. end
  420.  
  421. local tArgs = { ... }
  422. if #tArgs > 0 then
  423.     shell.run(...)
  424.  
  425. else
  426.  
  427.     term.setBackgroundColor(bgColour)
  428.     term.setTextColour(textColour)
  429.  
  430.     if parentShell == nil then
  431.         shell.run("/rom/startup.lua")
  432.     end
  433.  
  434.     local tCommandHistory = {}
  435.     while not bExit do
  436.    
  437.     term.redirect(parentTerm)
  438.     term.setBackgroundColor(bgColour)
  439.     term.setTextColour(promptColour)
  440.     local testString = "/"..shell.dir()
  441.     if #testString >= w/2.5 then
  442.     local q = #testString-1
  443.     local a = 2
  444.         repeat
  445.             hledej = string.sub(testString,a,a);
  446.             a = a+1
  447.             if (hledej=="/") then
  448.             jednotka = string.sub(testString,1,a-1)
  449.             a =#testString
  450.             end
  451.         until a == #testString
  452.         repeat
  453.             hledej = string.sub(testString,q,q);
  454.             q = q-1
  455.             if (hledej=="/") then
  456.             cesta = string.sub(testString,q+1,#testString)
  457.             q =0
  458.             end
  459.         until q == 0
  460.         write(jednotka..".."..cesta.."> ")
  461.         else
  462.         write(shell.dir() .. "> ")
  463.     end
  464.         term.setTextColour(textColour)
  465.  
  466.  
  467.         local sLine
  468.         if settings.get("shell.autocomplete") then
  469.             sLine = read(nil, tCommandHistory, shell.complete)
  470.         else
  471.             sLine = read(nil, tCommandHistory)
  472.         end
  473.         if sLine:match("%S") and tCommandHistory[#tCommandHistory] ~= sLine then
  474.             table.insert(tCommandHistory, sLine)
  475.         end
  476.         shell.run(sLine)
  477.     end
  478. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement