Skip to content

Commit

Permalink
Make detection of prompt types more robust
Browse files Browse the repository at this point in the history
  • Loading branch information
lionel- committed Sep 19, 2024
1 parent e252354 commit aa5c30a
Showing 1 changed file with 49 additions and 35 deletions.
84 changes: 49 additions & 35 deletions crates/ark/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,13 @@ impl RMain {
buflen: c_int,
_hist: c_int,
) -> ConsoleResult {
// TODO!: Document why incomplete is fine (vec is necessarily empty, if
// there's a syntax error R will throw and vec will be flushed)

// TODO!: If we detect an incomplete prompt and we no longer have any
// inputs to send, then it's a panic. We should have replied with an
// error to the frontend ahead of time.

if let Some(console_result) = self.handle_pending_line(buf, buflen) {
return console_result;
}
Expand Down Expand Up @@ -849,7 +856,7 @@ impl RMain {
self.error_occurred = false;

match input {
ConsoleInput::Input(mut code) => {
ConsoleInput::Input(code) => {
// Handle commands for the debug interpreter
if self.dap.is_debugging() {
let continue_cmds = vec!["n", "f", "c", "cont"];
Expand All @@ -858,13 +865,7 @@ impl RMain {
}
}

// In notebooks, wrap in braces so that only the last complete
// expression is auto-printed
if let SessionMode::Notebook = self.session_mode {
code = format!("{{ {code} }}");
}

// WIP: Split input into multiple lines
// TODO!: Check for incomplete inputs and immediately error
let code = self.handle_input(code);

Self::on_console_input(buf, buflen, code);
Expand Down Expand Up @@ -1348,33 +1349,46 @@ This is a Positron limitation we plan to fix. In the meantime, you can:
}
}

// If we are at top-level, we're handling visible output auto-printed by
// the R REPL. We accumulate this output (it typically comes in multiple
// parts) so we can emit it later on as part of the execution reply
// message sent to Shell, as opposed to an Stdout message sent on IOPub.
//
// However, if autoprint is dealing with an intermediate expression
// (i.e. `a` and `b` in `a\nb\nc`), we should emit it on IOPub. We
// only accumulate autoprint output for the very last expression. The
// way to distinguish between these cases is whether there are still
// lines of input pending. In that case, that means we are on an
// intermediate expression.
//
// Note that we implement this behaviour (streaming autoprint results of
// intermediate expressions) specifically for Positron, and specifically
// for versions that send multiple expressions selected by the user in
// one request. Other Jupyter frontends do not want to see output for
// these intermediate expressions. And future versions of Positron will
// never send multiple expressions in one request
// (https://github.com/posit-dev/positron/issues/1326).
//
// Note that warnings emitted lazily on stdout will appear to be part of
// autoprint. We currently emit them on stderr, which allows us to
// differentiate, but that could change in the future:
// https://github.com/posit-dev/positron/issues/1881
if otype == 0 && is_auto_printing() && self.pending_lines.is_empty() {
self.autoprint_output.push_str(&content);
return;
if stream == Stream::Stdout && is_auto_printing() {
// If we are at top-level, we're handling visible output auto-printed by
// the R REPL. We accumulate this output (it typically comes in multiple
// parts) so we can emit it later on as part of the execution reply
// message sent to Shell, as opposed to an Stdout message sent on IOPub.
//
// However, if autoprint is dealing with an intermediate expression
// (i.e. `a` and `b` in `a\nb\nc`), we should emit it on IOPub. We
// only accumulate autoprint output for the very last expression. The
// way to distinguish between these cases is whether there are still
// lines of input pending. In that case, that means we are on an
// intermediate expression.
//
// Note that we implement this behaviour (streaming autoprint results of
// intermediate expressions) specifically for Positron, and specifically
// for versions that send multiple expressions selected by the user in
// one request. Other Jupyter frontends do not want to see output for
// these intermediate expressions. And future versions of Positron will
// never send multiple expressions in one request
// (https://github.com/posit-dev/positron/issues/1326).
//
// Note that warnings emitted lazily on stdout will appear to be part of
// autoprint. We currently emit them on stderr, which allows us to
// differentiate, but that could change in the future:
// https://github.com/posit-dev/positron/issues/1881

// Handle last expression
if self.pending_lines.is_empty() {
self.autoprint_output.push_str(&content);
return;
}

// In notebooks, we don't emit results of intermediate expressions
if self.session_mode == SessionMode::Notebook {
return;
}

// In Positron, fall through if we have pending input. This allows
// autoprint output for intermediate expressions to be emitted on
// IOPub.
}

// Stream output via the IOPub channel.
Expand Down

0 comments on commit aa5c30a

Please sign in to comment.