Reduce calculation and improve pattern in infobox

- switch to use static OnceCell to calculate Info once
- pass Vec<(&[KeyEvent], &str)> rather than Vec<(Vec<KeyEvent>, &str)>
- expr -> tt to allow using | as separator, make it more like match
pull/412/head
Ivan Tham 3 years ago committed by Blaž Hrastnik
parent 64f83dfcbd
commit 5977b07e19

@ -34,7 +34,6 @@ use movement::Movement;
use crate::{ use crate::{
compositor::{self, Component, Compositor}, compositor::{self, Component, Compositor},
key,
ui::{self, Picker, Popup, Prompt, PromptEvent}, ui::{self, Picker, Popup, Prompt, PromptEvent},
}; };
@ -48,7 +47,7 @@ use std::{
path::{Path, PathBuf}, path::{Path, PathBuf},
}; };
use once_cell::sync::Lazy; use once_cell::sync::{Lazy, OnceCell};
use serde::de::{self, Deserialize, Deserializer}; use serde::de::{self, Deserialize, Deserializer};
pub struct Context<'a> { pub struct Context<'a> {
@ -3414,13 +3413,11 @@ fn select_register(cx: &mut Context) {
} }
macro_rules! mode_info { macro_rules! mode_info {
// TODO: how to use one expr for both pat and expr? // TODO: reuse $mode for $stat
// TODO: how to use replaced function name as str at compile time?
// TODO: extend to support multiple keys, but first solve the other two
(@join $first:expr $(,$rest:expr)*) => { (@join $first:expr $(,$rest:expr)*) => {
concat!($first, $(", ", $rest),*) concat!($first, $(", ", $rest),*)
}; };
{$mode:ident, $name:literal, $(#[doc = $desc:literal] $($key:expr),+ => $func:expr),+,} => { {$mode:ident, $stat:ident, $name:literal, $(#[doc = $desc:literal] $($key:tt)|+ => $func:expr),+,} => {
#[doc = $name] #[doc = $name]
#[doc = ""] #[doc = ""]
#[doc = "<table><tr><th>key</th><th>desc</th></tr><tbody>"] #[doc = "<table><tr><th>key</th><th>desc</th></tr><tbody>"]
@ -3439,12 +3436,14 @@ macro_rules! mode_info {
)+ )+
#[doc = "</tbody></table>"] #[doc = "</tbody></table>"]
pub fn $mode(cx: &mut Context) { pub fn $mode(cx: &mut Context) {
cx.editor.autoinfo = Some(Info::key( static $stat: OnceCell<Info> = OnceCell::new();
cx.editor.autoinfo = Some($stat.get_or_init(|| Info::key(
$name, $name,
vec![$((vec![$($key.parse().unwrap()),+], $desc)),+], vec![$((&[$($key.parse().unwrap()),+], $desc)),+],
)); )));
use helix_core::hashmap; use helix_core::hashmap;
let mut map = hashmap! { // TODO: try and convert this to match later
let map = hashmap! {
$($($key.parse::<KeyEvent>().unwrap() => $func as for<'r, 's> fn(&'r mut Context<'s>)),+),* $($($key.parse::<KeyEvent>().unwrap() => $func as for<'r, 's> fn(&'r mut Context<'s>)),+),*
}; };
cx.on_next_key_mode(map); cx.on_next_key_mode(map);
@ -3453,7 +3452,7 @@ macro_rules! mode_info {
} }
mode_info! { mode_info! {
space_mode, "space mode", space_mode, SPACE_MODE, "space mode",
/// file picker /// file picker
"f" => file_picker, "f" => file_picker,
/// buffer picker /// buffer picker

@ -1,11 +1,7 @@
pub use crate::commands::Command; pub use crate::commands::Command;
use crate::config::Config; use crate::config::Config;
use helix_core::hashmap; use helix_core::hashmap;
use helix_view::{ use helix_view::{document::Mode, input::KeyEvent};
document::Mode,
input::KeyEvent,
keyboard::{KeyCode, KeyModifiers},
};
use serde::Deserialize; use serde::Deserialize;
use std::{ use std::{
collections::HashMap, collections::HashMap,
@ -352,6 +348,7 @@ pub fn merge_keys(mut config: Config) -> Config {
#[test] #[test]
fn merge_partial_keys() { fn merge_partial_keys() {
use helix_view::keyboard::{KeyCode, KeyModifiers};
let config = Config { let config = Config {
keys: Keymaps(hashmap! { keys: Keymaps(hashmap! {
Mode::Normal => hashmap! { Mode::Normal => hashmap! {

@ -1,5 +1,5 @@
use crate::compositor::{Component, Context}; use crate::compositor::{Component, Context};
use helix_view::graphics::{Margin, Rect, Style}; use helix_view::graphics::Rect;
use helix_view::info::Info; use helix_view::info::Info;
use tui::buffer::Buffer as Surface; use tui::buffer::Buffer as Surface;
use tui::widgets::{Block, Borders, Widget}; use tui::widgets::{Block, Borders, Widget};

@ -33,7 +33,7 @@ pub struct Editor {
pub syn_loader: Arc<syntax::Loader>, pub syn_loader: Arc<syntax::Loader>,
pub theme_loader: Arc<theme::Loader>, pub theme_loader: Arc<theme::Loader>,
pub autoinfo: Option<Info>, pub autoinfo: Option<&'static Info>,
pub status_msg: Option<(String, Severity)>, pub status_msg: Option<(String, Severity)>,
} }

@ -16,7 +16,7 @@ pub struct Info {
} }
impl Info { impl Info {
pub fn key(title: &'static str, body: Vec<(Vec<KeyEvent>, &'static str)>) -> Info { pub fn key(title: &'static str, body: Vec<(&[KeyEvent], &'static str)>) -> Info {
let keymaps_width: u16 = body let keymaps_width: u16 = body
.iter() .iter()
.map(|r| r.0.iter().map(|e| e.width() as u16 + 2).sum::<u16>() - 2) .map(|r| r.0.iter().map(|e| e.width() as u16 + 2).sum::<u16>() - 2)
@ -25,11 +25,11 @@ impl Info {
let mut text = String::new(); let mut text = String::new();
let mut width = 0; let mut width = 0;
let height = body.len() as u16; let height = body.len() as u16;
for (mut keyevents, desc) in body { for (keyevents, desc) in body {
let keyevent = keyevents.remove(0); let keyevent = keyevents[0];
let mut left = keymaps_width - keyevent.width() as u16; let mut left = keymaps_width - keyevent.width() as u16;
write!(text, "{}", keyevent).ok(); write!(text, "{}", keyevent).ok();
for keyevent in keyevents { for keyevent in &keyevents[1..] {
write!(text, ", {}", keyevent).ok(); write!(text, ", {}", keyevent).ok();
left -= 2 + keyevent.width() as u16; left -= 2 + keyevent.width() as u16;
} }

Loading…
Cancel
Save