mirror of
https://github.com/wez/wezterm.git
synced 2024-11-30 14:49:26 +03:00
add helper for managing primary and alt screen
This commit is contained in:
parent
cee63e74e1
commit
c0ea601645
@ -49,13 +49,67 @@ impl TabStop {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TerminalState {
|
struct ScreenOrAlt {
|
||||||
/// The primary screen + scrollback
|
/// The primary screen + scrollback
|
||||||
screen: Screen,
|
screen: Screen,
|
||||||
/// The alternate screen; no scrollback
|
/// The alternate screen; no scrollback
|
||||||
alt_screen: Screen,
|
alt_screen: Screen,
|
||||||
/// Tells us which screen is active
|
/// Tells us which screen is active
|
||||||
alt_screen_is_active: bool,
|
alt_screen_is_active: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for ScreenOrAlt {
|
||||||
|
type Target = Screen;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Screen {
|
||||||
|
match self.alt_screen_is_active {
|
||||||
|
true => &self.alt_screen,
|
||||||
|
false => &self.screen,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DerefMut for ScreenOrAlt {
|
||||||
|
fn deref_mut(&mut self) -> &mut Screen {
|
||||||
|
match self.alt_screen_is_active {
|
||||||
|
true => &mut self.alt_screen,
|
||||||
|
false => &mut self.screen,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ScreenOrAlt {
|
||||||
|
pub fn new(physical_rows: usize, physical_cols: usize, scrollback_size: usize) -> Self {
|
||||||
|
let screen = Screen::new(physical_rows, physical_cols, scrollback_size);
|
||||||
|
let alt_screen = Screen::new(physical_rows, physical_cols, 0);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
screen,
|
||||||
|
alt_screen,
|
||||||
|
alt_screen_is_active: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn resize(&mut self, physical_rows: usize, physical_cols: usize) {
|
||||||
|
self.screen.resize(physical_rows, physical_cols);
|
||||||
|
self.alt_screen.resize(physical_rows, physical_cols);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn activate_alt_screen(&mut self) {
|
||||||
|
self.alt_screen_is_active = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn activate_primary_screen(&mut self) {
|
||||||
|
self.alt_screen_is_active = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_alt_screen_active(&self) -> bool {
|
||||||
|
self.alt_screen_is_active
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct TerminalState {
|
||||||
|
screen: ScreenOrAlt,
|
||||||
/// The current set of attributes in effect for the next
|
/// The current set of attributes in effect for the next
|
||||||
/// attempt to print to the display
|
/// attempt to print to the display
|
||||||
pen: CellAttributes,
|
pen: CellAttributes,
|
||||||
@ -149,13 +203,10 @@ impl TerminalState {
|
|||||||
scrollback_size: usize,
|
scrollback_size: usize,
|
||||||
hyperlink_rules: Vec<HyperlinkRule>,
|
hyperlink_rules: Vec<HyperlinkRule>,
|
||||||
) -> TerminalState {
|
) -> TerminalState {
|
||||||
let screen = Screen::new(physical_rows, physical_cols, scrollback_size);
|
let screen = ScreenOrAlt::new(physical_rows, physical_cols, scrollback_size);
|
||||||
let alt_screen = Screen::new(physical_rows, physical_cols, 0);
|
|
||||||
|
|
||||||
TerminalState {
|
TerminalState {
|
||||||
screen,
|
screen,
|
||||||
alt_screen,
|
|
||||||
alt_screen_is_active: false,
|
|
||||||
pen: CellAttributes::default(),
|
pen: CellAttributes::default(),
|
||||||
cursor: CursorPosition::default(),
|
cursor: CursorPosition::default(),
|
||||||
saved_cursor: CursorPosition::default(),
|
saved_cursor: CursorPosition::default(),
|
||||||
@ -185,20 +236,12 @@ impl TerminalState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn screen(&self) -> &Screen {
|
pub fn screen(&self) -> &Screen {
|
||||||
if self.alt_screen_is_active {
|
|
||||||
&self.alt_screen
|
|
||||||
} else {
|
|
||||||
&self.screen
|
&self.screen
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pub fn screen_mut(&mut self) -> &mut Screen {
|
pub fn screen_mut(&mut self) -> &mut Screen {
|
||||||
if self.alt_screen_is_active {
|
|
||||||
&mut self.alt_screen
|
|
||||||
} else {
|
|
||||||
&mut self.screen
|
&mut self.screen
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_selection_text(&self) -> String {
|
pub fn get_selection_text(&self) -> String {
|
||||||
let mut s = String::new();
|
let mut s = String::new();
|
||||||
@ -294,16 +337,8 @@ impl TerminalState {
|
|||||||
) -> Option<Rc<Hyperlink>> {
|
) -> Option<Rc<Hyperlink>> {
|
||||||
let rules = &self.hyperlink_rules;
|
let rules = &self.hyperlink_rules;
|
||||||
|
|
||||||
// manually inlining screen_mut() here because the borrow checker
|
let idx = self.screen.scrollback_or_visible_row(y);
|
||||||
// can't see that it is only mutating the screen otherwise.
|
match self.screen.lines.get_mut(idx) {
|
||||||
let screen = if self.alt_screen_is_active {
|
|
||||||
&mut self.alt_screen
|
|
||||||
} else {
|
|
||||||
&mut self.screen
|
|
||||||
};
|
|
||||||
|
|
||||||
let idx = screen.scrollback_or_visible_row(y);
|
|
||||||
match screen.lines.get_mut(idx) {
|
|
||||||
Some(ref mut line) => {
|
Some(ref mut line) => {
|
||||||
line.scan_and_create_hyperlinks(rules);
|
line.scan_and_create_hyperlinks(rules);
|
||||||
match line.cells().get(x) {
|
match line.cells().get(x) {
|
||||||
@ -549,7 +584,7 @@ impl TerminalState {
|
|||||||
event.x + 1,
|
event.x + 1,
|
||||||
event.y + 1
|
event.y + 1
|
||||||
)?;
|
)?;
|
||||||
} else if self.alt_screen_is_active {
|
} else if self.screen.is_alt_screen_active() {
|
||||||
// Send cursor keys instead (equivalent to xterm's alternateScroll mode)
|
// Send cursor keys instead (equivalent to xterm's alternateScroll mode)
|
||||||
self.key_down(key, KeyModifiers::default(), host)?;
|
self.key_down(key, KeyModifiers::default(), host)?;
|
||||||
} else {
|
} else {
|
||||||
@ -815,7 +850,6 @@ impl TerminalState {
|
|||||||
|
|
||||||
pub fn resize(&mut self, physical_rows: usize, physical_cols: usize) {
|
pub fn resize(&mut self, physical_rows: usize, physical_cols: usize) {
|
||||||
self.screen.resize(physical_rows, physical_cols);
|
self.screen.resize(physical_rows, physical_cols);
|
||||||
self.alt_screen.resize(physical_rows, physical_cols);
|
|
||||||
self.scroll_region = 0..physical_rows as i64;
|
self.scroll_region = 0..physical_rows as i64;
|
||||||
self.tabs.resize(physical_cols);
|
self.tabs.resize(physical_cols);
|
||||||
self.set_scroll_viewport(0);
|
self.set_scroll_viewport(0);
|
||||||
@ -1133,9 +1167,9 @@ impl TerminalState {
|
|||||||
Mode::SetDecPrivateMode(DecPrivateMode::Code(
|
Mode::SetDecPrivateMode(DecPrivateMode::Code(
|
||||||
DecPrivateModeCode::ClearAndEnableAlternateScreen,
|
DecPrivateModeCode::ClearAndEnableAlternateScreen,
|
||||||
)) => {
|
)) => {
|
||||||
if !self.alt_screen_is_active {
|
if !self.screen.is_alt_screen_active() {
|
||||||
self.save_cursor();
|
self.save_cursor();
|
||||||
self.alt_screen_is_active = true;
|
self.screen.activate_alt_screen();
|
||||||
self.set_cursor_pos(&Position::Absolute(0), &Position::Absolute(0));
|
self.set_cursor_pos(&Position::Absolute(0), &Position::Absolute(0));
|
||||||
self.erase_in_display(EraseInDisplay::EraseDisplay);
|
self.erase_in_display(EraseInDisplay::EraseDisplay);
|
||||||
self.set_scroll_viewport(0);
|
self.set_scroll_viewport(0);
|
||||||
@ -1144,8 +1178,8 @@ impl TerminalState {
|
|||||||
Mode::ResetDecPrivateMode(DecPrivateMode::Code(
|
Mode::ResetDecPrivateMode(DecPrivateMode::Code(
|
||||||
DecPrivateModeCode::ClearAndEnableAlternateScreen,
|
DecPrivateModeCode::ClearAndEnableAlternateScreen,
|
||||||
)) => {
|
)) => {
|
||||||
if self.alt_screen_is_active {
|
if self.screen.is_alt_screen_active() {
|
||||||
self.alt_screen_is_active = false;
|
self.screen.activate_primary_screen();
|
||||||
self.restore_cursor();
|
self.restore_cursor();
|
||||||
self.set_scroll_viewport(0);
|
self.set_scroll_viewport(0);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user