diff --git a/doc/stub/fs.lua b/doc/stub/fs.lua index e2d8f0741..a393d7cd2 100644 --- a/doc/stub/fs.lua +++ b/doc/stub/fs.lua @@ -22,13 +22,43 @@ directory exist) and one without it (meaning this entry is an immediate completion candidate). `include_dirs` can be set to @{false} to only include those with a trailing slash. -@tparam string path The path to complete. -@tparam string location The location where paths are resolved from. -@tparam[opt] boolean include_files When @{false}, only directories will be -included in the returned list. -@tparam[opt] boolean include_dirs When @{false}, "raw" directories will not be -included in the returned list. +@tparam[1] string path The path to complete. +@tparam[1] string location The location where paths are resolved from. +@tparam[1,opt=true] boolean include_files When @{false}, only directories will +be included in the returned list. +@tparam[1,opt=true] boolean include_dirs When @{false}, "raw" directories will +not be included in the returned list. + +@tparam[2] string path The path to complete. +@tparam[2] string location The location where paths are resolved from. +@tparam[2] { + include_dirs? = boolean, include_files? = boolean, + include_hidden? = boolean +} options +This table form is an expanded version of the previous syntax. The +`include_files` and `include_dirs` arguments from above are passed in as fields. + +This table also accepts the following options: + - `include_hidden`: Whether to include hidden files (those starting with `.`) + by default. They will still be shown when typing a `.`. + @treturn { string... } A list of possible completion candidates. @since 1.74 +@changed 1.101.0 +@usage Complete files in the root directory. + + read(nil, nil, function(str) + return fs.complete(str, "", true, false) + end) + +@usage Complete files in the root directory, hiding hidden files by default. + + read(nil, nil, function(str) + return fs.complete(str, "", { + include_files = true, + include_dirs = false, + included_hidden = false, + }) + end) ]] function complete(path, location, include_files, include_dirs) end diff --git a/gradle.properties b/gradle.properties index 5ed625dc7..e8df72c2e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ kotlin.stdlib.default.dependency=false kotlin.jvm.target.validation.mode=error # Mod properties -modVersion=1.100.10 +modVersion=1.101.0 # Minecraft properties: We want to configure this here so we can read it in settings.gradle mcVersion=1.18.2 diff --git a/src/main/java/dan200/computercraft/client/gui/widgets/ComputerSidebar.java b/src/main/java/dan200/computercraft/client/gui/widgets/ComputerSidebar.java index 71bc4c29d..de39db15a 100644 --- a/src/main/java/dan200/computercraft/client/gui/widgets/ComputerSidebar.java +++ b/src/main/java/dan200/computercraft/client/gui/widgets/ComputerSidebar.java @@ -16,6 +16,7 @@ import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.resources.ResourceLocation; import java.util.Arrays; +import java.util.Collections; import java.util.function.BooleanSupplier; import java.util.function.Consumer; @@ -56,9 +57,8 @@ public final class ComputerSidebar () -> isOn.getAsBoolean() ? Arrays.asList( new TranslatableComponent( "gui.computercraft.tooltip.turn_off" ), new TranslatableComponent( "gui.computercraft.tooltip.turn_off.key" ).withStyle( ChatFormatting.GRAY ) - ) : Arrays.asList( - new TranslatableComponent( "gui.computercraft.tooltip.turn_on" ), - new TranslatableComponent( "gui.computercraft.tooltip.turn_off.key" ).withStyle( ChatFormatting.GRAY ) + ) : Collections.singletonList( + new TranslatableComponent( "gui.computercraft.tooltip.turn_on" ) ) ) ); diff --git a/src/main/java/dan200/computercraft/shared/command/CommandComputerCraft.java b/src/main/java/dan200/computercraft/shared/command/CommandComputerCraft.java index 934ff3885..af328d3dd 100644 --- a/src/main/java/dan200/computercraft/shared/command/CommandComputerCraft.java +++ b/src/main/java/dan200/computercraft/shared/command/CommandComputerCraft.java @@ -371,8 +371,7 @@ public final class CommandComputerCraft private static final List DEFAULT_FIELDS = Arrays.asList( new AggregatedMetric( Metrics.COMPUTER_TASKS, Aggregate.COUNT ), new AggregatedMetric( Metrics.COMPUTER_TASKS, Aggregate.NONE ), - new AggregatedMetric( Metrics.COMPUTER_TASKS, Aggregate.AVG ), - new AggregatedMetric( Metrics.COMPUTER_TASKS, Aggregate.MAX ) + new AggregatedMetric( Metrics.COMPUTER_TASKS, Aggregate.AVG ) ); private static int displayTimings( CommandSourceStack source, AggregatedMetric sortField, List fields ) throws CommandSyntaxException diff --git a/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/EnergyMethods.java b/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/EnergyMethods.java index e320f514e..71d48e44a 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/EnergyMethods.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/EnergyMethods.java @@ -25,6 +25,7 @@ import javax.annotation.Nonnull; * ::: * * @cc.module energy_storage + * @cc.since 1.94.0 */ public class EnergyMethods implements GenericPeripheral { diff --git a/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/FluidMethods.java b/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/FluidMethods.java index 741d9150a..194435a75 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/FluidMethods.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/FluidMethods.java @@ -35,6 +35,7 @@ import static dan200.computercraft.shared.peripheral.generic.methods.ArgumentHel * Methods for interacting with tanks and other fluid storage blocks. * * @cc.module fluid_storage + * @cc.since 1.94.0 */ public class FluidMethods implements GenericPeripheral { diff --git a/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java b/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java index c56d0930c..646e2531a 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java @@ -37,6 +37,7 @@ import static dan200.computercraft.shared.peripheral.generic.methods.ArgumentHel * Methods for interacting with inventories. * * @cc.module inventory + * @cc.since 1.94.0 */ public class InventoryMethods implements GenericPeripheral { @@ -170,6 +171,7 @@ public class InventoryMethods implements GenericPeripheral * end * print(total) * } + * @cc.since 1.96.0 */ @LuaFunction( mainThread = true ) public static int getItemLimit( IItemHandler inventory, int slot ) throws LuaException diff --git a/src/main/resources/assets/computercraft/lang/en_us.json b/src/main/resources/assets/computercraft/lang/en_us.json index 4f6f730e5..ed420e7a0 100644 --- a/src/main/resources/assets/computercraft/lang/en_us.json +++ b/src/main/resources/assets/computercraft/lang/en_us.json @@ -111,7 +111,6 @@ "gui.computercraft.tooltip.computer_id": "Computer ID: %s", "gui.computercraft.tooltip.disk_id": "Disk ID: %s", "gui.computercraft.tooltip.turn_on": "Turn this computer on", - "gui.computercraft.tooltip.turn_on.key": "Hold Ctrl+R", "gui.computercraft.tooltip.turn_off": "Turn this computer off", "gui.computercraft.tooltip.turn_off.key": "Hold Ctrl+S", "gui.computercraft.tooltip.terminate": "Stop the currently running code", diff --git a/src/main/resources/data/computercraft/lua/bios.lua b/src/main/resources/data/computercraft/lua/bios.lua index d31e20335..a653c97a6 100644 --- a/src/main/resources/data/computercraft/lua/bios.lua +++ b/src/main/resources/data/computercraft/lua/bios.lua @@ -3,7 +3,7 @@ -- Ideally we'd use require, but that is part of the shell, and so is not -- available to the BIOS or any APIs. All APIs load this using dofile, but that -- has not been defined at this point. -local expect +local expect, field do local h = fs.open("rom/modules/main/cc/expect.lua", "r") @@ -11,7 +11,8 @@ do h.close() if not f then error(err) end - expect = f().expect + local res = f() + expect, field = res.expect, res.field end if _VERSION == "Lua 5.1" then @@ -716,9 +717,17 @@ local tEmpty = {} function fs.complete(sPath, sLocation, bIncludeFiles, bIncludeDirs) expect(1, sPath, "string") expect(2, sLocation, "string") - expect(3, bIncludeFiles, "boolean", "nil") - expect(4, bIncludeDirs, "boolean", "nil") + local bIncludeHidden = nil + if type(bIncludeFiles) == "table" then + bIncludeDirs = field(bIncludeFiles, "include_dirs", "boolean", "nil") + bIncludeHidden = field(bIncludeFiles, "include_hidden", "boolean", "nil") + bIncludeFiles = field(bIncludeFiles, "include_files", "boolean", "nil") + else + expect(3, bIncludeFiles, "boolean", "nil") + expect(4, bIncludeDirs, "boolean", "nil") + end + bIncludeHidden = bIncludeHidden ~= false bIncludeFiles = bIncludeFiles ~= false bIncludeDirs = bIncludeDirs ~= false local sDir = sLocation @@ -755,7 +764,9 @@ function fs.complete(sPath, sLocation, bIncludeFiles, bIncludeDirs) local tFiles = fs.list(sDir) for n = 1, #tFiles do local sFile = tFiles[n] - if #sFile >= #sName and string.sub(sFile, 1, #sName) == sName then + if #sFile >= #sName and string.sub(sFile, 1, #sName) == sName and ( + bIncludeHidden or sFile:sub(1, 1) ~= "." or sName:sub(1, 1) == "." + ) then local bIsDir = fs.isDir(fs.combine(sDir, sFile)) local sResult = string.sub(sFile, #sName + 1) if bIsDir then @@ -902,7 +913,7 @@ settings.define("paint.default_extension", { settings.define("list.show_hidden", { default = false, - description = [[Show hidden files (those starting with "." in the Lua REPL)]], + description = [[Show hidden files (those starting with "." in the Lua REPL).]], type = "boolean", }) @@ -937,6 +948,11 @@ settings.define("bios.strict_globals", { description = "Prevents assigning variables into a program's environment. Make sure you use the local keyword or assign to _G explicitly.", type = "boolean", }) +settings.define("shell.autocomplete_hidden", { + default = false, + description = [[Autocomplete hidden files and folders (those starting with ".").]], + type = "boolean", +}) if term.isColour() then settings.define("bios.use_multishell", { diff --git a/src/main/resources/data/computercraft/lua/rom/help/changelog.md b/src/main/resources/data/computercraft/lua/rom/help/changelog.md index 1937f7c16..77eaa75a9 100644 --- a/src/main/resources/data/computercraft/lua/rom/help/changelog.md +++ b/src/main/resources/data/computercraft/lua/rom/help/changelog.md @@ -1,10 +1,28 @@ +# New features in CC: Tweaked 1.101.0 + +* Improvee Dutch translation (Quezler) +* Better reporting of fatal computer timeouts in the server log. +* Convert detail providers into a registry, allowing peripheral mods to read item/block details. +* Redesign the metrics system. `/computercraft track` now allows computing aggregates (total, max, avg) on any metric, not just computer time. +* File drag-and-drop now queues a `file_transfer` event on the computer. The + built-in shell or the `import` program must now be running to upload files. +* The `peripheral` now searches for remote peripherals using any peripheral with the `peripheral_hub` type, not just wired modems. +* Add `include_hidden` option to `fs.complete`, which can be used to prevent hidden files showing up in autocomplete results. (IvoLeal72) +* Add `shell.autocomplete_hidden` setting. (IvoLeal72) + +Several bug fixes: +* Prevent `edit`'s "Run" command scrolling the terminal output on smaller + screens. +* Remove some non-determinism in computing item's `nbt` hash. +* Don't set the `Origin` header on outgoing websocket requests. + # New features in CC: Tweaked 1.100.10 * Mention WAV support in speaker help (MCJack123). * Add http programs to the path, even when http is not enabled. Several bug fixes: -* Fix example in textutils.pagedTabulate docs (IvoLeal72). +* Fix example in `textutils.pagedTabulate` docs (IvoLeal72). * Fix help program treating the terminal one line longer than it was. * Send block updates to client when turtle moves (roland-a). * Resolve several monitor issues when running Occulus shaders. @@ -231,7 +249,7 @@ And several bug fixes: # New features in CC: Tweaked 1.96.0 * Use lightGrey for folders within the "list" program. -* Add getLimit to inventory peripherals. +* Add `getItemLimit` to inventory peripherals. * Expose the generic peripheral system to the public API. * Add cc.expect.range (Lupus590). * Allow calling cc.expect directly (MCJack123). diff --git a/src/main/resources/data/computercraft/lua/rom/help/whatsnew.md b/src/main/resources/data/computercraft/lua/rom/help/whatsnew.md index 50ad6318a..874b04d8a 100644 --- a/src/main/resources/data/computercraft/lua/rom/help/whatsnew.md +++ b/src/main/resources/data/computercraft/lua/rom/help/whatsnew.md @@ -1,12 +1,19 @@ -New features in CC: Tweaked 1.100.10 +New features in CC: Tweaked 1.101.0 -* Mention WAV support in speaker help (MCJack123). -* Add http programs to the path, even when http is not enabled. +* Improvee Dutch translation (Quezler) +* Better reporting of fatal computer timeouts in the server log. +* Convert detail providers into a registry, allowing peripheral mods to read item/block details. +* Redesign the metrics system. `/computercraft track` now allows computing aggregates (total, max, avg) on any metric, not just computer time. +* File drag-and-drop now queues a `file_transfer` event on the computer. The + built-in shell or the `import` program must now be running to upload files. +* The `peripheral` now searches for remote peripherals using any peripheral with the `peripheral_hub` type, not just wired modems. +* Add `include_hidden` option to `fs.complete`, which can be used to prevent hidden files showing up in autocomplete results. (IvoLeal72) +* Add `shell.autocomplete_hidden` setting. (IvoLeal72) Several bug fixes: -* Fix example in textutils.pagedTabulate docs (IvoLeal72). -* Fix help program treating the terminal one line longer than it was. -* Send block updates to client when turtle moves (roland-a). -* Resolve several monitor issues when running Occulus shaders. +* Prevent `edit`'s "Run" command scrolling the terminal output on smaller + screens. +* Remove some non-determinism in computing item's `nbt` hash. +* Don't set the `Origin` header on outgoing websocket requests. Type "help changelog" to see the full version history. diff --git a/src/main/resources/data/computercraft/lua/rom/modules/main/cc/audio/dfpwm.lua b/src/main/resources/data/computercraft/lua/rom/modules/main/cc/audio/dfpwm.lua index fd8fa2686..fc8e8fa66 100644 --- a/src/main/resources/data/computercraft/lua/rom/modules/main/cc/audio/dfpwm.lua +++ b/src/main/resources/data/computercraft/lua/rom/modules/main/cc/audio/dfpwm.lua @@ -27,9 +27,9 @@ application or development builds of [FFmpeg]. @see guide!speaker_audio Gives a more general introduction to audio processing and the speaker. @see speaker.playAudio To play the decoded audio data. +@since 1.100.0 @usage Reads "data/example.dfpwm" in chunks, decodes them and then doubles the speed of the audio. The resulting audio is then re-encoded and saved to "speedy.dfpwm". This processed audio can then be played with the `speaker` program. -@since 1.100.0 ```lua local dfpwm = require("cc.audio.dfpwm") 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 4bdc24674..86a061c42 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 @@ -34,7 +34,11 @@ local completion = require "cc.completion" -- @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) + return fs.complete(text, shell.dir(), { + include_files = true, + include_dirs = false, + include_hidden = settings.get("shell.autocomplete_hidden"), + }) end --- Complete the name of a directory relative to the current working directory. @@ -43,7 +47,11 @@ end -- @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) + return fs.complete(text, shell.dir(), { + include_files = false, + include_dirs = true, + include_hidden = settings.get("shell.autocomplete_hidden"), + }) end --- Complete the name of a file or directory relative to the current working @@ -55,7 +63,11 @@ end -- @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) + local results = fs.complete(text, shell.dir(), { + include_files = true, + include_dirs = true, + include_hidden = settings.get("shell.autocomplete_hidden"), + }) if add_space then for n = 1, #results do local result = results[n] diff --git a/src/main/resources/data/computercraft/lua/rom/programs/shell.lua b/src/main/resources/data/computercraft/lua/rom/programs/shell.lua index f2b650d03..6add0424f 100644 --- a/src/main/resources/data/computercraft/lua/rom/programs/shell.lua +++ b/src/main/resources/data/computercraft/lua/rom/programs/shell.lua @@ -329,9 +329,14 @@ function shell.programs(include_hidden) end local function completeProgram(sLine) + local bIncludeHidden = settings.get("shell.autocomplete_hidden") if #sLine > 0 and (sLine:find("/") or sLine:find("\\")) then -- Add programs from the root - return fs.complete(sLine, sDir, true, false) + return fs.complete(sLine, sDir, { + include_files = true, + include_dirs = false, + include_hidden = bIncludeHidden, + }) else local tResults = {} @@ -349,7 +354,11 @@ local function completeProgram(sLine) end -- Add all subdirectories. We don't include files as they will be added in the block below - local tDirs = fs.complete(sLine, sDir, false, false) + local tDirs = fs.complete(sLine, sDir, { + include_files = false, + include_dirs = false, + include_hidden = bIncludeHidden, + }) for i = 1, #tDirs do local sResult = tDirs[i] if not tSeen[sResult] then diff --git a/src/test/resources/test-rom/spec/apis/fs_spec.lua b/src/test/resources/test-rom/spec/apis/fs_spec.lua index 32503598e..7bcab9e86 100644 --- a/src/test/resources/test-rom/spec/apis/fs_spec.lua +++ b/src/test/resources/test-rom/spec/apis/fs_spec.lua @@ -10,6 +10,46 @@ describe("The fs library", function() expect.error(fs.complete, "", "", 1):eq("bad argument #3 (expected boolean, got number)") expect.error(fs.complete, "", "", true, 1):eq("bad argument #4 (expected boolean, got number)") end) + + describe("include_hidden", function() + local dir = "tmp/hidden" + local function setup_tree() + fs.delete(dir) + fs.makeDir(dir) + fs.open(dir .. "/file.txt", "w").close() + fs.open(dir .. "/.hidden.txt", "w").close() + end + + it("hides hidden files", function() + setup_tree() + local opts = { include_files = true, include_dirs = false, include_hidden = false } + + expect(fs.complete("", dir, opts)):same { "../", "file.txt" } + expect(fs.complete(dir .. "/", "", opts)):same { "file.txt" } + end) + + it("shows hidden files when typing a dot", function() + setup_tree() + local opts = { include_files = true, include_dirs = false, include_hidden = false } + + expect(fs.complete(".", dir, opts)):same { "./", "hidden.txt" } + expect(fs.complete(dir .. "/.", "", opts)):same { "hidden.txt" } + + -- Also test + expect(fs.complete(dir .. "/file", "", opts)):same { ".txt" } + expect(fs.complete(dir .. "/file.", "", opts)):same { "txt" } + expect(fs.complete("file", dir, opts)):same { ".txt" } + expect(fs.complete("file.", dir, opts)):same { "txt" } + end) + + it("shows hidden files when include_hidden is true", function() + setup_tree() + local opts = { include_files = true, include_dirs = false, include_hidden = true } + + expect(fs.complete("", dir, opts)):same { "../", ".hidden.txt", "file.txt" } + expect(fs.complete(dir .. "/", "", opts)):same { ".hidden.txt", "file.txt" } + end) + end) end) describe("fs.isDriveRoot", function()