From 82c7f0818a688013d1266f2847657dc3054d468f Mon Sep 17 00:00:00 2001 From: daa Date: Sat, 31 Mar 2018 19:56:44 +0300 Subject: [PATCH] Prevent popup blink in case events hide/show come together --- src/nvim/handler.rs | 4 +++- src/nvim/redraw_handler.rs | 45 +++++++++++++++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/nvim/handler.rs b/src/nvim/handler.rs index c6ee331..3c62eae 100644 --- a/src/nvim/handler.rs +++ b/src/nvim/handler.rs @@ -19,9 +19,11 @@ impl NvimHandler { NvimHandler { shell: shell } } - fn nvim_cb(&self, method: &str, params: Vec) { + fn nvim_cb(&self, method: &str, mut params: Vec) { match method { "redraw" => { + redraw_handler::remove_uneeded_events(&mut params); + self.safe_call(move |ui| { let ui = &mut ui.borrow_mut(); let mut repaint_mode = RepaintMode::Nothing; diff --git a/src/nvim/redraw_handler.rs b/src/nvim/redraw_handler.rs index bef2e3f..f82d55b 100644 --- a/src/nvim/redraw_handler.rs +++ b/src/nvim/redraw_handler.rs @@ -116,7 +116,7 @@ pub fn call_gui_event( }, "Command" => { ui.on_command(args); - }, + } _ => return Err(format!("Unsupported event {}({:?})", method, args)), } Ok(()) @@ -247,6 +247,30 @@ pub fn call( Ok(repaint_mode) } +// menu content update call popupmenu_hide followed by popupmenu_show +// this generates unneded hide event +// so in case we get both events, just romove one +pub fn remove_uneeded_events(params: &mut Vec) { + let mut show_popup_finded = false; + let mut to_remove = Vec::new(); + + for (idx, val) in params.iter().enumerate().rev() { + if let Some(args) = val.as_array() { + match args[0].as_str() { + Some("popupmenu_show") => show_popup_finded = true, + Some("popupmenu_hide") if show_popup_finded => { + to_remove.push(idx); + } + _ => (), + } + } + } + + to_remove.iter().for_each(|&idx| { + params.remove(idx); + }); +} + pub struct CompleteItem<'a> { pub word: &'a str, pub kind: &'a str, @@ -266,3 +290,22 @@ impl<'a> CompleteItem<'a> { .collect() } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_remove_popup_menu_hide() { + // remove only first hide + let mut params = vec![ + Value::from(vec![Value::from("popupmenu_hide")]), + Value::from(vec![Value::from("popupmenu_show")]), + Value::from(vec![Value::from("popupmenu_hide")]), + ]; + + remove_uneeded_events(&mut params); + + assert_eq!(2, params.len()); + } +}