diff --git a/src/nvim/mod.rs b/src/nvim/mod.rs index 6873e1d..925db89 100644 --- a/src/nvim/mod.rs +++ b/src/nvim/mod.rs @@ -6,7 +6,7 @@ mod redraw_handler; mod repaint_mode; mod ext; -pub use self::redraw_handler::{RedrawEvents, GuiApi}; +pub use self::redraw_handler::{RedrawEvents, GuiApi, CompleteItem}; pub use self::repaint_mode::RepaintMode; pub use self::client::{NeovimClient, NeovimClientAsync, NeovimRef}; pub use self::mode_info::{ModeInfo, CursorShape}; diff --git a/src/nvim/redraw_handler.rs b/src/nvim/redraw_handler.rs index 095fbea..479a53b 100644 --- a/src/nvim/redraw_handler.rs +++ b/src/nvim/redraw_handler.rs @@ -43,7 +43,7 @@ pub trait RedrawEvents { fn popupmenu_show( &mut self, - menu: &[Vec<&str>], + menu: &[CompleteItem], selected: i64, row: u64, col: u64, @@ -182,7 +182,7 @@ pub fn call( })?; ui.popupmenu_show( - &menu_items, + &CompleteItem::map(&menu_items), try_int!(args[1]), try_uint!(args[2]), try_uint!(args[3]), @@ -229,3 +229,25 @@ pub fn call( Ok(repaint_mode) } + +pub struct CompleteItem<'a> { + pub word: &'a str, + pub kind: &'a str, + pub menu: &'a str, + pub info: &'a str, +} + +impl<'a> CompleteItem<'a> { + fn map(menu: &'a [Vec<&str>]) -> Vec { + menu.iter() + .map(|menu| { + CompleteItem { + word: menu[0], + kind: menu[1], + menu: menu[2], + info: menu[3], + } + }) + .collect() + } +} diff --git a/src/popup_menu.rs b/src/popup_menu.rs index 1dec3fa..b86e6da 100644 --- a/src/popup_menu.rs +++ b/src/popup_menu.rs @@ -10,7 +10,7 @@ use gdk::{EventButton, EventType}; use neovim_lib::{Neovim, NeovimApi}; use color::ColorModel; -use nvim::{self, ErrorReport}; +use nvim::{self, ErrorReport, CompleteItem}; use shell; use input; @@ -32,25 +32,50 @@ impl State { let style_context = tree.get_style_context().unwrap(); style_context.add_provider(&css_provider, gtk::STYLE_PROVIDER_PRIORITY_APPLICATION); + let renderer = gtk::CellRendererText::new(); + + // TODO: use info + // word + let column = gtk::TreeViewColumn::new(); + column.pack_start(&renderer, true); + column.add_attribute(&renderer, "text", 0); + tree.append_column(&column); + + // kind + let column = gtk::TreeViewColumn::new(); + column.pack_start(&renderer, true); + column.add_attribute(&renderer, "text", 1); + tree.append_column(&column); + + // menu + let column = gtk::TreeViewColumn::new(); + column.pack_start(&renderer, true); + column.add_attribute(&renderer, "text", 2); + tree.append_column(&column); + State { nvim: None, - renderer: gtk::CellRendererText::new(), tree, scroll: gtk::ScrolledWindow::new(None, None), + renderer, css_provider, } } - fn before_show(&mut self, shell: &shell::State, menu_items: &[Vec<&str>], selected: i64) { + fn before_show(&mut self, shell: &shell::State, menu_items: &[CompleteItem], selected: i64) { if self.nvim.is_none() { self.nvim = Some(shell.nvim_clone()); } + let max_width = shell.drawing_area.get_allocated_width(); + //self.scroll.set_min_content_width(max_width - 20); + self.scroll.set_max_content_width(max_width - 20); + self.scroll.set_propagate_natural_width(true); self.update_tree(menu_items, shell); self.select(selected); } - fn update_tree(&self, menu: &[Vec<&str>], shell: &shell::State) { + fn update_tree(&self, menu: &[CompleteItem], shell: &shell::State) { if menu.is_empty() { return; } @@ -69,25 +94,11 @@ impl State { self.update_css(color_model); - let col_count = menu[0].len(); - let columns = self.tree.get_columns(); - - if columns.len() != col_count { - for col in columns { - self.tree.remove_column(&col); - } - - for i in 0..col_count { - self.append_column(i as i32); - } - } - - let list_store = gtk::ListStore::new(&vec![gtk::Type::String; col_count]); - let all_column_ids: Vec = (0..col_count).map(|i| i as u32).collect(); + let list_store = gtk::ListStore::new(&vec![gtk::Type::String; 3]); + let all_column_ids: Vec = (0..3).map(|i| i as u32).collect(); for line in menu { - let line_array: Vec<&glib::ToValue> = - line.iter().map(|v| v as &glib::ToValue).collect(); + let line_array: [&glib::ToValue; 3] = [&line.word, &line.kind, &line.menu]; list_store.insert_with_values(None, &all_column_ids, &line_array[..]); } @@ -111,15 +122,6 @@ impl State { }; } - fn append_column(&self, id: i32) { - let renderer = &self.renderer; - - let column = gtk::TreeViewColumn::new(); - column.pack_start(renderer, true); - column.add_attribute(renderer, "text", id); - self.tree.append_column(&column); - } - fn select(&self, selected: i64) { if selected >= 0 { let selected_path = gtk::TreePath::new_from_string(&format!("{}", selected)); @@ -166,7 +168,7 @@ impl PopupMenu { state.scroll.set_policy( - gtk::PolicyType::Never, + gtk::PolicyType::Automatic, gtk::PolicyType::Automatic, ); @@ -218,7 +220,7 @@ impl PopupMenu { pub fn show( &mut self, shell: &shell::State, - menu_items: &[Vec<&str>], + menu_items: &[CompleteItem], selected: i64, x: i32, y: i32, diff --git a/src/shell.rs b/src/shell.rs index cf1fe50..4cdb950 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -22,7 +22,7 @@ use settings::{Settings, FontSource}; use ui_model::{UiModel, Attrs, ModelRect}; use color::{ColorModel, Color, COLOR_BLACK, COLOR_WHITE, COLOR_RED}; use nvim::{self, RedrawEvents, GuiApi, RepaintMode, ErrorReport, NeovimClient, - NeovimRef, NeovimClientAsync}; + NeovimRef, NeovimClientAsync, CompleteItem}; use input; use input::keyval_to_input_string; use cursor::Cursor; @@ -70,7 +70,7 @@ pub struct State { pub mode: mode::Mode, stack: gtk::Stack, - drawing_area: gtk::DrawingArea, + pub drawing_area: gtk::DrawingArea, tabs: Tabline, im_context: gtk::IMMulticontext, error_area: error::ErrorArea, @@ -1093,7 +1093,7 @@ impl RedrawEvents for State { fn popupmenu_show( &mut self, - menu: &[Vec<&str>], + menu: &[CompleteItem], selected: i64, row: u64, col: u64,