diff --git a/src/main.rs b/src/main.rs index 1a45193..23500de 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,13 +9,12 @@ mod ui_model; mod ui; use ui::Ui; -use nvim::Nvim; fn main() { let ui = Ui::new(); ui.show(); - let nvim = Nvim::start(ui).expect("Can't start nvim instance"); + let nvim = nvim::initialize(ui).expect("Can't start nvim instance"); gtk::main(); } diff --git a/src/nvim.rs b/src/nvim.rs index 2aa733e..cde1e27 100644 --- a/src/nvim.rs +++ b/src/nvim.rs @@ -1,49 +1,56 @@ use neovim_lib::{Neovim, NeovimApi, Session}; use std::io::{Result, Error, ErrorKind}; use std::sync::Arc; +use ui_mutex::UiMutex; use rmp::Value; use ui::Ui; -pub struct Nvim { - nvim: Neovim, -} +pub type SharedUi = Arc>; pub trait RedrawEvents { } -impl Nvim { - pub fn start(mut ui: Ui) -> Result { - // let mut session = try!(Session::new_tcp("127.0.0.1:6666")); - let session = if cfg!(target_os = "windows") { - Session::new_child_path("E:\\Neovim\\bin\\nvim.exe").unwrap() - } else { - Session::new_child().unwrap() - }; - let mut nvim = Neovim::new(session); +pub fn initialize(mut ui: Ui) -> Result { + // let mut session = try!(Session::new_tcp("127.0.0.1:6666")); + let session = if cfg!(target_os = "windows") { + Session::new_child_path("E:\\Neovim\\bin\\nvim.exe").unwrap() + } else { + Session::new_child().unwrap() + }; + let nvim = Neovim::new(session); + ui.set_nvim(nvim); - nvim.session.start_event_loop_cb(move |m, p| Nvim::cb(&mut ui, m, p)); + let sh_ui = Arc::new(UiMutex::new(ui)); + + + { + let mut ui = (*sh_ui).borrow_mut(); + let mut nvim = ui.nvim(); + + let moved_sh_ui = sh_ui.clone(); + nvim.session.start_event_loop_cb(move |m, p| nvim_cb(&moved_sh_ui, m, p)); // fix neovim --embed bug to start embed mode nvim.input("i").unwrap(); try!(nvim.ui_attach(80, 24, true).map_err(|e| Error::new(ErrorKind::Other, e))); - - Ok(Nvim { nvim: nvim }) } - fn cb(ui: &mut Ui, method: &str, params: Vec) { - if method == "redraw" { - for ev in params { - if let Value::Array(ev_args) = ev { - if let Value::String(ref ev_name) = ev_args[0] { - println!("Event {}", ev_name); - } else { - println!("Unsupported event {:?}", ev_args); - } + Ok(sh_ui) +} + +fn nvim_cb(ui: &SharedUi, method: &str, params: Vec) { + if method == "redraw" { + for ev in params { + if let Value::Array(ev_args) = ev { + if let Value::String(ref ev_name) = ev_args[0] { + println!("Event {}", ev_name); } else { - println!("Unsupported event type {:?}", ev); + println!("Unsupported event {:?}", ev_args); } + } else { + println!("Unsupported event type {:?}", ev); } - } else { - println!("Notification {}", method); } + } else { + println!("Notification {}", method); } } diff --git a/src/ui.rs b/src/ui.rs index c05f6d7..2caceae 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -2,21 +2,32 @@ use cairo; use gtk; use gtk::prelude::*; use gtk::{Window, WindowType, DrawingArea, Grid, ToolButton, ButtonBox, Orientation, Image}; +use neovim_lib::Neovim; use ui_model::UiModel; use nvim::RedrawEvents; pub struct Ui { model: UiModel, + nvim: Option, } impl Ui { pub fn new() -> Ui { Ui { model: UiModel::empty(), + nvim: None, } } + pub fn set_nvim(&mut self, nvim: Neovim) { + self.nvim = Some(nvim); + } + + pub fn nvim(&mut self) -> &mut Neovim { + self.nvim.as_mut().unwrap() + } + pub fn show(&self) { gtk::init().expect("Failed to initialize GTK"); let window = Window::new(WindowType::Toplevel); diff --git a/src/ui_mutex.rs b/src/ui_mutex.rs index 25b0ba2..578f2ca 100644 --- a/src/ui_mutex.rs +++ b/src/ui_mutex.rs @@ -4,18 +4,18 @@ use std::thread; use std::sync::Arc; use gtk; -pub struct MainLoopMutex { +pub struct UiMutex { data: RefCell, main_thread_name: Option, } // here sync used to mark that internal data is acessed only from main thread // this behaviour works because of borrow_mut check thread name -unsafe impl Sync for MainLoopMutex {} +unsafe impl Sync for UiMutex {} -impl MainLoopMutex { - pub fn new(t: T) -> MainLoopMutex { - MainLoopMutex { +impl UiMutex { + pub fn new(t: T) -> UiMutex { + UiMutex { data: RefCell::new(t), main_thread_name: thread::current().name().map(|v| v.to_owned()), } @@ -29,9 +29,9 @@ impl MainLoopMutex { self.data.borrow_mut() } - pub fn safe_call(mutex: Arc>, cb: F) + pub fn safe_call(mutex: Arc>, cb: F) where I: 'static, - F: Fn(&MainLoopMutex) + 'static + F: Fn(&UiMutex) + 'static { gtk::idle_add(move || { cb(&*mutex);