Skip to content

Commit

Permalink
Don't rerender the unchanging prefix
Browse files Browse the repository at this point in the history
Summary:
Before, the output might be:

```
Buck UI: https://www.internalfb.com/buck2/cabbd5fa-88a2-4570-9419-b2eaa4b01c5b
Test UI: https://www.internalfb.com/intern/testinfra/testrun/6755399647278609
Note:    Using experimental modern dice
Network: Up: 3.5KiB  Down: 5.9KiB  (reSessionID-10dc4c7d-d791-4976-9570-d842b7663c34)
```

But because we kept rewriting the Buck UI link, it was basically impossible to click on in VS Code. The URL detection kicked in, but the active site kept changing, and you failed.

Now, we don't rerender identical output. Will be a little faster, but mainly we can now click on the URLs.

Reviewed By: lmvasquezg

Differential Revision: D54412142

fbshipit-source-id: 2eb5bffddd7b62b26797408b2882e87b30602987
  • Loading branch information
ndmitchell authored and facebook-github-bot committed Mar 1, 2024
1 parent f70d025 commit 30e0b2a
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 5 deletions.
16 changes: 14 additions & 2 deletions src/content/lines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,13 +286,25 @@ impl Lines {

/// Formats and renders all lines to `stdout`.
/// Notably, this *queues* the lines for rendering. You must flush the buffer.
pub(crate) fn render(&self, writer: &mut Vec<u8>) -> anyhow::Result<()> {
for line in &self.0 {
pub(crate) fn render_from_line(
&self,
writer: &mut Vec<u8>,
start: usize,
) -> anyhow::Result<()> {
for line in self.0.iter().skip(start) {
line.render_with_clear_and_nl(writer)?;
}
Ok(())
}

pub(crate) fn lines_equal(&self, other: &Self) -> usize {
self.0
.iter()
.zip(other.0.iter())
.take_while(|(l1, l2)| l1 == l2)
.count()
}

/// Returns the maximum line width and the number of lines.
/// This corresponds to how much space a justified version of the output would take.
pub fn dimensions(&self) -> anyhow::Result<Dimensions> {
Expand Down
51 changes: 48 additions & 3 deletions src/superconsole.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,10 +232,17 @@ impl SuperConsole {
_ => None,
};

Self::clear_canvas_pre(buffer, self.canvas_contents.len())?;
self.canvas_contents = Lines::new();
// How much of the canvas hasn't changed, so I can avoid overwriting
// and thus avoid flickering things like URL's in VS Code terminal.
let reuse_prefix = if self.to_emit.is_empty() {
self.canvas_contents.lines_equal(&canvas)
} else {
0
};

Self::clear_canvas_pre(buffer, self.canvas_contents.len() - reuse_prefix)?;
self.to_emit.render_with_limit(buffer, limit)?;
canvas.render(buffer)?;
canvas.render_from_line(buffer, reuse_prefix)?;
Self::clear_canvas_post(buffer)?;
self.canvas_contents = canvas;

Expand Down Expand Up @@ -380,4 +387,42 @@ mod tests {

Ok(())
}

#[test]
fn test_reuse_buffer() -> anyhow::Result<()> {
let mut console = test_console();

console.render(&Echo(Lines(vec![
vec!["http://example.com/ link"].try_into()?,
vec!["number 1, special 1"].try_into()?,
])))?;
console.render(&Echo(Lines(vec![
vec!["http://example.com/ link"].try_into()?,
vec!["number 2, special 2"].try_into()?,
])))?;
console.emit(Lines(vec![vec!["special 3"].try_into()?]));
console.render(&Echo(Lines(vec![
vec!["http://example.com/ link"].try_into()?,
vec!["number 3"].try_into()?,
])))?;
console.render(&Echo(Lines(vec![
vec!["http://example.com/ link"].try_into()?,
vec!["special 4"].try_into()?,
vec!["number 4"].try_into()?,
])))?;

let frames = &console.test_output()?.frames;
assert_eq!(frames.len(), 4);
// We expect the URL to be omitted on some frames, because it didn't change.
let expect_url = [0, 2];
for (i, frame) in frames.iter().enumerate() {
assert_eq!(
frame_contains(frame, "http://example.com/"),
expect_url.contains(&i),
);
assert!(frame_contains(frame, format!("number {}", i + 1)));
assert!(frame_contains(frame, format!("special {}", i + 1)));
}
Ok(())
}
}

0 comments on commit 30e0b2a

Please sign in to comment.