From 94747615af51143072b601a0f2c5903600ec5180 Mon Sep 17 00:00:00 2001 From: daa84 Date: Wed, 13 Sep 2017 17:40:43 +0300 Subject: [PATCH] Move out resize/init code from draw handler --- src/nvim.rs | 203 ++++++++++++++++++--------------- src/project.rs | 12 +- src/settings.rs | 1 - src/shell.rs | 228 ++++++++++++++++++++----------------- src/shell_dlg.rs | 97 +++++++++------- src/sys/pango/item.rs | 7 -- src/ui_model/mod.rs | 26 ----- src/ui_model/model_rect.rs | 28 +++++ 8 files changed, 330 insertions(+), 272 deletions(-) diff --git a/src/nvim.rs b/src/nvim.rs index 9154b61..c209dd0 100644 --- a/src/nvim.rs +++ b/src/nvim.rs @@ -47,26 +47,29 @@ pub trait RedrawEvents { fn on_busy(&mut self, busy: bool) -> RepaintMode; - fn popupmenu_show(&mut self, - menu: &[Vec<&str>], - selected: i64, - row: u64, - col: u64) - -> RepaintMode; + fn popupmenu_show( + &mut self, + menu: &[Vec<&str>], + 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 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 mode_info_set( + &mut self, + cursor_style_enabled: bool, + mode_info: Vec, + ) -> RepaintMode; } pub trait GuiApi { @@ -116,19 +119,19 @@ pub enum CursorShape { impl CursorShape { fn new(shape_code: &Value) -> Result { - let str_code = shape_code - .as_str() - .ok_or_else(|| "Can't convert cursor shape to string".to_owned())?; + let str_code = shape_code.as_str().ok_or_else(|| { + "Can't convert cursor shape to string".to_owned() + })?; Ok(match str_code { - "block" => CursorShape::Block, - "horizontal" => CursorShape::Horizontal, - "vertical" => CursorShape::Vertical, - _ => { - error!("Unknown cursor_shape {}", str_code); - CursorShape::Unknown - } - }) + "block" => CursorShape::Block, + "horizontal" => CursorShape::Horizontal, + "vertical" => CursorShape::Vertical, + _ => { + error!("Unknown cursor_shape {}", str_code); + CursorShape::Unknown + } + }) } } @@ -155,9 +158,9 @@ impl ModeInfo { }; Ok(ModeInfo { - cursor_shape, - cell_percentage, - }) + cursor_shape, + cell_percentage, + }) } pub fn cursor_shape(&self) -> Option<&CursorShape> { @@ -177,7 +180,8 @@ pub struct NvimInitError { impl NvimInitError { pub fn new_post_init(error: E) -> NvimInitError - where E: Into> + where + E: Into>, { NvimInitError { cmd: None, @@ -186,7 +190,8 @@ impl NvimInitError { } pub fn new(cmd: &Command, error: E) -> NvimInitError - where E: Into> + where + E: Into>, { NvimInitError { cmd: Some(format!("{:?}", cmd)), @@ -219,9 +224,10 @@ impl error::Error for NvimInitError { } } -pub fn start(shell: Arc>, - nvim_bin_path: Option<&String>) - -> 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 { @@ -237,11 +243,14 @@ pub fn start(shell: Arc>, .stderr(Stdio::inherit()); if let Ok(runtime_path) = env::var("NVIM_GTK_RUNTIME_PATH") { - cmd.arg("--cmd") - .arg(format!("let &rtp.=',{}'", runtime_path)); + cmd.arg("--cmd").arg( + format!("let &rtp.=',{}'", runtime_path), + ); } else if let Some(prefix) = option_env!("PREFIX") { - cmd.arg("--cmd") - .arg(format!("let &rtp.=',{}/share/nvim-gtk/runtime'", prefix)); + cmd.arg("--cmd").arg(format!( + "let &rtp.=',{}/share/nvim-gtk/runtime'", + prefix + )); } else { cmd.arg("--cmd").arg("let &rtp.=',runtime'"); } @@ -255,28 +264,33 @@ pub fn start(shell: Arc>, let mut nvim = Neovim::new(session); - nvim.session - .start_event_loop_handler(NvimHandler::new(shell)); + 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> { +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(NvimInitError::new_post_init)?; - nvim.command("runtime! ginit.vim") - .map_err(NvimInitError::new_post_init)?; + nvim.ui_attach(cols, rows, opts).map_err( + NvimInitError::new_post_init, + )?; + nvim.command("runtime! ginit.vim").map_err( + NvimInitError::new_post_init, + )?; if let Some(path) = open_path { - nvim.command(&format!("e {}", path)) - .map_err(NvimInitError::new_post_init)?; + nvim.command(&format!("e {}", path)).map_err( + NvimInitError::new_post_init, + )?; } Ok(()) @@ -325,10 +339,10 @@ impl NvimHandler { if let Some(ev_name) = params[0].as_str().map(String::from) { let args = params.iter().skip(1).cloned().collect(); self.safe_call(move |ui| { - call_gui_event(ui, &ev_name, &args)?; - ui.on_redraw(&RepaintMode::All); - Ok(()) - }); + call_gui_event(ui, &ev_name, &args)?; + ui.on_redraw(&RepaintMode::All); + Ok(()) + }); } else { println!("Unsupported event {:?}", params); } @@ -343,15 +357,16 @@ impl NvimHandler { } fn safe_call(&self, cb: F) - where F: Fn(&mut shell::State) -> result::Result<(), String> + 'static + Send + where + F: Fn(&mut shell::State) -> result::Result<(), String> + 'static + Send, { let shell = self.shell.clone(); glib::idle_add(move || { - if let Err(msg) = cb(&mut shell.borrow_mut()) { - println!("Error call function: {}", msg); - } - glib::Continue(false) - }); + if let Err(msg) = cb(&mut shell.borrow_mut()) { + println!("Error call function: {}", msg); + } + glib::Continue(false) + }); } } @@ -362,21 +377,24 @@ impl Handler for NvimHandler { } -fn call_gui_event(ui: &mut shell::State, - method: &str, - args: &Vec) - -> result::Result<(), String> { +fn call_gui_event( + ui: &mut shell::State, + method: &str, + args: &Vec, +) -> result::Result<(), String> { match method { "Font" => ui.set_font(try_str!(args[0])), "Option" => { match try_str!(args[0]) { "Popupmenu" => { ui.nvim() + .unwrap() .set_option(UiOption::ExtPopupmenu(try_uint!(args[1]) == 1)) .map_err(|e| e.to_string())? } "Tabline" => { ui.nvim() + .unwrap() .set_option(UiOption::ExtTabline(try_uint!(args[1]) == 1)) .map_err(|e| e.to_string())? } @@ -388,10 +406,11 @@ fn call_gui_event(ui: &mut shell::State, Ok(()) } -fn call(ui: &mut shell::State, - method: &str, - args: &[Value]) - -> result::Result { +fn call( + ui: &mut shell::State, + method: &str, + args: &[Value], +) -> result::Result { let repaint_mode = match method { "cursor_goto" => ui.on_cursor_goto(try_uint!(args[0]), try_uint!(args[1])), "put" => ui.on_put(try_str!(args[0])), @@ -407,10 +426,12 @@ fn call(ui: &mut shell::State, } "eol_clear" => ui.on_eol_clear(), "set_scroll_region" => { - ui.on_set_scroll_region(try_uint!(args[0]), - try_uint!(args[1]), - try_uint!(args[2]), - try_uint!(args[3])); + ui.on_set_scroll_region( + try_uint!(args[0]), + try_uint!(args[1]), + try_uint!(args[2]), + try_uint!(args[3]), + ); RepaintMode::Nothing } "scroll" => ui.on_scroll(try_int!(args[0])), @@ -424,15 +445,17 @@ fn call(ui: &mut shell::State, "busy_stop" => ui.on_busy(false), "popupmenu_show" => { let menu_items = map_array!(args[0], "Error get menu list array", |item| { - map_array!(item, - "Error get menu item array", - |col| col.as_str().ok_or("Error get menu column")) + map_array!(item, "Error get menu item array", |col| { + col.as_str().ok_or("Error get menu column") + }) })?; - ui.popupmenu_show(&menu_items, - try_int!(args[1]), - try_uint!(args[2]), - try_uint!(args[3])) + ui.popupmenu_show( + &menu_items, + try_int!(args[1]), + try_uint!(args[2]), + try_uint!(args[3]), + ) } "popupmenu_hide" => ui.popupmenu_hide(), "popupmenu_select" => ui.popupmenu_select(try_int!(args[0])), @@ -442,9 +465,9 @@ fn call(ui: &mut shell::State, .ok_or_else(|| "Error get map for tab".to_owned()) .and_then(|tab_map| tab_map.to_attrs_map()) .map(|tab_attrs| { - let name_attr = tab_attrs - .get("name") - .and_then(|n| n.as_str().map(|s| s.to_owned())); + let name_attr = tab_attrs.get("name").and_then( + |n| n.as_str().map(|s| s.to_owned()), + ); let tab_attr = tab_attrs .get("tab") .map(|tab_id| Tabpage::new(tab_id.clone())) @@ -456,13 +479,15 @@ fn call(ui: &mut shell::State, ui.tabline_update(Tabpage::new(args[0].clone()), tabs_out) } "mode_info_set" => { - let mode_info = map_array!(args[1], - "Error get array key value for mode_info".to_owned(), - |mi| { - mi.as_map() - .ok_or_else(|| "Erro get map for mode_info".to_owned()) - .and_then(|mi_map| ModeInfo::new(mi_map)) - })?; + let mode_info = map_array!( + args[1], + "Error get array key value for mode_info".to_owned(), + |mi| { + mi.as_map() + .ok_or_else(|| "Erro get map for mode_info".to_owned()) + .and_then(|mi_map| ModeInfo::new(mi_map)) + } + )?; ui.mode_info_set(try_bool!(args[0]), mode_info) } _ => { diff --git a/src/project.rs b/src/project.rs index deeaf4a..60fe38b 100644 --- a/src/project.rs +++ b/src/project.rs @@ -245,15 +245,17 @@ impl Projects { fn load_oldfiles(&mut self) { let shell_borrow = self.shell.borrow(); let shell_state = shell_borrow.state.borrow_mut(); - let mut nvim = shell_state.nvim(); - let store = EntryStore::load(&mut nvim); - store.populate(&self.get_list_store(), None); - self.store = Some(store); + let nvim = shell_state.nvim(); + if let Some(mut nvim) = nvim { + let store = EntryStore::load(&mut nvim); + store.populate(&self.get_list_store(), None); + self.store = Some(store); + } } pub fn clear(&mut self) { - self.store.take().unwrap().save(); + self.store.take().map(|s| s.save()); self.get_list_store().clear(); } diff --git a/src/settings.rs b/src/settings.rs index 679f9fb..80c1430 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -96,6 +96,5 @@ fn monospace_font_changed(mut shell: &mut Shell, state: &mut State) { // rpc is priority for font if state.font_source != FontSource::Rpc { state.update_font(&mut shell); - shell.redraw(&RepaintMode::All); } } diff --git a/src/shell.rs b/src/shell.rs index ec6e2ad..bf9714b 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -48,6 +48,12 @@ macro_rules! idle_cb_call { ) } +enum ResizeState { + RequestNvimResize(glib::SourceId), + RequestWindowResize, + Wait, +} + pub struct State { pub model: UiModel, color_model: ColorModel, @@ -67,9 +73,7 @@ pub struct State { im_context: gtk::IMMulticontext, error_area: error::ErrorArea, - request_resize: bool, - request_nvim_resize: bool, - resize_timer: Option, + resize_state: ResizeState, options: ShellOptions, @@ -102,9 +106,7 @@ impl State { im_context: gtk::IMMulticontext::new(), error_area: error::ErrorArea::new(), - resize_timer: None, - request_resize: false, - request_nvim_resize: false, + resize_state: ResizeState::Wait, options, @@ -120,8 +122,12 @@ impl State { &self.color_model.bg_color } - pub fn nvim(&self) -> RefMut { - RefMut::map(self.nvim.borrow_mut(), |n| n.nvim_mut()) + pub fn nvim(&self) -> Option> { + if self.nvim.borrow().is_initialized() { + Some(RefMut::map(self.nvim.borrow_mut(), |n| n.nvim_mut())) + } else { + None + } } pub fn nvim_clone(&self) -> Rc> { @@ -151,37 +157,36 @@ impl State { } pub fn open_file(&self, path: &str) { - let mut nvim = self.nvim(); - nvim.command(&format!("e {}", path)).report_err(&mut *nvim); + if let Some(mut nvim) = self.nvim() { + nvim.command(&format!("e {}", path)).report_err(&mut *nvim); + } } pub fn cd(&self, path: &str) { - let mut nvim = self.nvim(); - nvim.command(&format!("cd {}", path)).report_err(&mut *nvim); - } - - fn request_resize(&mut self) { - self.request_resize = true; - } - - fn request_nvim_resize(&mut self) { - self.request_nvim_resize = true; + if let Some(mut nvim) = self.nvim() { + nvim.command(&format!("cd {}", path)).report_err(&mut *nvim); + } } fn close_popup_menu(&self) { if self.popup_menu.borrow().is_open() { - let mut nvim = self.nvim(); - nvim.input("").report_err(&mut *nvim); + if let Some(mut nvim) = self.nvim() { + nvim.input("").report_err(&mut *nvim); + } } } fn queue_draw_area>(&mut self, rect_list: &[M]) { // extends by items before, then after changes - let rects: Vec<_> = rect_list.iter().map(|rect| rect.as_ref().clone()).map(|mut rect| { - rect.extend_by_items(&self.model); - rect - }).collect(); + let rects: Vec<_> = rect_list + .iter() + .map(|rect| rect.as_ref().clone()) + .map(|mut rect| { + rect.extend_by_items(&self.model); + rect + }) + .collect(); self.update_dirty_glyphs(); @@ -239,6 +244,38 @@ impl State { self.im_context.reset(); } + + fn resize_main_window(&mut self) { + match self.resize_state { + ResizeState::RequestNvimResize(_) => return, + _ => (), + } + + let &CellMetrics { + line_height, + char_width, + .. + } = self.font_ctx.cell_metrics(); + + let width = self.drawing_area.get_allocated_width(); + let height = self.drawing_area.get_allocated_height(); + let request_height = (self.model.rows as f64 * line_height) as i32; + let request_width = (self.model.columns as f64 * char_width) as i32; + + if width != request_width || height != request_height { + self.resize_state = ResizeState::RequestWindowResize; + + let window: gtk::Window = self.drawing_area + .get_toplevel() + .unwrap() + .downcast() + .unwrap(); + let (win_width, win_height) = window.get_size(); + let h_border = win_width - width; + let v_border = win_height - height; + window.resize(request_width + h_border, request_height + v_border); + } + } } pub struct UiState { @@ -419,11 +456,12 @@ impl Shell { try_nvim_resize(&ref_state); false }); - } - #[cfg(unix)] - pub fn redraw(&self, mode: &RepaintMode) { - self.state.borrow_mut().on_redraw(mode); + let ref_state = self.state.clone(); + state.drawing_area.connect_size_allocate( + move |_, _| init_nvim(&ref_state), + ); + } #[cfg(unix)] @@ -445,7 +483,11 @@ impl Shell { pub fn detach_ui(&mut self) { let state = self.state.borrow(); - state.nvim().ui_detach().expect("Error in ui_detach"); + + let nvim = state.nvim(); + if let Some(mut nvim) = nvim { + nvim.ui_detach().expect("Error in ui_detach"); + } } pub fn edit_paste(&self) { @@ -456,14 +498,19 @@ impl Shell { "\"*pa" }; - let mut nvim = state.nvim(); - nvim.input(paste_command).report_err(&mut *nvim); + let nvim = state.nvim(); + if let Some(mut nvim) = nvim { + nvim.input(paste_command).report_err(&mut *nvim); + } } pub fn edit_save_all(&self) { let state = self.state.borrow(); - let nvim = &mut *state.nvim(); - nvim.command(":wa").report_err(nvim); + + let nvim = state.nvim(); + if let Some(mut nvim) = nvim { + nvim.command(":wa").report_err(&mut *nvim); + } } pub fn set_detach_cb(&self, cb: Option) @@ -544,14 +591,17 @@ fn mouse_input(shell: &mut State, input: &str, state: ModifierType, position: (f char_width, .. } = shell.font_ctx.cell_metrics(); - let mut nvim = shell.nvim(); let (x, y) = position; let col = (x / char_width).trunc() as u64; let row = (y / line_height).trunc() as u64; let input_str = format!("{}<{},{}>", keyval_to_input_string(input, state), col, row); - nvim.input(&input_str).expect( - "Can't send mouse input event", - ); + + let nvim = shell.nvim(); + if let Some(mut nvim) = nvim { + nvim.input(&input_str).expect( + "Can't send mouse input event", + ); + } } fn gtk_button_release(ui_state: &mut UiState) -> Inhibit { @@ -567,15 +617,9 @@ fn gtk_motion_notify(shell: &mut State, ui_state: &mut UiState, ev: &EventMotion } fn gtk_draw(state_arc: &Arc>, ctx: &cairo::Context) -> Inhibit { - if state_arc.borrow_mut().request_nvim_resize { - try_nvim_resize(state_arc); - } - init_nvim(state_arc); - - let mut state = state_arc.borrow_mut(); + let state = state_arc.borrow(); if state.nvim.borrow().is_initialized() { - request_window_resize(&mut *state); render::render( ctx, state.cursor.as_ref().unwrap(), @@ -664,21 +708,6 @@ fn init_nvim_async( }); } -fn init_nvim(state_arc: &Arc>) { - let state = state_arc.borrow(); - - let mut nvim = state.nvim.borrow_mut(); - if nvim.is_uninitialized() { - nvim.set_in_progress(); - - let (cols, rows) = state.calc_nvim_size(); - - let state_arc = state_arc.clone(); - let options = state.options.clone(); - thread::spawn(move || init_nvim_async(state_arc, options, cols, rows)); - } -} - fn draw_initializing(state: &State, ctx: &cairo::Context) { let layout = ctx.create_pango_layout(); let desc = state.get_font_desc(); @@ -719,47 +748,32 @@ fn draw_initializing(state: &State, ctx: &cairo::Context) { ); } -fn request_window_resize(state: &mut State) { - if !state.request_resize { - return; - } - if state.resize_timer.is_some() { - return; - } +fn init_nvim(state_ref: &Arc>) { + let state = state_ref.borrow(); + let mut nvim = state.nvim.borrow_mut(); + if nvim.is_uninitialized() { + nvim.set_in_progress(); - let &CellMetrics { - line_height, - char_width, - .. - } = state.font_ctx.cell_metrics(); - state.request_resize = false; + let (cols, rows) = state.calc_nvim_size(); - let width = state.drawing_area.get_allocated_width(); - let height = state.drawing_area.get_allocated_height(); - let request_height = (state.model.rows as f64 * line_height) as i32; - let request_width = (state.model.columns as f64 * char_width) as i32; - - if width != request_width || height != request_height { - let window: gtk::Window = state - .drawing_area - .get_toplevel() - .unwrap() - .downcast() - .unwrap(); - let (win_width, win_height) = window.get_size(); - let h_border = win_width - width; - let v_border = win_height - height; - window.resize(request_width + h_border, request_height + v_border); + let state_arc = state_ref.clone(); + let options = state.options.clone(); + thread::spawn(move || init_nvim_async(state_arc, options, cols, rows)); } } fn try_nvim_resize(state: &Arc>) { let mut state_ref = state.borrow_mut(); - state_ref.request_nvim_resize = false; - - if let Some(timer) = state_ref.resize_timer { - glib::source_remove(timer); + match state_ref.resize_state { + ResizeState::RequestWindowResize => { + state_ref.resize_state = ResizeState::Wait; + return; + } + ResizeState::RequestNvimResize(timer) => { + glib::source_remove(timer); + } + ResizeState::Wait => (), } if !state_ref.nvim.borrow().is_initialized() { @@ -768,14 +782,17 @@ fn try_nvim_resize(state: &Arc>) { let (columns, rows) = state_ref.calc_nvim_size(); let state = state.clone(); - state_ref.resize_timer = Some(glib::timeout_add(250, move || { + state_ref.resize_state = ResizeState::RequestNvimResize(gtk::timeout_add(250, move || { let mut state_ref = state.borrow_mut(); - state_ref.resize_timer = None; + state_ref.resize_state = ResizeState::Wait; if state_ref.model.rows != rows || state_ref.model.columns != columns { - if let Err(err) = state_ref.nvim().ui_try_resize(columns as u64, rows as u64) { - error!("Error trying resize nvim {}", err); + let nvim = state_ref.nvim(); + if let Some(mut nvim) = nvim { + if let Err(err) = nvim.ui_try_resize(columns as u64, rows as u64) { + error!("Error trying resize nvim {}", err); + } } } Continue(false) @@ -804,7 +821,8 @@ impl RedrawEvents for State { fn on_resize(&mut self, columns: u64, rows: u64) -> RepaintMode { self.model = UiModel::new(rows, columns); - self.request_resize(); + self.resize_main_window(); + RepaintMode::Nothing } @@ -813,7 +831,7 @@ impl RedrawEvents for State { RepaintMode::All => { self.update_dirty_glyphs(); self.drawing_area.queue_draw(); - }, + } RepaintMode::Area(ref rect) => self.queue_draw_area(&[rect]), RepaintMode::AreaList(ref list) => self.queue_draw_area(&list.list), RepaintMode::Nothing => (), @@ -968,10 +986,12 @@ impl RedrawEvents for State { impl GuiApi for State { fn set_font(&mut self, font_desc: &str) { - self.set_font_desc(font_desc); - self.request_nvim_resize(); + { + let mut settings = self.settings.borrow_mut(); + settings.set_font_source(FontSource::Rpc); + } - let mut settings = self.settings.borrow_mut(); - settings.set_font_source(FontSource::Rpc); + self.set_font_desc(font_desc); + self.resize_main_window(); } } diff --git a/src/shell_dlg.rs b/src/shell_dlg.rs index 29fb0df..e7cf96e 100644 --- a/src/shell_dlg.rs +++ b/src/shell_dlg.rs @@ -24,10 +24,7 @@ pub fn can_close_window(comps: &UiMutex, shell: &RefCell) -> } } -fn show_not_saved_dlg(comps: &UiMutex, - shell: &Shell, - changed_bufs: &[String]) - -> bool { +fn show_not_saved_dlg(comps: &UiMutex, shell: &Shell, changed_bufs: &[String]) -> bool { let mut changed_files = changed_bufs .iter() .map(|n| if n.is_empty() { "" } else { n }) @@ -35,24 +32,30 @@ fn show_not_saved_dlg(comps: &UiMutex, changed_files.pop(); let flags = gtk::DIALOG_MODAL | gtk::DIALOG_DESTROY_WITH_PARENT; - let dlg = MessageDialog::new(Some(comps.borrow().window()), - flags, - MessageType::Question, - ButtonsType::None, - &format!("Save changes to '{}'?", changed_files)); + let dlg = MessageDialog::new( + Some(comps.borrow().window()), + flags, + MessageType::Question, + ButtonsType::None, + &format!("Save changes to '{}'?", changed_files), + ); const SAVE_ID: i32 = 0; const CLOSE_WITHOUT_SAVE: i32 = 1; const CANCEL_ID: i32 = 2; - dlg.add_buttons(&[("_Yes", SAVE_ID), - ("_No", CLOSE_WITHOUT_SAVE), - ("_Cancel", CANCEL_ID)]); + dlg.add_buttons( + &[ + ("_Yes", SAVE_ID), + ("_No", CLOSE_WITHOUT_SAVE), + ("_Cancel", CANCEL_ID), + ], + ); let res = match dlg.run() { SAVE_ID => { let state = shell.state.borrow(); - let mut nvim = state.nvim(); + let mut nvim = state.nvim().unwrap(); match nvim.command("wa") { Err(ref err) => { println!("Error: {}", err); @@ -72,32 +75,46 @@ fn show_not_saved_dlg(comps: &UiMutex, fn get_changed_buffers(shell: &Shell) -> Result, CallError> { let state = shell.state.borrow(); - let mut nvim = state.nvim(); - let buffers = nvim.list_bufs().unwrap(); + let nvim = state.nvim(); + if let Some(mut nvim) = nvim { + let buffers = nvim.list_bufs().unwrap(); - Ok(buffers - .iter() - .map(|buf| { - (match buf.get_option(&mut nvim, "modified") { - Ok(Value::Boolean(val)) => val, - Ok(_) => { - println!("Value must be boolean"); - false - } - Err(ref err) => { - println!("Something going wrong while getting buffer option: {}", err); - false - } - }, - match buf.get_name(&mut nvim) { - Ok(name) => name, - Err(ref err) => { - println!("Something going wrong while getting buffer name: {}", err); - "".to_owned() - } - }) - }) - .filter(|e| e.0) - .map(|e| e.1) - .collect()) + Ok( + buffers + .iter() + .map(|buf| { + ( + match buf.get_option(&mut nvim, "modified") { + Ok(Value::Boolean(val)) => val, + Ok(_) => { + println!("Value must be boolean"); + false + } + Err(ref err) => { + println!( + "Something going wrong while getting buffer option: {}", + err + ); + false + } + }, + match buf.get_name(&mut nvim) { + Ok(name) => name, + Err(ref err) => { + println!( + "Something going wrong while getting buffer name: {}", + err + ); + "".to_owned() + } + }, + ) + }) + .filter(|e| e.0) + .map(|e| e.1) + .collect(), + ) + } else { + Ok(vec![]) + } } diff --git a/src/sys/pango/item.rs b/src/sys/pango/item.rs index 797cd74..26d7d9f 100644 --- a/src/sys/pango/item.rs +++ b/src/sys/pango/item.rs @@ -27,13 +27,6 @@ impl Item { } } - #[cfg(test)] - pub fn set_offset(&mut self, offset: i32, length: i32, num_chars: i32) { - self.0.offset = offset; - self.0.length = length; - self.0.num_chars = num_chars; - } - pub fn analysis(&self) -> analysis::Analysis { analysis::Analysis::from(&self.0.analysis) } diff --git a/src/ui_model/mod.rs b/src/ui_model/mod.rs index e5cc799..1585a48 100644 --- a/src/ui_model/mod.rs +++ b/src/ui_model/mod.rs @@ -231,32 +231,6 @@ mod tests { assert_eq!(2, list.list.len()); } - #[test] - fn test_from_area() { - let rect = ModelRect::from_area(10.0, 5.0, 3.0, 3.0, 9.0, 17.0); - - assert_eq!(0, rect.top); - assert_eq!(0, rect.left); - assert_eq!(1, rect.bot); - assert_eq!(1, rect.right); - - - let rect = ModelRect::from_area(10.0, 5.0, 0.0, 0.0, 10.0, 20.0); - - assert_eq!(0, rect.top); - assert_eq!(0, rect.left); - assert_eq!(1, rect.bot); - assert_eq!(1, rect.right); - - - let rect = ModelRect::from_area(10.0, 5.0, 0.0, 0.0, 11.0, 21.0); - - assert_eq!(0, rect.top); - assert_eq!(0, rect.left); - assert_eq!(2, rect.bot); - assert_eq!(2, rect.right); - } - #[test] fn test_cursor_area() { let mut model = UiModel::new(10, 20); diff --git a/src/ui_model/model_rect.rs b/src/ui_model/model_rect.rs index 3287cbe..c2117b4 100644 --- a/src/ui_model/model_rect.rs +++ b/src/ui_model/model_rect.rs @@ -301,4 +301,32 @@ mod tests { assert_eq!(5, width); assert_eq!(10, height); } + + + #[test] + fn test_from_area() { + let rect = ModelRect::from_area(&CellMetrics::new_hw(10.0, 5.0), 3.0, 3.0, 9.0, 17.0); + + assert_eq!(0, rect.top); + assert_eq!(0, rect.left); + assert_eq!(1, rect.bot); + assert_eq!(1, rect.right); + + + let rect = ModelRect::from_area(&CellMetrics::new_hw(10.0, 5.0), 0.0, 0.0, 10.0, 20.0); + + assert_eq!(0, rect.top); + assert_eq!(0, rect.left); + assert_eq!(1, rect.bot); + assert_eq!(1, rect.right); + + + let rect = ModelRect::from_area(&CellMetrics::new_hw(10.0, 5.0), 0.0, 0.0, 11.0, 21.0); + + assert_eq!(0, rect.top); + assert_eq!(0, rect.left); + assert_eq!(2, rect.bot); + assert_eq!(2, rect.right); + } + }