From 5dfc401b453d97bbe31b413c18fbfc4ae7cb8833 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Sun, 18 May 2025 10:05:27 +0100 Subject: [PATCH 1/9] Update build plugin versions --- gradle/libs.versions.toml | 6 +++--- .../client/render/TurtleBlockEntityRenderer.java | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 948f8a959..7dd857e81 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -58,8 +58,8 @@ jmh = "1.37" # Build tools cctJavadoc = "1.8.4" -checkstyle = "10.21.4" -errorProne-core = "2.37.0" +checkstyle = "10.23.1" +errorProne-core = "2.38.0" errorProne-plugin = "4.1.0" fabric-loom = "1.10.4" githubRelease = "2.5.2" @@ -69,7 +69,7 @@ illuaminate = "0.1.0-83-g1131f68" lwjgl = "3.3.3" minotaur = "2.8.7" modDevGradle = "2.0.78" -nullAway = "0.12.4" +nullAway = "0.12.7" shadow = "8.3.1" spotless = "7.0.2" taskTree = "2.1.1" diff --git a/projects/common/src/client/java/dan200/computercraft/client/render/TurtleBlockEntityRenderer.java b/projects/common/src/client/java/dan200/computercraft/client/render/TurtleBlockEntityRenderer.java index 48a1e9895..fea18d967 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/render/TurtleBlockEntityRenderer.java +++ b/projects/common/src/client/java/dan200/computercraft/client/render/TurtleBlockEntityRenderer.java @@ -66,8 +66,8 @@ public class TurtleBlockEntityRenderer implements BlockEntityRenderer Date: Sun, 25 May 2025 16:24:26 -0400 Subject: [PATCH 2/9] Add notes about minor changed file handle behavior in 1.109.0 (#2203) --- .../dan200/computercraft/core/apis/handles/AbstractHandle.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/projects/core/src/main/java/dan200/computercraft/core/apis/handles/AbstractHandle.java b/projects/core/src/main/java/dan200/computercraft/core/apis/handles/AbstractHandle.java index 395f27d45..05b6a9820 100644 --- a/projects/core/src/main/java/dan200/computercraft/core/apis/handles/AbstractHandle.java +++ b/projects/core/src/main/java/dan200/computercraft/core/apis/handles/AbstractHandle.java @@ -76,6 +76,7 @@ public abstract class AbstractHandle { * @cc.treturn [2] nil If seeking failed. * @cc.treturn string The reason seeking failed. * @cc.since 1.80pr1.9 + * @cc.changed 1.109.0 Now available on all file handles, not just binary-mode handles. */ public Object @Nullable [] seek(Optional whence, Optional offset) throws LuaException { checkOpen(); @@ -179,6 +180,8 @@ public abstract class AbstractHandle { * @throws LuaException If the file has been closed. * @cc.treturn string|nil The remaining contents of the file, or {@code nil} in the event of an error. * @cc.since 1.80pr1 + * @cc.changed 1.109.0 Binary-mode handles are now consistent with non-binary files, and return an empty string at + * the end of the file, rather than {@code nil}. */ public Object @Nullable [] readAll() throws LuaException { checkOpen(); From ee3b1343b5c795457521c71bfb61aca88efd8663 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Sun, 25 May 2025 22:28:40 +0100 Subject: [PATCH 3/9] Handle keyboard layouts for our computer shortcuts Convert GLFW's key codes back to their actual key, and then use that when checking keyboard shortcuts. We *don't* do this for the paste key, just to be consistent with vanilla's behaviour. Fixes #2207. --- .../client/gui/KeyConverter.java | 39 +++++++++++++++++++ .../client/gui/widgets/TerminalWidget.java | 5 ++- 2 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 projects/common/src/client/java/dan200/computercraft/client/gui/KeyConverter.java diff --git a/projects/common/src/client/java/dan200/computercraft/client/gui/KeyConverter.java b/projects/common/src/client/java/dan200/computercraft/client/gui/KeyConverter.java new file mode 100644 index 000000000..99ee64077 --- /dev/null +++ b/projects/common/src/client/java/dan200/computercraft/client/gui/KeyConverter.java @@ -0,0 +1,39 @@ +// SPDX-FileCopyrightText: 2025 The CC: Tweaked Developers +// +// SPDX-License-Identifier: MPL-2.0 + +package dan200.computercraft.client.gui; + +import org.lwjgl.glfw.GLFW; + +/** + * Supports for converting/translating key codes. + */ +public class KeyConverter { + /** + * GLFW's key events refer to the physical key code, rather than the "actual" key code (with keyboard layout + * applied). + *

