diff --git a/src/cmd_line.rs b/src/cmd_line.rs index 678c77d..03dbfc3 100644 --- a/src/cmd_line.rs +++ b/src/cmd_line.rs @@ -11,6 +11,7 @@ use pango; use neovim_lib::Value; +use nvim::{self, NeovimClient}; use mode; use ui_model::{Attrs, ModelLayout}; use ui::UiMutex; @@ -173,6 +174,7 @@ fn prompt_lines( } struct State { + nvim: Option>, levels: Vec, block: Option, render_state: Rc>, @@ -183,6 +185,7 @@ struct State { impl State { fn new(drawing_area: gtk::DrawingArea, render_state: Rc>) -> Self { State { + nvim: None, levels: Vec::new(), block: None, render_state, @@ -292,7 +295,7 @@ impl CmdLine { drawing_area.connect_draw(clone!(state => move |_, ctx| gtk_draw(ctx, &state))); let (wild_scroll, wild_tree, wild_css_provider, wild_renderer, wild_column) = - CmdLine::create_widlmenu(); + CmdLine::create_widlmenu(&state); content.pack_start(&wild_scroll, false, true, 0); popover.add(&content); @@ -311,7 +314,9 @@ impl CmdLine { } } - fn create_widlmenu() -> ( + fn create_widlmenu( + state: &Arc>, + ) -> ( gtk::ScrolledWindow, gtk::TreeView, gtk::CssProvider, @@ -342,11 +347,23 @@ impl CmdLine { scroll.add(&tree); + tree.connect_button_press_event(clone!(state => move |tree, ev| { + let state = state.borrow(); + let nvim = state.nvim.as_ref().unwrap().nvim(); + if let Some(mut nvim) = nvim { + popup_menu::tree_button_press(tree, ev, &mut *nvim, ""); + } + Inhibit(false) + })); + (scroll, tree, css_provider, renderer, column) } pub fn show_level(&mut self, ctx: &CmdLineContext) { let mut state = self.state.borrow_mut(); + if state.nvim.is_none() { + state.nvim = Some(ctx.nvim.clone()); + } let render_state = state.render_state.clone(); let render_state = render_state.borrow(); @@ -560,7 +577,8 @@ fn gtk_draw(ctx: &cairo::Context, state: &Arc>) -> Inhibit { Inhibit(false) } -pub struct CmdLineContext { +pub struct CmdLineContext<'a> { + pub nvim: &'a Rc, pub content: Vec<(HashMap, String)>, pub pos: u64, pub firstc: String, @@ -574,7 +592,7 @@ pub struct CmdLineContext { pub max_width: i32, } -impl CmdLineContext { +impl<'a> CmdLineContext<'a> { fn get_lines(&self) -> LineContent { let content_line: Vec<(Option, Vec)> = self.content .iter() diff --git a/src/popup_menu.rs b/src/popup_menu.rs index 961041a..bbf03bf 100644 --- a/src/popup_menu.rs +++ b/src/popup_menu.rs @@ -1,6 +1,7 @@ use std::rc::Rc; use std::cell::RefCell; use std::cmp::min; +use std::iter; use gtk; use gtk::prelude::*; @@ -235,10 +236,9 @@ impl PopupMenu { let state = state_ref.borrow(); let nvim = state.nvim.as_ref().unwrap().nvim(); if let Some(mut nvim) = nvim { - tree_button_press(tree, ev, &mut *nvim) - } else { - Inhibit(false) + tree_button_press(tree, ev, &mut *nvim, ""); } + Inhibit(false) }); let state_ref = state.clone(); @@ -302,9 +302,14 @@ pub struct PopupMenuContext<'a> { pub max_width: i32, } -fn tree_button_press(tree: >k::TreeView, ev: &EventButton, nvim: &mut Neovim) -> Inhibit { +pub fn tree_button_press( + tree: >k::TreeView, + ev: &EventButton, + nvim: &mut Neovim, + last_command: &str, +) { if ev.get_event_type() != EventType::ButtonPress { - return Inhibit(false); + return; } let (paths, ..) = tree.get_selection().get_selected_rows(); @@ -325,21 +330,20 @@ fn tree_button_press(tree: >k::TreeView, ev: &EventButton, nvim: &mut Neovim) let scroll_count = find_scroll_count(selected_idx, target_idx); - let mut apply_command = String::new(); - - for _ in 0..scroll_count { - if target_idx > selected_idx { - apply_command.push_str(""); - } else { - apply_command.push_str(""); - } - } - apply_command.push_str(""); + let mut apply_command: String = if target_idx > selected_idx { + (0..scroll_count) + .map(|_| "") + .chain(iter::once(last_command)) + .collect() + } else { + (0..scroll_count) + .map(|_| "") + .chain(iter::once(last_command)) + .collect() + }; nvim.input(&apply_command).report_err(); } - - Inhibit(false) } fn find_scroll_count(selected_idx: i32, target_idx: i32) -> i32 { diff --git a/src/shell.rs b/src/shell.rs index e15e2b6..c66c6f0 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -1364,6 +1364,7 @@ impl State { let render_state = self.render_state.borrow(); let (x, y, width, height) = cursor.to_area(render_state.font_ctx.cell_metrics()); let ctx = CmdLineContext { + nvim: &self.nvim, content, pos, firstc,