From 88f44f5b5f4e21b3a64d07dd21e6deb66e5f9056 Mon Sep 17 00:00:00 2001 From: Dylan Frankland Date: Mon, 25 Jan 2021 21:26:23 -0800 Subject: [PATCH] Add erase mode to ClearScrollback action (#439) * Add ClearBuffer action Clears all lines, both visible and those scrolled off the top of the viewport, making the prompt line the new first line and resetting the scrollbar thumb to the full height of the window. This is the behavior that Hyper / xterm has for clearing the terminal. * Combine ClearBuffer into ClearScrollback as enum with associated erase mode Makes it easier to manage the different options of clearing the terminal. --- config/src/keyassignment.rs | 26 ++++++++++++++++--- .../lua/keyassignment/ClearScrollback.md | 11 +++++--- mux/src/localpane.rs | 12 +++++++-- mux/src/pane.rs | 3 ++- mux/src/termwiztermtab.rs | 12 +++++++-- term/src/terminalstate.rs | 13 ++++++++++ wezterm-gui/src/gui/overlay/copy.rs | 5 ++-- wezterm-gui/src/gui/overlay/search.rs | 5 ++-- wezterm-gui/src/gui/termwindow.rs | 4 +-- 9 files changed, 73 insertions(+), 18 deletions(-) diff --git a/config/src/keyassignment.rs b/config/src/keyassignment.rs index 55c38d6d4..18e490945 100644 --- a/config/src/keyassignment.rs +++ b/config/src/keyassignment.rs @@ -111,6 +111,18 @@ pub enum PaneDirection { Right, } +#[derive(Debug, Copy, Clone, Deserialize, Serialize, PartialEq, Eq)] +pub enum ScrollbackEraseMode { + ScrollbackOnly, + ScrollbackAndViewport, +} + +impl Default for ScrollbackEraseMode { + fn default() -> Self { + Self::ScrollbackOnly + } +} + #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)] pub enum KeyAssignment { SpawnTab(SpawnTabDomain), @@ -143,7 +155,7 @@ pub enum KeyAssignment { SplitHorizontal(SpawnCommand), SplitVertical(SpawnCommand), ShowLauncher, - ClearScrollback, + ClearScrollback(ScrollbackEraseMode), Search(Pattern), ActivateCopyMode, @@ -216,8 +228,16 @@ impl InputMap { [Modifiers::SUPER, KeyCode::Char('n'), SpawnWindow], [Modifiers::CTRL, KeyCode::Char('M'), Hide], [Modifiers::CTRL, KeyCode::Char('N'), SpawnWindow], - [Modifiers::SUPER, KeyCode::Char('k'), ClearScrollback], - [Modifiers::CTRL, KeyCode::Char('K'), ClearScrollback], + [ + Modifiers::SUPER, + KeyCode::Char('k'), + ClearScrollback(ScrollbackEraseMode::ScrollbackOnly) + ], + [ + Modifiers::CTRL, + KeyCode::Char('K'), + ClearScrollback(ScrollbackEraseMode::ScrollbackOnly) + ], [ Modifiers::SUPER, KeyCode::Char('f'), diff --git a/docs/config/lua/keyassignment/ClearScrollback.md b/docs/config/lua/keyassignment/ClearScrollback.md index 19853533c..3d10391e0 100644 --- a/docs/config/lua/keyassignment/ClearScrollback.md +++ b/docs/config/lua/keyassignment/ClearScrollback.md @@ -1,14 +1,17 @@ # ClearScrollback Clears the lines that have scrolled off the top of the viewport, resetting -the scrollbar thumb to the full height of the window. +the scrollbar thumb to the full height of the window, and additionally the +viewport depending on the argument: ```lua return { keys = { - {key="K", mods="CTRL|SHIFT", action="ClearScrollback"} + -- Clears only the scrollback and leaves the viewport intact. + -- This is the default behavior. + {key="K", mods="CTRL|SHIFT", action=wezterm.action{ClearScrollback="ScrollbackOnly"}} + -- Clears the scrollback and viewport leaving the prompt line the new first line. + {key="K", mods="CTRL|SHIFT", action=wezterm.action{ClearScrollback="ScrollbackAndViewport"}} } } ``` - - diff --git a/mux/src/localpane.rs b/mux/src/localpane.rs index 097b4a974..892e88924 100644 --- a/mux/src/localpane.rs +++ b/mux/src/localpane.rs @@ -5,6 +5,7 @@ use crate::tmux::{TmuxDomain, TmuxDomainState}; use crate::{Domain, Mux}; use anyhow::Error; use async_trait::async_trait; +use config::keyassignment::ScrollbackEraseMode; use portable_pty::{Child, MasterPty, PtySize}; use rangeset::RangeSet; use std::cell::{RefCell, RefMut}; @@ -147,8 +148,15 @@ impl Pane for LocalPane { self.domain_id } - fn erase_scrollback(&self) { - self.terminal.borrow_mut().erase_scrollback(); + fn erase_scrollback(&self, erase_mode: ScrollbackEraseMode) { + match erase_mode { + ScrollbackEraseMode::ScrollbackOnly => { + self.terminal.borrow_mut().erase_scrollback(); + } + ScrollbackEraseMode::ScrollbackAndViewport => { + self.terminal.borrow_mut().erase_scrollback_and_viewport(); + } + } } fn focus_changed(&self, focused: bool) { diff --git a/mux/src/pane.rs b/mux/src/pane.rs index 9d7e8872e..bd37e5389 100644 --- a/mux/src/pane.rs +++ b/mux/src/pane.rs @@ -2,6 +2,7 @@ use crate::domain::DomainId; use crate::renderable::*; use crate::Mux; use async_trait::async_trait; +use config::keyassignment::ScrollbackEraseMode; use downcast_rs::{impl_downcast, Downcast}; use portable_pty::PtySize; use rangeset::RangeSet; @@ -117,7 +118,7 @@ pub trait Pane: Downcast { fn palette(&self) -> ColorPalette; fn domain_id(&self) -> DomainId; - fn erase_scrollback(&self) {} + fn erase_scrollback(&self, _erase_mode: ScrollbackEraseMode) {} /// Called to advise on whether this tab has focus fn focus_changed(&self, _focused: bool) {} diff --git a/mux/src/termwiztermtab.rs b/mux/src/termwiztermtab.rs index 17bb97770..cd21e835f 100644 --- a/mux/src/termwiztermtab.rs +++ b/mux/src/termwiztermtab.rs @@ -11,6 +11,7 @@ use crate::window::WindowId; use crate::Mux; use anyhow::bail; use async_trait::async_trait; +use config::keyassignment::ScrollbackEraseMode; use crossbeam::channel::{unbounded as channel, Receiver, Sender}; use filedescriptor::{FileDescriptor, Pipe}; use portable_pty::*; @@ -248,8 +249,15 @@ impl Pane for TermWizTerminalPane { self.terminal.borrow().get_current_dir().cloned() } - fn erase_scrollback(&self) { - self.terminal.borrow_mut().erase_scrollback(); + fn erase_scrollback(&self, erase_mode: ScrollbackEraseMode) { + match erase_mode { + ScrollbackEraseMode::ScrollbackOnly => { + self.terminal.borrow_mut().erase_scrollback(); + } + ScrollbackEraseMode::ScrollbackAndViewport => { + self.terminal.borrow_mut().erase_scrollback_and_viewport(); + } + } } } diff --git a/term/src/terminalstate.rs b/term/src/terminalstate.rs index 70d69dd85..cb5440f43 100644 --- a/term/src/terminalstate.rs +++ b/term/src/terminalstate.rs @@ -674,6 +674,19 @@ impl TerminalState { } } + pub fn erase_scrollback_and_viewport(&mut self) { + self.erase_in_display(EraseInDisplay::EraseScrollback); + + let row_index = self.screen.phys_row(self.cursor.y); + let row = self.screen.lines[row_index].clone(); + + self.erase_in_display(EraseInDisplay::EraseDisplay); + + self.screen.lines[0] = row; + + self.cursor.y = 0; + } + /// Discards the scrollback, leaving only the data that is present /// in the viewport. pub fn erase_scrollback(&mut self) { diff --git a/wezterm-gui/src/gui/overlay/copy.rs b/wezterm-gui/src/gui/overlay/copy.rs index b9ce68df9..db21f4551 100644 --- a/wezterm-gui/src/gui/overlay/copy.rs +++ b/wezterm-gui/src/gui/overlay/copy.rs @@ -1,5 +1,6 @@ use crate::gui::selection::{SelectionCoordinate, SelectionRange}; use crate::gui::termwindow::TermWindow; +use config::keyassignment::ScrollbackEraseMode; use mux::domain::DomainId; use mux::pane::{Pane, PaneId}; use mux::renderable::*; @@ -497,8 +498,8 @@ impl Pane for CopyOverlay { self.delegate.domain_id() } - fn erase_scrollback(&self) { - self.delegate.erase_scrollback() + fn erase_scrollback(&self, erase_mode: ScrollbackEraseMode) { + self.delegate.erase_scrollback(erase_mode) } fn is_mouse_grabbed(&self) -> bool { diff --git a/wezterm-gui/src/gui/overlay/search.rs b/wezterm-gui/src/gui/overlay/search.rs index 67687f36d..b8bdd13fe 100644 --- a/wezterm-gui/src/gui/overlay/search.rs +++ b/wezterm-gui/src/gui/overlay/search.rs @@ -1,5 +1,6 @@ use crate::gui::selection::{SelectionCoordinate, SelectionRange}; use crate::gui::termwindow::TermWindow; +use config::keyassignment::ScrollbackEraseMode; use mux::domain::DomainId; use mux::pane::{Pane, PaneId, Pattern, SearchResult}; use mux::renderable::*; @@ -235,8 +236,8 @@ impl Pane for SearchOverlay { self.delegate.domain_id() } - fn erase_scrollback(&self) { - self.delegate.erase_scrollback() + fn erase_scrollback(&self, erase_mode: ScrollbackEraseMode) { + self.delegate.erase_scrollback(erase_mode) } fn is_mouse_grabbed(&self) -> bool { diff --git a/wezterm-gui/src/gui/termwindow.rs b/wezterm-gui/src/gui/termwindow.rs index fe7c5e96a..bcbc40069 100644 --- a/wezterm-gui/src/gui/termwindow.rs +++ b/wezterm-gui/src/gui/termwindow.rs @@ -2078,8 +2078,8 @@ impl TermWindow { window.invalidate(); } } - ClearScrollback => { - pane.erase_scrollback(); + ClearScrollback(erase_mode) => { + pane.erase_scrollback(*erase_mode); let window = self.window.as_ref().unwrap(); window.invalidate(); }