Sirshark10

NShell

Feb 17th, 2017
163
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.52 KB | None | 0 0
  1. local multishell = multishell
  2. local parentShell = shell
  3. local parentTerm = term.current()
  4.  
  5. --if multishell then
  6. -- multishell.setTitle( multishell.getCurrent(), "shell" )
  7. --end
  8.  
  9. local bExit = false
  10. local sDir = (parentShell and parentShell.dir()) or ""
  11. local sPath = (parentShell and parentShell.path()) or ".:/rom/programs"
  12. local tAliases = (parentShell and parentShell.aliases()) or {}
  13. local tCompletionInfo = (parentShell and parentShell.getCompletionInfo()) or {}
  14. local tProgramStack = {}
  15.  
  16. local shell = {}
  17. local tEnv = {
  18. [ "shell" ] = shell,
  19. [ "multishell" ] = multishell,
  20. }
  21.  
  22. -- Colours
  23. local promptColour, textColour, bgColour
  24. if term.isColour() then
  25. promptColour = colours.yellow
  26. textColour = colours.white
  27. bgColour = colours.black
  28. else
  29. promptColour = colours.white
  30. textColour = colours.white
  31. bgColour = colours.black
  32. end
  33.  
  34. local function run( _sCommand, ... )
  35. local sPath = shell.resolveProgram( _sCommand )
  36. if sPath ~= nil then
  37. tProgramStack[#tProgramStack + 1] = sPath
  38. if multishell then
  39. multishell.setTitle( multishell.getCurrent(), fs.getName( sPath ) )
  40. end
  41. local result = os.run( tEnv, sPath, ... )
  42. tProgramStack[#tProgramStack] = nil
  43. if multishell then
  44. if #tProgramStack > 0 then
  45. multishell.setTitle( multishell.getCurrent(), fs.getName( tProgramStack[#tProgramStack] ) )
  46. else
  47. multishell.setTitle( multishell.getCurrent(), "shell" )
  48. end
  49. end
  50. return result
  51. else
  52. printError( "No such program" )
  53. return false
  54. end
  55. end
  56.  
  57. local function tokenise( ... )
  58. local sLine = table.concat( { ... }, " " )
  59. local tWords = {}
  60. local bQuoted = false
  61. for match in string.gmatch( sLine .. "\"", "(.-)\"" ) do
  62. if bQuoted then
  63. table.insert( tWords, match )
  64. else
  65. for m in string.gmatch( match, "[^ \t]+" ) do
  66. table.insert( tWords, m )
  67. end
  68. end
  69. bQuoted = not bQuoted
  70. end
  71. return tWords
  72. end
  73.  
  74. -- Install shell API
  75. function shell.run( ... )
  76. local tWords = tokenise( ... )
  77. local sCommand = tWords[1]
  78. if sCommand then
  79. return run( sCommand, table.unpack( tWords, 2 ) )
  80. end
  81. return false
  82. end
  83.  
  84. function shell.exit()
  85. bExit = true
  86. end
  87.  
  88. function shell.dir()
  89. return sDir
  90. end
  91.  
  92. function shell.setDir( _sDir )
  93. sDir = _sDir
  94. end
  95.  
  96. function shell.path()
  97. return sPath
  98. end
  99.  
  100. function shell.setPath( _sPath )
  101. sPath = _sPath
  102. end
  103.  
  104. function shell.resolve( _sPath )
  105. local sStartChar = string.sub( _sPath, 1, 1 )
  106. if sStartChar == "/" or sStartChar == "\\" then
  107. return fs.combine( "", _sPath )
  108. else
  109. return fs.combine( sDir, _sPath )
  110. end
  111. end
  112.  
  113. function shell.resolveProgram( _sCommand )
  114. -- Substitute aliases firsts
  115. if tAliases[ _sCommand ] ~= nil then
  116. _sCommand = tAliases[ _sCommand ]
  117. end
  118.  
  119. -- If the path is a global path, use it directly
  120. local sStartChar = string.sub( _sCommand, 1, 1 )
  121. if sStartChar == "/" or sStartChar == "\\" then
  122. local sPath = fs.combine( "", _sCommand )
  123. if fs.exists( sPath ) and not fs.isDir( sPath ) then
  124. return sPath
  125. end
  126. return nil
  127. end
  128.  
  129. -- Otherwise, look on the path variable
  130. for sPath in string.gmatch(sPath, "[^:]+") do
  131. sPath = fs.combine( shell.resolve( sPath ), _sCommand )
  132. if fs.exists( sPath ) and not fs.isDir( sPath ) then
  133. return sPath
  134. end
  135. end
  136.  
  137. -- Not found
  138. return nil
  139. end
  140.  
  141. function shell.programs( _bIncludeHidden )
  142. local tItems = {}
  143.  
  144. -- Add programs from the path
  145. for sPath in string.gmatch(sPath, "[^:]+") do
  146. sPath = shell.resolve( sPath )
  147. if fs.isDir( sPath ) then
  148. local tList = fs.list( sPath )
  149. for n=1,#tList do
  150. local sFile = tList[n]
  151. if not fs.isDir( fs.combine( sPath, sFile ) ) and
  152. (_bIncludeHidden or string.sub( sFile, 1, 1 ) ~= ".") then
  153. tItems[ sFile ] = true
  154. end
  155. end
  156. end
  157. end
  158.  
  159. -- Sort and return
  160. local tItemList = {}
  161. for sItem, b in pairs( tItems ) do
  162. table.insert( tItemList, sItem )
  163. end
  164. table.sort( tItemList )
  165. return tItemList
  166. end
  167.  
  168. local function completeProgram( sLine )
  169. if #sLine > 0 and string.sub( sLine, 1, 1 ) == "/" then
  170. -- Add programs from the root
  171. Print("TEST")
  172. sleep(1)
  173. return fs.complete( sLine, "", true, false )
  174.  
  175. else
  176. local tResults = {}
  177. local tSeen = {}
  178.  
  179. -- Add aliases
  180. for sAlias, sCommand in pairs( tAliases ) do
  181. if #sAlias > #sLine and string.sub( sAlias, 1, #sLine ) == sLine then
  182. local sResult = string.sub( sAlias, #sLine + 1 )
  183. if not tSeen[ sResult ] then
  184. table.insert( tResults, sResult )
  185. tSeen[ sResult ] = true
  186. end
  187. end
  188. end
  189.  
  190. -- Add programs from the path
  191. local tPrograms = shell.programs()
  192. for n=1,#tPrograms do
  193. local sProgram = tPrograms[n]
  194. if #sProgram > #sLine and string.sub( sProgram, 1, #sLine ) == sLine then
  195. local sResult = string.sub( sProgram, #sLine + 1 )
  196. if not tSeen[ sResult ] then
  197. table.insert( tResults, sResult )
  198. tSeen[ sResult ] = true
  199. end
  200. end
  201. end
  202.  
  203. -- Sort and return
  204. table.sort( tResults )
  205. return tResults
  206. end
  207. end
  208.  
  209. local function completeProgramArgument( sProgram, nArgument, sPart, tPreviousParts )
  210. local tInfo = tCompletionInfo[ sProgram ]
  211. if tInfo then
  212. return tInfo.fnComplete( shell, nArgument, sPart, tPreviousParts )
  213. end
  214. return nil
  215. end
  216.  
  217. function shell.complete( sLine )
  218. print("entered complete")
  219. if #sLine > 0 then
  220. local tWords = tokenise( sLine )
  221. local nIndex = #tWords
  222. if string.sub( sLine, #sLine, #sLine ) == " " then
  223. nIndex = nIndex + 1
  224. end
  225. if nIndex == 1 then
  226. local sBit = tWords[1] or ""
  227. print("local sPath = shell.resolveProgram( sBit )")
  228. local sPath = shell.resolveProgram( sBit )
  229. if tCompletionInfo[ sPath ] then
  230. print("return { ' ' }")
  231. return { " " }
  232. else
  233. print("local tResults = completeProgram( sBit )")
  234. local tResults = completeProgram( sBit )
  235. for n=1,#tResults do
  236. local sResult = tResults[n]
  237.  
  238.  
  239. print("local sPath = shell.resolveProgram( sBit .. sResult )")
  240. local sPath = shell.resolveProgram( sBit .. sResult )
  241. if tCompletionInfo[ sPath ] then
  242. tResults[n] = sResult .. " "
  243. end
  244. end
  245. return tResults
  246. end
  247.  
  248. elseif nIndex > 1 then
  249. print("SpathSparttPrevParts")
  250. local sPath = shell.resolveProgram( tWords[1] )
  251. local sPart = tWords[nIndex] or ""
  252. local tPreviousParts = tWords
  253. tPreviousParts[nIndex] = nil
  254. print("returning completeProgramArgument")
  255. return completeProgramArgument( sPath , nIndex - 1, sPart, tPreviousParts )
  256.  
  257. end
  258. end
  259. print("Returning Nil")
  260. return nil
  261. end
  262.  
  263. function shell.completeProgram( sProgram )
  264. return completeProgram( sProgram )
  265. end
  266.  
  267. function shell.setCompletionFunction( sProgram, fnComplete )
  268. tCompletionInfo[ sProgram ] = {
  269. fnComplete = fnComplete
  270. }
  271. end
  272.  
  273. function shell.getCompletionInfo()
  274. return tCompletionInfo
  275. end
  276.  
  277. function shell.getRunningProgram()
  278. if #tProgramStack > 0 then
  279. return tProgramStack[#tProgramStack]
  280. end
  281. return nil
  282. end
  283.  
  284. function shell.setAlias( _sCommand, _sProgram )
  285. tAliases[ _sCommand ] = _sProgram
  286. end
  287.  
  288. function shell.clearAlias( _sCommand )
  289. tAliases[ _sCommand ] = nil
  290. end
  291.  
  292. function shell.aliases()
  293. -- Copy aliases
  294. local tCopy = {}
  295. for sAlias, sCommand in pairs( tAliases ) do
  296. tCopy[sAlias] = sCommand
  297. end
  298. return tCopy
  299. end
  300.  
  301. if multishell then
  302. function shell.openTab( ... )
  303. local tWords = tokenise( ... )
  304. local sCommand = tWords[1]
  305. if sCommand then
  306. local sPath = shell.resolveProgram( sCommand )
  307. if sPath == "rom/programs/shell" then
  308. return multishell.launch( tEnv, sPath, table.unpack( tWords, 2 ) )
  309. elseif sPath ~= nil then
  310. return multishell.launch( tEnv, "rom/programs/shell", sCommand, table.unpack( tWords, 2 ) )
  311. else
  312. printError( "No such program" )
  313. end
  314. end
  315. end
  316.  
  317. function shell.switchTab( nID )
  318. multishell.setFocus( nID )
  319. end
  320. end
  321.  
  322. local tArgs = { ... }
  323. if #tArgs > 0 then
  324. -- "shell x y z"
  325. -- Run the program specified on the commandline
  326. shell.run( ... )
  327.  
  328. else
  329. -- "shell"
  330. -- Print the header
  331. term.setBackgroundColor( bgColour )
  332. term.setTextColour( promptColour )
  333. print( os.version() )
  334. term.setTextColour( textColour )
  335.  
  336. -- Run the startup program
  337. --if parentShell == nil then
  338. -- shell.run( "/rom/startup" )
  339. --end
  340.  
  341. -- Read commands and execute them
  342. local tCommandHistory = {}
  343. while not bExit do
  344. print("test")
  345. term.redirect( parentTerm )
  346. term.setBackgroundColor( bgColour )
  347. term.setTextColour( promptColour )
  348. write( shell.dir() .. "> " )
  349. term.setTextColour( textColour )
  350.  
  351. local sLine = read( nil, tCommandHistory, shell.complete )
  352. table.insert( tCommandHistory, sLine )
  353. shell.run( sLine )
  354. end
  355. end
Advertisement
Add Comment
Please, Sign In to add comment