Starting point

This commit is contained in:
daa84 2017-07-11 18:14:46 +03:00
parent 491de706d0
commit 7a46e1cac5
2 changed files with 119 additions and 46 deletions

View File

@ -172,15 +172,24 @@ impl ModeInfo {
#[derive(Debug)] #[derive(Debug)]
pub struct NvimInitError { pub struct NvimInitError {
source: Box<error::Error>, source: Box<error::Error>,
cmd: String, cmd: Option<String>,
} }
impl NvimInitError { impl NvimInitError {
pub fn new_post_init<E>(error: E) -> NvimInitError
where E: Into<Box<error::Error>>
{
NvimInitError {
cmd: None,
source: error.into(),
}
}
pub fn new<E>(cmd: &Command, error: E) -> NvimInitError pub fn new<E>(cmd: &Command, error: E) -> NvimInitError
where E: Into<Box<error::Error>> where E: Into<Box<error::Error>>
{ {
NvimInitError { NvimInitError {
cmd: format!("{:?}", cmd), cmd: Some(format!("{:?}", cmd)),
source: error.into(), source: error.into(),
} }
} }
@ -189,8 +198,8 @@ impl NvimInitError {
format!("{}", self.source) format!("{}", self.source)
} }
pub fn cmd(&self) -> &str { pub fn cmd(&self) -> Option<&String> {
&self.cmd self.cmd.as_ref()
} }
} }
@ -210,11 +219,9 @@ impl error::Error for NvimInitError {
} }
} }
pub fn initialize(shell: Arc<UiMutex<shell::State>>, pub fn start(shell: Arc<UiMutex<shell::State>>,
nvim_bin_path: Option<&String>, nvim_bin_path: Option<&String>)
cols: u64, -> result::Result<Neovim, NvimInitError> {
rows: u64)
-> result::Result<Neovim, NvimInitError> {
let mut cmd = if let Some(path) = nvim_bin_path { let mut cmd = if let Some(path) = nvim_bin_path {
Command::new(path) Command::new(path)
} else { } else {
@ -250,15 +257,29 @@ pub fn initialize(shell: Arc<UiMutex<shell::State>>,
nvim.session nvim.session
.start_event_loop_handler(NvimHandler::new(shell)); .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(); let mut opts = UiAttachOptions::new();
opts.set_popupmenu_external(false); opts.set_popupmenu_external(false);
opts.set_tabline_external(true); opts.set_tabline_external(true);
nvim.ui_attach(cols, rows, opts) 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") 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 { pub struct NvimHandler {
@ -507,11 +528,19 @@ impl RepaintMode {
enum NeovimClientWrapper { enum NeovimClientWrapper {
Uninitialized, Uninitialized,
InitInProgress,
Initialized(Neovim), Initialized(Neovim),
Error, Error,
} }
impl NeovimClientWrapper { impl NeovimClientWrapper {
pub fn is_uninitialized(&self) -> bool {
match *self {
NeovimClientWrapper::Uninitialized => true,
_ => false,
}
}
pub fn is_initialized(&self) -> bool { pub fn is_initialized(&self) -> bool {
match *self { match *self {
NeovimClientWrapper::Initialized(_) => true, NeovimClientWrapper::Initialized(_) => true,
@ -529,6 +558,7 @@ impl NeovimClientWrapper {
pub fn nvim(&self) -> &Neovim { pub fn nvim(&self) -> &Neovim {
match *self { match *self {
NeovimClientWrapper::Initialized(ref nvim) => nvim, NeovimClientWrapper::Initialized(ref nvim) => nvim,
NeovimClientWrapper::InitInProgress |
NeovimClientWrapper::Uninitialized => panic!("Access to uninitialized neovim client"), NeovimClientWrapper::Uninitialized => panic!("Access to uninitialized neovim client"),
NeovimClientWrapper::Error => { NeovimClientWrapper::Error => {
panic!("Access to neovim client that is not started due to some 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 { pub fn nvim_mut(&mut self) -> &mut Neovim {
match *self { match *self {
NeovimClientWrapper::Initialized(ref mut nvim) => nvim, NeovimClientWrapper::Initialized(ref mut nvim) => nvim,
NeovimClientWrapper::InitInProgress |
NeovimClientWrapper::Uninitialized => panic!("Access to uninitialized neovim client"), NeovimClientWrapper::Uninitialized => panic!("Access to uninitialized neovim client"),
NeovimClientWrapper::Error => { NeovimClientWrapper::Error => {
panic!("Access to neovim client that is not started due to some error") panic!("Access to neovim client that is not started due to some error")
@ -568,6 +599,10 @@ impl NeovimClient {
self.nvim.is_initialized() self.nvim.is_initialized()
} }
pub fn is_uninitialized(&self) -> bool {
self.nvim.is_uninitialized()
}
pub fn is_error(&self) -> bool { pub fn is_error(&self) -> bool {
self.nvim.is_error() self.nvim.is_error()
} }

View File

@ -250,6 +250,7 @@ impl UiState {
} }
} }
#[derive(Clone)]
pub struct ShellOptions { pub struct ShellOptions {
nvim_bin_path: Option<String>, nvim_bin_path: Option<String>,
open_path: Option<String>, open_path: Option<String>,
@ -545,46 +546,82 @@ fn gtk_draw(state_arc: &Arc<UiMutex<State>>, ctx: &cairo::Context) -> Inhibit {
Inhibit(false) Inhibit(false)
} }
fn init_nvim_async(state_arc: Arc<UiMutex<State>>,
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<UiMutex<State>>) { fn init_nvim(state_arc: &Arc<UiMutex<State>>) {
let state = state_arc.borrow(); let state = state_arc.borrow();
let mut nvim_client = state.nvim.borrow_mut(); if state.nvim.borrow().is_uninitialized() {
if !nvim_client.is_initialized() && !nvim_client.is_error() {
let (cols, rows) = state.calc_nvim_size().unwrap(); 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(); let state_arc = state_arc.clone();
gtk::idle_add(move || { let options = state.options.clone();
stack.set_visible_child_name("Error"); thread::spawn(move || { init_nvim_async(state_arc, options, cols, rows); });
Continue(false)
});
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, fn mode_info_set(&mut self,
cursor_style_enabled: bool, cursor_style_enabled: bool,
mode_info: Vec<nvim::ModeInfo>) -> RepaintMode { mode_info: Vec<nvim::ModeInfo>)
-> RepaintMode {
self.mode.set_info(cursor_style_enabled, mode_info); self.mode.set_info(cursor_style_enabled, mode_info);
RepaintMode::Nothing RepaintMode::Nothing
} }