mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-01-15 19:55:42 +00:00
Refactor shell completion into a separate module (#281)
- Adds cc.completions module, with a couple of helper functions for working with the more general completion functionality (i.e. that provided by read). - Adds cc.shell.completions module, which provides shell-specific completion functions. - Add a "program completion builder", which allows you to write stuff like this: shell.setCompletionFunction( "rom/programs/redstone.lua", completion.build( { completion.choice, { "probe", "set ", "pulse " } }, completion.side) ) Closes #232
This commit is contained in:
parent
9bd8c86a94
commit
8e4d311cd9
@ -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,
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
|
local completion = require "cc.shell.completion"
|
||||||
|
|
||||||
-- Setup paths
|
-- Setup paths
|
||||||
local sPath = ".:/rom/programs"
|
local sPath = ".:/rom/programs"
|
||||||
@ -39,217 +40,86 @@ if term.isColor() then
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Setup completion functions
|
-- Setup completion functions
|
||||||
local function completeMultipleChoice( sText, tOptions, bAddSpaces )
|
|
||||||
local tResults = {}
|
local function completePastebinPut(shell, text, previous)
|
||||||
for n=1,#tOptions do
|
if previous[2] == "put" then
|
||||||
local sOption = tOptions[n]
|
return fs.complete(text, shell.dir(), true, false )
|
||||||
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
|
end
|
||||||
end
|
|
||||||
return tResults
|
shell.setCompletionFunction( "rom/programs/alias.lua", completion.build(nil, completion.program) )
|
||||||
end
|
shell.setCompletionFunction( "rom/programs/cd.lua", completion.build(completion.dir) )
|
||||||
local function completePeripheralName( sText, bAddSpaces )
|
shell.setCompletionFunction( "rom/programs/copy.lua", completion.build(
|
||||||
return completeMultipleChoice( sText, peripheral.getNames(), bAddSpaces )
|
{ completion.dirOrFile, true },
|
||||||
end
|
completion.dirOrFile
|
||||||
local tRedstoneSides = redstone.getSides()
|
) )
|
||||||
local function completeSide( sText, bAddSpaces )
|
shell.setCompletionFunction( "rom/programs/delete.lua", completion.build({ completion.dirOrFile, many = true }) )
|
||||||
return completeMultipleChoice( sText, tRedstoneSides, bAddSpaces )
|
shell.setCompletionFunction( "rom/programs/drive.lua", completion.build(completion.dir) )
|
||||||
end
|
shell.setCompletionFunction( "rom/programs/edit.lua", completion.build(completion.file) )
|
||||||
local function completeFile( shell, nIndex, sText, tPreviousText )
|
shell.setCompletionFunction( "rom/programs/eject.lua", completion.build(completion.peripheral) )
|
||||||
if nIndex == 1 then
|
shell.setCompletionFunction( "rom/programs/gps.lua", completion.build({ completion.choice, { "host", "host ", "locate" } }) )
|
||||||
return fs.complete( sText, shell.dir(), true, false )
|
shell.setCompletionFunction( "rom/programs/help.lua", completion.build(completion.help) )
|
||||||
end
|
shell.setCompletionFunction( "rom/programs/id.lua", completion.build(completion.peripheral) )
|
||||||
end
|
shell.setCompletionFunction( "rom/programs/label.lua", completion.build(
|
||||||
local function completeFileMany( shell, nIndex, sText, tPreviousText )
|
{ completion.choice, { "get", "get ", "set ", "clear", "clear " } },
|
||||||
return fs.complete( sText, shell.dir(), true, false )
|
completion.peripheral
|
||||||
end
|
) )
|
||||||
local function completeDir( shell, nIndex, sText, tPreviousText )
|
shell.setCompletionFunction( "rom/programs/list.lua", completion.build(completion.dir) )
|
||||||
if nIndex == 1 then
|
shell.setCompletionFunction( "rom/programs/mkdir.lua", completion.build({ completion.dir, many = true }) )
|
||||||
return fs.complete( sText, shell.dir(), false, true )
|
shell.setCompletionFunction( "rom/programs/monitor.lua", completion.build(
|
||||||
end
|
{ completion.peripheral, true },
|
||||||
end
|
completion.program
|
||||||
local function completeEither( shell, nIndex, sText, tPreviousText )
|
) )
|
||||||
if nIndex == 1 then
|
shell.setCompletionFunction( "rom/programs/move.lua", completion.build(
|
||||||
return fs.complete( sText, shell.dir(), true, true )
|
{ completion.dirOrFile, true },
|
||||||
end
|
completion.dirOrFile
|
||||||
end
|
) )
|
||||||
local function completeEitherMany( shell, nIndex, sText, tPreviousText )
|
shell.setCompletionFunction( "rom/programs/redstone.lua", completion.build(
|
||||||
return fs.complete( sText, shell.dir(), true, true )
|
{ completion.choice, { "probe", "set ", "pulse " } },
|
||||||
end
|
completion.side
|
||||||
local function completeEitherEither( shell, nIndex, sText, tPreviousText )
|
) )
|
||||||
if nIndex == 1 then
|
shell.setCompletionFunction( "rom/programs/rename.lua", completion.build(
|
||||||
local tResults = fs.complete( sText, shell.dir(), true, true )
|
{ completion.dirOrFile, true },
|
||||||
for n=1,#tResults do
|
completion.dirOrFile
|
||||||
local sResult = tResults[n]
|
) )
|
||||||
if string.sub( sResult, #sResult, #sResult ) ~= "/" then
|
shell.setCompletionFunction( "rom/programs/shell.lua", completion.build(completion.program) )
|
||||||
tResults[n] = sResult .. " "
|
shell.setCompletionFunction( "rom/programs/type.lua", completion.build(completion.dirOrFile) )
|
||||||
end
|
shell.setCompletionFunction( "rom/programs/set.lua", completion.build({ completion.setting, true }) )
|
||||||
end
|
shell.setCompletionFunction( "rom/programs/advanced/bg.lua", completion.build(completion.program) )
|
||||||
return tResults
|
shell.setCompletionFunction( "rom/programs/advanced/fg.lua", completion.build(completion.program) )
|
||||||
elseif nIndex == 2 then
|
shell.setCompletionFunction( "rom/programs/fun/dj.lua", completion.build(
|
||||||
return fs.complete( sText, shell.dir(), true, true )
|
{ completion.choice, { "play", "play ", "stop " } },
|
||||||
end
|
completion.peripheral
|
||||||
end
|
) )
|
||||||
local function completeProgram( shell, nIndex, sText, tPreviousText )
|
shell.setCompletionFunction( "rom/programs/fun/advanced/paint.lua", completion.build(completion.file) )
|
||||||
if nIndex == 1 then
|
shell.setCompletionFunction( "rom/programs/http/pastebin.lua", completion.build(
|
||||||
return shell.completeProgram( sText )
|
{ completion.choice, { "put ", "get ", "run " } },
|
||||||
end
|
completePastebinPut
|
||||||
end
|
) )
|
||||||
local function completeHelp( shell, nIndex, sText, tPreviousText )
|
shell.setCompletionFunction( "rom/programs/rednet/chat.lua", completion.build({ completion.choice, { "host ", "join " } }) )
|
||||||
if nIndex == 1 then
|
shell.setCompletionFunction( "rom/programs/command/exec.lua", completion.build(completion.command) )
|
||||||
return help.completeTopic( sText )
|
shell.setCompletionFunction( "rom/programs/http/wget.lua", completion.build({ completion.choice, { "run " } }) )
|
||||||
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 )
|
|
||||||
|
|
||||||
if turtle then
|
if turtle then
|
||||||
local tGoOptions = { "left", "right", "forward", "back", "down", "up" }
|
shell.setCompletionFunction( "rom/programs/turtle/go.lua", completion.build(
|
||||||
local function completeGo( shell, nIndex, sText )
|
{ completion.choice, { "left", "right", "forward", "back", "down", "up" }, true, many = true }
|
||||||
return completeMultipleChoice( sText, tGoOptions, 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
|
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 )
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- Run autorun files
|
-- Run autorun files
|
||||||
if fs.exists( "/rom/autorun" ) and fs.isDir( "/rom/autorun" ) then
|
if fs.exists( "/rom/autorun" ) and fs.isDir( "/rom/autorun" ) then
|
||||||
local tFiles = fs.list( "/rom/autorun" )
|
local tFiles = fs.list( "/rom/autorun" )
|
||||||
table.sort( tFiles )
|
for _, sFile in ipairs( tFiles ) do
|
||||||
for n, sFile in ipairs( tFiles ) do
|
|
||||||
if string.sub( sFile, 1, 1 ) ~= "." then
|
if string.sub( sFile, 1, 1 ) ~= "." then
|
||||||
local sPath = "/rom/autorun/"..sFile
|
local sPath = "/rom/autorun/"..sFile
|
||||||
if not fs.isDir( sPath ) then
|
if not fs.isDir( sPath ) then
|
||||||
|
@ -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()
|
io.open("/test-files.a.txt", "w"):close()
|
||||||
|
|
||||||
local complete = shell.getCompletionInfo()["rom/programs/mkdir.lua"].fnComplete
|
local complete = shell.getCompletionInfo()["rom/programs/mkdir.lua"].fnComplete
|
||||||
expect(complete(shell, 1, "/test-files/", {})):same { "a/", "b/" }
|
expect(complete(shell, 1, "/test-files/", {})):same { "a/", "a", "b/", "b" }
|
||||||
expect(complete(shell, 2, "/test-files/", { "/" })):same { "a/", "b/" }
|
expect(complete(shell, 2, "/test-files/", { "/" })):same { "a/", "a", "b/", "b" }
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
Loading…
Reference in New Issue
Block a user