diff --git a/core/src/command.rs b/core/src/command.rs index ceb08469..451bdb61 100644 --- a/core/src/command.rs +++ b/core/src/command.rs @@ -24,7 +24,6 @@ proxy::TerminalContent, split::SplitMoveDirection, state::LapceWorkspace, - terminal::TermId, }; pub const LAPCE_NEW_COMMAND: Selector = @@ -379,7 +378,7 @@ pub enum LapceUICommand { PublishDiagnostics(PublishDiagnosticsParams), UpdateDiffFiles(Vec), TerminalUpdateContent( - TermId, + WidgetId, TerminalContent, alacritty_terminal::index::Point, CursorShape, @@ -394,6 +393,7 @@ pub enum LapceUICommand { ScrollTo((f64, f64)), ForceScrollTo(f64, f64), SplitTerminal(bool, WidgetId), + SplitTerminalClose(WidgetId), SplitEditor(bool, WidgetId), SplitEditorMove(SplitMoveDirection, WidgetId), SplitEditorExchange(WidgetId), diff --git a/core/src/proxy.rs b/core/src/proxy.rs index f4507551..788a9fb8 100644 --- a/core/src/proxy.rs +++ b/core/src/proxy.rs @@ -27,7 +27,6 @@ use crate::command::LapceUICommand; use crate::state::LapceWorkspace; use crate::state::LapceWorkspaceType; -use crate::terminal::TermId; use crate::{buffer::BufferId, command::LAPCE_UI_COMMAND}; pub type TerminalContent = Vec<(alacritty_terminal::index::Point, Cell)>; diff --git a/core/src/split.rs b/core/src/split.rs index 666776ad..7ddf1029 100644 --- a/core/src/split.rs +++ b/core/src/split.rs @@ -312,7 +312,7 @@ pub fn split_terminal( let terminal = LapcePadding::new(10.0, LapceTerminal::new(&terminal_data)); Arc::make_mut(&mut data.terminal) .terminals - .insert(terminal_data.id, terminal_data.clone()); + .insert(terminal_data.widget_id, terminal_data.clone()); self.insert_flex_child( index + 1, @@ -324,6 +324,55 @@ pub fn split_terminal( ctx.children_changed(); } + pub fn split_terminal_close( + &mut self, + ctx: &mut EventCtx, + data: &mut LapceTabData, + widget_id: WidgetId, + ) { + if self.children.len() == 0 { + return; + } + + if self.children.len() == 1 { + return; + } + + let mut index = 0; + for (i, child_id) in self.children_ids.iter().enumerate() { + if child_id == &widget_id { + index = i; + break; + } + } + + let new_index = if index >= self.children.len() - 1 { + index - 1 + } else { + index + 1 + }; + let terminal_id = self.children[index].widget.id(); + let new_terminal_id = self.children[new_index].widget.id(); + // let new_terminal = data.terminal.terminals.get(&new_terminal_id).unwrap(); + + ctx.submit_command(Command::new( + LAPCE_UI_COMMAND, + LapceUICommand::Focus, + Target::Widget(new_terminal_id), + )); + // if *data.main_split.active == view_id { + // data.main_split.active = Arc::new(new_editor.view_id); + // data.focus = new_editor.view_id; + // ctx.set_focus(new_editor.view_id); + // } + data.main_split.editors.remove(&terminal_id); + self.children.remove(index); + self.children_ids.remove(index); + + self.even_flex_children(); + ctx.children_changed(); + } + pub fn split_editor( &mut self, ctx: &mut EventCtx, @@ -408,6 +457,9 @@ fn event( LapceUICommand::SplitTerminal(vertical, widget_id) => { self.split_terminal(ctx, data, *vertical, *widget_id); } + LapceUICommand::SplitTerminalClose(widget_id) => { + self.split_terminal_close(ctx, data, *widget_id); + } _ => (), } } diff --git a/core/src/terminal.rs b/core/src/terminal.rs index 3271e283..6832cbd6 100644 --- a/core/src/terminal.rs +++ b/core/src/terminal.rs @@ -38,7 +38,7 @@ pub struct TerminalSplitData { pub widget_id: WidgetId, pub split_id: WidgetId, - pub terminals: im::HashMap>, + pub terminals: im::HashMap>, } impl TerminalSplitData { @@ -47,7 +47,7 @@ pub fn new(proxy: Arc) -> Self { let mut terminals = im::HashMap::new(); let terminal = Arc::new(LapceTerminalData::new(split_id, proxy)); - terminals.insert(terminal.id, terminal); + terminals.insert(terminal.widget_id, terminal); Self { widget_id: WidgetId::next(), @@ -124,7 +124,6 @@ fn insert(&mut self, ctx: &mut EventCtx, c: &str) { #[derive(Clone)] pub struct LapceTerminalData { - pub id: TermId, pub widget_id: WidgetId, pub split_id: WidgetId, pub content: TerminalContent, @@ -136,10 +135,8 @@ pub struct LapceTerminalData { impl LapceTerminalData { pub fn new(split_id: WidgetId, proxy: Arc) -> Self { - let id = TermId::next(); let (terminal, receiver) = Terminal::new(50, 20); Self { - id, widget_id: WidgetId::next(), split_id, content: TerminalContent::new(), @@ -241,7 +238,6 @@ fn paint(&mut self, ctx: &mut PaintCtx, data: &LapceTabData, env: &Env) { } pub struct LapceTerminal { - term_id: TermId, widget_id: WidgetId, width: f64, height: f64, @@ -250,7 +246,6 @@ pub struct LapceTerminal { impl LapceTerminal { pub fn new(data: &LapceTerminalData) -> Self { Self { - term_id: data.id, widget_id: data.widget_id, width: 0.0, height: 0.0, @@ -270,8 +265,12 @@ fn event( data: &mut LapceTabData, env: &Env, ) { - let old_terminal_data = - data.terminal.terminals.get(&self.term_id).unwrap().clone(); + let old_terminal_data = data + .terminal + .terminals + .get(&self.widget_id) + .unwrap() + .clone(); let mut term_data = LapceTerminalViewData { terminal: old_terminal_data.clone(), proxy: data.proxy.clone(), @@ -330,8 +329,9 @@ fn event( if let Some(receiver) = Arc::make_mut(&mut term_data.terminal).receiver.take() { - let term_id = term_data.terminal.id; + let widget_id = term_data.terminal.widget_id; let event_sink = ctx.get_external_handle(); + let split_id = term_data.terminal.split_id; std::thread::spawn(move || -> Result<()> { loop { let event = receiver.recv()?; @@ -343,7 +343,7 @@ fn event( event_sink.submit_command( LAPCE_UI_COMMAND, LapceUICommand::TerminalUpdateContent( - term_id, + widget_id, content, cursor.point, cursor.shape, @@ -351,6 +351,15 @@ fn event( Target::Auto, ); } + TerminalHostEvent::Exit => { + event_sink.submit_command( + LAPCE_UI_COMMAND, + LapceUICommand::SplitTerminalClose( + widget_id, + ), + Target::Widget(split_id), + ); + } } } }); @@ -364,7 +373,7 @@ fn event( if !term_data.terminal.same(&old_terminal_data) { Arc::make_mut(&mut data.terminal) .terminals - .insert(term_data.terminal.id, term_data.terminal.clone()); + .insert(term_data.terminal.widget_id, term_data.terminal.clone()); } } @@ -414,7 +423,7 @@ fn layout( let line_height = data.config.editor.line_height as f64; let width = (self.width / width).floor() as usize; let height = (self.height / line_height).floor() as usize; - let terminal = data.terminal.terminals.get(&self.term_id).unwrap(); + let terminal = data.terminal.terminals.get(&self.widget_id).unwrap(); terminal.terminal.resize(width, height); } size @@ -426,7 +435,7 @@ fn paint(&mut self, ctx: &mut PaintCtx, data: &LapceTabData, env: &Env) { let line_height = data.config.editor.line_height as f64; let y_shift = (line_height - char_size.height) / 2.0; - let terminal = data.terminal.terminals.get(&self.term_id).unwrap(); + let terminal = data.terminal.terminals.get(&self.widget_id).unwrap(); let rect = Size::new(char_width, line_height) @@ -486,16 +495,6 @@ fn paint(&mut self, ctx: &mut PaintCtx, data: &LapceTabData, env: &Env) { } } -#[derive(Eq, PartialEq, Hash, Copy, Clone, Debug, Serialize, Deserialize)] -pub struct TermId(pub u64); - -impl TermId { - pub fn next() -> Self { - static TERM_ID_COUNTER: Counter = Counter::new(); - Self(TERM_ID_COUNTER.next()) - } -} - pub enum TerminalEvent { resize(usize, usize), event(alacritty_terminal::event::Event), @@ -506,6 +505,7 @@ pub enum TerminalHostEvent { cursor: RenderableCursor, content: Vec<(alacritty_terminal::index::Point, Cell)>, }, + Exit, } #[derive(Clone)] @@ -622,7 +622,9 @@ fn run(&self, receiver: Receiver, mut notifier: Notifier) { host_sender.send(event); } alacritty_terminal::event::Event::Bell => {} - alacritty_terminal::event::Event::Exit => {} + alacritty_terminal::event::Event::Exit => { + host_sender.send(TerminalHostEvent::Exit); + } }, } }