Improve speed and responsiveness for code entered or sent to the Console - #15078
Conversation
|
E2E Tests 🚀 Why these tags?
More on automatic tags from changed files. Warning This PR touches a Positron directory that isn't mapped in test-tag-paths-map.json: |
seeM
left a comment
There was a problem hiding this comment.
I am still reading through the code, but did some manual tests and found a possible issue with the responsiveness improvements where code disappears.
R multiple ✅
Screen.Recording.2026-08-06.at.19.35.59.mov
R incomplete ✅
Screen.Recording.2026-08-06.at.19.40.18.mov
Python incomplete ✅
Screen.Recording.2026-08-06.at.19.42.32.mov
Responsiveness
I added a 5 second timeout to the beginning of PositronConsoleInstance.tryProvideInputBoundaries and ran code.
The code disappears after I press Enter, and only reappears when the 5 seconds completes. So there is also no barber pole. ❎
Could be that I am putting the timeout at the wrong place?
Screen.Recording.2026-08-06.at.19.53.09.mov
The "Submitting" popup shows, and clicking "Cancel" does cancel the execution and repopulate the console input box. ✅
Screen.Recording.2026-08-06.at.19.54.30.mov
1 frame flicker
There is a momentary (~1 frame) flicker when I press Enter in both R cases. I am sensitive to flickers like that but it doesn't seem to bother most. It could also be related to the code disappearing above.
Frame before enter:
Frame immediately after enter:
Next frame:
|
It can also dim the wrong text if I type while the code is being submitted. Screen.Recording.2026-08-06.at.20.14.25.mov |
seeM
left a comment
There was a problem hiding this comment.
Code changes look good as best as I could read given the size of the PR. I think this one may be best tested with exposure in dailies.
670ad54 to
a4213b5
Compare
seeM
left a comment
There was a problem hiding this comment.
Looks good! I found one more non-blocking edge case, which again might just be because of where I added the 5 sec timeout (tryProvideInputBoundaries). I tried to execute multiple statements waiting <5s between each attempt. It extends the pending state and the restarts the "Submitting" popup debounce timer (and the interrupt button debounce timer), so I only get a result when all executions finish.
Screen.Recording.2026-08-07.at.19.53.01.mov
This is intentional, and it is somewhat necessary because during the 5s, we don't know if the input is complete or not. So imagine you did this:
Until the 5s finishes, we don't know whether the first thing you typed and the second thing you typed go together or not. It is harmless if we guess that they go together and they don't, but it is harmful if we guess that they don't go together and they do (you will get a syntax error and a continuation prompt). So the approach we take is that if you submit more stuff before we are finished analyzing what you've already submitted, we restart the evaluation with the new code. |
Fixes #8915
Summary
This PR holistically addresses a number of performance and responsiveness problems around running and sending code to the console, especially in Workbench and Remote SSH scenarios.
It has the following goals:
Previously, pressing Enter in the Console triggered up to three separate
is_complete_requestroundtrips to the kernel (Enter handler,enqueueCode, and the pending-input queue drain), each of which is especially costly on remote configurations, and none of which gave the user any feedback or a way to cancel while it was in flight.This PR introduces a single submission entry point (
submitCode) on the Console instance that chooses the cheapest available completeness strategy:InputBoundaryProvider(R does, via Ark), the input is split locally over LSP with no kernel queue. Complete statements are executed and queued individually as pre-verified fragments (so the queue drain no longer re-checks each one); an incomplete tail yields a continuation prompt; an invalid fragment executes the whole input as-is so the interpreter surfacesthe error.
Unprocessedmode (Flow 2) - when no provider matches (e.g. Python), code is sent with a newUnprocessedexecution mode. The supervisor (running in the possibly-remote extension host) performs theis_complete_requestitself beforeexecute_request, eliminating the client-to-remote roundtrip. Incomplete code rejects withCodeIncompleteErrorand the Console shows the continuation prompt.console.promptWhenIncompletedisabled, code runs immediately with no completeness check at all. This makes execution very snappy for people who don't want prompting.When the code is sent to the console from the Editor via a statement range provider, we now skip the completeness check entirely (Flow 3), making this common path more responsive.
Submission is now observable state on the Console instance with debounced visuals: at 400ms the input dims slightly and a green barber pole appears; at 1000ms a "Submitting..." overlay with a Cancel button appears bottom-right.
The action bar stop button and Ctrl+C both cancel the in-flight submission (which also aborts the supervisor-side check for Flow 2). The
Unprocessedmode is an internal wire detail only - accepted executions are reported asInteractiveinonDidExecuteCode.To support this,
LanguageRuntimeSession.execute()is now awaitable end to end (Thenable<void> | void) so a completeness rejection can propagate back across the RPC boundary, identified byerror.name(
CodeIncompleteError/ExecutionCancelledError).Release Notes
New Features
console.promptWhenIncompletesetting to run submitted code immediately without a completeness check.Bug Fixes
Validation Steps
@:console @:ark
R (input boundary provider path):
print("a") <CR> Sys.sleep(4) <CR> print("B")both execute with interleaved echo; the second appears as a dimmed queued pending-input item, then runs.f <- function(-> a continuation prompt appears and nothing executes. Confirm the barber pole does NOT flicker for fast checks (< 400ms).Python (
Unprocessedpath):def f():and press Enter -> a continuation prompt appears.Submission feedback / cancel (any language, simulate a slow check):
Setting / regression:
console.promptWhenIncompletetofalse-> incomplete input submits immediately and the interpreter reports the syntax error; no dim/barber pole appears.