+ * This makes sense for WASD-style input, but is a right pain for keyboard shortcuts — this function attempts to + * translate those keys back to their "actual" key code. See also + * this discussion on GLFW's GitHub. + * + * @param key The current key code. + * @param scanCode The current scan code. + * @return The translated key code. + */ + public static int physicalToActual(int key, int scanCode) { + var name = GLFW.glfwGetKeyName(key, scanCode); + if (name == null || name.length() != 1) return key; + + // If we've got a single character key name, try to translate it to a + var character = name.charAt(0); + + // 0-9 and A-Z map directly to their GLFW key (they're the same ASCII code). + if ((character >= '0' && character <= '9') || (character >= 'A' && character <= 'Z')) return character; + // a-z map to GLFW_KEY_{A,Z} + if (character >= 'a' && character <= 'z') return GLFW.GLFW_KEY_A + (character - 'a'); + + return key; + } +} diff --git a/projects/common/src/client/java/dan200/computercraft/client/gui/widgets/TerminalWidget.java b/projects/common/src/client/java/dan200/computercraft/client/gui/widgets/TerminalWidget.java index 2bf9a4494..b2e14cd88 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/gui/widgets/TerminalWidget.java +++ b/projects/common/src/client/java/dan200/computercraft/client/gui/widgets/TerminalWidget.java @@ -5,6 +5,7 @@ package dan200.computercraft.client.gui.widgets; import com.mojang.blaze3d.vertex.Tesselator; +import dan200.computercraft.client.gui.KeyConverter; import dan200.computercraft.client.render.RenderTypes; import dan200.computercraft.client.render.text.FixedWidthFontRenderer; import dan200.computercraft.core.terminal.Terminal; @@ -85,7 +86,7 @@ public class TerminalWidget extends AbstractWidget { } if ((modifiers & GLFW.GLFW_MOD_CONTROL) != 0) { - switch (key) { + switch (KeyConverter.physicalToActual(key, scancode)) { case GLFW.GLFW_KEY_T -> { if (terminateTimer < 0) terminateTimer = 0; } @@ -121,7 +122,7 @@ public class TerminalWidget extends AbstractWidget { computer.keyUp(key); } - switch (key) { + switch (KeyConverter.physicalToActual(key, scancode)) { case GLFW.GLFW_KEY_T -> terminateTimer = -1; case GLFW.GLFW_KEY_R -> rebootTimer = -1; case GLFW.GLFW_KEY_S -> shutdownTimer = -1; From 876fd8ddb805365c33942afb81d6da7cbd0cbca5 Mon Sep 17 00:00:00 2001 From: SpartanSoftware Date: Sat, 31 May 2025 02:46:03 -0500 Subject: [PATCH 4/9] Fix 0 being treated as a valid colour (#2211) --- .../data/computercraft/lua/rom/apis/colors.lua | 2 +- .../data/computercraft/lua/rom/apis/window.lua | 2 +- .../test/resources/test-rom/spec/apis/colors_spec.lua | 1 + .../test/resources/test-rom/spec/apis/window_spec.lua | 10 ++++++++++ 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/projects/core/src/main/resources/data/computercraft/lua/rom/apis/colors.lua b/projects/core/src/main/resources/data/computercraft/lua/rom/apis/colors.lua index b98ff8d75..f013a29e1 100644 --- a/projects/core/src/main/resources/data/computercraft/lua/rom/apis/colors.lua +++ b/projects/core/src/main/resources/data/computercraft/lua/rom/apis/colors.lua @@ -371,7 +371,7 @@ function toBlit(color) local hex = color_hex_lookup[color] if hex then return hex end - if color < 0 or color > 0xffff then error("Colour out of range", 2) end + if color < 1 or color > 0xffff then error("Colour out of range", 2) end return string.format("%x", math.floor(math.log(color, 2))) end diff --git a/projects/core/src/main/resources/data/computercraft/lua/rom/apis/window.lua b/projects/core/src/main/resources/data/computercraft/lua/rom/apis/window.lua index 7be7aebaf..5b5678d63 100644 --- a/projects/core/src/main/resources/data/computercraft/lua/rom/apis/window.lua +++ b/projects/core/src/main/resources/data/computercraft/lua/rom/apis/window.lua @@ -65,7 +65,7 @@ local function parse_color(color) return expect(1, color, "number") end - if color < 0 or color > 0xffff then error("Colour out of range", 3) end + if color < 1 or color > 0xffff then error("Colour out of range", 3) end return 2 ^ math.floor(math.log(color, 2)) end diff --git a/projects/core/src/test/resources/test-rom/spec/apis/colors_spec.lua b/projects/core/src/test/resources/test-rom/spec/apis/colors_spec.lua index 46c77dcf8..8f50b0d56 100644 --- a/projects/core/src/test/resources/test-rom/spec/apis/colors_spec.lua +++ b/projects/core/src/test/resources/test-rom/spec/apis/colors_spec.lua @@ -94,6 +94,7 @@ describe("The colors library", function() end) it("errors on out-of-range colours", function() + expect.error(colors.toBlit, 0):eq("Colour out of range") expect.error(colors.toBlit, -120):eq("Colour out of range") expect.error(colors.toBlit, 0x10000):eq("Colour out of range") end) diff --git a/projects/core/src/test/resources/test-rom/spec/apis/window_spec.lua b/projects/core/src/test/resources/test-rom/spec/apis/window_spec.lua index 89e4e2993..4ad3d797c 100644 --- a/projects/core/src/test/resources/test-rom/spec/apis/window_spec.lua +++ b/projects/core/src/test/resources/test-rom/spec/apis/window_spec.lua @@ -59,6 +59,16 @@ describe("The window library", function() expect.error(w.setTextColour, nil):eq("bad argument #1 (number expected, got nil)") expect.error(w.setTextColour, -5):eq("Colour out of range") + expect.error(w.setTextColour, 0):eq("Colour out of range") + expect.error(w.setTextColour, 0x10000):eq("Colour out of range") + end) + + it("accepts valid colours", function() + local w = mk() + for i = 0, 15 do + w.setBackgroundColour(2 ^ i) + expect(w.getBackgroundColour()):eq(2 ^ i) + end end) it("supports invalid combined colours", function() From b5c0c6e104c626fbfb6276b01bf0882603fb5d09 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Mon, 2 Jun 2025 08:58:43 +0100 Subject: [PATCH 5/9] Fix out-of-bounds when pasting too-long text Used a `<=` instead of a `<`! How did I mess this up!? Fixes #2209 --- .../client/gui/KeyConverter.java | 3 +- .../computercraft/core/util/StringUtil.java | 2 +- .../core/util/StringUtilTest.java | 36 +++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 projects/core/src/test/java/dan200/computercraft/core/util/StringUtilTest.java diff --git a/projects/common/src/client/java/dan200/computercraft/client/gui/KeyConverter.java b/projects/common/src/client/java/dan200/computercraft/client/gui/KeyConverter.java index 99ee64077..f99a254bf 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/gui/KeyConverter.java +++ b/projects/common/src/client/java/dan200/computercraft/client/gui/KeyConverter.java @@ -26,7 +26,8 @@ public class KeyConverter { var name = GLFW.glfwGetKeyName(key, scanCode); if (name == null || name.length() != 1) return key; - // If we've got a single character key name, try to translate it to a + // If we've got a single character as the key name, treat that as the ASCII value of the key, + // and map that back to a key code. var character = name.charAt(0); // 0-9 and A-Z map directly to their GLFW key (they're the same ASCII code). diff --git a/projects/core/src/main/java/dan200/computercraft/core/util/StringUtil.java b/projects/core/src/main/java/dan200/computercraft/core/util/StringUtil.java index 234127244..2916929f1 100644 --- a/projects/core/src/main/java/dan200/computercraft/core/util/StringUtil.java +++ b/projects/core/src/main/java/dan200/computercraft/core/util/StringUtil.java @@ -120,7 +120,7 @@ public final class StringUtil { var idx = 0; var iterator = clipboard.codePoints().iterator(); - while (iterator.hasNext() && idx <= output.length) { + while (iterator.hasNext() && idx < output.length) { var chr = unicodeToTerminal(iterator.next()); if (chr < 0) continue; // Strip out unconvertible characters if (!isTypableChar(chr)) break; // Stop at untypable ones. diff --git a/projects/core/src/test/java/dan200/computercraft/core/util/StringUtilTest.java b/projects/core/src/test/java/dan200/computercraft/core/util/StringUtilTest.java new file mode 100644 index 000000000..69e9d3c07 --- /dev/null +++ b/projects/core/src/test/java/dan200/computercraft/core/util/StringUtilTest.java @@ -0,0 +1,36 @@ +// SPDX-FileCopyrightText: 2025 The CC: Tweaked Developers +// +// SPDX-License-Identifier: MPL-2.0 + +package dan200.computercraft.core.util; + +import dan200.computercraft.api.lua.LuaValues; +import dan200.computercraft.test.core.ReplaceUnderscoresDisplayNameGenerator; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@DisplayNameGeneration(ReplaceUnderscoresDisplayNameGenerator.class) +class StringUtilTest { + @ParameterizedTest + @ValueSource(strings = { "hello\nworld", "hello\n\rworld", "hello\rworld" }) + public void getClipboardString_returns_a_single_line(String input) { + var result = StringUtil.getClipboardString(input); + assertEquals(LuaValues.encode("hello"), result); + } + + @Test + public void getClipboardString_limits_length() { + var input = "abcdefghijklmnop".repeat(50); + var result = StringUtil.getClipboardString(input); + assertEquals(StringUtil.MAX_PASTE_LENGTH, result.limit()); + + assertEquals( + LuaValues.encode(input.substring(0, StringUtil.MAX_PASTE_LENGTH)), + result + ); + } +} From 2557dd0af91f00cd849fcfee2492447176f21fab Mon Sep 17 00:00:00 2001 From: Wojbie Date: Tue, 3 Jun 2025 01:03:02 +0200 Subject: [PATCH 6/9] Update motd path in startup.lua Removes situations where shell resolution caused arbitrary program called `motd` at root get executed instead of expected /rom one. --- .../src/main/resources/data/computercraft/lua/rom/startup.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/core/src/main/resources/data/computercraft/lua/rom/startup.lua b/projects/core/src/main/resources/data/computercraft/lua/rom/startup.lua index f3b9f7a08..a14e999ef 100644 --- a/projects/core/src/main/resources/data/computercraft/lua/rom/startup.lua +++ b/projects/core/src/main/resources/data/computercraft/lua/rom/startup.lua @@ -191,7 +191,7 @@ end -- Show MOTD if settings.get("motd.enable") then - shell.run("motd") + shell.run("/rom/programs/motd") end -- Run the user created startup, either from disk drives or the root From 1c5128242624df4b4b8fe947fad677a581615673 Mon Sep 17 00:00:00 2001 From: LorneHyde <60600315+LorneHyde@users.noreply.github.com> Date: Sun, 8 Jun 2025 20:55:14 +0100 Subject: [PATCH 7/9] Fix syntax highlighting for strings ending in an escaped backslash (#2194) --- .../computercraft/lua/rom/programs/edit.lua | 37 +++++++++++++++---- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/projects/core/src/main/resources/data/computercraft/lua/rom/programs/edit.lua b/projects/core/src/main/resources/data/computercraft/lua/rom/programs/edit.lua index e05ec1766..d5207de87 100644 --- a/projects/core/src/main/resources/data/computercraft/lua/rom/programs/edit.lua +++ b/projects/core/src/main/resources/data/computercraft/lua/rom/programs/edit.lua @@ -214,15 +214,38 @@ local function tryWrite(sLine, regex, colour) return nil end +local function tryWriteString(sLine) + local quotationChar = string.sub(sLine, 1, 1) + if quotationChar ~= '"' and quotationChar ~= "'" then + return nil + end + + -- Scan through the rest of the string, skipping over escapes, + -- until we find the closing quote. + local i = 2 + while i <= #sLine do + local nextChar = string.sub(sLine, i, i) + if nextChar == "\\" then + i = i + 2 -- Skip over escapes + elseif nextChar == quotationChar then + break + else + i = i + 1 + end + end + + term.setTextColor(stringColour) + term.write(string.sub(sLine, 1, i)) + term.setTextColor(textColour) + return string.sub(sLine, i + 1) +end + local function writeHighlighted(sLine) while #sLine > 0 do sLine = tryWrite(sLine, "^%-%-%[%[.-%]%]", commentColour) or tryWrite(sLine, "^%-%-.*", commentColour) or - tryWrite(sLine, "^\"\"", stringColour) or - tryWrite(sLine, "^\".-[^\\]\"", stringColour) or - tryWrite(sLine, "^\'\'", stringColour) or - tryWrite(sLine, "^\'.-[^\\]\'", stringColour) or + tryWriteString(sLine) or tryWrite(sLine, "^%[%[.-%]%]", stringColour) or tryWrite(sLine, "^[%w_]+", function(match) if tKeywords[match] then @@ -352,7 +375,7 @@ local tMenuFuncs = { if bReadOnly then set_status("Access denied", false) else - local ok, _, fileerr = save(sPath, function(file) + local ok, _, fileerr = save(sPath, function(file) for _, sLine in ipairs(tLines) do file.write(sLine .. "\n") end @@ -547,7 +570,7 @@ local function acceptCompletion() -- Append the completion local sCompletion = tCompletions[nCompletion] tLines[y] = tLines[y] .. sCompletion - setCursor(x + #sCompletion , y) + setCursor(x + #sCompletion, y) end end @@ -805,7 +828,7 @@ while bRunning do -- Input text local sLine = tLines[y] tLines[y] = string.sub(sLine, 1, x - 1) .. param .. string.sub(sLine, x) - setCursor(x + #param , y) + setCursor(x + #param, y) end elseif sEvent == "mouse_click" then From ff363dca5a6a1448ec198cd16b3f6852f81c1468 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Sat, 14 Jun 2025 18:44:16 +0100 Subject: [PATCH 8/9] Move sidebar_advanced.png down by one pixel Apparently this has been broken since the file was created in 53546b9f57d9acaa4cdca14ae00eaf68ce8c50bd!? I'm sure I fixed this before, but maybe that was a different but similar issue >_>. --- .../textures/gui/sidebar_advanced.png | Bin 148 -> 136 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/projects/common/src/main/resources/assets/computercraft/textures/gui/sidebar_advanced.png b/projects/common/src/main/resources/assets/computercraft/textures/gui/sidebar_advanced.png index 8d96a99c8bc834e562611a297c5467842f961633..ad80081cb61cb0e2dfa8c12811e9b0ceb1bf7591 100644 GIT binary patch delta 107 zcmbQj*ugkKCB@&<#W6(Vd~!+yQ)=qd|2!#7ZW@38-@BX1GeyE_BBR0qrY~$=2Tor% z_b_Ye3}QCmQ55fya#D7Vcz16v_j4JmlJ1=823nfwflq|ovQiuvln;q~HfDEKW?*1o N@O1TaS?83{1OTsxCi4IQ delta 119 zcmeBRoWeLkr6AhV#WAE}PI8JzN_;Qj9o15xWovxTeCnj(tYRCuu^WUgAg@NJX X5;5P%%Az|A3=9mOu6{1-oD!M Date: Sun, 15 Jun 2025 13:18:45 +0100 Subject: [PATCH 9/9] Use lexer for edit's syntax highlighting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is slightly more accurate for long strings and comments. Note that we still work a line at a time (and in a non-incremental manner), so doesn't actaully support multi-line strings (#1396). We do now treat goto as a keyword (fixes #1653). We don't currently support labels — those *technically* aren't a token (`:: foo --[[ a comment ]] ::` is a valid label!), but maybe we could special-case the short `::foo::` form. --- .../modules/main/cc/internal/syntax/lexer.lua | 4 +- .../computercraft/lua/rom/programs/edit.lua | 122 +++++++----------- .../modules/cc/internal/syntax/lexer_spec.md | 4 +- 3 files changed, 53 insertions(+), 77 deletions(-) diff --git a/projects/core/src/main/resources/data/computercraft/lua/rom/modules/main/cc/internal/syntax/lexer.lua b/projects/core/src/main/resources/data/computercraft/lua/rom/modules/main/cc/internal/syntax/lexer.lua index 9faf3b5a9..2d8d91938 100644 --- a/projects/core/src/main/resources/data/computercraft/lua/rom/modules/main/cc/internal/syntax/lexer.lua +++ b/projects/core/src/main/resources/data/computercraft/lua/rom/modules/main/cc/internal/syntax/lexer.lua @@ -238,7 +238,7 @@ local function lex_token(context, str, pos) if end_pos then return tokens.STRING, end_pos end context.report(errors.unfinished_long_string, pos, boundary_pos, boundary_pos - pos) - return tokens.ERROR, #str + return tokens.STRING, #str elseif pos + 1 == boundary_pos then -- Just a "[" return tokens.OSQUARE, pos else -- Malformed long string, for instance "[=" @@ -260,7 +260,7 @@ local function lex_token(context, str, pos) if end_pos then return tokens.COMMENT, end_pos end context.report(errors.unfinished_long_comment, pos, boundary_pos, boundary_pos - comment_pos) - return tokens.ERROR, #str + return tokens.COMMENT, #str end end diff --git a/projects/core/src/main/resources/data/computercraft/lua/rom/programs/edit.lua b/projects/core/src/main/resources/data/computercraft/lua/rom/programs/edit.lua index d5207de87..0e7a131e8 100644 --- a/projects/core/src/main/resources/data/computercraft/lua/rom/programs/edit.lua +++ b/projects/core/src/main/resources/data/computercraft/lua/rom/programs/edit.lua @@ -175,86 +175,62 @@ local function save(_sPath, fWrite) return ok, err, fileerr end -local tKeywords = { - ["and"] = true, - ["break"] = true, - ["do"] = true, - ["else"] = true, - ["elseif"] = true, - ["end"] = true, - ["false"] = true, - ["for"] = true, - ["function"] = true, - ["if"] = true, - ["in"] = true, - ["local"] = true, - ["nil"] = true, - ["not"] = true, - ["or"] = true, - ["repeat"] = true, - ["return"] = true, - ["then"] = true, - ["true"] = true, - ["until"] = true, - ["while"] = true, + +local tokens = require "cc.internal.syntax.parser".tokens +local lex_one = require "cc.internal.syntax.lexer".lex_one + +local token_colours = { + [tokens.STRING] = stringColour, + [tokens.COMMENT] = commentColour, + -- Keywords + [tokens.AND] = keywordColour, + [tokens.BREAK] = keywordColour, + [tokens.DO] = keywordColour, + [tokens.ELSE] = keywordColour, + [tokens.ELSEIF] = keywordColour, + [tokens.END] = keywordColour, + [tokens.FALSE] = keywordColour, + [tokens.FOR] = keywordColour, + [tokens.FUNCTION] = keywordColour, + [tokens.GOTO] = keywordColour, + [tokens.IF] = keywordColour, + [tokens.IN] = keywordColour, + [tokens.LOCAL] = keywordColour, + [tokens.NIL] = keywordColour, + [tokens.NOT] = keywordColour, + [tokens.OR] = keywordColour, + [tokens.REPEAT] = keywordColour, + [tokens.RETURN] = keywordColour, + [tokens.THEN] = keywordColour, + [tokens.TRUE] = keywordColour, + [tokens.UNTIL] = keywordColour, + [tokens.WHILE] = keywordColour, } - -local function tryWrite(sLine, regex, colour) - local match = string.match(sLine, regex) - if match then - if type(colour) == "number" then - term.setTextColour(colour) - else - term.setTextColour(colour(match)) - end - term.write(match) - term.setTextColour(textColour) - return string.sub(sLine, #match + 1) - end - return nil +-- Fill in the remaining tokens. +for _, token in pairs(tokens) do + if not token_colours[token] then token_colours[token] = textColour end end -local function tryWriteString(sLine) - local quotationChar = string.sub(sLine, 1, 1) - if quotationChar ~= '"' and quotationChar ~= "'" then - return nil - end +local lex_context = { line = function() end, report = function() end } - -- Scan through the rest of the string, skipping over escapes, - -- until we find the closing quote. - local i = 2 - while i <= #sLine do - local nextChar = string.sub(sLine, i, i) - if nextChar == "\\" then - i = i + 2 -- Skip over escapes - elseif nextChar == quotationChar then - break - else - i = i + 1 +local function writeHighlighted(line) + local pos, colour = 1, nil + + while true do + local token, _, finish = lex_one(lex_context, line, pos) + if not token then break end + + local new_colour = token_colours[token] + if new_colour ~= colour then + term.setTextColor(new_colour) + colour = new_colour end + + term.write(line:sub(pos, finish)) + pos = finish + 1 end - term.setTextColor(stringColour) - term.write(string.sub(sLine, 1, i)) - term.setTextColor(textColour) - return string.sub(sLine, i + 1) -end - -local function writeHighlighted(sLine) - while #sLine > 0 do - sLine = - tryWrite(sLine, "^%-%-%[%[.-%]%]", commentColour) or - tryWrite(sLine, "^%-%-.*", commentColour) or - tryWriteString(sLine) or - tryWrite(sLine, "^%[%[.-%]%]", stringColour) or - tryWrite(sLine, "^[%w_]+", function(match) - if tKeywords[match] then - return keywordColour - end - return textColour - end) or - tryWrite(sLine, "^[^%w_]", textColour) - end + term.write(line:sub(pos)) end local tCompletions diff --git a/projects/core/src/test/resources/test-rom/spec/modules/cc/internal/syntax/lexer_spec.md b/projects/core/src/test/resources/test-rom/spec/modules/cc/internal/syntax/lexer_spec.md index 9d5af0531..e73c4f62f 100644 --- a/projects/core/src/test/resources/test-rom/spec/modules/cc/internal/syntax/lexer_spec.md +++ b/projects/core/src/test/resources/test-rom/spec/modules/cc/internal/syntax/lexer_spec.md @@ -67,7 +67,7 @@ This comment was never finished. 1 | --[=[ | ^^^^^ Comment was started here. We expected a closing delimiter (]=]) somewhere after this comment was started. -1:1-1:5 ERROR --[=[ +1:1-1:5 COMMENT --[=[ ``` Nested comments are rejected, just as Lua 5.1 does: @@ -191,7 +191,7 @@ This string was never finished. 1 | return [[ | ^^ String was started here. We expected a closing delimiter (]]) somewhere after this string was started. -1:8-1:9 ERROR [[ +1:8-1:9 STRING [[ ``` We also handle malformed opening strings: