Repository navigation
Add undo/redo and fix lost edits in the scripting terminal - #85
Merged
Merged
Conversation
Scripts are saved on every edit and right-click selected the whole script, so a right-click followed by a single key press replaced and saved the entire script, without any way to get it back. Add a per-file undo history (ctrl+z, and ctrl+y or ctrl+shift+z to redo) that groups consecutive typing, and stop selecting everything on right-click. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018MRyTdV3fSV5Q5NPGep4q9
When the client synced a script, the server sent the same version back. If the player typed in the meantime, this echo overwrote the newer client version, which was then synced instead, losing the last keystrokes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018MRyTdV3fSV5Q5NPGep4q9
Scripts were flushed by truncating and rewriting the file, so the file watcher could reload a partially written or empty script into memory and send it to clients. Write to a temporary file outside the watched directories and move it into place instead, keeping the permissions of existing files and the default permissions for new ones. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018MRyTdV3fSV5Q5NPGep4q9
When a script changed outside the editor, for example by editing the file on disk, the open editor kept showing the old text, and the next key press synced that old text back, discarding the external change. Reload the active script when the server sends a newer version, as an undoable edit that keeps the cursor position. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018MRyTdV3fSV5Q5NPGep4q9
When the file watcher reloaded a disk directory, it replaced the scripts in memory with whatever was on disk at that moment. As it also triggers on the server's own writes, it could run while a script was not written yet, for example right after creating the directory of a new disk, which made that script disappear. Concurrent reloads could also overwrite each other. Remember the contents last written or read for each file, only apply files that changed outside of the mod, and don't let reloads, flushes and script changes run at the same time. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018MRyTdV3fSV5Q5NPGep4q9
Files created outside of the game did not always show up until another file changed. Every reload cancelled and re-registered the directory watchers, losing events that happened in between, and only directories that already contained scripts were watched, so files in new, empty or intermediate directories were missed. Watch all directories of a disk before reading its files, keep existing watchers registered, and clean up watchers of deleted directories. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018MRyTdV3fSV5Q5NPGep4q9
This was referenced Oct 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replaces #78, with the same changes and a clean commit history: every commit is one standalone change. Phase 2 of the scripting terminal UX improvements, and the base of the remaining stack.
I reproduced every problem in a dev client driven by clientdevbridge (or with a unit test that fails on the old code) before fixing it, then checked it again with this branch.
z). No undo existed.abc, Enter,deundo as 3 steps). History is kept per file. Unit tests added.aABbutaAwas saved.aABis saved.rw-r--r--(a first version usedFiles.createTempFile, which made flushed scriptsrw-------; covered by a test).lib/helpers/folder) in one shell command left the terminal showing the old list.About the watcher reload commit
I found it because the partial-contents test was flaky: run 15 times in one JVM, it failed 13 times, always observing the script as
null. That was this race, not partial contents. After both watcher commits, 30 runs of the wholeScriptingDataTestclass had no failures.Why the atomic write commit is needed
Without it, the external-changes commit caused a regression: typing
hello worldinto a new file gaveorld,o worldllheandrldhello wo, because the editor applied the half-written content that the watcher had read back.Testing
./gradlew buildpasses, including the new unit tests../gradlew runGameTestServer: all 23 tests pass.Generated by Claude Code