From c5b84d14d05dac45f1d4c89c42ad55debcdef049 Mon Sep 17 00:00:00 2001 From: fengqi <362254883@qq.com> Date: Fri, 12 Jul 2024 23:36:23 +0800 Subject: [PATCH] Terminal: right-click to add "clear all" function --- lapce-app/src/command.rs | 6 +++ lapce-app/src/panel/terminal_view.rs | 72 ++++++++++++++++++++-------- lapce-app/src/window_tab.rs | 33 +++++++++++++ 3 files changed, 92 insertions(+), 19 deletions(-) diff --git a/lapce-app/src/command.rs b/lapce-app/src/command.rs index 23a17797a9..ba9ae6fd96 100644 --- a/lapce-app/src/command.rs +++ b/lapce-app/src/command.rs @@ -3,6 +3,7 @@ use std::{path::PathBuf, rc::Rc, sync::Arc}; pub use floem::views::editor::command::CommandExecuted; use floem::{ keyboard::Modifiers, peniko::kurbo::Vec2, views::editor::command::Command, + ViewId, }; use indexmap::IndexMap; use lapce_core::command::{ @@ -724,6 +725,11 @@ pub enum InternalCommand { program: String, arguments: Vec, }, + ClearTerminalBuffer { + view_id: ViewId, + tab_index: usize, + terminal_index: usize, + }, } #[derive(Clone)] diff --git a/lapce-app/src/panel/terminal_view.rs b/lapce-app/src/panel/terminal_view.rs index 39c20840ea..462e145a14 100644 --- a/lapce-app/src/panel/terminal_view.rs +++ b/lapce-app/src/panel/terminal_view.rs @@ -1,5 +1,7 @@ use std::rc::Rc; +use floem::action::show_context_menu; +use floem::menu::{Menu, MenuItem}; use floem::{ event::{Event, EventListener, EventPropagation}, kurbo::Size, @@ -9,10 +11,12 @@ use floem::{ scroll::{scroll, Thickness, VerticalScrollAsHorizontal}, stack, svg, tab, Decorators, }, - View, + View, ViewId, }; use super::kind::PanelKind; +use crate::command::InternalCommand; +use crate::listener::Listener; use crate::{ app::clickable_icon, command::LapceWorkbenchCommand, @@ -252,6 +256,7 @@ fn terminal_tab_header(window_tab_data: Rc) -> impl View { fn terminal_tab_split( terminal_panel_data: TerminalPanelData, terminal_tab_data: TerminalTabData, + tab_index: usize, ) -> impl View { let config = terminal_panel_data.common.config; let internal_command = terminal_panel_data.common.internal_command; @@ -273,7 +278,7 @@ fn terminal_tab_split( let terminal_panel_data = terminal_panel_data.clone(); let terminal_scope = terminal.scope; container({ - terminal_view( + let terminal_view = terminal_view( terminal.term_id, terminal.raw.read_only(), terminal.mode.read_only(), @@ -282,22 +287,32 @@ fn terminal_tab_split( terminal.launch_error, internal_command, workspace.clone(), - ) - .on_event_cont(EventListener::PointerDown, move |_| { - active.set(index.get_untracked()); - }) - .on_event(EventListener::PointerWheel, move |event| { - if let Event::PointerWheel(pointer_event) = event { - terminal.clone().wheel_scroll(pointer_event.delta.y); - EventPropagation::Stop - } else { - EventPropagation::Continue - } - }) - .on_cleanup(move || { - terminal_scope.dispose(); - }) - .style(|s| s.size_pct(100.0, 100.0)) + ); + let view_id = terminal_view.id(); + terminal_view + .on_event_cont(EventListener::PointerDown, move |_| { + active.set(index.get_untracked()); + }) + .on_secondary_click_stop(move |_| { + tab_secondary_click( + internal_command, + view_id, + tab_index, + index.get_untracked(), + ); + }) + .on_event(EventListener::PointerWheel, move |event| { + if let Event::PointerWheel(pointer_event) = event { + terminal.clone().wheel_scroll(pointer_event.delta.y); + EventPropagation::Stop + } else { + EventPropagation::Continue + } + }) + .on_cleanup(move || { + terminal_scope.dispose(); + }) + .style(|s| s.size_pct(100.0, 100.0)) }) .style(move |s| { s.size_pct(100.0, 100.0).padding_horiz(10.0).apply_if( @@ -323,7 +338,26 @@ fn terminal_tab_content(window_tab_data: Rc) -> impl View { move || terminal.tab_info.with(|info| info.active), move || terminal.tab_info.with(|info| info.tabs.clone()), |(_, tab)| tab.terminal_tab_id, - move |(_, tab)| terminal_tab_split(terminal.clone(), tab), + move |(tab_index, tab)| { + terminal_tab_split(terminal.clone(), tab, tab_index.get_untracked()) + }, ) .style(|s| s.size_pct(100.0, 100.0)) } + +fn tab_secondary_click( + internal_command: Listener, + view_id: ViewId, + tab_index: usize, + terminal_index: usize, +) { + let mut menu = Menu::new(""); + menu = menu.entry(MenuItem::new("Clear All").action(move || { + internal_command.send(InternalCommand::ClearTerminalBuffer { + view_id, + tab_index, + terminal_index, + }); + })); + show_context_menu(menu, None); +} diff --git a/lapce-app/src/window_tab.rs b/lapce-app/src/window_tab.rs index f2060fd5ca..cdc63cd583 100644 --- a/lapce-app/src/window_tab.rs +++ b/lapce-app/src/window_tab.rs @@ -1,3 +1,4 @@ +use alacritty_terminal::vte::ansi::Handler; use std::{ collections::{BTreeMap, HashSet}, env, @@ -1780,6 +1781,38 @@ impl WindowTabData { } }; } + InternalCommand::ClearTerminalBuffer { + view_id, + tab_index, + terminal_index, + } => { + let Some(tab) = self.terminal.tab_info.with_untracked(|x| { + x.tabs.iter().find_map(|(index, data)| { + if index.get_untracked() == tab_index { + Some(data.clone()) + } else { + None + } + }) + }) else { + error!("cound not find terminal tab data: index={tab_index}"); + return; + }; + let Some(raw) = tab.terminals.with_untracked(|x| { + x.iter().find_map(|(index, data)| { + if index.get_untracked() == terminal_index { + Some(data.raw.get_untracked()) + } else { + None + } + }) + }) else { + error!("cound not find terminal data: index={terminal_index}"); + return; + }; + raw.write().term.reset_state(); + view_id.request_paint(); + } } }