This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
#![forbid(unsafe_code)]
|
||||
|
||||
use alacritty_terminal::event::{Event, EventListener, WindowSize};
|
||||
use alacritty_terminal::grid::Dimensions;
|
||||
use alacritty_terminal::grid::{Dimensions, Scroll};
|
||||
use alacritty_terminal::term::cell::Flags;
|
||||
use alacritty_terminal::term::{Config, Osc52, Term, TermMode, point_to_viewport};
|
||||
use alacritty_terminal::vte::ansi::{Color, CursorShape, NamedColor, Processor};
|
||||
@@ -259,12 +259,23 @@ impl TerminalModes {
|
||||
pub struct TerminalSnapshot {
|
||||
pub revision: u64,
|
||||
pub dimensions: TerminalDimensions,
|
||||
pub display_offset: usize,
|
||||
pub cells: Vec<TerminalCell>,
|
||||
pub cursor: TerminalCursor,
|
||||
pub modes: TerminalModes,
|
||||
pub title: Option<String>,
|
||||
}
|
||||
|
||||
/// Framework-neutral movement through the retained terminal history.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum TerminalScroll {
|
||||
Delta(i32),
|
||||
PageUp,
|
||||
PageDown,
|
||||
Top,
|
||||
Bottom,
|
||||
}
|
||||
|
||||
impl TerminalSnapshot {
|
||||
#[must_use]
|
||||
pub fn cell(&self, row: u16, column: u16) -> Option<&TerminalCell> {
|
||||
@@ -544,6 +555,31 @@ impl TerminalEngine {
|
||||
}
|
||||
}
|
||||
|
||||
/// Moves the visible viewport without writing bytes to the child PTY.
|
||||
///
|
||||
/// Returns `true` only when the retained-history offset changed.
|
||||
pub fn scroll_display(&mut self, scroll: TerminalScroll) -> bool {
|
||||
let previous_offset = self.terminal.grid().display_offset();
|
||||
let scroll = match scroll {
|
||||
TerminalScroll::Delta(lines) => Scroll::Delta(lines),
|
||||
TerminalScroll::PageUp => Scroll::PageUp,
|
||||
TerminalScroll::PageDown => Scroll::PageDown,
|
||||
TerminalScroll::Top => Scroll::Top,
|
||||
TerminalScroll::Bottom => Scroll::Bottom,
|
||||
};
|
||||
self.terminal.scroll_display(scroll);
|
||||
if self.terminal.grid().display_offset() == previous_offset {
|
||||
return false;
|
||||
}
|
||||
self.revision = self.revision.saturating_add(1);
|
||||
true
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn display_offset(&self) -> usize {
|
||||
self.terminal.grid().display_offset()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn snapshot(&self) -> TerminalSnapshot {
|
||||
let renderable = self.terminal.renderable_content();
|
||||
@@ -571,6 +607,7 @@ impl TerminalEngine {
|
||||
TerminalSnapshot {
|
||||
revision: self.revision,
|
||||
dimensions: self.dimensions,
|
||||
display_offset: renderable.display_offset,
|
||||
cells,
|
||||
cursor: TerminalCursor {
|
||||
row: u16::try_from(cursor_point.line).unwrap_or(u16::MAX),
|
||||
@@ -874,6 +911,7 @@ mod tests {
|
||||
use super::{
|
||||
KeyModifiers, TerminalCellStyle, TerminalDimensions, TerminalEngine, TerminalEngineOptions,
|
||||
TerminalEvent, TerminalKey, TerminalKeyEvent, TerminalModes, TerminalNamedColor,
|
||||
TerminalScroll,
|
||||
};
|
||||
|
||||
fn engine(rows: u16, columns: u16) -> TerminalEngine {
|
||||
@@ -917,6 +955,23 @@ mod tests {
|
||||
assert_eq!(engine.snapshot().plain_rows()[0], "primary");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn scrolls_retained_history_without_touching_the_pty_input_path() {
|
||||
let mut engine = engine(2, 8);
|
||||
engine.process(b"one\r\ntwo\r\nthree\r\nfour");
|
||||
assert_eq!(engine.display_offset(), 0);
|
||||
|
||||
let revision = engine.revision();
|
||||
assert!(engine.scroll_display(TerminalScroll::PageUp));
|
||||
assert!(engine.display_offset() > 0);
|
||||
assert!(engine.revision() > revision);
|
||||
assert_eq!(engine.snapshot().display_offset, engine.display_offset());
|
||||
|
||||
assert!(engine.scroll_display(TerminalScroll::Bottom));
|
||||
assert_eq!(engine.display_offset(), 0);
|
||||
assert!(!engine.scroll_display(TerminalScroll::Bottom));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn emits_protocol_replies_without_logging_input_content() {
|
||||
let mut engine = engine(4, 10);
|
||||
|
||||
Reference in New Issue
Block a user