Skip to content

Commit

Permalink
feat(terminal): cli and bindable action to clear all buffers for a sp…
Browse files Browse the repository at this point in the history
…ecific pane (#2239)

* fix typo

* Add clear screen action

* add proper test

* added bindable action; remove pointless default impl

* add default binding

* use imsnif's variant

* remove commented example config

* remove log line

---------

Co-authored-by: Aram Drevekenin <[email protected]>
  • Loading branch information
olekspickle and imsnif authored Mar 29, 2023
1 parent 638f2ad commit bdb39b1
Show file tree
Hide file tree
Showing 14 changed files with 83 additions and 2 deletions.
1 change: 1 addition & 0 deletions docs/MANPAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ ACTIONS
next ID.
* __MoveFocus: <Direction\>__ - moves focus in the specified direction (Left,
Right, Up, Down).
* __Clear__ - clears current screen.
* __DumpScreen: <File\>__ - dumps the screen in the specified file.
* __EditScrollback__ - replaces the current pane with the scrollback buffer.
* __ScrollUp__ - scrolls up 1 line in the focused pane.
Expand Down
2 changes: 1 addition & 1 deletion src/sessions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ pub(crate) fn assert_session_ne(name: &str) {
process::exit(1);
}
if name.contains('/') {
eprintln!("Session name cannot contains '/'.");
eprintln!("Session name cannot contain '/'.");
process::exit(1);
}

Expand Down
1 change: 1 addition & 0 deletions zellij-client/src/input_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ impl InputHandler {
.send_to_server(ClientToServerMsg::Action(action, None));
},
Action::CloseFocus
| Action::ClearScreen
| Action::NewPane(..)
| Action::Run(_)
| Action::ToggleFloatingPanes
Expand Down
11 changes: 10 additions & 1 deletion zellij-server/src/panes/grid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1109,7 +1109,16 @@ impl Grid {
Some((self.cursor.x, self.cursor.y))
}
}

