diff --git a/core/src/data.rs b/core/src/data.rs index 0c0fff0d..cf688d9b 100644 --- a/core/src/data.rs +++ b/core/src/data.rs @@ -241,6 +241,7 @@ fn same(&self, other: &Self) -> bool { && self.panel_size.same(&other.panel_size) && self.window_origin.same(&other.window_origin) && self.config.same(&other.config) + && self.terminal.same(&other.terminal) && self.focus == other.focus } } diff --git a/core/src/editor.rs b/core/src/editor.rs index ff23a9bc..15e43ca5 100644 --- a/core/src/editor.rs +++ b/core/src/editor.rs @@ -3049,21 +3049,11 @@ fn event( editor_data.get_code_actions(ctx); data.keypress = keypress.clone(); - data.update_from_editor_buffer_data( - editor_data, - &editor, - &buffer, - ); } Event::Command(cmd) if cmd.is(LAPCE_NEW_COMMAND) => { let command = cmd.get_unchecked(LAPCE_NEW_COMMAND); if let Ok(command) = LapceCommand::from_str(&command.cmd) { editor_data.run_command(ctx, &command, None, env); - data.update_from_editor_buffer_data( - editor_data, - &editor, - &buffer, - ); } } Event::Command(cmd) if cmd.is(LAPCE_UI_COMMAND) => { @@ -3074,14 +3064,10 @@ fn event( &mut editor_data, env, ); - data.update_from_editor_buffer_data( - editor_data, - &editor, - &buffer, - ); } _ => (), } + data.update_from_editor_buffer_data(editor_data, &editor, &buffer); } EditorContent::None => match event { Event::KeyDown(key_event) => { diff --git a/core/src/proxy.rs b/core/src/proxy.rs index 1a9583bf..b369afa5 100644 --- a/core/src/proxy.rs +++ b/core/src/proxy.rs @@ -143,12 +143,25 @@ pub fn new_buffer(&self, buffer_id: BufferId, path: PathBuf) -> Result { return Ok(resp.content); } - pub fn new_terminal(&self, term_id: TermId) { + pub fn new_terminal(&self, term_id: TermId, width: usize, height: usize) { self.wait(); self.peer.lock().as_ref().unwrap().send_rpc_notification( "new_terminal", &json!({ "term_id": term_id, + "width": width, + "height": height, + }), + ) + } + + pub fn terminal_resize(&self, term_id: TermId, width: usize, height: usize) { + self.peer.lock().as_ref().unwrap().send_rpc_notification( + "terminal_resize", + &json!({ + "term_id": term_id, + "width": width, + "height": height, }), ) } diff --git a/core/src/terminal.rs b/core/src/terminal.rs index 1f988b8e..066330dd 100644 --- a/core/src/terminal.rs +++ b/core/src/terminal.rs @@ -1,6 +1,7 @@ use std::sync::Arc; use druid::{ + piet::{Text, TextLayoutBuilder}, BoxConstraints, Data, Env, Event, EventCtx, LayoutCtx, LifeCycle, LifeCycleCtx, PaintCtx, Point, RenderContext, Size, UpdateCtx, Widget, WidgetExt, WidgetId, WidgetPod, @@ -47,7 +48,7 @@ impl LapceTerminalData { pub fn new(proxy: Arc) -> Self { let id = TermId::next(); std::thread::spawn(move || { - proxy.new_terminal(id); + proxy.new_terminal(id, 1, 1); }); Self { id, @@ -146,11 +147,17 @@ fn paint(&mut self, ctx: &mut PaintCtx, data: &LapceTabData, env: &Env) { pub struct LapceTerminal { term_id: TermId, + width: f64, + height: f64, } impl LapceTerminal { pub fn new(term_id: TermId) -> Self { - Self { term_id } + Self { + term_id, + width: 0.0, + height: 0.0, + } } } @@ -189,11 +196,37 @@ fn layout( data: &LapceTabData, env: &Env, ) -> Size { - bc.max() + let size = bc.max(); + if self.width != size.width || self.height != size.height { + self.width = size.width; + self.height = size.height; + let width = data.config.editor_text_width(ctx.text(), "W"); + let line_height = data.config.editor.line_height as f64; + let width = (self.width / width).ceil() as usize; + let height = (self.height / line_height).ceil() as usize; + data.proxy.terminal_resize(self.term_id, width, height); + } + size } fn paint(&mut self, ctx: &mut PaintCtx, data: &LapceTabData, env: &Env) { + let width = data.config.editor_text_width(ctx.text(), "W"); + let line_height = data.config.editor.line_height as f64; + let terminal = data.terminal.terminals.get(&self.term_id).unwrap(); - println!("{:?}", terminal.content); + for (p, cell) in terminal.content.iter() { + let x = p.column.0 as f64 * width; + let y = p.line.0 as f64 * line_height; + let text_layout = ctx + .text() + .new_text_layout(cell.c.to_string()) + .font( + data.config.editor.font_family(), + data.config.editor.font_size as f64, + ) + .build() + .unwrap(); + ctx.draw_text(&text_layout, Point::new(x, y)); + } } } diff --git a/proxy/src/dispatch.rs b/proxy/src/dispatch.rs index 5c856898..5e407982 100644 --- a/proxy/src/dispatch.rs +++ b/proxy/src/dispatch.rs @@ -115,6 +115,13 @@ pub enum Notification { rev: u64, }, NewTerminal { + width: usize, + height: usize, + term_id: TermId, + }, + TerminalResize { + width: usize, + height: usize, term_id: TermId, }, } @@ -406,8 +413,21 @@ fn handle_notification(&self, rpc: Notification) { self.lsp.lock().update(buffer, &content_change, buffer.rev); } } - Notification::NewTerminal { term_id } => { - let (terminal, receiver) = Terminal::new(); + Notification::TerminalResize { + term_id, + width, + height, + } => { + if let Some(terminal) = self.terminals.lock().get(&term_id) { + terminal.resize(width, height); + } + } + Notification::NewTerminal { + term_id, + width, + height, + } => { + let (terminal, receiver) = Terminal::new(width, height); self.terminals.lock().insert(term_id, terminal); let local_proxy = self.clone(); @@ -415,14 +435,15 @@ fn handle_notification(&self, rpc: Notification) { loop { let event = receiver.recv()?; match event { - TerminalEvent::UpdateContent(content) => local_proxy - .send_notification( + TerminalEvent::UpdateContent(content) => { + local_proxy.send_notification( "terminal_update_content", json!({ "id": term_id, "content": content, }), - ), + ); + } } } }); diff --git a/proxy/src/terminal.rs b/proxy/src/terminal.rs index 092423f2..4cbb3382 100644 --- a/proxy/src/terminal.rs +++ b/proxy/src/terminal.rs @@ -71,13 +71,14 @@ fn send_event(&self, event: alacritty_terminal::event::Event) { } impl Terminal { - pub fn new() -> (Self, Receiver) { + pub fn new(width: usize, height: usize) -> (Self, Receiver) { let config = TermConfig::default(); let (sender, receiver) = crossbeam_channel::unbounded(); let event_proxy = EventProxy { sender: sender.clone(), }; - let size = SizeInfo::new(10.0, 10.0, 1.0, 1.0, 0.0, 0.0, true); + let size = + SizeInfo::new(width as f32, height as f32, 1.0, 1.0, 0.0, 0.0, true); let pty = tty::new(&config, &size, None); let terminal = Term::new(&config, size, event_proxy.clone()); let terminal = Arc::new(FairMutex::new(terminal)); @@ -97,6 +98,18 @@ pub fn new() -> (Self, Receiver) { (terminal, host_receiver) } + pub fn resize(&self, width: usize, height: usize) { + self.term.lock().resize(SizeInfo::new( + width as f32, + height as f32, + 1.0, + 1.0, + 0.0, + 0.0, + true, + )); + } + fn run(&self, receiver: Receiver, notifier: Notifier) { let term = self.term.clone(); let host_sender = self.host_sender.clone();