Fix REPL history navigation and double Ctrl+C exit timing #365
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.
Problem
The REPL had two critical usability issues:
Root Cause
History Issue
The REPL spawned a new thread for each readline operation, and each thread created a new
Editorinstance. While the code attempted to maintain history by loading strings into each new editor, rustyline's built-in history navigation requires a persistentEditorinstance with its own internal history state, not just a list of strings being copied around.Double Ctrl+C Issue
The exit logic tracked
last_was_interruptedas a boolean and checked if the readline had been active for less than 300ms. This meant users had to press Ctrl+C twice within 300ms of the prompt appearing, not within 300ms of each other - a timing that was nearly impossible to achieve reliably.Solution
History Fix
Editorinstance inArc<Mutex>and share it across threadsDouble Ctrl+C Fix
last_interrupt_time: Option<Instant>instead of a boolean flagChanges
cli/main.rsonlyTesting
✅ All 76 existing tests pass
✅ No clippy warnings
✅ Code properly formatted
✅ Manual testing confirms both issues are resolved
The threading approach remains necessary because
readline()is a blocking call and we need the event loop to continue processing async operations. This fix preserves that architecture while fixing the usability issues.Original prompt
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.