mirror of
				https://github.com/SquidDev-CC/CC-Tweaked
				synced 2025-10-31 05:33:00 +00:00 
			
		
		
		
	Merge branch 'master' into mc-1.14.x
This commit is contained in:
		
							
								
								
									
										18
									
								
								.github/workflows/main-ci.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								.github/workflows/main-ci.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| name: Build | ||||
|  | ||||
| on: [push, pull_request] | ||||
|  | ||||
| jobs: | ||||
|   build: | ||||
|     runs-on: ubuntu-latest | ||||
|  | ||||
|     steps: | ||||
|     - uses: actions/checkout@v1 | ||||
|  | ||||
|     - name: Set up JDK 1.8 | ||||
|       uses: actions/setup-java@v1 | ||||
|       with: | ||||
|         java-version: 1.8 | ||||
|  | ||||
|     - name: Build with Gradle | ||||
|       run: ./gradlew build --no-daemon | ||||
							
								
								
									
										14
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								.travis.yml
									
									
									
									
									
								
							| @@ -1,14 +0,0 @@ | ||||
| language: java | ||||
|  | ||||
| script: ./gradlew build --no-daemon | ||||
|  | ||||
| before_cache: | ||||
|   - rm -f  $HOME/.gradle/caches/modules-2/modules-2.lock | ||||
|   - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ | ||||
| cache: | ||||
|   directories: | ||||
|     - $HOME/.gradle/caches/ | ||||
|     - $HOME/.gradle/wrapper/s | ||||
|  | ||||
| jdk: | ||||
|     - openjdk8 | ||||
| @@ -1,5 +1,5 @@ | ||||
| #  | ||||
| [](https://travis-ci.org/SquidDev-CC/CC-Tweaked "Current build status") [](https://minecraft.curseforge.com/projects/cc-tweaked "Download CC: Tweaked on CurseForge") | ||||
| [](https://github.com/SquidDev-CC/CC-Tweaked/actions "Current build status") [](https://minecraft.curseforge.com/projects/cc-tweaked "Download CC: Tweaked on CurseForge") | ||||
|  | ||||
| CC: Tweaked is a fork of [ComputerCraft](https://github.com/dan200/ComputerCraft), adding programmable computers, | ||||
| turtles and more to Minecraft. | ||||
|   | ||||
| @@ -85,7 +85,7 @@ public class CommandAPI implements ILuaAPI | ||||
|         { | ||||
|             receiver.clearOutput(); | ||||
|             int result = commandManager.handleCommand( m_computer.getSource(), command ); | ||||
|             return new Object[] { result > 0, receiver.copyOutput() }; | ||||
|             return new Object[] { result > 0, receiver.copyOutput(), result }; | ||||
|         } | ||||
|         catch( Throwable t ) | ||||
|         { | ||||
|   | ||||
| @@ -36,7 +36,6 @@ public final class DropConsumer | ||||
|     private static Function<ItemStack, ItemStack> dropConsumer; | ||||
|     private static List<ItemStack> remainingDrops; | ||||
|     private static WeakReference<World> dropWorld; | ||||
|     private static BlockPos dropPos; | ||||
|     private static AxisAlignedBB dropBounds; | ||||
|     private static WeakReference<Entity> dropEntity; | ||||
|  | ||||
| @@ -46,7 +45,6 @@ public final class DropConsumer | ||||
|         remainingDrops = new ArrayList<>(); | ||||
|         dropEntity = new WeakReference<>( entity ); | ||||
|         dropWorld = new WeakReference<>( entity.world ); | ||||
|         dropPos = null; | ||||
|         dropBounds = new AxisAlignedBB( entity.getPosition() ).grow( 2, 2, 2 ); | ||||
|  | ||||
|         entity.captureDrops( new ArrayList<>() ); | ||||
| @@ -55,10 +53,9 @@ public final class DropConsumer | ||||
|     public static void set( World world, BlockPos pos, Function<ItemStack, ItemStack> consumer ) | ||||
|     { | ||||
|         dropConsumer = consumer; | ||||
|         remainingDrops = new ArrayList<>(); | ||||
|         remainingDrops = new ArrayList<>( 2 ); | ||||
|         dropEntity = null; | ||||
|         dropWorld = new WeakReference<>( world ); | ||||
|         dropPos = pos; | ||||
|         dropBounds = new AxisAlignedBB( pos ).grow( 2, 2, 2 ); | ||||
|     } | ||||
|  | ||||
| @@ -83,7 +80,6 @@ public final class DropConsumer | ||||
|         remainingDrops = null; | ||||
|         dropEntity = null; | ||||
|         dropWorld = null; | ||||
|         dropPos = null; | ||||
|         dropBounds = null; | ||||
|  | ||||
|         return remainingStacks; | ||||
| @@ -95,34 +91,7 @@ public final class DropConsumer | ||||
|         if( !remaining.isEmpty() ) remainingDrops.add( remaining ); | ||||
|     } | ||||
|  | ||||
|     @SubscribeEvent( priority = EventPriority.LOWEST ) | ||||
|     public static void onEntityLivingDrops( LivingDropsEvent event ) | ||||
|     { | ||||
|         // Capture any mob drops for the current entity | ||||
|         if( dropEntity != null && event.getEntity() == dropEntity.get() ) | ||||
|         { | ||||
|             Collection<ItemEntity> drops = event.getDrops(); | ||||
|             for( ItemEntity entityItem : drops ) handleDrops( entityItem.getItem() ); | ||||
|             drops.clear(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @SubscribeEvent( priority = EventPriority.LOWEST ) | ||||
|     public static void onHarvestDrops( BlockEvent.HarvestDropsEvent event ) | ||||
|     { | ||||
|         // Capture block drops for the current entity | ||||
|         if( dropWorld != null && dropWorld.get() == event.getWorld() | ||||
|             && dropPos != null && dropPos.equals( event.getPos() ) ) | ||||
|         { | ||||
|             for( ItemStack item : event.getDrops() ) | ||||
|             { | ||||
|                 if( event.getWorld().getRandom().nextFloat() < event.getDropChance() ) handleDrops( item ); | ||||
|             } | ||||
|             event.getDrops().clear(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @SubscribeEvent( priority = EventPriority.LOWEST ) | ||||
|     @SubscribeEvent( priority = EventPriority.HIGHEST ) | ||||
|     public static void onEntitySpawn( EntityJoinWorldEvent event ) | ||||
|     { | ||||
|         // Capture any nearby item spawns | ||||
|   | ||||
| @@ -0,0 +1,105 @@ | ||||
| --- A collection of helper methods for working with input completion, such | ||||
| -- as that require by @{read}. | ||||
| -- | ||||
| -- @module craftos.completion | ||||
| -- @see cc.shell.completion For additional helpers to use with | ||||
| -- @{shell.setCompletionFunction}. | ||||
|  | ||||
| local expect = require "cc.expect".expect | ||||
|  | ||||
| local function choice_impl(text, choices, add_space) | ||||
|     local results = {} | ||||
|     for n = 1, #choices do | ||||
|         local option = choices[n] | ||||
|         if #option + (add_space and 1 or 0) > #text and option:sub(1, #text) == text then | ||||
|             local result = option:sub(#text + 1) | ||||
|             if add_space then | ||||
|                 table.insert(results, result .. " ") | ||||
|             else | ||||
|                 table.insert(results, result) | ||||
|             end | ||||
|         end | ||||
|     end | ||||
|     return results | ||||
| end | ||||
|  | ||||
| --- Complete from a choice of one or more strings. | ||||
| -- | ||||
| -- @tparam string text The input string to complete. | ||||
| -- @tparam { string... } choices The list of choices to complete from. | ||||
| -- @tparam[opt] boolean add_space Whether to add a space after the completed item. | ||||
| -- @treturn { string... } A list of suffixes of matching strings. | ||||
| -- @usage Call @{read}, completing the names of various animals. | ||||
| -- | ||||
| --     local animals = { "dog", "cat", "lion", "unicorn" } | ||||
| --     read(nil, nil, function(text) return choice(text, animals) end) | ||||
| local function choice(text, choices, add_space) | ||||
|     expect(1, text, "string") | ||||
|     expect(2, choices, "table") | ||||
|     expect(3, add_space, "boolean", "nil") | ||||
|     return choice_impl(text, choices, add_space) | ||||
| end | ||||
|  | ||||
| --- Complete the name of a currently attached peripheral. | ||||
| -- | ||||
| -- @tparam string text The input string to complete. | ||||
| -- @tparam[opt] boolean add_space Whether to add a space after the completed name. | ||||
| -- @treturn { string... } A list of suffixes of matching peripherals. | ||||
| -- @usage read(nil, nil, peripheral) | ||||
| local function peripheral_(text, add_space) | ||||
|     expect(1, text, "string") | ||||
|     expect(2, add_space, "boolean", "nil") | ||||
|     return choice_impl(text, peripheral.getNames(), add_space) | ||||
| end | ||||
|  | ||||
| local sides = redstone.getSides() | ||||
|  | ||||
| --- Complete the side of a computer. | ||||
| -- | ||||
| -- @tparam string text The input string to complete. | ||||
| -- @tparam[opt] boolean add_space Whether to add a space after the completed side. | ||||
| -- @treturn { string... } A list of suffixes of matching sides. | ||||
| -- @usage read(nil, nil, side) | ||||
| local function side(text, add_space) | ||||
|     expect(1, text, "string") | ||||
|     expect(2, add_space, "boolean", "nil") | ||||
|     return choice_impl(text, sides, add_space) | ||||
| end | ||||
|  | ||||
| --- Complete a @{settings|setting}. | ||||
| -- | ||||
| -- @tparam string text The input string to complete. | ||||
| -- @tparam[opt] boolean add_space Whether to add a space after the completed settings. | ||||
| -- @treturn { string... } A list of suffixes of matching settings. | ||||
| -- @usage read(nil, nil, setting) | ||||
| local function setting(text, add_space) | ||||
|     expect(1, text, "string") | ||||
|     expect(2, add_space, "boolean", "nil") | ||||
|     return choice_impl(text, settings.getNames(), add_space) | ||||
| end | ||||
|  | ||||
| local command_list | ||||
|  | ||||
| --- Complete the name of a Minecraft @{commands|command}. | ||||
| -- | ||||
| -- @tparam string text The input string to complete. | ||||
| -- @tparam[opt] boolean add_space Whether to add a space after the completed command. | ||||
| -- @treturn { string... } A list of suffixes of matching commands. | ||||
| -- @usage read(nil, nil, command) | ||||
| local function command(text, add_space) | ||||
|     expect(1, text, "string") | ||||
|     expect(2, add_space, "boolean", "nil") | ||||
|     if command_list == nil then | ||||
|         command_list = commands and commands.list() or {} | ||||
|     end | ||||
|  | ||||
|     return choice_impl(text, command_list, add_space) | ||||
| end | ||||
|  | ||||
| return { | ||||
|     choice = choice, | ||||
|     peripheral = peripheral_, | ||||
|     side = side, | ||||
|     setting = setting, | ||||
|     command = command, | ||||
| } | ||||
| @@ -0,0 +1,151 @@ | ||||
| --- A collection of helper methods for working with shell completion. | ||||
| -- | ||||
| -- Most programs may be completed using the @{build} helper method, rather than | ||||
| -- manually switching on the argument index. | ||||
| -- | ||||
| -- Note, the helper functions within this module do not accept an argument index, | ||||
| -- and so are not directly usable with the @{shell.setCompletionFunction}. Instead, | ||||
| -- wrap them using @{build}, or your own custom function. | ||||
| -- | ||||
| -- @module craftos.shell.completion | ||||
| -- @see cc.completion For more general helpers, suitable for use with @{read}. | ||||
| -- @see shell.setCompletionFunction | ||||
|  | ||||
| local expect = require "cc.expect".expect | ||||
| local completion = require "cc.completion" | ||||
|  | ||||
| --- Complete the name of a file relative to the current working directory. | ||||
| -- | ||||
| -- @tparam shell shell The shell we're completing in | ||||
| -- @tparam { string... } choices The list of choices to complete from. | ||||
| -- @treturn { string... } A list of suffixes of matching files. | ||||
| local function file(shell, text) | ||||
|     return fs.complete(text, shell.dir(), true, false) | ||||
| end | ||||
|  | ||||
| --- Complete the name of a directory relative to the current working directory. | ||||
| -- | ||||
| -- @tparam shell shell The shell we're completing in | ||||
| -- @tparam { string... } choices The list of choices to complete from. | ||||
| -- @treturn { string... } A list of suffixes of matching directories. | ||||
| local function dir(shell, text) | ||||
|     return fs.complete(text, shell.dir(), false, true) | ||||
| end | ||||
|  | ||||
| --- Complete the name of a file or directory relative to the current working | ||||
| -- directory. | ||||
| -- | ||||
| -- @tparam shell shell The shell we're completing in | ||||
| -- @tparam { string... } choices The list of choices to complete from. | ||||
| -- @tparam { string... } previous The shell arguments before this one. | ||||
| -- @tparam[opt] boolean add_space Whether to add a space after the completed item. | ||||
| -- @treturn { string... } A list of suffixes of matching files and directories. | ||||
| local function dirOrFile(shell, text, previous, add_space) | ||||
|     local results = fs.complete(text, shell.dir(), true, true) | ||||
|     if add_space then | ||||
|         for n = 1, #results do | ||||
|             local result = results[n] | ||||
|             if result:sub(-1) ~= "/" then | ||||
|                 results[n] = result .. " " | ||||
|             end | ||||
|         end | ||||
|     end | ||||
|     return results | ||||
| end | ||||
|  | ||||
| local function wrap(func) | ||||
|     return function(shell, text, previous, ...) | ||||
|         return func(text, ...) | ||||
|     end | ||||
| end | ||||
|  | ||||
| --- Complete the name of a program. | ||||
| -- | ||||
| -- @tparam shell shell The shell we're completing in | ||||
| -- @tparam { string... } choices The list of choices to complete from. | ||||
| -- @treturn { string... } A list of suffixes of matching programs. | ||||
| local function program(shell, text) | ||||
|     return shell.completeProgram(text) | ||||
| end | ||||
|  | ||||
| --- A helper function for building shell completion arguments. | ||||
| -- | ||||
| -- This accepts a series of single-argument completion functions, and combines | ||||
| -- them into a function suitable for use with @{shell.setCompletionFunction}. | ||||
| -- | ||||
| -- @tparam nil|table|function ... Every argument to @{build} represents an argument | ||||
| -- to the program you wish to complete. Each argument can be one of three types: | ||||
| -- | ||||
| --  - `nil`: This argument will not be completed. | ||||
| -- | ||||
| --  - A function: This argument will be completed with the given function. It is | ||||
| --    called with the @{shell} object, the string to complete and the arguments | ||||
| --    before this one. | ||||
| -- | ||||
| --  - A table: This acts as a more powerful version of the function case. The table | ||||
| --    must have a function as the first item - this will be called with the shell, | ||||
| --    string and preceding arguments as above, but also followed by any additional | ||||
| --    items in the table. This provides a more convenient interface to pass | ||||
| --    options to your completion functions. | ||||
| -- | ||||
| --    If this table is the last argument, it may also set the `many` key to true, | ||||
| --    which states this function should be used to complete any remaining arguments. | ||||
| -- | ||||
| -- @usage Prompt for a choice of options, followed by a directory, and then multiple | ||||
| -- files. | ||||
| -- | ||||
| --     complete.build( | ||||
| --       { complete.choice, { "get", "put" } }, | ||||
| --       complete.dir, | ||||
| --       } complete.file, many = true } | ||||
| --     ) | ||||
| local function build(...) | ||||
|     local arguments = table.pack(...) | ||||
|     for i = 1, arguments.n do | ||||
|         local arg = arguments[i] | ||||
|         if arg ~= nil then | ||||
|             expect(i, arg, "table", "function") | ||||
|             if type(arg) == "function" then | ||||
|                 arg = { arg } | ||||
|                 arguments[i] = arg | ||||
|             end | ||||
|  | ||||
|             if type(arg[1]) ~= "function" then | ||||
|                 error(("Bad table entry #1 at argument #%d (expected function, got %s)"):format(i, type(arg[1])), 2) | ||||
|             end | ||||
|  | ||||
|             if arg.many and i < arguments.n then | ||||
|                 error(("Unexpected 'many' field on argument #%d (should only occur on the last argument)"):format(i), 2) | ||||
|             end | ||||
|         end | ||||
|     end | ||||
|  | ||||
|     return function(shell, index, text, previous) | ||||
|         local arg = arguments[index] | ||||
|         if not arg then | ||||
|             if index <= arguments.n then return end | ||||
|  | ||||
|             arg = arguments[arguments.n] | ||||
|             if not arg or not arg.many then return end | ||||
|         end | ||||
|  | ||||
|         return arg[1](shell, text, previous, table.unpack(arg, 2)) | ||||
|     end | ||||
| end | ||||
|  | ||||
| return { | ||||
|     file = file, | ||||
|     dir = dir, | ||||
|     dirOrFile = dirOrFile, | ||||
|     program = program, | ||||
|  | ||||
|     -- Re-export various other functions | ||||
|     help = wrap(help.completeTopic), | ||||
|     choice = wrap(completion.choice), | ||||
|     peripheral = wrap(completion.peripheral), | ||||
|     side = wrap(completion.side), | ||||
|     setting = wrap(completion.setting), | ||||
|     command = wrap(completion.command), | ||||
|  | ||||
|     build = build, | ||||
| } | ||||
| @@ -431,16 +431,20 @@ function create( parent, nX, nY, nWidth, nHeight, bStartVisible ) | ||||
|         return nX, nY | ||||
|     end | ||||
|  | ||||
|     function window.reposition( nNewX, nNewY, nNewWidth, nNewHeight ) | ||||
|     function window.reposition( nNewX, nNewY, nNewWidth, nNewHeight, newParent ) | ||||
|         if type(nNewX) ~= "number" then expect(1, nNewX, "number") end | ||||
|         if type(nNewY) ~= "number" then expect(2, nNewY, "number") end | ||||
|         if nNewWidth ~= nil or nNewHeight ~= nil then | ||||
|             expect(3, nNewWidth, "number") | ||||
|             expect(4, nNewHeight, "number") | ||||
|         end | ||||
|         if newParent ~= nil and type(newParent) ~= "table" then expect(5, newParent, "table") end | ||||
|  | ||||
|         nX = nNewX | ||||
|         nY = nNewY | ||||
|  | ||||
|         if newParent then parent = newParent end | ||||
|  | ||||
|         if nNewWidth and nNewHeight then | ||||
|             local tNewLines = {} | ||||
|             createEmptyLines( nNewWidth ) | ||||
|   | ||||
| @@ -7,7 +7,7 @@ else | ||||
| end | ||||
|  | ||||
| if sTopic == "index" then | ||||
|     print( "Help topics availiable:" ) | ||||
|     print( "Help topics available:" ) | ||||
|     local tTopics = help.topics() | ||||
|     textutils.pagedTabulate( tTopics ) | ||||
|     return | ||||
|   | ||||
| @@ -1,3 +1,4 @@ | ||||
| local completion = require "cc.shell.completion" | ||||
|  | ||||
| -- Setup paths | ||||
| local sPath = ".:/rom/programs" | ||||
| @@ -39,217 +40,86 @@ if term.isColor() then | ||||
| end | ||||
|  | ||||
| -- Setup completion functions | ||||
| local function completeMultipleChoice( sText, tOptions, bAddSpaces ) | ||||
|     local tResults = {} | ||||
|     for n=1,#tOptions do | ||||
|         local sOption = tOptions[n] | ||||
|         if #sOption + (bAddSpaces and 1 or 0) > #sText and string.sub( sOption, 1, #sText ) == sText then | ||||
|             local sResult = string.sub( sOption, #sText + 1 ) | ||||
|             if bAddSpaces then | ||||
|                 table.insert( tResults, sResult .. " " ) | ||||
|             else | ||||
|                 table.insert( tResults, sResult ) | ||||
|             end | ||||
|         end | ||||
|     end | ||||
|     return tResults | ||||
| end | ||||
| local function completePeripheralName( sText, bAddSpaces ) | ||||
|     return completeMultipleChoice( sText, peripheral.getNames(), bAddSpaces ) | ||||
| end | ||||
| local tRedstoneSides = redstone.getSides() | ||||
| local function completeSide( sText, bAddSpaces ) | ||||
|     return completeMultipleChoice( sText, tRedstoneSides, bAddSpaces ) | ||||
| end | ||||
| local function completeFile( shell, nIndex, sText, tPreviousText ) | ||||
|     if nIndex == 1 then | ||||
|         return fs.complete( sText, shell.dir(), true, false ) | ||||
|  | ||||
| local function completePastebinPut(shell, text, previous) | ||||
|     if previous[2] == "put" then | ||||
|         return fs.complete(text, shell.dir(), true, false ) | ||||
|     end | ||||
| end | ||||
| local function completeFileMany( shell, nIndex, sText, tPreviousText ) | ||||
|     return fs.complete( sText, shell.dir(), true, false ) | ||||
| end | ||||
| local function completeDir( shell, nIndex, sText, tPreviousText ) | ||||
|     if nIndex == 1 then | ||||
|         return fs.complete( sText, shell.dir(), false, true ) | ||||
|     end | ||||
| end | ||||
| local function completeEither( shell, nIndex, sText, tPreviousText ) | ||||
|     if nIndex == 1 then | ||||
|         return fs.complete( sText, shell.dir(), true, true ) | ||||
|     end | ||||
| end | ||||
| local function completeEitherMany( shell, nIndex, sText, tPreviousText ) | ||||
|     return fs.complete( sText, shell.dir(), true, true ) | ||||
| end | ||||
| local function completeEitherEither( shell, nIndex, sText, tPreviousText ) | ||||
|     if nIndex == 1 then | ||||
|         local tResults = fs.complete( sText, shell.dir(), true, true ) | ||||
|         for n=1,#tResults do | ||||
|             local sResult = tResults[n] | ||||
|             if string.sub( sResult, #sResult, #sResult ) ~= "/" then | ||||
|                 tResults[n] = sResult .. " " | ||||
|             end | ||||
|         end | ||||
|         return tResults | ||||
|     elseif nIndex == 2 then | ||||
|         return fs.complete( sText, shell.dir(), true, true ) | ||||
|     end | ||||
| end | ||||
| local function completeProgram( shell, nIndex, sText, tPreviousText ) | ||||
|     if nIndex == 1 then | ||||
|         return shell.completeProgram( sText ) | ||||
|     end | ||||
| end | ||||
| local function completeHelp( shell, nIndex, sText, tPreviousText ) | ||||
|     if nIndex == 1 then | ||||
|         return help.completeTopic( sText ) | ||||
|     end | ||||
| end | ||||
| local function completeAlias( shell, nIndex, sText, tPreviousText ) | ||||
|     if nIndex == 2 then | ||||
|         return shell.completeProgram( sText ) | ||||
|     end | ||||
| end | ||||
| local function completePeripheral( shell, nIndex, sText, tPreviousText ) | ||||
|     if nIndex == 1 then | ||||
|         return completePeripheralName( sText ) | ||||
|     end | ||||
| end | ||||
| local tGPSOptions = { "host", "host ", "locate" } | ||||
| local function completeGPS( shell, nIndex, sText, tPreviousText ) | ||||
|     if nIndex == 1 then | ||||
|         return completeMultipleChoice( sText, tGPSOptions ) | ||||
|     end | ||||
| end | ||||
| local tLabelOptions = { "get", "get ", "set ", "clear", "clear " } | ||||
| local function completeLabel( shell, nIndex, sText, tPreviousText ) | ||||
|     if nIndex == 1 then | ||||
|         return completeMultipleChoice( sText, tLabelOptions ) | ||||
|     elseif nIndex == 2 then | ||||
|         return completePeripheralName( sText ) | ||||
|     end | ||||
| end | ||||
| local function completeMonitor( shell, nIndex, sText, tPreviousText ) | ||||
|     if nIndex == 1 then | ||||
|         return completePeripheralName( sText, true ) | ||||
|     elseif nIndex == 2 then | ||||
|         return shell.completeProgram( sText ) | ||||
|     end | ||||
| end | ||||
| local tRedstoneOptions = { "probe", "set ", "pulse " } | ||||
| local function completeRedstone( shell, nIndex, sText, tPreviousText ) | ||||
|     if nIndex == 1 then | ||||
|         return completeMultipleChoice( sText, tRedstoneOptions ) | ||||
|     elseif nIndex == 2 then | ||||
|         return completeSide( sText ) | ||||
|     end | ||||
| end | ||||
| local tDJOptions = { "play", "play ", "stop " } | ||||
| local function completeDJ( shell, nIndex, sText, tPreviousText ) | ||||
|     if nIndex == 1 then | ||||
|         return completeMultipleChoice( sText, tDJOptions ) | ||||
|     elseif nIndex == 2 then | ||||
|         return completePeripheralName( sText ) | ||||
|     end | ||||
| end | ||||
| local tPastebinOptions = { "put ", "get ", "run " } | ||||
| local function completePastebin( shell, nIndex, sText, tPreviousText ) | ||||
|     if nIndex == 1 then | ||||
|         return completeMultipleChoice( sText, tPastebinOptions ) | ||||
|     elseif nIndex == 2 then | ||||
|         if tPreviousText[2] == "put" then | ||||
|             return fs.complete( sText, shell.dir(), true, false ) | ||||
|         end | ||||
|     end | ||||
| end | ||||
| local tChatOptions = { "host ", "join " } | ||||
| local function completeChat( shell, nIndex, sText, tPreviousText ) | ||||
|     if nIndex == 1 then | ||||
|         return completeMultipleChoice( sText, tChatOptions ) | ||||
|     end | ||||
| end | ||||
| local function completeSet( shell, nIndex, sText, tPreviousText ) | ||||
|     if nIndex == 1 then | ||||
|         return completeMultipleChoice( sText, settings.getNames(), true ) | ||||
|     end | ||||
| end | ||||
| local tCommands | ||||
| if commands then | ||||
|     tCommands = commands.list() | ||||
| end | ||||
| local function completeExec( shell, nIndex, sText, tPreviousText ) | ||||
|     if nIndex == 1 and commands then | ||||
|         return completeMultipleChoice( sText, tCommands, true ) | ||||
|     end | ||||
| end | ||||
| local tWgetOptions = { "run" } | ||||
| local function completeWget( shell, nIndex, sText, tPreviousText ) | ||||
|     if nIndex == 1 then | ||||
|         return completeMultipleChoice( sText, tWgetOptions, true ) | ||||
|     end | ||||
| end | ||||
| shell.setCompletionFunction( "rom/programs/alias.lua", completeAlias ) | ||||
| shell.setCompletionFunction( "rom/programs/cd.lua", completeDir ) | ||||
| shell.setCompletionFunction( "rom/programs/copy.lua", completeEitherEither ) | ||||
| shell.setCompletionFunction( "rom/programs/delete.lua", completeEitherMany ) | ||||
| shell.setCompletionFunction( "rom/programs/drive.lua", completeDir ) | ||||
| shell.setCompletionFunction( "rom/programs/edit.lua", completeFile ) | ||||
| shell.setCompletionFunction( "rom/programs/eject.lua", completePeripheral ) | ||||
| shell.setCompletionFunction( "rom/programs/gps.lua", completeGPS ) | ||||
| shell.setCompletionFunction( "rom/programs/help.lua", completeHelp ) | ||||
| shell.setCompletionFunction( "rom/programs/id.lua", completePeripheral ) | ||||
| shell.setCompletionFunction( "rom/programs/label.lua", completeLabel ) | ||||
| shell.setCompletionFunction( "rom/programs/list.lua", completeDir ) | ||||
| shell.setCompletionFunction( "rom/programs/mkdir.lua", completeFileMany ) | ||||
| shell.setCompletionFunction( "rom/programs/monitor.lua", completeMonitor ) | ||||
| shell.setCompletionFunction( "rom/programs/move.lua", completeEitherEither ) | ||||
| shell.setCompletionFunction( "rom/programs/redstone.lua", completeRedstone ) | ||||
| shell.setCompletionFunction( "rom/programs/rename.lua", completeEitherEither ) | ||||
| shell.setCompletionFunction( "rom/programs/shell.lua", completeProgram ) | ||||
| shell.setCompletionFunction( "rom/programs/type.lua", completeEither ) | ||||
| shell.setCompletionFunction( "rom/programs/set.lua", completeSet ) | ||||
| shell.setCompletionFunction( "rom/programs/advanced/bg.lua", completeProgram ) | ||||
| shell.setCompletionFunction( "rom/programs/advanced/fg.lua", completeProgram ) | ||||
| shell.setCompletionFunction( "rom/programs/fun/dj.lua", completeDJ ) | ||||
| shell.setCompletionFunction( "rom/programs/fun/advanced/paint.lua", completeFile ) | ||||
| shell.setCompletionFunction( "rom/programs/http/pastebin.lua", completePastebin ) | ||||
| shell.setCompletionFunction( "rom/programs/rednet/chat.lua", completeChat ) | ||||
| shell.setCompletionFunction( "rom/programs/command/exec.lua", completeExec ) | ||||
| shell.setCompletionFunction( "rom/programs/http/wget.lua", completeWget ) | ||||
|  | ||||
| shell.setCompletionFunction( "rom/programs/alias.lua", completion.build(nil, completion.program) ) | ||||
| shell.setCompletionFunction( "rom/programs/cd.lua", completion.build(completion.dir) ) | ||||
| shell.setCompletionFunction( "rom/programs/copy.lua", completion.build( | ||||
|     { completion.dirOrFile, true }, | ||||
|     completion.dirOrFile | ||||
| ) ) | ||||
| shell.setCompletionFunction( "rom/programs/delete.lua", completion.build({ completion.dirOrFile, many = true }) ) | ||||
| shell.setCompletionFunction( "rom/programs/drive.lua", completion.build(completion.dir) ) | ||||
| shell.setCompletionFunction( "rom/programs/edit.lua", completion.build(completion.file) ) | ||||
| shell.setCompletionFunction( "rom/programs/eject.lua", completion.build(completion.peripheral) ) | ||||
| shell.setCompletionFunction( "rom/programs/gps.lua", completion.build({ completion.choice, { "host", "host ", "locate" } }) ) | ||||
| shell.setCompletionFunction( "rom/programs/help.lua", completion.build(completion.help) ) | ||||
| shell.setCompletionFunction( "rom/programs/id.lua", completion.build(completion.peripheral) ) | ||||
| shell.setCompletionFunction( "rom/programs/label.lua", completion.build( | ||||
|     { completion.choice, { "get", "get ", "set ", "clear", "clear " } }, | ||||
|     completion.peripheral | ||||
| ) ) | ||||
| shell.setCompletionFunction( "rom/programs/list.lua", completion.build(completion.dir) ) | ||||
| shell.setCompletionFunction( "rom/programs/mkdir.lua", completion.build({ completion.dir, many = true }) ) | ||||
| shell.setCompletionFunction( "rom/programs/monitor.lua", completion.build( | ||||
|     { completion.peripheral, true }, | ||||
|     completion.program | ||||
| ) ) | ||||
| shell.setCompletionFunction( "rom/programs/move.lua", completion.build( | ||||
|     { completion.dirOrFile, true }, | ||||
|     completion.dirOrFile | ||||
| ) ) | ||||
| shell.setCompletionFunction( "rom/programs/redstone.lua", completion.build( | ||||
|     { completion.choice, { "probe", "set ", "pulse " } }, | ||||
|     completion.side | ||||
| ) ) | ||||
| shell.setCompletionFunction( "rom/programs/rename.lua", completion.build( | ||||
|     { completion.dirOrFile, true }, | ||||
|     completion.dirOrFile | ||||
| ) ) | ||||
| shell.setCompletionFunction( "rom/programs/shell.lua", completion.build(completion.program) ) | ||||
| shell.setCompletionFunction( "rom/programs/type.lua", completion.build(completion.dirOrFile) ) | ||||
| shell.setCompletionFunction( "rom/programs/set.lua", completion.build({ completion.setting, true }) ) | ||||
| shell.setCompletionFunction( "rom/programs/advanced/bg.lua", completion.build(completion.program) ) | ||||
| shell.setCompletionFunction( "rom/programs/advanced/fg.lua", completion.build(completion.program) ) | ||||
| shell.setCompletionFunction( "rom/programs/fun/dj.lua", completion.build( | ||||
|     { completion.choice, { "play", "play ", "stop " } }, | ||||
|     completion.peripheral | ||||
| ) ) | ||||
| shell.setCompletionFunction( "rom/programs/fun/advanced/paint.lua", completion.build(completion.file) ) | ||||
| shell.setCompletionFunction( "rom/programs/http/pastebin.lua", completion.build( | ||||
|     { completion.choice, { "put ", "get ", "run " } }, | ||||
|     completePastebinPut | ||||
| ) ) | ||||
| shell.setCompletionFunction( "rom/programs/rednet/chat.lua", completion.build({ completion.choice, { "host ", "join " } }) ) | ||||
| shell.setCompletionFunction( "rom/programs/command/exec.lua", completion.build(completion.command) ) | ||||
| shell.setCompletionFunction( "rom/programs/http/wget.lua", completion.build({ completion.choice, { "run " } }) ) | ||||
|  | ||||
| if turtle then | ||||
|     local tGoOptions = { "left", "right", "forward", "back", "down", "up" } | ||||
|     local function completeGo( shell, nIndex, sText ) | ||||
|         return completeMultipleChoice( sText, tGoOptions, true) | ||||
|     end | ||||
|     local tTurnOptions = { "left", "right" } | ||||
|     local function completeTurn( shell, nIndex, sText ) | ||||
|             return completeMultipleChoice( sText, tTurnOptions, true ) | ||||
|     end | ||||
|     local tEquipOptions = { "left", "right" } | ||||
|     local function completeEquip( shell, nIndex, sText ) | ||||
|         if nIndex == 2 then | ||||
|             return completeMultipleChoice( sText, tEquipOptions ) | ||||
|         end | ||||
|     end | ||||
|     local function completeUnequip( shell, nIndex, sText ) | ||||
|         if nIndex == 1 then | ||||
|             return completeMultipleChoice( sText, tEquipOptions ) | ||||
|         end | ||||
|     end | ||||
|     shell.setCompletionFunction( "rom/programs/turtle/go.lua", completeGo ) | ||||
|     shell.setCompletionFunction( "rom/programs/turtle/turn.lua", completeTurn ) | ||||
|     shell.setCompletionFunction( "rom/programs/turtle/equip.lua", completeEquip ) | ||||
|     shell.setCompletionFunction( "rom/programs/turtle/unequip.lua", completeUnequip ) | ||||
|     shell.setCompletionFunction( "rom/programs/turtle/go.lua", completion.build( | ||||
|         { completion.choice, { "left", "right", "forward", "back", "down", "up" }, true, many = true } | ||||
|     ) ) | ||||
|     shell.setCompletionFunction( "rom/programs/turtle/turn.lua", completion.build( | ||||
|         { completion.choice, { "left", "right" }, true, many = true } | ||||
|     )) | ||||
|     shell.setCompletionFunction( "rom/programs/turtle/equip.lua", completion.build( | ||||
|         nil, | ||||
|         { completion.choice, { "left", "right" } } | ||||
|     ) ) | ||||
|     shell.setCompletionFunction( "rom/programs/turtle/unequip.lua", completion.build( | ||||
|         { completion.choice, { "left", "right" } } | ||||
|     ) ) | ||||
| end | ||||
|  | ||||
|  | ||||
| -- Run autorun files | ||||
| if fs.exists( "/rom/autorun" ) and fs.isDir( "/rom/autorun" ) then | ||||
|     local tFiles = fs.list( "/rom/autorun" ) | ||||
|     table.sort( tFiles ) | ||||
|     for n, sFile in ipairs( tFiles ) do | ||||
|     for _, sFile in ipairs( tFiles ) do | ||||
|         if string.sub( sFile, 1, 1 ) ~= "." then | ||||
|             local sPath = "/rom/autorun/"..sFile | ||||
|             if not fs.isDir( sPath ) then | ||||
|   | ||||
| @@ -118,6 +118,26 @@ describe("The window library", function() | ||||
|             expect.error(w.reposition, 1, 1, false, 1):eq("bad argument #3 (expected number, got boolean)") | ||||
|             expect.error(w.reposition, 1, 1, nil, 1):eq("bad argument #3 (expected number, got nil)") | ||||
|             expect.error(w.reposition, 1, 1, 1, nil):eq("bad argument #4 (expected number, got nil)") | ||||
|             expect.error(w.reposition, 1, 1, 1, 1, true):eq("bad argument #5 (expected table, got boolean)") | ||||
|         end) | ||||
|  | ||||
|         it("can change the buffer", function() | ||||
|             local a, b = mk(), mk() | ||||
|             local target = window.create(a, 1, 1, a.getSize()) | ||||
|  | ||||
|             target.write("Test") | ||||
|             expect((a.getLine(1))):equal("Test ") | ||||
|             expect({ a.getCursorPos() }):same { 5, 1 } | ||||
|  | ||||
|             target.reposition(1, 1, nil, nil, b) | ||||
|  | ||||
|             target.redraw() | ||||
|             expect((a.getLine(1))):equal("Test ") | ||||
|             expect({ a.getCursorPos() }):same { 5, 1 } | ||||
|  | ||||
|             target.setCursorPos(1, 1) target.write("More") | ||||
|             expect((a.getLine(1))):equal("Test ") | ||||
|             expect((b.getLine(1))):equal("More ") | ||||
|         end) | ||||
|     end) | ||||
|  | ||||
|   | ||||
| @@ -0,0 +1,57 @@ | ||||
| describe("cc.completion", function() | ||||
|     local c = require("cc.completion") | ||||
|  | ||||
|     describe("choice", function() | ||||
|         it("provides all choices", function() | ||||
|             expect(c.choice("", { "some text", "some other", "other" })) | ||||
|                 :same { "some text", "some other", "other" } | ||||
|         end) | ||||
|  | ||||
|         it("provides a filtered list of choices", function() | ||||
|             expect(c.choice("som", { "some text", "some other", "other" })) | ||||
|                 :same { "e text", "e other" } | ||||
|  | ||||
|             expect(c.choice("none", { "some text", "some other", "other" })) | ||||
|                 :same { } | ||||
|         end) | ||||
|  | ||||
|         it("adds text if needed", function() | ||||
|             expect(c.choice("som", { "some text", "some other", "other" }, true)) | ||||
|                 :same { "e text ", "e other " } | ||||
|         end) | ||||
|     end) | ||||
|  | ||||
|     describe("peripheral", function() | ||||
|         it("provides a choice of peripherals", function() | ||||
|             stub(peripheral, "getNames", function() return { "drive_0", "left" } end) | ||||
|  | ||||
|             expect(c.peripheral("dri")):same { "ve_0" } | ||||
|             expect(c.peripheral("dri", true)):same { "ve_0 " } | ||||
|         end) | ||||
|     end) | ||||
|  | ||||
|     describe("side", function() | ||||
|         it("provides a choice of sides", function() | ||||
|             expect(c.side("le")):same { "ft" } | ||||
|             expect(c.side("le", true)):same { "ft " } | ||||
|         end) | ||||
|     end) | ||||
|  | ||||
|     describe("setting", function() | ||||
|         it("provides a choice of setting names", function() | ||||
|             stub(settings, "getNames", function() return { "shell.allow_startup", "list.show_hidden" } end) | ||||
|  | ||||
|             expect(c.setting("li")):same { "st.show_hidden" } | ||||
|             expect(c.setting("li", true)):same { "st.show_hidden " } | ||||
|         end) | ||||
|     end) | ||||
|  | ||||
|     describe("command", function() | ||||
|         it("provides a choice of command names", function() | ||||
|             stub(_G, "commands", { list = function() return { "list", "say" } end }) | ||||
|  | ||||
|             expect(c.command("li")):same { "st" } | ||||
|             expect(c.command("li", true)):same { "st " } | ||||
|         end) | ||||
|     end) | ||||
| end) | ||||
| @@ -0,0 +1,41 @@ | ||||
| describe("cc.shell.completion", function() | ||||
|     local c = require "cc.shell.completion" | ||||
|  | ||||
|     describe("dirOrFile", function() | ||||
|         it("completes both", function() | ||||
|             expect(c.dirOrFile(shell, "rom/")):same { | ||||
|                 "apis/", "apis", "autorun/", "autorun", "help/", "help", | ||||
|                 "modules/", "modules", "motd.txt", "programs/", "programs", "startup.lua" | ||||
|             } | ||||
|         end) | ||||
|  | ||||
|         it("adds a space", function() | ||||
|             expect(c.dirOrFile(shell, "rom/", nil, true)):same { | ||||
|                 "apis/", "apis ", "autorun/", "autorun ", "help/", "help ", | ||||
|                 "modules/", "modules ", "motd.txt ", "programs/", "programs ", "startup.lua ", | ||||
|             } | ||||
|         end) | ||||
|     end) | ||||
|  | ||||
|     describe("build", function() | ||||
|         it("completes multiple arguments", function() | ||||
|             local spec = c.build( | ||||
|                 function() return { "a", "b", "c" } end, | ||||
|                 nil, | ||||
|                 { c.choice, { "d", "e", "f"} } | ||||
|             ) | ||||
|  | ||||
|             expect(spec(shell, 1, "")):same { "a", "b", "c" } | ||||
|             expect(spec(shell, 2, "")):same(nil) | ||||
|             expect(spec(shell, 3, "")):same { "d", "e", "f" } | ||||
|             expect(spec(shell, 4, "")):same(nil) | ||||
|         end) | ||||
|  | ||||
|         it("supports variadic completions", function() | ||||
|             local spec = c.build({ function() return { "a", "b", "c" } end, many = true }) | ||||
|  | ||||
|             expect(spec(shell, 1, "")):same({ "a", "b", "c" }) | ||||
|             expect(spec(shell, 2, "")):same({ "a", "b", "c" }) | ||||
|         end) | ||||
|     end) | ||||
| end) | ||||
| @@ -23,7 +23,7 @@ describe("The mkdir program", function() | ||||
|         io.open("/test-files.a.txt", "w"):close() | ||||
|  | ||||
|         local complete = shell.getCompletionInfo()["rom/programs/mkdir.lua"].fnComplete | ||||
|         expect(complete(shell, 1, "/test-files/", {})):same { "a/", "b/" } | ||||
|         expect(complete(shell, 2, "/test-files/", { "/" })):same { "a/", "b/" } | ||||
|         expect(complete(shell, 1, "/test-files/", {})):same { "a/", "a", "b/", "b" } | ||||
|         expect(complete(shell, 2, "/test-files/", { "/" })):same { "a/", "a", "b/", "b" } | ||||
|     end) | ||||
| end) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 SquidDev
					SquidDev