From 3042289df47aa206bb18230fa6965818a46f6674 Mon Sep 17 00:00:00 2001 From: Paul Colomiets Date: Thu, 29 Sep 2022 17:36:04 +0300 Subject: [PATCH] Remove flicker on external print (#488) * Remove flicker on external print Previously each external print was causing a visible flicker on at least two terminal emulators I've tested (alacritty, xfce4-terminal). * Make `Painter.print_external_message()` crate local * Put external_printer Painter members behind flag * Add `external_printer` feature to CI Co-authored-by: Stefan Holderbach --- .github/workflows/ci.yml | 4 +++- src/painting/painter.rs | 18 ++++++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index aba7003..92ce34f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,10 +15,12 @@ jobs: rust: - stable # Define the feature sets that will be built here (for caching you define a separate name) - style: [bashisms, default, sqlite, basqlite] + style: [bashisms, default, sqlite, basqlite, external_printer] include: - style: bashisms flags: "--features bashisms" + - style: external_printer + flags: "--features external_printer" - style: default flags: "" - style: sqlite diff --git a/src/painting/painter.rs b/src/painting/painter.rs index 072eae1..55ab44b 100644 --- a/src/painting/painter.rs +++ b/src/painting/painter.rs @@ -3,16 +3,18 @@ use { crate::{ menu::{Menu, ReedlineMenu}, painting::PromptLines, - LineBuffer, Prompt, + Prompt, }, crossterm::{ - cursor::{self, MoveTo, MoveUp, RestorePosition, SavePosition}, + cursor::{self, MoveTo, RestorePosition, SavePosition}, style::{Attribute, Print, ResetColor, SetAttribute, SetForegroundColor}, terminal::{self, Clear, ClearType, ScrollUp}, QueueableCommand, Result, }, std::io::Write, }; +#[cfg(feature = "external_printer")] +use {crate::LineBuffer, crossterm::cursor::MoveUp}; // Returns a string that skips N number of lines with the next offset of lines // An offset of 0 would return only one line after skipping the required lines @@ -454,7 +456,11 @@ impl Painter { } /// Prints an external message - pub fn print_external_message( + /// + /// This function doesn't flush the buffer. So buffer should be flushed + /// afterwards perhaps by repainting the prompt via `repaint_buffer()`. + #[cfg(feature = "external_printer")] + pub(crate) fn print_external_message( &mut self, messages: Vec, line_buffer: &LineBuffer, @@ -486,7 +492,11 @@ impl Painter { let erase_line = format!("\r{}\r", " ".repeat(self.screen_width().into())); for line in messages { self.stdout.queue(Print(&erase_line))?; - self.paint_line(&line)?; + // Note: we don't use `print_line` here because we don't want to + // flush right now. The subsequent repaint of the prompt will cause + // immediate flush anyways. And if we flush here, every external + // print causes visible flicker. + self.stdout.queue(Print(line))?.queue(Print("\r\n"))?; let new_start = self.prompt_start_row.saturating_add(1); let height = self.screen_height(); if new_start >= height {