mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-11-02 14:43:00 +00:00
Merge branch 'mc-1.21.x' into mc-1.21.y
This commit is contained in:
@@ -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<String> whence, Optional<Long> 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();
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -175,63 +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 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
|
||||
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,
|
||||
}
|
||||
-- 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 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
|
||||
tryWrite(sLine, "^%[%[.-%]%]", stringColour) or
|
||||
tryWrite(sLine, "^[%w_]+", function(match)
|
||||
if tKeywords[match] then
|
||||
return keywordColour
|
||||
end
|
||||
return textColour
|
||||
end) or
|
||||
tryWrite(sLine, "^[^%w_]", textColour)
|
||||
local lex_context = { line = function() end, report = function() end }
|
||||
|
||||
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.write(line:sub(pos))
|
||||
end
|
||||
|
||||
local tCompletions
|
||||
@@ -352,7 +351,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 +546,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 +804,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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user