/// Clears all buffers with text for a current screen
pub fn clear_screen(&mut self) {
if self.alternate_screen_state.is_some() {
log::warn!("Tried to clear pane with alternate_screen_state");
return;
}
self.reset_terminal_state();
self.mark_for_rerender();
}
/// Dumps all lines above terminal vieport and the viewport itself to a string
pub fn dump_screen(&mut self, full: bool) -> String {
let viewport: String = dump_screen!(self.viewport);
if !full {
Expand Down
3 changes: 3 additions & 0 deletions zellij-server/src/panes/plugin_pane.rs
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,9 @@ impl Pane for PluginPane {
)]))
.unwrap();
}
fn clear_screen(&mut self) {
// do nothing
}
fn clear_scroll(&mut self) {
// noop
}
Expand Down
3 changes: 3 additions & 0 deletions zellij-server/src/panes/terminal_pane.rs
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,9 @@ impl Pane for TerminalPane {
fn dump_screen(&mut self, _client_id: ClientId, full: bool) -> String {
self.grid.dump_screen(full)
}
fn clear_screen(&mut self) {
self.grid.clear_screen()
}
fn scroll_up(&mut self, count: usize, _client_id: ClientId) {
self.grid.move_viewport_up(count);
self.set_should_render(true);
Expand Down
6 changes: 6 additions & 0 deletions zellij-server/src/route.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,12 @@ pub(crate) fn route_action(
.send_to_screen(ScreenInstruction::MovePaneBackwards(client_id))
.with_context(err_context)?;
},
Action::ClearScreen => {
session
.senders
.send_to_screen(ScreenInstruction::ClearScreen(client_id))
.with_context(err_context)?;
},
Action::DumpScreen(val, full) => {
session
.senders
Expand Down
14 changes: 14 additions & 0 deletions zellij-server/src/screen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ pub enum ScreenInstruction {
MovePaneRight(ClientId),
MovePaneLeft(ClientId),
Exit,
ClearScreen(ClientId),
DumpScreen(String, ClientId, bool),
EditScrollback(ClientId),
ScrollUp(ClientId),
Expand Down Expand Up @@ -327,6 +328,7 @@ impl From<&ScreenInstruction> for ScreenContext {
ScreenInstruction::MovePaneRight(..) => ScreenContext::MovePaneRight,
ScreenInstruction::MovePaneLeft(..) => ScreenContext::MovePaneLeft,
ScreenInstruction::Exit => ScreenContext::Exit,
ScreenInstruction::ClearScreen(..) => ScreenContext::ClearScreen,
ScreenInstruction::DumpScreen(..) => ScreenContext::DumpScreen,
ScreenInstruction::EditScrollback(..) => ScreenContext::EditScrollback,
ScreenInstruction::ScrollUp(..) => ScreenContext::ScrollUp,
Expand Down Expand Up @@ -1764,6 +1766,18 @@ pub(crate) fn screen_thread_main(
screen.render()?;
screen.unblock_input()?;
},
ScreenInstruction::ClearScreen(client_id) => {
active_tab_and_connected_client_id!(
screen,
client_id,
|tab: &mut Tab, client_id: ClientId| tab.clear_active_terminal_screen(
client_id,
),
?
);
screen.render()?;
screen.unblock_input()?;
},
ScreenInstruction::DumpScreen(file, client_id, full) => {
active_tab_and_connected_client_id!(
screen,
Expand Down
7 changes: 7 additions & 0 deletions zellij-server/src/tab/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ pub trait Pane {
fn push_right(&mut self, count: usize);
fn pull_left(&mut self, count: usize);
fn pull_up(&mut self, count: usize);
fn clear_screen(&mut self);
fn dump_screen(&mut self, _client_id: ClientId, _full: bool) -> String {
"".to_owned()
}
Expand Down Expand Up @@ -2419,6 +2420,12 @@ impl Tab {
}
Ok(())
}
pub fn clear_active_terminal_screen(&mut self, client_id: ClientId) -> Result<()> {
if let Some(active_pane) = self.get_active_pane_or_floating_pane_mut(client_id) {
active_pane.clear_screen();
}
Ok(())
}
pub fn dump_active_terminal_screen(
&mut self,
file: Option<String>,
Expand Down
29 changes: 29 additions & 0 deletions zellij-server/src/tab/unit/tab_integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,35 @@ fn dump_screen() {
);
}

#[test]
fn clear_screen() {
let size = Size {
cols: 121,
rows: 20,
};
let client_id = 1;
let mut tab = create_new_tab(size, ModeInfo::default());
let map = Arc::new(Mutex::new(HashMap::new()));
tab.os_api = Box::new(FakeInputOutput {
file_dumps: map.clone(),
..Default::default()
});
let new_pane_id = PaneId::Terminal(2);
tab.new_pane(new_pane_id, None, None, Some(client_id))
.unwrap();
tab.handle_pty_bytes(2, Vec::from("scratch".as_bytes()))
.unwrap();
let file = "/tmp/log-clear-screen.sh";
tab.clear_active_terminal_screen(client_id).unwrap();
tab.dump_active_terminal_screen(Some(file.to_string()), client_id, false)
.unwrap();
assert_eq!(
map.lock().unwrap().get(file).unwrap(),
"",
"screen was cleared properly"
);
}

#[test]
fn new_floating_pane() {
let size = Size {
Expand Down
2 changes: 2 additions & 0 deletions zellij-utils/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,8 @@ pub enum CliAction {
},
/// Rotate the location of the previous pane backwards
MovePaneBackwards,
/// Clear all buffers for a focused pane
Clear,
/// Dump the focused pane to a file
DumpScreen {
path: PathBuf,
Expand Down
1 change: 1 addition & 0 deletions zellij-utils/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ pub enum ScreenContext {
MovePaneRight,
MovePaneLeft,
Exit,
ClearScreen,
DumpScreen,
EditScrollback,
ScrollUp,
Expand Down
3 changes: 3 additions & 0 deletions zellij-utils/src/input/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ pub enum Action {
MoveFocusOrTab(Direction),
MovePane(Option<Direction>),
MovePaneBackwards,
/// Clear all buffers of a current screen
ClearScreen,
/// Dumps the screen to a file
DumpScreen(String, bool),
/// Scroll up in focus pane.
Expand Down Expand Up @@ -255,6 +257,7 @@ impl Action {
CliAction::MoveFocusOrTab { direction } => Ok(vec![Action::MoveFocusOrTab(direction)]),
CliAction::MovePane { direction } => Ok(vec![Action::MovePane(direction)]),
CliAction::MovePaneBackwards => Ok(vec![Action::MovePaneBackwards]),
CliAction::Clear => Ok(vec![Action::ClearScreen]),
CliAction::DumpScreen { path, full } => Ok(vec![Action::DumpScreen(
path.as_os_str().to_string_lossy().into(),
full,
Expand Down
2 changes: 2 additions & 0 deletions zellij-utils/src/kdl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ macro_rules! parse_kdl_action_arguments {
"ToggleMouseMode" => Ok(Action::ToggleMouseMode),
"PreviousSwapLayout" => Ok(Action::PreviousSwapLayout),
"NextSwapLayout" => Ok(Action::NextSwapLayout),
"Clear" => Ok(Action::ClearScreen),
_ => Err(ConfigError::new_kdl_error(
format!("Unsupported action: {:?}", $action_name),
$action_node.span().offset(),
Expand Down Expand Up @@ -689,6 +690,7 @@ impl TryFrom<(&KdlNode, &Options)> for Action {
},
"Detach" => parse_kdl_action_arguments!(action_name, action_arguments, kdl_action),
"Copy" => parse_kdl_action_arguments!(action_name, action_arguments, kdl_action),
"Clear" => parse_kdl_action_arguments!(action_name, action_arguments, kdl_action),
"Confirm" => parse_kdl_action_arguments!(action_name, action_arguments, kdl_action),
"Deny" => parse_kdl_action_arguments!(action_name, action_arguments, kdl_action),
"Write" => parse_kdl_action_u8_arguments!(action_name, action_arguments, kdl_action),
Expand Down

0 comments on commit bdb39b1

Please sign in to comment.