From 5345d178bfb12518af5434a5f48602ce4ee3565a Mon Sep 17 00:00:00 2001 From: daa Date: Sat, 4 Nov 2017 23:04:03 +0300 Subject: [PATCH] Update vim configuration on save source configuration one Ok pressed --- src/nvim.rs | 3 +- src/nvim_config.rs | 15 ++++++- src/plug_manager/manager.rs | 3 +- src/plug_manager/plugin_settings_dlg.rs | 57 ++++++++++++++++++++++--- src/plug_manager/ui.rs | 21 ++++++--- src/plug_manager/vim_plug.rs | 6 +++ src/plug_manager/vimawesome.rs | 24 ++++++++--- src/shell.rs | 15 +++---- src/ui.rs | 7 +-- 9 files changed, 113 insertions(+), 38 deletions(-) diff --git a/src/nvim.rs b/src/nvim.rs index aef6c11..2f5cec0 100644 --- a/src/nvim.rs +++ b/src/nvim.rs @@ -228,7 +228,6 @@ impl error::Error for NvimInitError { pub fn start( shell: Arc>, nvim_bin_path: Option<&String>, - nvim_config: NvimConfig, ) -> result::Result { let mut cmd = if let Some(path) = nvim_bin_path { Command::new(path) @@ -259,7 +258,7 @@ pub fn start( cmd.arg("--cmd").arg("let &rtp.=',runtime'"); } - if let Some(nvim_config) = nvim_config.generate_config() { + if let Some(nvim_config) = NvimConfig::config_path() { if let Some(path) = nvim_config.to_str() { cmd.arg("--cmd").arg(format!("source {}", path)); } diff --git a/src/nvim_config.rs b/src/nvim_config.rs index c0d328a..592eb3d 100644 --- a/src/nvim_config.rs +++ b/src/nvim_config.rs @@ -11,6 +11,8 @@ pub struct NvimConfig { } impl NvimConfig { + const CONFIG_PATH: &'static str = "settings.vim"; + pub fn new(plug_config: Option) -> Self { NvimConfig { plug_config } } @@ -29,9 +31,20 @@ impl NvimConfig { } } + pub fn config_path() -> Option { + if let Ok(mut path) = dirs::get_app_config_dir() { + path.push(NvimConfig::CONFIG_PATH); + if path.is_file() { + return Some(path); + } + } + + None + } + fn write_file(&self) -> Result { let mut config_dir = dirs::get_app_config_dir_create()?; - config_dir.push("plugins.vim"); + config_dir.push(NvimConfig::CONFIG_PATH); let mut file = OpenOptions::new() .create(true) diff --git a/src/plug_manager/manager.rs b/src/plug_manager/manager.rs index a81c830..1ac6382 100644 --- a/src/plug_manager/manager.rs +++ b/src/plug_manager/manager.rs @@ -7,14 +7,13 @@ use super::store::{Store, PlugInfo}; use nvim::NeovimClient; pub struct Manager { - vim_plug: vim_plug::Manager, + pub vim_plug: vim_plug::Manager, pub store: Store, pub plug_manage_state: PlugManageState, } impl Manager { pub fn new() -> Self { - let (plug_manage_state, store) = if Store::is_config_exists() { (PlugManageState::NvimGtk, Store::load()) } else { diff --git a/src/plug_manager/plugin_settings_dlg.rs b/src/plug_manager/plugin_settings_dlg.rs index 26c680d..6f27b1d 100644 --- a/src/plug_manager/plugin_settings_dlg.rs +++ b/src/plug_manager/plugin_settings_dlg.rs @@ -28,22 +28,41 @@ impl<'a> Builder<'a> { list.set_selection_mode(gtk::SelectionMode::None); let path = gtk::Box::new(gtk::Orientation::Horizontal, 0); - let label = gtk::Label::new("Repo"); - let entry = gtk::Entry::new(); + let path_lbl = gtk::Label::new("Repo"); + let path_e = gtk::Entry::new(); - path.pack_start(&label, true, true, 0); - path.pack_end(&entry, false, true, 0); + path.pack_start(&path_lbl, true, true, 0); + path.pack_end(&path_e, false, true, 0); list.add(&path); + let name = gtk::Box::new(gtk::Orientation::Horizontal, 0); + let name_lbl = gtk::Label::new("Name"); + let name_e = gtk::Entry::new(); + + name.pack_start(&name_lbl, true, true, 0); + name.pack_end(&name_e, false, true, 0); + + list.add(&name); + content.add(&list); content.show_all(); let ok: i32 = gtk::ResponseType::Ok.into(); let res = if dlg.run() == ok { - entry.get_text().map(|name| { - store::PlugInfo::new(name.to_owned(), name.to_owned()) + path_e.get_text().map(|path| { + let name = name_e + .get_text() + .and_then(|name| if name.trim().is_empty() { + None + } else { + Some(name) + }) + .or_else(|| Builder::extract_name(&path)) + .unwrap_or_else(|| path.clone()); + + store::PlugInfo::new(name.to_owned(), path.to_owned()) }) } else { None @@ -53,4 +72,30 @@ impl<'a> Builder<'a> { res } + + fn extract_name(path: &str) -> Option { + if let Some(idx) = path.rfind(|c| c == '/' || c == '\\') { + if idx < path.len() - 1 { + let path = path.trim_right_matches(".git"); + Some(path[idx + 1..].to_owned()) + } else { + None + } + } else { + None + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_extract_name() { + assert_eq!( + Some("plugin_name"), + Builder::extract_name("http://github.com/somebody/plugin_name.git") + ); + } } diff --git a/src/plug_manager/ui.rs b/src/plug_manager/ui.rs index fa8aee5..5f13c82 100644 --- a/src/plug_manager/ui.rs +++ b/src/plug_manager/ui.rs @@ -13,6 +13,7 @@ use super::manager; use super::store::{Store, PlugInfo}; use super::plugin_settings_dlg; use super::vimawesome; +use nvim_config::NvimConfig; pub struct Ui<'a> { manager: &'a Arc>, @@ -78,17 +79,20 @@ impl<'a> Ui<'a> { add_help_tab( &pages, - &format!("NeovimGtk plugin manager is a GUI for vim-plug.\n\ + &format!( + "NeovimGtk plugin manager is a GUI for vim-plug.\n\ It can load plugins from vim-plug configuration if vim-plug sarted and self settings is empty.\n\ When enabled it generate and load vim-plug as simple vim file at startup before init.vim is processed.\n\ So after enabling this manager you must disable vim-plug configuration in init.vim.\n\ This manager currently only manage vim-plug configuration and do not any actions on plugin management.\n\ So you must call all vim-plug (PlugInstall, PlugUpdate, PlugClean) commands manually.\n\ - Current configuration source is {}", match self.manager.borrow().plug_manage_state { - manager::PlugManageState::NvimGtk => "config file", - manager::PlugManageState::VimPlug => "loaded from vim-plug", - manager::PlugManageState::Unknown => "Unknown", - }), + Current configuration source is {}", + match self.manager.borrow().plug_manage_state { + manager::PlugManageState::NvimGtk => "config file", + manager::PlugManageState::VimPlug => "loaded from vim-plug", + manager::PlugManageState::Unknown => "Unknown", + } + ), ); let manager_ref = self.manager.clone(); @@ -111,6 +115,11 @@ impl<'a> Ui<'a> { let mut manager = self.manager.borrow_mut(); manager.clear_removed(); manager.save(); + if let Some(config_path) = NvimConfig::new(manager.load_config()).generate_config() { + if let Some(path) = config_path.to_str() { + manager.vim_plug.reload(path); + } + } } dlg.destroy(); diff --git a/src/plug_manager/vim_plug.rs b/src/plug_manager/vim_plug.rs index d878d65..e6327d8 100644 --- a/src/plug_manager/vim_plug.rs +++ b/src/plug_manager/vim_plug.rs @@ -87,6 +87,12 @@ impl Manager { false } } + + pub fn reload(&self, path: &str) { + if let Some(mut nvim) = self.nvim() { + nvim.command(&format!("source {}", path)).report_err(&mut *nvim); + } + } } #[derive(Debug)] diff --git a/src/plug_manager/vimawesome.rs b/src/plug_manager/vimawesome.rs index 82497cc..78b53d3 100644 --- a/src/plug_manager/vimawesome.rs +++ b/src/plug_manager/vimawesome.rs @@ -16,9 +16,11 @@ where F: FnOnce(io::Result) + Send + 'static, { thread::spawn(move || { + let mut result = Some(request(query.as_ref().map(|s| s.as_ref()))); let mut cb = Some(cb); + glib::idle_add(move || { - cb.take().unwrap()(request(query.as_ref().map(|s| s.as_ref()))); + cb.take().unwrap()(result.take().unwrap()); Continue(false) }) }); @@ -37,10 +39,14 @@ fn request(query: Option<&str>) -> io::Result { let out = child.wait_with_output()?; if out.status.success() { - let description_list: DescriptionList = serde_json::from_slice(&out.stdout).map_err(|e| { - io::Error::new(io::ErrorKind::Other, e) - })?; - Ok(description_list) + if out.stdout.is_empty() { + Ok(DescriptionList::empty()) + } else { + let description_list: DescriptionList = serde_json::from_slice(&out.stdout).map_err(|e| { + io::Error::new(io::ErrorKind::Other, e) + })?; + Ok(description_list) + } } else { Err(io::Error::new( io::ErrorKind::Other, @@ -139,6 +145,14 @@ pub struct DescriptionList { pub plugins: Box<[Description]>, } +impl DescriptionList { + fn empty() -> DescriptionList { + DescriptionList { + plugins: Box::new([]), + } + } +} + #[derive(Deserialize, Debug, Clone)] pub struct Description { pub name: String, diff --git a/src/shell.rs b/src/shell.rs index 70af8d1..10facfb 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -22,7 +22,6 @@ use ui_model::{UiModel, Attrs, ModelRect}; use color::{ColorModel, Color, COLOR_BLACK, COLOR_WHITE, COLOR_RED}; use nvim; use nvim::{RedrawEvents, GuiApi, RepaintMode, ErrorReport, NeovimClient}; -use nvim_config::NvimConfig; use input; use input::keyval_to_input_string; use cursor::Cursor; @@ -78,14 +77,13 @@ pub struct State { resize_state: Rc>, options: ShellOptions, - nvim_config: NvimConfig, detach_cb: Option>>, nvim_started_cb: Option>>, } impl State { - pub fn new(settings: Rc>, options: ShellOptions, nvim_config: NvimConfig) -> State { + pub fn new(settings: Rc>, options: ShellOptions) -> State { let drawing_area = gtk::DrawingArea::new(); let popup_menu = RefCell::new(PopupMenu::new(&drawing_area)); let font_ctx = render::Context::new(FontDescription::from_string(DEFAULT_FONT_NAME)); @@ -113,7 +111,6 @@ impl State { resize_state: Rc::new(Cell::new(ResizeState::Wait)), options, - nvim_config, detach_cb: None, nvim_started_cb: None, @@ -393,9 +390,9 @@ pub struct Shell { } impl Shell { - pub fn new(settings: Rc>, options: ShellOptions, nvim_config: NvimConfig) -> Shell { + pub fn new(settings: Rc>, options: ShellOptions) -> Shell { let shell = Shell { - state: Arc::new(UiMutex::new(State::new(settings, options, nvim_config))), + state: Arc::new(UiMutex::new(State::new(settings, options))), ui_state: Rc::new(RefCell::new(UiState::new())), widget: gtk::Box::new(gtk::Orientation::Vertical, 0), @@ -768,12 +765,11 @@ fn show_nvim_init_error(err: &nvim::NvimInitError, state_arc: Arc fn init_nvim_async( state_arc: Arc>, options: ShellOptions, - nvim_config: NvimConfig, cols: usize, rows: usize, ) { // execute nvim - let mut nvim = match nvim::start(state_arc.clone(), options.nvim_bin_path.as_ref(), nvim_config) { + let mut nvim = match nvim::start(state_arc.clone(), options.nvim_bin_path.as_ref()) { Ok(nvim) => nvim, Err(err) => { show_nvim_start_error(&err, state_arc); @@ -868,8 +864,7 @@ fn init_nvim(state_ref: &Arc>) { let state_arc = state_ref.clone(); let options = state.options.clone(); - let nvim_config = state.nvim_config.clone(); - thread::spawn(move || init_nvim_async(state_arc, options, nvim_config, cols, rows)); + thread::spawn(move || init_nvim_async(state_arc, options, cols, rows)); } } diff --git a/src/ui.rs b/src/ui.rs index 48b87c8..5bd89c5 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -10,7 +10,6 @@ use gtk::{ApplicationWindow, HeaderBar, ToolButton, Image, AboutDialog}; use gio::prelude::*; use gio::{Menu, MenuExt, MenuItem, MenuItemExt, SimpleAction}; -use nvim_config::NvimConfig; use settings::Settings; use shell::{Shell, ShellOptions}; use shell_dlg; @@ -54,15 +53,11 @@ impl Components { impl Ui { pub fn new(options: ShellOptions) -> Ui { let plug_manager = plug_manager::Manager::new(); - let plug_config = plug_manager.load_config(); - let nvim_config = NvimConfig::new(plug_config); let plug_manager = Arc::new(UiMutex::new(plug_manager)); let comps = Arc::new(UiMutex::new(Components::new())); let settings = Rc::new(RefCell::new(Settings::new())); - let shell = Rc::new(RefCell::new( - Shell::new(settings.clone(), options, nvim_config), - )); + let shell = Rc::new(RefCell::new(Shell::new(settings.clone(), options))); settings.borrow_mut().set_shell(Rc::downgrade(&shell)); let projects = Projects::new(&comps.borrow().open_btn, shell.clone());