From 186edf18190bb403427365ff285431b0c272c900 Mon Sep 17 00:00:00 2001 From: Keith Simmons Date: Mon, 16 Dec 2019 17:48:37 -0800 Subject: [PATCH] better neovim process tracking and separated background/foreground rendering --- src/main.rs | 53 +++++++++++++++++++++++++++++---------------------- src/window.rs | 32 +++++++++++++++++++++++++------ 2 files changed, 56 insertions(+), 29 deletions(-) diff --git a/src/main.rs b/src/main.rs index 026d276..770ced1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,33 +24,15 @@ use events::parse_neovim_event; const INITIAL_WIDTH: u64 = 100; const INITIAL_HEIGHT: u64 = 50; - -fn nvim_event_loop(receiver: Receiver<(String, Vec)>, editor: &Arc>) { - println!("UI thread spawned"); - loop { - let (event_name, events) = receiver.recv().expect("Could not receive event."); - let parsed_events = parse_neovim_event(event_name, events).expect("Event parse failed..."); - for event in parsed_events { - let mut editor = editor.lock().unwrap(); - editor.handle_redraw_event(event); - } - } -} - #[cfg(target_os = "windows")] fn set_windows_creation_flags(cmd: &mut Command) { use std::os::windows::process::CommandExt; cmd.creation_flags(0x08000000); // CREATE_NO_WINDOW } -fn main() { - env_logger::from_env(LoggerEnv::default().default_filter_or("warn")).init(); - - panic::set_hook(Box::new(|_| { - exit(1); - })); - +fn create_nvim_command() -> Command { let mut cmd = Command::new("nvim"); + cmd.arg("--embed") .args(std::env::args().skip(1)) .stderr(Stdio::inherit()); @@ -58,8 +40,14 @@ fn main() { #[cfg(target_os = "windows")] set_windows_creation_flags(&mut cmd); + cmd +} + +fn start_nvim(editor: Arc>) -> Neovim { + let mut cmd = create_nvim_command(); let mut session = Session::new_child_cmd(&mut cmd).unwrap(); let receiver = session.start_event_loop_channel(); + let join_handle = session.take_dispatch_guard(); let mut nvim = Neovim::new(session); let mut options = UiAttachOptions::new(); options.set_cmdline_external(false); @@ -68,12 +56,31 @@ fn main() { options.set_rgb(true); nvim.ui_attach(INITIAL_WIDTH as i64, INITIAL_HEIGHT as i64, &options).unwrap(); - let editor = Arc::new(Mutex::new(Editor::new(INITIAL_WIDTH, INITIAL_HEIGHT))); + // Listen to neovim events + thread::spawn(move || { + println!("UI thread spawned"); + loop { + let (event_name, events) = receiver.recv().expect("Could not receive event."); + let parsed_events = parse_neovim_event(event_name, events).expect("Event parse failed..."); + for event in parsed_events { + let mut editor = editor.lock().unwrap(); + editor.handle_redraw_event(event); + } + } + }); - let nvim_editor = editor.clone(); + // Quit process when nvim exits thread::spawn(move || { - nvim_event_loop(receiver, &nvim_editor); + join_handle.join(); + std::process::exit(0); }); + nvim +} + +fn main() { + // env_logger::from_env(LoggerEnv::default().default_filter_or("warn")).init(); + let editor = Arc::new(Mutex::new(Editor::new(INITIAL_WIDTH, INITIAL_HEIGHT))); + let nvim = start_nvim(editor.clone()); ui_loop(editor, nvim, (INITIAL_WIDTH, INITIAL_HEIGHT)); } diff --git a/src/window.rs b/src/window.rs index 1007fe2..30ecf3b 100644 --- a/src/window.rs +++ b/src/window.rs @@ -109,7 +109,7 @@ impl Renderer { Renderer { editor, title, paint, font, shaper, font_width, font_height, cursor_pos, fps_tracker } } - fn draw_text(&mut self, canvas: &mut Canvas, text: &str, grid_pos: (u64, u64), style: &Style, default_colors: &Colors, update_cache: bool) { + fn draw_background(&mut self, canvas: &mut Canvas, text: &str, grid_pos: (u64, u64), style: &Style, default_colors: &Colors) { let (grid_x, grid_y) = grid_pos; let x = grid_x as f32 * self.font_width; let y = grid_y as f32 * self.font_height; @@ -118,6 +118,13 @@ impl Renderer { let region = Rect::new(x, y, x + width, y + height); self.paint.set_color(style.background(default_colors).to_color()); canvas.draw_rect(region, &self.paint); + } + + fn draw_foreground(&mut self, canvas: &mut Canvas, text: &str, grid_pos: (u64, u64), style: &Style, default_colors: &Colors, update_cache: bool) { + let (grid_x, grid_y) = grid_pos; + let x = grid_x as f32 * self.font_width; + let y = grid_y as f32 * self.font_height; + let width = text.chars().count() as f32 * self.font_width; if style.underline || style.undercurl { let (_, metrics) = self.font.metrics(); @@ -141,6 +148,11 @@ impl Renderer { } } + fn draw_text(&mut self, canvas: &mut Canvas, text: &str, grid_pos: (u64, u64), style: &Style, default_colors: &Colors, update_cache: bool) { + self.draw_background(canvas, text, grid_pos, style, default_colors); + self.draw_foreground(canvas, text, grid_pos, style, default_colors, update_cache); + } + pub fn draw(&mut self, window: &Window, canvas: &mut Canvas) { let (draw_commands, title, default_colors, (width, height), cursor_grid_pos, cursor_type, cursor_foreground, cursor_background, cursor_enabled) = { let editor = self.editor.lock().unwrap(); @@ -159,8 +171,11 @@ impl Renderer { canvas.clear(default_colors.background.clone().unwrap().to_color()); + for command in draw_commands.iter() { + self.draw_background(canvas, &command.text, command.grid_position.clone(), &command.style, &default_colors); + } for command in draw_commands { - self.draw_text(canvas, &command.text, command.grid_position, &command.style, &default_colors, true); + self.draw_foreground(canvas, &command.text, command.grid_position.clone(), &command.style, &default_colors, true); } self.fps_tracker.record_frame(); @@ -309,12 +324,17 @@ pub fn ui_loop(editor: Arc>, nvim: Neovim, initial_size: (u64, u64 .. } => { let input_type = if delta > 0.0 { - "up" + Some("up") + } else if delta < 0.0 { + Some("down") } else { - "down" + None }; - let (grid_x, grid_y) = mouse_pos; - nvim.input_mouse("wheel", input_type, "", 0, grid_y, grid_x).expect("Could not send mouse input"); + + if let Some(input_type) = input_type { + let (grid_x, grid_y) = mouse_pos; + nvim.input_mouse("wheel", input_type, "", 0, grid_y, grid_x).expect("Could not send mouse input"); + } } Event::EventsCleared => {