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 <sholderbach@users.noreply.github.com>
This commit is contained in:
Paul Colomiets 2022-09-29 17:36:04 +03:00 committed by GitHub
parent f994cc9d38
commit 3042289df4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 17 additions and 5 deletions

View File

@ -15,10 +15,12 @@ jobs:
rust: rust:
- stable - stable
# Define the feature sets that will be built here (for caching you define a separate name) # 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: include:
- style: bashisms - style: bashisms
flags: "--features bashisms" flags: "--features bashisms"
- style: external_printer
flags: "--features external_printer"
- style: default - style: default
flags: "" flags: ""
- style: sqlite - style: sqlite

View File

@ -3,16 +3,18 @@ use {
crate::{ crate::{
menu::{Menu, ReedlineMenu}, menu::{Menu, ReedlineMenu},
painting::PromptLines, painting::PromptLines,
LineBuffer, Prompt, Prompt,
}, },
crossterm::{ crossterm::{
cursor::{self, MoveTo, MoveUp, RestorePosition, SavePosition}, cursor::{self, MoveTo, RestorePosition, SavePosition},
style::{Attribute, Print, ResetColor, SetAttribute, SetForegroundColor}, style::{Attribute, Print, ResetColor, SetAttribute, SetForegroundColor},
terminal::{self, Clear, ClearType, ScrollUp}, terminal::{self, Clear, ClearType, ScrollUp},
QueueableCommand, Result, QueueableCommand, Result,
}, },
std::io::Write, 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 // 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 // An offset of 0 would return only one line after skipping the required lines
@ -454,7 +456,11 @@ impl Painter {
} }
/// Prints an external message /// 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, &mut self,
messages: Vec<String>, messages: Vec<String>,
line_buffer: &LineBuffer, line_buffer: &LineBuffer,
@ -486,7 +492,11 @@ impl Painter {
let erase_line = format!("\r{}\r", " ".repeat(self.screen_width().into())); let erase_line = format!("\r{}\r", " ".repeat(self.screen_width().into()));
for line in messages { for line in messages {
self.stdout.queue(Print(&erase_line))?; 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 new_start = self.prompt_start_row.saturating_add(1);
let height = self.screen_height(); let height = self.screen_height();
if new_start >= height { if new_start >= height {