Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
91640c3
Don't reset the editor scroll position on every edit
claude Oct 17, 2026
776430e
Keep the cursor visible in the editor
claude Oct 17, 2026
36b7e7a
Don't lose editor focus on unhandled keys
claude Oct 17, 2026
89d189e
Keep trailing newlines when syncing scripts
claude Oct 17, 2026
bb7247d
Start editor line numbers at 1
claude Oct 17, 2026
136e9f1
Don't wrap editor text below the scrollbar
claude Oct 17, 2026
6e9c2e0
Make page up and page down move through the editor
claude Oct 17, 2026
0fb7488
Keep the open script when the scripting terminal is resized
claude Oct 17, 2026
1030ef3
Show what variable card would bind to (#83)
rubensworks Oct 18, 2026
fe0388e
Avoid long disk labels to overlap with disk selector (#84)
rubensworks Oct 18, 2026
968d44c
Use the macOS keys for moving by word and line in the script editor
claude Oct 18, 2026
076603e
Don't draw the selection over the bottom border of the script editor
claude Oct 18, 2026
c913def
Don't block dragging items over slots in the scripting terminal
claude Oct 18, 2026
4145642
Don't put the cursor on the hidden row below the script editor's last…
claude Oct 18, 2026
afcdb74
Merge pull request #77 from CyclopsMC/terminal-ux/1-editor-fixes
rubensworks Oct 18, 2026
7dea53d
Add undo and redo to the script editor
claude Oct 17, 2026
1ffe4be
Don't echo synced scripts back to the client
claude Oct 17, 2026
89a1342
Write scripts to disk atomically
claude Oct 17, 2026
9622668
Show external script changes in the open editor
claude Oct 17, 2026
63e7aa2
Only apply external changes when the file watcher reloads scripts
claude Oct 18, 2026
926fd65
Notice all externally created script files
claude Oct 18, 2026
fb034c8
Indent with tab in the script editor
claude Oct 17, 2026
f99fae6
Keep indentation on enter in the script editor
claude Oct 17, 2026
ddb91eb
Highlight matching brackets in the script editor
claude Oct 17, 2026
6e95b6a
Add find and go to line to the script editor
claude Oct 17, 2026
37205c1
Add toggle comment and move lines to the script editor
claude Oct 17, 2026
738511b
Scroll the script editor while drag-selecting
claude Oct 17, 2026
c840233
Make the indent size of the script editor configurable
claude Oct 18, 2026
4a9c280
Add toolbar buttons for editor actions
claude Oct 18, 2026
8cf7fdc
Make the script editor shortcuts rebindable
claude Oct 18, 2026
5a82006
Merge pull request #85 from CyclopsMC/terminal-ux-clean/2-undo-and-sync
rubensworks Oct 18, 2026
db8c8e6
Improve syntax highlighting in the script editor
claude Oct 17, 2026
bf7170f
Document the script editor shortcuts in the info book
claude Oct 18, 2026
7c6fa71
Show syntax errors in the script editor
claude Oct 17, 2026
f105ac8
Only re-wrap and re-highlight the editor text when it changes
claude Oct 17, 2026
d5fe10e
Show full script paths when hovering the script list
claude Oct 17, 2026
d88a8f3
Allow renaming scripts in the scripting terminal
claude Oct 17, 2026
bfc3760
Add a focus mode to enlarge the script editor
claude Oct 18, 2026
8b0ec43
Fix the scripts directory path in the info book
claude Oct 18, 2026
120ad29
Add a button to open the scripts folder of a disk
claude Oct 18, 2026
51d352b
Merge pull request #86 from CyclopsMC/terminal-ux-clean/3-editing-fea…
rubensworks Oct 18, 2026
e117d1b
Fix wrong operator names in the info book
claude Oct 18, 2026
ee16f1a
Wrap long lines at spaces and punctuation in the script editor
claude Oct 18, 2026
0989a66
Add completion of idContext.ops in the script editor
claude Oct 18, 2026
62276da
Only bind variable cards to top-level declarations
claude Oct 18, 2026
ad76d8b
Show the last evaluation of the bound card in the scripting terminal
claude Oct 18, 2026
77d5d2b
Show the signature of idContext.ops calls in the script editor
claude Oct 18, 2026
b62d74e
Fix broken JavaScript examples in the info book
claude Oct 18, 2026
8c46675
Merge pull request #92 from CyclopsMC/fix/infobook-operator-names
rubensworks Oct 19, 2026
699853d
Fix display panels not recovering from script errors after external e…
rubensworks Oct 19, 2026
0c8cd80
Show syntax error tooltips below their line, pointing at the error
claude Oct 19, 2026
9508b99
Make the script editor scrollbar narrower
claude Oct 19, 2026
59bbc1e
Show syntax errors when hovering their scrollbar mark
claude Oct 19, 2026
accc4fe
Hide JEI in the focus mode of the scripting terminal
claude Oct 19, 2026
0a2a0f2
Keep JEI's buttons clear of the focus mode editor
claude Oct 19, 2026
bcb3259
Open new scripts after creating them in the terminal
claude Oct 18, 2026
b968d83
Merge pull request #87 from CyclopsMC/terminal-ux-clean/4-feedback
rubensworks Oct 19, 2026
99af7bd
Merge pull request #88 from CyclopsMC/terminal-ux-clean/5-highlightin…
rubensworks Oct 19, 2026
f6c598b
Merge remote-tracking branch 'origin/master-1.21-lts' into fix/open-n…
claude Oct 19, 2026
973ac6e
Warn that renaming a script breaks its variable cards
claude Oct 19, 2026
48613ed
Add a rebindable hotkey to enlarge the script editor
claude Oct 19, 2026
aa707d8
Merge pull request #89 from CyclopsMC/terminal-ux-clean/6-layout-and-…
rubensworks Oct 19, 2026
4ded9d4
Merge pull request #90 from CyclopsMC/terminal-ux-clean/7-open-folder
rubensworks Oct 19, 2026
adcaf7c
Merge pull request #93 from CyclopsMC/terminal-ux-clean/8-wrap-and-cr…
rubensworks Oct 19, 2026
d27867b
Merge pull request #94 from CyclopsMC/terminal-ux-clean/9-toplevel-bi…
rubensworks Oct 19, 2026
a27befb
Merge remote-tracking branch 'origin/master-1.21-lts' into fix/open-n…
claude Oct 19, 2026
7b23a96
Merge remote-tracking branch 'origin/master-1.21-lts' into terminal-u…
claude Oct 19, 2026
aef7972
Merge pull request #97 from CyclopsMC/fix/open-new-script
rubensworks Oct 19, 2026
c75339c
Merge pull request #95 from CyclopsMC/terminal-ux-clean/10-last-value
rubensworks Oct 20, 2026
70e093a
Insert completions by clicking them in the script editor
claude Oct 20, 2026
741db40
Color value types in script editor completions and signatures
claude Oct 20, 2026
7caad76
Merge branch 'terminal-ux-clean/11-completion' into terminal-ux-clean…
claude Oct 20, 2026
26d4be9
Merge pull request #96 from CyclopsMC/terminal-ux-clean/11-completion
rubensworks Oct 20, 2026
bddb856
Merge pull request #98 from CyclopsMC/terminal-ux-clean/12-editor-polish
rubensworks Oct 20, 2026
0b43951
Fix empty scripting drives exposing a disk with ID -1
claude Oct 20, 2026
8f8f4ef
Show a hint in the scripting terminal editor when no script is open
claude Oct 20, 2026
12cd49f
Update to CyclopsCore 1.30.0
claude Oct 20, 2026
574f129
Merge pull request #99 from CyclopsMC/fix/no-disk
rubensworks Oct 23, 2026
bb54593
Merge remote-tracking branch 'origin/master-1.21-lts' into master-26-lts
claude Oct 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,7 @@ config

# Ignore Minecraft runtime logs
/logs

# ClientDevBridge session state (golden images are intentionally kept)
.clientdevbridge/*
!.clientdevbridge/golden/
7 changes: 7 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ test {
repositories {
mavenCentral()
mavenLocal()
maven {
name "JEI"
url "https://maven.blamejared.com"
}
maven {
name "Cyclops Repo"
url "https://maven.pkg.github.com/CyclopsMC/packages"
Expand Down Expand Up @@ -156,6 +160,9 @@ dependencies {
}
}

// Optional, only used to hide JEI in focus mode
compileOnly "mezz.jei:jei-${project.minecraft_version}-neoforge-api:${project.jei_version}"

modLib "com.google.re2j:re2j:1.1"
modLib ("io.netty:netty-codec-http:4.1.77.Final") {
transitive = false
Expand Down
1 change: 1 addition & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ graal_version=25.2.4
cyclopscore_version=1.30.1-1051
integrateddynamics_version=1.32.11-1809
commoncapabilities_version=2.11.4-344
jei_version=29.5.0.28
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ public class GeneralConfig extends DummyConfigCommon<IModBase> {
public static int terminalScriptingBaseConsumption = 1;
@ConfigurablePropertyCommon(category = "general", comment = "The minimum number of ticks inbetween sending a script change packet from client to server.", minimalValue = 0, configLocation = ModConfigLocation.SERVER)
public static int terminalScriptingClientSyncTickInterval = 20;
@ConfigurablePropertyCommon(category = "general", comment = "The number of spaces that tab inserts in the scripting terminal editor.", minimalValue = 1, maximalValue = 16, configLocation = ModConfigLocation.CLIENT)
public static int terminalScriptingIndentSize = 2;

@ConfigurablePropertyCommon(category = "general", comment = "If new processes can be created from guest languages. Only enable this on private servers and if you know what you are doing.", configLocation = ModConfigLocation.SERVER)
public static boolean graalAllowCreateProcess = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.cyclops.integratedscripting.command.CommandTestScript;
import org.cyclops.integratedscripting.component.DataComponentDiskIdConfig;
import org.cyclops.integratedscripting.core.client.model.ScriptingVariableModelProviders;
import org.cyclops.integratedscripting.core.evaluate.ScriptEvaluationStatuses;
import org.cyclops.integratedscripting.core.evaluate.ScriptVariableFacadeHandler;
import org.cyclops.integratedscripting.core.packageddependencies.PackagedDependenciesLoader;
import org.cyclops.integratedscripting.core.language.LanguageHandlerRegistry;
Expand All @@ -43,7 +44,9 @@
import org.cyclops.integratedscripting.evaluate.translation.ValueTranslatorRegistry;
import org.cyclops.integratedscripting.evaluate.translation.ValueTranslators;
import org.cyclops.integratedscripting.gametest.GameTestsAdvancements;
import org.cyclops.integratedscripting.gametest.GameTestsScriptingDrive;
import org.cyclops.integratedscripting.gametest.GameTestsScripts;
import org.cyclops.integratedscripting.gametest.GameTestsTerminalScripting;
import org.cyclops.integratedscripting.inventory.container.ContainerScriptingDriveConfig;
import org.cyclops.integratedscripting.inventory.container.ContainerTerminalScriptingConfig;
import org.cyclops.integratedscripting.item.ItemScriptingDiskConfig;
Expand Down Expand Up @@ -127,6 +130,7 @@ protected void onServerStopping(ServerStoppingEvent event) {
}
this.scriptingData = null;
EvaluationExceptionResolutionHelpers.reset();
ScriptEvaluationStatuses.reset();
}

@SubscribeEvent
Expand Down Expand Up @@ -187,7 +191,9 @@ protected ICommonProxy constructCommonProxy() {
public Class<?>[] getGameTestClasses() {
return new Class<?>[]{
GameTestsAdvancements.class,
GameTestsScripts.class
GameTestsScripts.class,
GameTestsScriptingDrive.class,
GameTestsTerminalScripting.class
};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
package org.cyclops.integratedscripting.api.language;

import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.Style;
import org.apache.commons.lang3.tuple.Pair;
import org.cyclops.cyclopscore.client.gui.image.IImage;
import org.cyclops.integrateddynamics.api.evaluate.EvaluationException;
import org.cyclops.integratedscripting.api.network.IScriptFactory;

import javax.annotation.Nullable;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;

/**
* Logic for handling a specific programming language.
Expand All @@ -22,8 +28,73 @@ public interface ILanguageHandler {

public List<Pair<Style, String>> markupLine(String line);

/**
* Mark up a full script, which allows constructs such as block comments to span multiple lines.
* @param script The script contents.
* @return Styled segments that together form the full script.
*/
public default List<Pair<Style, String>> markupScript(String script) {
List<Pair<Style, String>> segments = new ArrayList<>();
String[] lines = script.split("\n", -1);
for (int i = 0; i < lines.length; i++) {
if (i > 0) {
segments.add(Pair.of(Style.EMPTY, "\n"));
}
segments.addAll(markupLine(lines[i]));
}
return segments;
}

public IScriptFactory getScriptFactory() throws EvaluationException;

/**
* @return Words of the language that can not be the name of a script member, such as keywords.
*/
public default Set<String> getReservedWords() {
return Collections.emptySet();
}

/**
* @param script The script contents.
* @return The names of the members declared at the top level of the script,
* or null if they can not be determined.
*/
@Nullable
public default Set<String> getTopLevelMembers(String script) {
return null;
}

/**
* @param script The script contents.
* @param cursor The cursor position.
* @return Completion candidates at the cursor, or null if there are none.
*/
@Nullable
public default ScriptCompletions getCompletions(String script, int cursor) {
return null;
}

/**
* @param script The script contents.
* @param cursor The cursor position.
* @return The signature of the function call the cursor is in, or null if unknown.
*/
@Nullable
public default Component getSignatureHint(String script, int cursor) {
return null;
}

/**
* Check a script for syntax errors, without executing it.
* @param path The script path.
* @param script The script contents.
* @return The first syntax error, or null if there is none or if checking is not supported.
*/
@Nullable
public default ScriptSyntaxError checkSyntax(Path path, String script) {
return null;
}

public void onServerStarted();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.cyclops.integratedscripting.api.language;

import net.minecraft.network.chat.Component;

import java.util.List;

/**
* Completion candidates at a position in a script.
* @param start The position from which the text before the cursor is replaced when accepting a candidate.
* @param items The candidates.
* @author rubensworks
*/
public record ScriptCompletions(int start, List<Item> items) {

/**
* @param name The text to insert.
* @param detail A short description, such as a signature.
*/
public record Item(String name, Component detail) {
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.cyclops.integratedscripting.api.language;

/**
* A syntax error in a script.
* @param message The error message.
* @param line The 1-based line of the error.
* @param column The 1-based column of the error.
* @author rubensworks
*/
public record ScriptSyntaxError(String message, int line, int column) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,11 @@ public void setExposedDiskId(int exposedDiskId) {
this.onDirty();
ScriptingNetworkHelpers.getScriptingNetwork(getNetwork())
.ifPresent(scriptingNetwork -> {
if (exposedDiskId == -1) {
// Also remove the old disk when it is directly replaced by another one
if (oldExposedDiskId >= 0) {
scriptingNetwork.removeDisk(oldExposedDiskId);
} else {
}
if (exposedDiskId >= 0) {
scriptingNetwork.addDisk(exposedDiskId);
}
});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.cyclops.integratedscripting.client.gui.component.button;

import net.minecraft.client.gui.GuiGraphicsExtractor;
import net.minecraft.network.chat.Component;
import org.cyclops.cyclopscore.client.gui.component.button.ButtonExtended;
import org.cyclops.cyclopscore.client.gui.image.IImage;

/**
* A button with a centered icon, which is dimmed when the button is inactive.
* @author rubensworks
*/
public class ButtonIcon extends ButtonExtended {

private final IImage image;

public ButtonIcon(int x, int y, int width, int height, Component narrationMessage, OnPress onPress, IImage image) {
super(x, y, width, height, narrationMessage, onPress, true);
this.image = image;
}

@Override
protected void drawButtonInner(GuiGraphicsExtractor guiGraphics, int mouseX, int mouseY) {
float color = this.active ? 1F : 0.4F;
this.image.drawWithColor(guiGraphics, this.getX() + (this.width - this.image.getWidth()) / 2,
this.getY() + (this.height - this.image.getHeight()) / 2, color, color, color, 1F);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.cyclops.integratedscripting.client.gui.component.input;

import org.lwjgl.glfw.GLFW;

/**
* Platform conventions for moving the cursor in text editors.
* @author rubensworks
*/
public final class EditorKeys {

private EditorKeys() {
}

/**
* @return If the cursor should move or delete by word: Option on macOS, Ctrl elsewhere.
*/
public static boolean isWordModifier(int modifiers, boolean osx) {
return (modifiers & (osx ? GLFW.GLFW_MOD_ALT : GLFW.GLFW_MOD_CONTROL)) != 0;
}

/**
* @return If arrow keys should jump to the line or document start or end, which is Cmd on macOS.
*/
public static boolean isLineModifier(int modifiers, boolean osx) {
return osx && (modifiers & GLFW.GLFW_MOD_SUPER) != 0;
}

}
Loading
Loading