Show infobox with register contents

This commit is contained in:
Gokul Soumya 2021-11-05 00:03:31 +05:30 committed by Blaž Hrastnik
parent 5995568c1d
commit bf773db451
6 changed files with 56 additions and 27 deletions

View File

@ -68,4 +68,8 @@ pub fn write(&mut self, name: char, values: Vec<String>) {
pub fn read(&self, name: char) -> Option<&[String]> { pub fn read(&self, name: char) -> Option<&[String]> {
self.get(name).map(|reg| reg.read()) self.get(name).map(|reg| reg.read())
} }
pub fn inner(&self) -> &HashMap<char, Register> {
&self.inner
}
} }

View File

@ -20,6 +20,7 @@
clipboard::ClipboardType, clipboard::ClipboardType,
document::{Mode, SCRATCH_BUFFER_NAME}, document::{Mode, SCRATCH_BUFFER_NAME},
editor::{Action, Motion}, editor::{Action, Motion},
info::Info,
input::KeyEvent, input::KeyEvent,
keyboard::KeyCode, keyboard::KeyCode,
view::View, view::View,
@ -5745,8 +5746,10 @@ fn wonly(cx: &mut Context) {
} }
fn select_register(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| { cx.on_next_key(move |cx, event| {
if let Some(ch) = event.char() { if let Some(ch) = event.char() {
cx.editor.autoinfo = None;
cx.editor.selected_register = Some(ch); cx.editor.selected_register = Some(ch);
} }
}) })

View File

@ -222,9 +222,8 @@ pub fn infobox(&self) -> Info {
.map(|(desc, keys)| (desc.strip_prefix(&prefix).unwrap(), keys)) .map(|(desc, keys)| (desc.strip_prefix(&prefix).unwrap(), keys))
.collect(); .collect();
} }
Info::new(self.name(), body) Info::from_keymap(self.name(), body)
} }
/// Get a reference to the key trie node's order. /// Get a reference to the key trie node's order.
pub fn order(&self) -> &[KeyEvent] { pub fn order(&self) -> &[KeyEvent] {
self.order.as_slice() self.order.as_slice()

View File

@ -21,7 +21,6 @@
document::{Mode, SCRATCH_BUFFER_NAME}, document::{Mode, SCRATCH_BUFFER_NAME},
editor::CursorShapeConfig, editor::CursorShapeConfig,
graphics::{CursorKind, Modifier, Rect, Style}, graphics::{CursorKind, Modifier, Rect, Style},
info::Info,
input::KeyEvent, input::KeyEvent,
keyboard::{KeyCode, KeyModifiers}, keyboard::{KeyCode, KeyModifiers},
Document, Editor, Theme, View, Document, Editor, Theme, View,
@ -37,7 +36,6 @@ pub struct EditorView {
last_insert: (commands::MappableCommand, Vec<KeyEvent>), last_insert: (commands::MappableCommand, Vec<KeyEvent>),
pub(crate) completion: Option<Completion>, pub(crate) completion: Option<Completion>,
spinners: ProgressSpinners, spinners: ProgressSpinners,
autoinfo: Option<Info>,
} }
impl Default for EditorView { impl Default for EditorView {
@ -54,7 +52,6 @@ pub fn new(keymaps: Keymaps) -> Self {
last_insert: (commands::MappableCommand::normal_mode, Vec::new()), last_insert: (commands::MappableCommand::normal_mode, Vec::new()),
completion: None, completion: None,
spinners: ProgressSpinners::default(), spinners: ProgressSpinners::default(),
autoinfo: None,
} }
} }
@ -678,13 +675,13 @@ fn handle_keymap_event(
cxt: &mut commands::Context, cxt: &mut commands::Context,
event: KeyEvent, event: KeyEvent,
) -> Option<KeymapResult> { ) -> Option<KeymapResult> {
self.autoinfo = None; cxt.editor.autoinfo = None;
let key_result = self.keymaps.get_mut(&mode).unwrap().get(event); 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 { match &key_result.kind {
KeymapResultKind::Matched(command) => command.execute(cxt), 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) => { KeymapResultKind::MatchedSequence(commands) => {
for command in commands { for command in commands {
command.execute(cxt); command.execute(cxt);
@ -1093,8 +1090,9 @@ fn render(&mut self, area: Rect, surface: &mut Surface, cx: &mut Context) {
} }
if cx.editor.config.auto_info { 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); info.render(area, surface, cx);
cx.editor.autoinfo = Some(info)
} }
} }

View File

@ -2,6 +2,7 @@
clipboard::{get_clipboard_provider, ClipboardProvider}, clipboard::{get_clipboard_provider, ClipboardProvider},
document::{Mode, SCRATCH_BUFFER_NAME}, document::{Mode, SCRATCH_BUFFER_NAME},
graphics::{CursorKind, Rect}, graphics::{CursorKind, Rect},
info::Info,
input::KeyEvent, input::KeyEvent,
theme::{self, Theme}, theme::{self, Theme},
tree::{self, Tree}, tree::{self, Tree},
@ -243,6 +244,7 @@ pub struct Editor {
pub theme_loader: Arc<theme::Loader>, pub theme_loader: Arc<theme::Loader>,
pub status_msg: Option<(String, Severity)>, pub status_msg: Option<(String, Severity)>,
pub autoinfo: Option<Info>,
pub config: Config, pub config: Config,
@ -286,6 +288,7 @@ pub fn new(
registers: Registers::default(), registers: Registers::default(),
clipboard_provider: get_clipboard_provider(), clipboard_provider: get_clipboard_provider(),
status_msg: None, status_msg: None,
autoinfo: None,
idle_timer: Box::pin(sleep(config.idle_timeout)), idle_timer: Box::pin(sleep(config.idle_timeout)),
last_motion: None, last_motion: None,
config, config,

View File

@ -1,5 +1,5 @@
use crate::input::KeyEvent; use crate::input::KeyEvent;
use helix_core::unicode::width::UnicodeWidthStr; use helix_core::{register::Registers, unicode::width::UnicodeWidthStr};
use std::{collections::BTreeSet, fmt::Write}; use std::{collections::BTreeSet, fmt::Write};
#[derive(Debug)] #[derive(Debug)]
@ -16,26 +16,21 @@ pub struct Info {
} }
impl Info { impl Info {
pub fn new(title: &str, body: Vec<(&str, BTreeSet<KeyEvent>)>) -> Self { pub fn new(title: &str, body: Vec<(String, String)>) -> Self {
let body = body if body.is_empty() {
.into_iter() return Self {
.map(|(desc, events)| { title: title.to_string(),
let events = events.iter().map(ToString::to_string).collect::<Vec<_>>(); height: 1,
(desc, events.join(", ")) width: title.len() as u16,
}) text: "".to_string(),
.collect::<Vec<_>>(); };
}
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(); let mut text = String::new();
for (desc, keyevents) in &body { for (item, desc) in &body {
let _ = writeln!( let _ = writeln!(text, "{:width$} {}", item, desc, width = item_width);
text,
"{:width$} {}",
keyevents,
desc,
width = keymaps_width
);
} }
Self { Self {
@ -45,4 +40,31 @@ pub fn new(title: &str, body: Vec<(&str, BTreeSet<KeyEvent>)>) -> Self {
text, text,
} }
} }
pub fn from_keymap(title: &str, body: Vec<(&str, BTreeSet<KeyEvent>)>) -> Self {
let body = body
.into_iter()
.map(|(desc, events)| {
let events = events.iter().map(ToString::to_string).collect::<Vec<_>>();
(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
}
} }