From 7a46e1cac57cbc308c111bfe8fec37e1fd74ff66 Mon Sep 17 00:00:00 2001 From: daa84 Date: Tue, 11 Jul 2017 18:14:46 +0300 Subject: [PATCH] Starting point --- src/nvim.rs | 59 ++++++++++++++++++++++------ src/shell.rs | 106 ++++++++++++++++++++++++++++++++++----------------- 2 files changed, 119 insertions(+), 46 deletions(-) diff --git a/src/nvim.rs b/src/nvim.rs index eabcae5..0e4f800 100644 --- a/src/nvim.rs +++ b/src/nvim.rs @@ -172,15 +172,24 @@ impl ModeInfo { #[derive(Debug)] pub struct NvimInitError { source: Box, - cmd: String, + cmd: Option, } impl NvimInitError { + pub fn new_post_init(error: E) -> NvimInitError + where E: Into> + { + NvimInitError { + cmd: None, + source: error.into(), + } + } + pub fn new(cmd: &Command, error: E) -> NvimInitError where E: Into> { NvimInitError { - cmd: format!("{:?}", cmd), + cmd: Some(format!("{:?}", cmd)), source: error.into(), } } @@ -189,8 +198,8 @@ impl NvimInitError { format!("{}", self.source) } - pub fn cmd(&self) -> &str { - &self.cmd + pub fn cmd(&self) -> Option<&String> { + self.cmd.as_ref() } } @@ -210,11 +219,9 @@ impl error::Error for NvimInitError { } } -pub fn initialize(shell: Arc>, - nvim_bin_path: Option<&String>, - cols: u64, - rows: u64) - -> result::Result { +pub fn start(shell: Arc>, + nvim_bin_path: Option<&String>) + -> result::Result { let mut cmd = if let Some(path) = nvim_bin_path { Command::new(path) } else { @@ -250,15 +257,29 @@ pub fn initialize(shell: Arc>, nvim.session .start_event_loop_handler(NvimHandler::new(shell)); + + Ok(nvim) +} + +pub fn post_start_init(nvim: &mut Neovim, + open_path: Option<&String>, + cols: u64, + rows: u64) + -> result::Result<(), NvimInitError> { let mut opts = UiAttachOptions::new(); opts.set_popupmenu_external(false); opts.set_tabline_external(true); nvim.ui_attach(cols, rows, opts) - .map_err(|e| NvimInitError::new(&cmd, e))?; + .map_err(|e| NvimInitError::new_post_init(e))?; nvim.command("runtime! ginit.vim") - .map_err(|e| NvimInitError::new(&cmd, e))?; + .map_err(|e| NvimInitError::new_post_init(e))?; - Ok(nvim) + if let Some(path) = open_path { + nvim.command(&format!("e {}", path)) + .map_err(|e| NvimInitError::new_post_init(e))?; + } + + Ok(()) } pub struct NvimHandler { @@ -507,11 +528,19 @@ impl RepaintMode { enum NeovimClientWrapper { Uninitialized, + InitInProgress, Initialized(Neovim), Error, } impl NeovimClientWrapper { + pub fn is_uninitialized(&self) -> bool { + match *self { + NeovimClientWrapper::Uninitialized => true, + _ => false, + } + } + pub fn is_initialized(&self) -> bool { match *self { NeovimClientWrapper::Initialized(_) => true, @@ -529,6 +558,7 @@ impl NeovimClientWrapper { pub fn nvim(&self) -> &Neovim { match *self { NeovimClientWrapper::Initialized(ref nvim) => nvim, + NeovimClientWrapper::InitInProgress | NeovimClientWrapper::Uninitialized => panic!("Access to uninitialized neovim client"), NeovimClientWrapper::Error => { panic!("Access to neovim client that is not started due to some error") @@ -539,6 +569,7 @@ impl NeovimClientWrapper { pub fn nvim_mut(&mut self) -> &mut Neovim { match *self { NeovimClientWrapper::Initialized(ref mut nvim) => nvim, + NeovimClientWrapper::InitInProgress | NeovimClientWrapper::Uninitialized => panic!("Access to uninitialized neovim client"), NeovimClientWrapper::Error => { panic!("Access to neovim client that is not started due to some error") @@ -568,6 +599,10 @@ impl NeovimClient { self.nvim.is_initialized() } + pub fn is_uninitialized(&self) -> bool { + self.nvim.is_uninitialized() + } + pub fn is_error(&self) -> bool { self.nvim.is_error() } diff --git a/src/shell.rs b/src/shell.rs index cdba5cd..49a7e36 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -250,6 +250,7 @@ impl UiState { } } +#[derive(Clone)] pub struct ShellOptions { nvim_bin_path: Option, open_path: Option, @@ -545,46 +546,82 @@ fn gtk_draw(state_arc: &Arc>, ctx: &cairo::Context) -> Inhibit { Inhibit(false) } +fn init_nvim_async(state_arc: Arc>, + options: ShellOptions, + cols: usize, + rows: usize) { + // execute nvim + let mut nvim = match nvim::start(state_arc.clone(), options.nvim_bin_path.as_ref()) { + Ok(nvim) => nvim, + Err(err) => { + // TODO: process error // + return; + } + }; + + // add callback on session end + let guard = nvim.session.take_dispatch_guard(); + let state_ref = state_arc.clone(); + thread::spawn(move || { + guard.join().expect("Can't join dispatch thread"); + + idle_cb_call!(state_ref.detach_cb()); + }); + + // attach ui + let state_ref = state_arc.clone(); + let mut post_init = Some(move || { + let mut nvim = nvim; + if let Err(err) = nvim::post_start_init(&mut nvim, + options.open_path.as_ref(), + cols as u64, + rows as u64) { + // TODO: process error // + } + + let state = state_arc.borrow_mut(); + state.nvim.borrow_mut().set_nvim(nvim); + }); + + glib::idle_add(move || { + let cl = post_init.take(); + cl(); + Continue(false) + }); + + //{ + //Ok(nvim) => nvim, + //Err(err) => { + //nvim_client.set_error(); + //state + //.error_area + //.show_nvim_start_error(&err.source(), err.cmd()); + + //let stack = state.stack.clone(); + //gtk::idle_add(move || { + //stack.set_visible_child_name("Error"); + //Continue(false) + //}); + + //return; + //} + //}; + + + + //nvim_client.set_nvim(nvim); +} fn init_nvim(state_arc: &Arc>) { let state = state_arc.borrow(); - let mut nvim_client = state.nvim.borrow_mut(); - if !nvim_client.is_initialized() && !nvim_client.is_error() { + if state.nvim.borrow().is_uninitialized() { let (cols, rows) = state.calc_nvim_size().unwrap(); - let mut nvim = match nvim::initialize(state_arc.clone(), - state.options.nvim_bin_path.as_ref(), - cols as u64, - rows as u64) { - Ok(nvim) => nvim, - Err(err) => { - nvim_client.set_error(); - state.error_area.show_nvim_start_error(&err.source(), err.cmd()); - let stack = state.stack.clone(); - gtk::idle_add(move || { - stack.set_visible_child_name("Error"); - Continue(false) - }); + let state_arc = state_arc.clone(); + let options = state.options.clone(); + thread::spawn(move || { init_nvim_async(state_arc, options, cols, rows); }); - return; - } - }; - - if let Some(ref path) = state.options.open_path { - nvim.command(&format!("e {}", path)).report_err(&mut nvim); - } - - let guard = nvim.session.take_dispatch_guard(); - - let state_ref = state_arc.clone(); - thread::spawn(move || { - guard.join().expect("Can't join dispatch thread"); - - idle_cb_call!(state_ref.detach_cb()); - }); - - nvim_client.set_nvim(nvim); } } @@ -1008,7 +1045,8 @@ impl RedrawEvents for State { fn mode_info_set(&mut self, cursor_style_enabled: bool, - mode_info: Vec) -> RepaintMode { + mode_info: Vec) + -> RepaintMode { self.mode.set_info(cursor_style_enabled, mode_info); RepaintMode::Nothing }