diff --git a/src/main/resources/data/computercraft/lua/rom/modules/main/cc/shell/completion.lua b/src/main/resources/data/computercraft/lua/rom/modules/main/cc/shell/completion.lua index 06619c7f1..5b2c21552 100644 --- a/src/main/resources/data/computercraft/lua/rom/modules/main/cc/shell/completion.lua +++ b/src/main/resources/data/computercraft/lua/rom/modules/main/cc/shell/completion.lua @@ -29,8 +29,8 @@ local completion = require "cc.completion" --- Complete the name of a file relative to the current working directory. -- --- @tparam table shell The shell we're completing in --- @tparam { string... } choices The list of choices to complete from. +-- @tparam table shell The shell we're completing in. +-- @tparam string text Current text to complete. -- @treturn { string... } A list of suffixes of matching files. local function file(shell, text) return fs.complete(text, shell.dir(), true, false) @@ -38,8 +38,8 @@ end --- Complete the name of a directory relative to the current working directory. -- --- @tparam table shell The shell we're completing in --- @tparam { string... } choices The list of choices to complete from. +-- @tparam table shell The shell we're completing in. +-- @tparam string text Current text to complete. -- @treturn { string... } A list of suffixes of matching directories. local function dir(shell, text) return fs.complete(text, shell.dir(), false, true) @@ -48,8 +48,8 @@ end --- Complete the name of a file or directory relative to the current working -- directory. -- --- @tparam table shell The shell we're completing in --- @tparam { string... } choices The list of choices to complete from. +-- @tparam table shell The shell we're completing in. +-- @tparam string text Current text to complete. -- @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. @@ -74,14 +74,46 @@ end --- Complete the name of a program. -- --- @tparam table shell The shell we're completing in --- @tparam { string... } choices The list of choices to complete from. +-- @tparam table shell The shell we're completing in. +-- @tparam string text Current text to complete. -- @treturn { string... } A list of suffixes of matching programs. -- @see shell.completeProgram local function program(shell, text) return shell.completeProgram(text) end +--- Complete arguments of a program. +-- +-- @tparam table shell The shell we're completing in. +-- @tparam string text Current text to complete. +-- @tparam { string... } previous The shell arguments before this one. +-- @tparam number starting Which argument index this program and args start at. +-- @treturn { string... } A list of suffixes of matching programs or arguments. +local function programWithArgs(shell, text, previous, starting) + if #previous + 1 == starting then + local tCompletionInfo = shell.getCompletionInfo() + if text:sub(-1) ~= "/" and tCompletionInfo[shell.resolveProgram(text)] then + return { " " } + else + local results = shell.completeProgram(text) + for n = 1, #results do + local sResult = results[n] + if sResult:sub(-1) ~= "/" and tCompletionInfo[shell.resolveProgram(text .. sResult)] then + results[n] = sResult .. " " + end + end + return results + end + else + local program = previous[starting] + local resolved = shell.resolveProgram(program) + if not resolved then return end + local tCompletion = shell.getCompletionInfo()[resolved] + if not tCompletion then return end + return tCompletion.fnComplete(shell, #previous - starting + 1, text, { program, table.unpack(previous, starting + 1, #previous) }) + end +end + --[[- A helper function for building shell completion arguments. This accepts a series of single-argument completion functions, and combines @@ -144,6 +176,7 @@ return { dir = dir, dirOrFile = dirOrFile, program = program, + programWithArgs = programWithArgs, -- Re-export various other functions help = wrap(help.completeTopic), --- Wraps @{help.completeTopic} as a @{build} compatible function. diff --git a/src/main/resources/data/computercraft/lua/rom/startup.lua b/src/main/resources/data/computercraft/lua/rom/startup.lua index c5ce1a1da..8c03b4852 100644 --- a/src/main/resources/data/computercraft/lua/rom/startup.lua +++ b/src/main/resources/data/computercraft/lua/rom/startup.lua @@ -81,9 +81,17 @@ shell.setCompletionFunction("rom/programs/monitor.lua", completion.build( if previous[2] == "scale" then return completion.peripheral(shell, text, previous, true) else - return completion.program(shell, text, previous) + return completion.programWithArgs(shell, text, previous, 3) end - end + end, + { + function(shell, text, previous) + if previous[2] ~= "scale" then + return completion.programWithArgs(shell, text, previous, 3) + end + end, + many = true, + } )) shell.setCompletionFunction("rom/programs/move.lua", completion.build( @@ -98,11 +106,11 @@ 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/shell.lua", completion.build({ completion.programWithArgs, 2, many = true })) 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/advanced/bg.lua", completion.build({ completion.programWithArgs, 2, many = true })) +shell.setCompletionFunction("rom/programs/advanced/fg.lua", completion.build({ completion.programWithArgs, 2, many = true })) shell.setCompletionFunction("rom/programs/fun/dj.lua", completion.build( { completion.choice, { "play", "play ", "stop " } }, completion.peripheral diff --git a/src/test/resources/test-rom/spec/modules/cc/shell/completion_spec.lua b/src/test/resources/test-rom/spec/modules/cc/shell/completion_spec.lua index 6b2c0aaa1..4ecc6056f 100644 --- a/src/test/resources/test-rom/spec/modules/cc/shell/completion_spec.lua +++ b/src/test/resources/test-rom/spec/modules/cc/shell/completion_spec.lua @@ -17,6 +17,30 @@ describe("cc.shell.completion", function() end) end) + describe("program", function() + it("completes programs", function() + expect(c.program(shell, "rom/")):same { + "apis/", "autorun/", "help/", "modules/", "motd.txt", "programs/", "startup.lua", + } + end) + end) + + describe("programWithArgs", function() + it("completes program name", function() + shell.setCompletionFunction("rom/motd.txt", function() end) + expect(c.programWithArgs(shell, "rom/", { "rom/programs/shell.lua" }, 2)):same { + "apis/", "autorun/", "help/", "modules/", "motd.txt ", "programs/", "startup.lua", + } + end) + + it("completes program arguments", function() + expect(c.programWithArgs(shell, "", { "rom/programs/shell.lua", "pastebin" }, 2)):same { + "put ", "get ", "run ", + } + end) + + end) + describe("build", function() it("completes multiple arguments", function() local spec = c.build(