From 9ef88bc30b0ae9d800cbda53fc6fe1b08a8c0e29 Mon Sep 17 00:00:00 2001 From: daa Date: Fri, 30 Mar 2018 23:54:37 +0300 Subject: [PATCH] Add NGToggleSidebar command (#79) --- runtime/plugin/nvim_gui_shim.vim | 3 + src/nvim/handler.rs | 3 +- src/nvim/mod.rs | 2 +- src/nvim/redraw_handler.rs | 96 ++------------------------ src/shell.rs | 114 ++++++++++++++++++++----------- src/ui.rs | 18 +++++ 6 files changed, 101 insertions(+), 135 deletions(-) diff --git a/runtime/plugin/nvim_gui_shim.vim b/runtime/plugin/nvim_gui_shim.vim index 565b2ff..2815e55 100644 --- a/runtime/plugin/nvim_gui_shim.vim +++ b/runtime/plugin/nvim_gui_shim.vim @@ -54,3 +54,6 @@ function s:GuiFontCommand(fname, bang) abort endfunction command! -nargs=? -bang Guifont call s:GuiFontCommand("", "") command! -nargs=? -bang GuiFont call s:GuiFontCommand("", "") + +command! NGToggleSidebar call rpcnotify(1, 'Gui', 'Command', 'ToggleSidebar') + diff --git a/src/nvim/handler.rs b/src/nvim/handler.rs index 3718dc1..c6ee331 100644 --- a/src/nvim/handler.rs +++ b/src/nvim/handler.rs @@ -9,7 +9,6 @@ use glib; use super::repaint_mode::RepaintMode; use super::redraw_handler; -use super::redraw_handler::RedrawEvents; pub struct NvimHandler { shell: Arc>, @@ -68,7 +67,7 @@ impl NvimHandler { redraw_handler::call_gui_event( ui, ev_name.as_str().ok_or_else(|| "Event name does not exists")?, - &args, + args, )?; ui.on_redraw(&RepaintMode::All); Ok(()) diff --git a/src/nvim/mod.rs b/src/nvim/mod.rs index 1916fe6..95a1c78 100644 --- a/src/nvim/mod.rs +++ b/src/nvim/mod.rs @@ -5,7 +5,7 @@ mod redraw_handler; mod repaint_mode; mod ext; -pub use self::redraw_handler::{CompleteItem, GuiApi, RedrawEvents}; +pub use self::redraw_handler::CompleteItem; pub use self::repaint_mode::RepaintMode; pub use self::client::{NeovimClient, NeovimClientAsync, NeovimRef}; pub use self::mode_info::{CursorShape, ModeInfo}; diff --git a/src/nvim/redraw_handler.rs b/src/nvim/redraw_handler.rs index 9e52b87..bef2e3f 100644 --- a/src/nvim/redraw_handler.rs +++ b/src/nvim/redraw_handler.rs @@ -1,5 +1,4 @@ use std::result; -use std::collections::HashMap; use std::sync::Arc; use neovim_lib::{UiOption, Value}; @@ -15,94 +14,6 @@ use rmpv; use super::repaint_mode::RepaintMode; use super::mode_info::ModeInfo; -pub trait RedrawEvents { - fn on_cursor_goto(&mut self, row: u64, col: u64) -> RepaintMode; - - fn on_put(&mut self, text: String) -> RepaintMode; - - fn on_clear(&mut self) -> RepaintMode; - - fn on_resize(&mut self, columns: u64, rows: u64) -> RepaintMode; - - fn on_redraw(&mut self, mode: &RepaintMode); - - fn on_highlight_set(&mut self, attrs: HashMap) -> RepaintMode; - - fn on_eol_clear(&mut self) -> RepaintMode; - - fn on_set_scroll_region(&mut self, top: u64, bot: u64, left: u64, right: u64) -> RepaintMode; - - fn on_scroll(&mut self, count: i64) -> RepaintMode; - - fn on_update_bg(&mut self, bg: i64) -> RepaintMode; - - fn on_update_fg(&mut self, fg: i64) -> RepaintMode; - - fn on_update_sp(&mut self, sp: i64) -> RepaintMode; - - fn on_mode_change(&mut self, mode: String, idx: u64) -> RepaintMode; - - fn on_mouse(&mut self, on: bool) -> RepaintMode; - - fn on_busy(&mut self, busy: bool) -> RepaintMode; - - fn popupmenu_show( - &mut self, - menu: &[CompleteItem], - selected: i64, - row: u64, - col: u64, - ) -> RepaintMode; - - fn popupmenu_hide(&mut self) -> RepaintMode; - - fn popupmenu_select(&mut self, selected: i64) -> RepaintMode; - - fn tabline_update( - &mut self, - selected: Tabpage, - tabs: Vec<(Tabpage, Option)>, - ) -> RepaintMode; - - fn mode_info_set( - &mut self, - cursor_style_enabled: bool, - mode_info: Vec, - ) -> RepaintMode; - - fn cmdline_show( - &mut self, - content: Vec<(HashMap, String)>, - pos: u64, - firstc: String, - prompt: String, - indent: u64, - level: u64, - ) -> RepaintMode; - - fn cmdline_hide(&mut self, level: u64) -> RepaintMode; - - fn cmdline_block_show( - &mut self, - content: Vec, String)>>, - ) -> RepaintMode; - - fn cmdline_block_append( - &mut self, - content: Vec<(HashMap, String)>, - ) -> RepaintMode; - - fn cmdline_block_hide(&mut self) -> RepaintMode; - - fn cmdline_pos(&mut self, pos: u64, level: u64) -> RepaintMode; - - fn cmdline_special_char(&mut self, c: String, shift: bool, level: u64) -> RepaintMode; -} - -pub trait GuiApi { - fn set_font(&mut self, font_desc: &str); -} - macro_rules! try_str { ($exp:expr) => ($exp.as_str().ok_or_else(|| "Can't convert argument to string".to_owned())?) } @@ -171,10 +82,10 @@ macro_rules! call { pub fn call_gui_event( ui: &mut shell::State, method: &str, - args: &Vec, + args: Vec, ) -> result::Result<(), String> { match method { - "Font" => ui.set_font(try_str!(args[0])), + "Font" => call!(ui->set_font(args: str)), "Clipboard" => match try_str!(args[0]) { "Set" => match try_str!(args[1]) { "*" => ui.clipboard_primary_set(try_str!(args[2])), @@ -203,6 +114,9 @@ pub fn call_gui_event( })?, opt => error!("Unknown option {}", opt), }, + "Command" => { + ui.on_command(args); + }, _ => return Err(format!("Unsupported event {}({:?})", method, args)), } Ok(()) diff --git a/src/shell.rs b/src/shell.rs index 444487f..fd7a8fa 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -23,8 +23,8 @@ use misc::{decode_uri, escape_filename}; use settings::{FontSource, Settings}; use ui_model::{Attrs, ModelRect, UiModel}; use color::{Color, ColorModel, COLOR_BLACK, COLOR_RED, COLOR_WHITE}; -use nvim::{self, CompleteItem, ErrorReport, GuiApi, NeovimClient, NeovimClientAsync, NeovimRef, - RedrawEvents, RepaintMode}; +use nvim::{self, CompleteItem, ErrorReport, NeovimClient, NeovimClientAsync, NeovimRef, + RepaintMode}; use input; use input::keyval_to_input_string; use cursor::{BlinkCursor, Cursor, CursorRedrawCb}; @@ -98,6 +98,7 @@ pub struct State { detach_cb: Option>>, nvim_started_cb: Option>>, + command_cb: Option) + Send + 'static>>, subscriptions: RefCell, } @@ -139,6 +140,7 @@ impl State { detach_cb: None, nvim_started_cb: None, + command_cb: None, subscriptions: RefCell::new(Subscriptions::new()), } @@ -191,6 +193,17 @@ impl State { } } + pub fn set_nvim_command_cb(&mut self, cb: Option) + where + F: FnMut(Vec) + Send + 'static, + { + if cb.is_some() { + self.command_cb = Some(Box::new(cb.unwrap())); + } else { + self.command_cb = None; + } + } + pub fn set_font_desc(&mut self, desc: &str) { self.render_state .borrow_mut() @@ -395,6 +408,21 @@ impl State { .borrow() .run_now(handle, &mut self.nvim().unwrap()); } + + pub fn set_font(&mut self, font_desc: String) { + { + let mut settings = self.settings.borrow_mut(); + settings.set_font_source(FontSource::Rpc); + } + + self.set_font_desc(&font_desc); + } + + pub fn on_command(&mut self, args: Vec) { + if let Some(ref mut cb) = self.command_cb { + cb(args); + } + } } pub struct UiState { @@ -688,6 +716,14 @@ impl Shell { let mut state = self.state.borrow_mut(); state.set_nvim_started_cb(cb); } + + pub fn set_nvim_command_cb(&self, cb: Option) + where + F: FnMut(Vec) + Send + 'static, + { + let mut state = self.state.borrow_mut(); + state.set_nvim_command_cb(cb); + } } impl Deref for Shell { @@ -1022,31 +1058,32 @@ fn init_nvim(state_ref: &Arc>) { } } -impl RedrawEvents for State { - fn on_cursor_goto(&mut self, row: u64, col: u64) -> RepaintMode { +// Neovim redraw events +impl State { + pub fn on_cursor_goto(&mut self, row: u64, col: u64) -> RepaintMode { let repaint_area = self.model.set_cursor(row as usize, col as usize); self.set_im_location(); RepaintMode::AreaList(repaint_area) } - fn on_put(&mut self, text: String) -> RepaintMode { + pub fn on_put(&mut self, text: String) -> RepaintMode { let ch = text.chars().last().unwrap_or(' '); let double_width = text.is_empty(); RepaintMode::Area(self.model.put(ch, double_width, self.cur_attrs.as_ref())) } - fn on_clear(&mut self) -> RepaintMode { + pub fn on_clear(&mut self) -> RepaintMode { debug!("clear model"); self.model.clear(); RepaintMode::All } - fn on_eol_clear(&mut self) -> RepaintMode { + pub fn on_eol_clear(&mut self) -> RepaintMode { RepaintMode::Area(self.model.eol_clear()) } - fn on_resize(&mut self, columns: u64, rows: u64) -> RepaintMode { + pub fn on_resize(&mut self, columns: u64, rows: u64) -> RepaintMode { debug!("on_resize {}/{}", columns, rows); if self.model.columns != columns as usize || self.model.rows != rows as usize { @@ -1060,7 +1097,7 @@ impl RedrawEvents for State { RepaintMode::Nothing } - fn on_redraw(&mut self, mode: &RepaintMode) { + pub fn on_redraw(&mut self, mode: &RepaintMode) { match *mode { RepaintMode::All => { self.update_dirty_glyphs(); @@ -1072,23 +1109,29 @@ impl RedrawEvents for State { } } - fn on_set_scroll_region(&mut self, top: u64, bot: u64, left: u64, right: u64) -> RepaintMode { + pub fn on_set_scroll_region( + &mut self, + top: u64, + bot: u64, + left: u64, + right: u64, + ) -> RepaintMode { self.model.set_scroll_region(top, bot, left, right); RepaintMode::Nothing } - fn on_scroll(&mut self, count: i64) -> RepaintMode { + pub fn on_scroll(&mut self, count: i64) -> RepaintMode { RepaintMode::Area(self.model.scroll(count)) } - fn on_highlight_set(&mut self, attrs: HashMap) -> RepaintMode { + pub fn on_highlight_set(&mut self, attrs: HashMap) -> RepaintMode { let model_attrs = Attrs::from_value_map(&attrs); self.cur_attrs = Some(model_attrs); RepaintMode::Nothing } - fn on_update_bg(&mut self, bg: i64) -> RepaintMode { + pub fn on_update_bg(&mut self, bg: i64) -> RepaintMode { let mut render_state = self.render_state.borrow_mut(); if bg >= 0 { render_state.color_model.bg_color = Color::from_indexed_color(bg as u64); @@ -1098,7 +1141,7 @@ impl RedrawEvents for State { RepaintMode::Nothing } - fn on_update_fg(&mut self, fg: i64) -> RepaintMode { + pub fn on_update_fg(&mut self, fg: i64) -> RepaintMode { let mut render_state = self.render_state.borrow_mut(); if fg >= 0 { render_state.color_model.fg_color = Color::from_indexed_color(fg as u64); @@ -1108,7 +1151,7 @@ impl RedrawEvents for State { RepaintMode::Nothing } - fn on_update_sp(&mut self, sp: i64) -> RepaintMode { + pub fn on_update_sp(&mut self, sp: i64) -> RepaintMode { let mut render_state = self.render_state.borrow_mut(); if sp >= 0 { render_state.color_model.sp_color = Color::from_indexed_color(sp as u64); @@ -1118,18 +1161,18 @@ impl RedrawEvents for State { RepaintMode::Nothing } - fn on_mode_change(&mut self, mode: String, idx: u64) -> RepaintMode { + pub fn on_mode_change(&mut self, mode: String, idx: u64) -> RepaintMode { let mut render_state = self.render_state.borrow_mut(); render_state.mode.update(&mode, idx as usize); RepaintMode::Area(self.model.cur_point()) } - fn on_mouse(&mut self, on: bool) -> RepaintMode { + pub fn on_mouse(&mut self, on: bool) -> RepaintMode { self.mouse_enabled = on; RepaintMode::Nothing } - fn on_busy(&mut self, busy: bool) -> RepaintMode { + pub fn on_busy(&mut self, busy: bool) -> RepaintMode { if busy { self.cursor.as_mut().unwrap().busy_on(); } else { @@ -1138,7 +1181,7 @@ impl RedrawEvents for State { RepaintMode::Area(self.model.cur_point()) } - fn popupmenu_show( + pub fn popupmenu_show( &mut self, menu: &[CompleteItem], selected: i64, @@ -1167,17 +1210,17 @@ impl RedrawEvents for State { RepaintMode::Nothing } - fn popupmenu_hide(&mut self) -> RepaintMode { + pub fn popupmenu_hide(&mut self) -> RepaintMode { self.popup_menu.hide(); RepaintMode::Nothing } - fn popupmenu_select(&mut self, selected: i64) -> RepaintMode { + pub fn popupmenu_select(&mut self, selected: i64) -> RepaintMode { self.popup_menu.select(selected); RepaintMode::Nothing } - fn tabline_update( + pub fn tabline_update( &mut self, selected: Tabpage, tabs: Vec<(Tabpage, Option)>, @@ -1187,7 +1230,7 @@ impl RedrawEvents for State { RepaintMode::Nothing } - fn mode_info_set( + pub fn mode_info_set( &mut self, cursor_style_enabled: bool, mode_info: Vec, @@ -1197,7 +1240,7 @@ impl RedrawEvents for State { RepaintMode::Nothing } - fn cmdline_show( + pub fn cmdline_show( &mut self, content: Vec<(HashMap, String)>, pos: u64, @@ -1230,12 +1273,12 @@ impl RedrawEvents for State { self.on_busy(true) } - fn cmdline_hide(&mut self, level: u64) -> RepaintMode { + pub fn cmdline_hide(&mut self, level: u64) -> RepaintMode { self.cmd_line.hide_level(level); self.on_busy(false) } - fn cmdline_block_show( + pub fn cmdline_block_show( &mut self, content: Vec, String)>>, ) -> RepaintMode { @@ -1244,7 +1287,7 @@ impl RedrawEvents for State { self.on_busy(true) } - fn cmdline_block_append( + pub fn cmdline_block_append( &mut self, content: Vec<(HashMap, String)>, ) -> RepaintMode { @@ -1252,18 +1295,18 @@ impl RedrawEvents for State { RepaintMode::Nothing } - fn cmdline_block_hide(&mut self) -> RepaintMode { + pub fn cmdline_block_hide(&mut self) -> RepaintMode { self.cmd_line.block_hide(); self.on_busy(false) } - fn cmdline_pos(&mut self, pos: u64, level: u64) -> RepaintMode { + pub fn cmdline_pos(&mut self, pos: u64, level: u64) -> RepaintMode { let render_state = self.render_state.borrow(); self.cmd_line.pos(&*render_state, pos, level); RepaintMode::Nothing } - fn cmdline_special_char(&mut self, c: String, shift: bool, level: u64) -> RepaintMode { + pub fn cmdline_special_char(&mut self, c: String, shift: bool, level: u64) -> RepaintMode { let render_state = self.render_state.borrow(); self.cmd_line.special_char(&*render_state, c, shift, level); RepaintMode::Nothing @@ -1276,14 +1319,3 @@ impl CursorRedrawCb for State { self.on_redraw(&RepaintMode::Area(cur_point)); } } - -impl GuiApi for State { - fn set_font(&mut self, font_desc: &str) { - { - let mut settings = self.settings.borrow_mut(); - settings.set_font_source(FontSource::Rpc); - } - - self.set_font_desc(font_desc); - } -} diff --git a/src/ui.rs b/src/ui.rs index a01706f..d3831b4 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -10,8 +10,12 @@ use gtk::prelude::*; use gtk::{AboutDialog, ApplicationWindow, Button, HeaderBar, Orientation, Paned, SettingsExt}; use gio::prelude::*; use gio::{Menu, MenuExt, MenuItem, SimpleAction}; +use glib::variant::FromVariant; + use toml; +use neovim_lib::Value; + use settings::{Settings, SettingsLoader}; use shell::{self, Shell, ShellOptions}; use shell_dlg; @@ -277,6 +281,20 @@ impl Ui { state.run_now(&update_subtitle); } })); + + let sidebar_action = UiMutex::new(show_sidebar_action); + shell.set_nvim_command_cb(Some(move |args: Vec| { + if let Some(cmd) = args[0].as_str() { + match cmd { + "ToggleSidebar" => { + let action = sidebar_action.borrow(); + let state = !bool::from_variant(&action.get_state().unwrap()).unwrap(); + action.change_state(&state.to_variant()); + } + _ => {} + } + } + })); } fn create_header_bar(&self) -> SubscriptionHandle {