From bf773db45171b59a758b7dabf9f10ffb8852dcf0 Mon Sep 17 00:00:00 2001 From: Gokul Soumya Date: Fri, 5 Nov 2021 00:03:31 +0530 Subject: [PATCH] Show infobox with register contents --- helix-core/src/register.rs | 4 +++ helix-term/src/commands.rs | 3 ++ helix-term/src/keymap.rs | 3 +- helix-term/src/ui/editor.rs | 12 ++++---- helix-view/src/editor.rs | 3 ++ helix-view/src/info.rs | 58 +++++++++++++++++++++++++------------ 6 files changed, 56 insertions(+), 27 deletions(-) diff --git a/helix-core/src/register.rs b/helix-core/src/register.rs index b9eb497df..b39e4034e 100644 --- a/helix-core/src/register.rs +++ b/helix-core/src/register.rs @@ -68,4 +68,8 @@ impl Registers { pub fn read(&self, name: char) -> Option<&[String]> { self.get(name).map(|reg| reg.read()) } + + pub fn inner(&self) -> &HashMap { + &self.inner + } } diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index e766417c1..2e4301063 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -20,6 +20,7 @@ use helix_view::{ clipboard::ClipboardType, document::{Mode, SCRATCH_BUFFER_NAME}, editor::{Action, Motion}, + info::Info, input::KeyEvent, keyboard::KeyCode, view::View, @@ -5745,8 +5746,10 @@ fn wonly(cx: &mut Context) { } fn select_register(cx: &mut Context) { + cx.editor.autoinfo = Some(Info::from_registers(&cx.editor.registers)); cx.on_next_key(move |cx, event| { if let Some(ch) = event.char() { + cx.editor.autoinfo = None; cx.editor.selected_register = Some(ch); } }) diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs index e5990d72e..212b27a96 100644 --- a/helix-term/src/keymap.rs +++ b/helix-term/src/keymap.rs @@ -222,9 +222,8 @@ impl KeyTrieNode { .map(|(desc, keys)| (desc.strip_prefix(&prefix).unwrap(), keys)) .collect(); } - Info::new(self.name(), body) + Info::from_keymap(self.name(), body) } - /// Get a reference to the key trie node's order. pub fn order(&self) -> &[KeyEvent] { self.order.as_slice() diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index d3af921e5..e68f5ff02 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -21,7 +21,6 @@ use helix_view::{ document::{Mode, SCRATCH_BUFFER_NAME}, editor::CursorShapeConfig, graphics::{CursorKind, Modifier, Rect, Style}, - info::Info, input::KeyEvent, keyboard::{KeyCode, KeyModifiers}, Document, Editor, Theme, View, @@ -37,7 +36,6 @@ pub struct EditorView { last_insert: (commands::MappableCommand, Vec), pub(crate) completion: Option, spinners: ProgressSpinners, - autoinfo: Option, } impl Default for EditorView { @@ -54,7 +52,6 @@ impl EditorView { last_insert: (commands::MappableCommand::normal_mode, Vec::new()), completion: None, spinners: ProgressSpinners::default(), - autoinfo: None, } } @@ -678,13 +675,13 @@ impl EditorView { cxt: &mut commands::Context, event: KeyEvent, ) -> Option { - self.autoinfo = None; + cxt.editor.autoinfo = None; let key_result = self.keymaps.get_mut(&mode).unwrap().get(event); - self.autoinfo = key_result.sticky.map(|node| node.infobox()); + cxt.editor.autoinfo = key_result.sticky.map(|node| node.infobox()); match &key_result.kind { KeymapResultKind::Matched(command) => command.execute(cxt), - KeymapResultKind::Pending(node) => self.autoinfo = Some(node.infobox()), + KeymapResultKind::Pending(node) => cxt.editor.autoinfo = Some(node.infobox()), KeymapResultKind::MatchedSequence(commands) => { for command in commands { command.execute(cxt); @@ -1093,8 +1090,9 @@ impl Component for EditorView { } if cx.editor.config.auto_info { - if let Some(ref mut info) = self.autoinfo { + if let Some(mut info) = cx.editor.autoinfo.take() { info.render(area, surface, cx); + cx.editor.autoinfo = Some(info) } } diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 27e6f1371..43ea8d156 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -2,6 +2,7 @@ use crate::{ clipboard::{get_clipboard_provider, ClipboardProvider}, document::{Mode, SCRATCH_BUFFER_NAME}, graphics::{CursorKind, Rect}, + info::Info, input::KeyEvent, theme::{self, Theme}, tree::{self, Tree}, @@ -243,6 +244,7 @@ pub struct Editor { pub theme_loader: Arc, pub status_msg: Option<(String, Severity)>, + pub autoinfo: Option, pub config: Config, @@ -286,6 +288,7 @@ impl Editor { registers: Registers::default(), clipboard_provider: get_clipboard_provider(), status_msg: None, + autoinfo: None, idle_timer: Box::pin(sleep(config.idle_timeout)), last_motion: None, config, diff --git a/helix-view/src/info.rs b/helix-view/src/info.rs index 738561540..fbe27ea09 100644 --- a/helix-view/src/info.rs +++ b/helix-view/src/info.rs @@ -1,5 +1,5 @@ use crate::input::KeyEvent; -use helix_core::unicode::width::UnicodeWidthStr; +use helix_core::{register::Registers, unicode::width::UnicodeWidthStr}; use std::{collections::BTreeSet, fmt::Write}; #[derive(Debug)] @@ -16,26 +16,21 @@ pub struct Info { } impl Info { - pub fn new(title: &str, body: Vec<(&str, BTreeSet)>) -> Self { - let body = body - .into_iter() - .map(|(desc, events)| { - let events = events.iter().map(ToString::to_string).collect::>(); - (desc, events.join(", ")) - }) - .collect::>(); + pub fn new(title: &str, body: Vec<(String, String)>) -> Self { + if body.is_empty() { + return Self { + title: title.to_string(), + height: 1, + width: title.len() as u16, + text: "".to_string(), + }; + } - let keymaps_width = body.iter().map(|r| r.1.len()).max().unwrap(); + let item_width = body.iter().map(|(item, _)| item.width()).max().unwrap(); let mut text = String::new(); - for (desc, keyevents) in &body { - let _ = writeln!( - text, - "{:width$} {}", - keyevents, - desc, - width = keymaps_width - ); + for (item, desc) in &body { + let _ = writeln!(text, "{:width$} {}", item, desc, width = item_width); } Self { @@ -45,4 +40,31 @@ impl Info { text, } } + + pub fn from_keymap(title: &str, body: Vec<(&str, BTreeSet)>) -> Self { + let body = body + .into_iter() + .map(|(desc, events)| { + let events = events.iter().map(ToString::to_string).collect::>(); + (events.join(", "), desc.to_string()) + }) + .collect(); + + Self::new(title, body) + } + + pub fn from_registers(registers: &Registers) -> Self { + let body = registers + .inner() + .iter() + .map(|(ch, reg)| { + let content = reg.read().join(", ").trim_end().to_string(); + (ch.to_string(), content) + }) + .collect(); + + let mut infobox = Self::new("Registers", body); + infobox.width = 30; // copied content could be very long + infobox + } }