on master help sign in
Add infobox
8985c58Ivan Tham
Cargo.lock+1
@@ -419,6 +419,7 @@ dependencies = [
419 "slotmap",
419 "slotmap",
420 "tokio",
420 "tokio",
421 "toml",
421 "toml",
422+ "unicode-width",
422 "url",
423 "url",
423 "which",
424 "which",
424]
425]
helix-term/src/commands.rs+81−24
@@ -16,6 +16,7 @@ use helix_core::{
16use helix_view::{
16use helix_view::{
17 document::{IndentStyle, Mode},
17 document::{IndentStyle, Mode},
18 editor::Action,
18 editor::Action,
19+ info::Info,
19 input::KeyEvent,
20 input::KeyEvent,
20 keyboard::KeyCode,
21 keyboard::KeyCode,
21 view::{View, PADDING},
22 view::{View, PADDING},
@@ -33,6 +34,7 @@ use movement::Movement;
33
34
34use crate::{
35use crate::{
35 compositor::{self, Component, Compositor},
36 compositor::{self, Component, Compositor},
37+ key,
36 ui::{self, Picker, Popup, Prompt, PromptEvent},
38 ui::{self, Picker, Popup, Prompt, PromptEvent},
37};
39};
38
40
@@ -3400,33 +3402,88 @@ fn select_register(cx: &mut Context) {
3400 })
3402 })
3401}
3403}
3402
3404
3403−fn space_mode(cx: &mut Context) {
3405+macro_rules! mode_info {
3404− cx.on_next_key(move |cx, event| {
3406+ // TODO: how to use one expr for both pat and expr?
3405− if let KeyEvent {
3407+ // TODO: how to use replaced function name as str at compile time?
3406− code: KeyCode::Char(ch),
3408+ // TODO: extend to support multiple keys, but first solve the other two
3407− ..
3409+ {$name:literal, $cx:expr, $($key:expr => $func:expr; $funcs:literal),+,} => {
3408− } = event
3410+ mode_info! {
3409− {
3411+ $name, $cx,
3410− // TODO: temporarily show SPC in the mode list
3412+ $($key; $key => $func; $funcs,)+
3411− match ch {
3412− 'f' => file_picker(cx),
3413− 'b' => buffer_picker(cx),
3414− 's' => symbol_picker(cx),
3415− 'w' => window_mode(cx),
3416− 'y' => yank_joined_to_clipboard(cx),
3417− 'Y' => yank_main_selection_to_clipboard(cx),
3418− 'p' => paste_clipboard_after(cx),
3419− 'P' => paste_clipboard_before(cx),
3420− 'R' => replace_selections_with_clipboard(cx),
3421− // ' ' => toggle_alternate_buffer(cx),
3422− // TODO: temporary since space mode took its old key
3423− ' ' => keep_primary_selection(cx),
3424− _ => (),
3425− }
3426 }
3413 }
3427− })
3414+ };
3415+ {$name:literal, $cx:expr, $($key:expr; $keyp:pat => $func:expr; $funcs:literal),+,} => {
3416+ $cx.editor.autoinfo = Some(Info::key(
3417+ $name,
3418+ vec![
3419+ $(
3420+ (vec![$key], $funcs),
3421+ )+
3422+ ],
3423+ ));
3424+ $cx.on_next_key(move |cx, event| {
3425+ match event {
3426+ $(
3427+ $keyp => $func(cx),
3428+ )+
3429+ _ => {}
3430+ }
3431+ })
3432+ }
3428}
3433}
3429
3434
3435+fn space_mode(cx: &mut Context) {
3436+ mode_info! {
3437+ "space mode", cx,
3438+ key!('f'); key!('f') => file_picker; "file picker",
3439+ key!('b'); key!('b') => buffer_picker; "buffer picker",
3440+ key!('s'); key!('s') => symbol_picker; "symbol picker",
3441+ key!('w'); key!('w') => window_mode; "window mode",
3442+ key!('y'); key!('y') => yank_joined_to_clipboard; "yank joined to clipboard",
3443+ key!('Y'); key!('Y') => yank_main_selection_to_clipboard; "yank main selection to clipboard",
3444+ key!('p'); key!('p') => paste_clipboard_after; "paste clipboard after",
3445+ key!('P'); key!('P') => paste_clipboard_before; "paste clipboard before",
3446+ key!('R'); key!('R') => replace_selections_with_clipboard; "replace selections with clipboard",
3447+ key!(' '); key!(' ') => keep_primary_selection; "keep primary selection",
3448+ }
3449+}
3450+
3451+// TODO: generated, delete it later
3452+// fn space_mode(cx: &mut Context) {
3453+// cx.editor.autoinfo = Some(Info::key(
3454+// "space",
3455+// vec![
3456+// (vec![key!('f')], "file picker"),
3457+// (vec![key!('b')], "buffer picker"),
3458+// (vec![key!('s')], "symbol picker"),
3459+// (vec![key!('w')], "window mode"),
3460+// (vec![key!('y')], "yank joined to clipboard"),
3461+// (vec![key!('Y')], "yank main selection to clipboard"),
3462+// (vec![key!('p')], "paste clipboard after"),
3463+// (vec![key!('P')], "paste clipboard before"),
3464+// (vec![key!('R')], "replace selections with clipboard"),
3465+// (vec![key!(' ')], "keep primary selection"),
3466+// ],
3467+// ));
3468+// cx.on_next_key(move |cx, event| {
3469+// match event {
3470+// key!('f') => file_picker(cx),
3471+// key!('b') => buffer_picker(cx),
3472+// key!('s') => symbol_picker(cx),
3473+// key!('w') => window_mode(cx),
3474+// key!('y') => yank_joined_to_clipboard(cx),
3475+// key!('Y') => yank_main_selection_to_clipboard(cx),
3476+// key!('p') => paste_clipboard_after(cx),
3477+// key!('P') => paste_clipboard_before(cx),
3478+// key!('R') => replace_selections_with_clipboard(cx),
3479+// // key!(' ') => toggle_alternate_buffer(cx),
3480+// // TODO: temporary since space mode took its old key
3481+// key!(' ') => keep_primary_selection(cx),
3482+// _ => {}
3483+// }
3484+// })
3485+// }
3486+
3430fn view_mode(cx: &mut Context) {
3487fn view_mode(cx: &mut Context) {
3431 cx.on_next_key(move |cx, event| {
3488 cx.on_next_key(move |cx, event| {
3432 if let KeyEvent {
3489 if let KeyEvent {
helix-term/src/keymap.rs+8−8
@@ -105,14 +105,14 @@ use std::{
105macro_rules! key {
105macro_rules! key {
106 ($key:ident) => {
106 ($key:ident) => {
107 KeyEvent {
107 KeyEvent {
108− code: KeyCode::$key,
108+ code: helix_view::keyboard::KeyCode::$key,
109− modifiers: KeyModifiers::NONE,
109+ modifiers: helix_view::keyboard::KeyModifiers::NONE,
110 }
110 }
111 };
111 };
112 ($($ch:tt)*) => {
112 ($($ch:tt)*) => {
113 KeyEvent {
113 KeyEvent {
114− code: KeyCode::Char($($ch)*),
114+ code: helix_view::keyboard::KeyCode::Char($($ch)*),
115− modifiers: KeyModifiers::NONE,
115+ modifiers: helix_view::keyboard::KeyModifiers::NONE,
116 }
116 }
117 };
117 };
118}
118}
@@ -120,8 +120,8 @@ macro_rules! key {
120macro_rules! ctrl {
120macro_rules! ctrl {
121 ($($ch:tt)*) => {
121 ($($ch:tt)*) => {
122 KeyEvent {
122 KeyEvent {
123− code: KeyCode::Char($($ch)*),
123+ code: helix_view::keyboard::KeyCode::Char($($ch)*),
124− modifiers: KeyModifiers::CONTROL,
124+ modifiers: helix_view::keyboard::KeyModifiers::CONTROL,
125 }
125 }
126 };
126 };
127}
127}
@@ -129,8 +129,8 @@ macro_rules! ctrl {
129macro_rules! alt {
129macro_rules! alt {
130 ($($ch:tt)*) => {
130 ($($ch:tt)*) => {
131 KeyEvent {
131 KeyEvent {
132− code: KeyCode::Char($($ch)*),
132+ code: helix_view::keyboard::KeyCode::Char($($ch)*),
133− modifiers: KeyModifiers::ALT,
133+ modifiers: helix_view::keyboard::KeyModifiers::ALT,
134 }
134 }
135 };
135 };
136}
136}
helix-term/src/ui/editor.rs+5−2
@@ -717,6 +717,10 @@ impl Component for EditorView {
717 self.render_view(doc, view, area, surface, &cx.editor.theme, is_focused);
717 self.render_view(doc, view, area, surface, &cx.editor.theme, is_focused);
718 }
718 }
719
719
720+ if let Some(info) = std::mem::take(&mut cx.editor.autoinfo) {
721+ info.render(area, surface, cx);
722+ }
723+
720 // render status msg
724 // render status msg
721 if let Some((status_msg, severity)) = &cx.editor.status_msg {
725 if let Some((status_msg, severity)) = &cx.editor.status_msg {
722 use helix_view::editor::Severity;
726 use helix_view::editor::Severity;
@@ -735,8 +739,7 @@ impl Component for EditorView {
735 }
739 }
736
740
737 if let Some(completion) = &self.completion {
741 if let Some(completion) = &self.completion {
738− completion.render(area, surface, cx)
742+ completion.render(area, surface, cx);
739− // render completion here
740 }
743 }
741 }
744 }
742
745
helix-term/src/ui/info.rsnew file+24
@@ -0,0 +1,24 @@
1+use crate::compositor::{Component, Context};
2+use helix_view::graphics::{Margin, Rect, Style};
3+use helix_view::info::Info;
4+use tui::buffer::Buffer as Surface;
5+use tui::widgets::{Block, Borders, Widget};
6+
7+impl Component for Info {
8+ fn render(&self, viewport: Rect, surface: &mut Surface, cx: &mut Context) {
9+ let block = Block::default().title(self.title).borders(Borders::ALL);
10+ let Info { width, height, .. } = self;
11+ let (w, h) = (*width + 2, *height + 2);
12+ // -2 to subtract command line + statusline. a bit of a hack, because of splits.
13+ let area = Rect::new(viewport.width - w, viewport.height - h - 2, w, h);
14+ let margin = Margin {
15+ vertical: 1,
16+ horizontal: 1,
17+ };
18+ let Rect { x, y, .. } = area.inner(&margin);
19+ for (y, line) in (y..).zip(self.text.lines()) {
20+ surface.set_string(x, y, line, Style::default());
21+ }
22+ block.render(area, surface);
23+ }
24+}
helix-term/src/ui/mod.rs+1
@@ -1,5 +1,6 @@
1mod completion;
1mod completion;
2mod editor;
2mod editor;
3+mod info;
3mod markdown;
4mod markdown;
4mod menu;
5mod menu;
5mod picker;
6mod picker;
helix-view/Cargo.toml+1
@@ -31,6 +31,7 @@ slotmap = "1"
31
31
32encoding_rs = "0.8"
32encoding_rs = "0.8"
33chardetng = "0.1"
33chardetng = "0.1"
34+unicode-width = "0.1"
34
35
35serde = { version = "1.0", features = ["derive"] }
36serde = { version = "1.0", features = ["derive"] }
36toml = "0.5"
37toml = "0.5"
helix-view/src/editor.rs+3
@@ -1,6 +1,7 @@
1use crate::{
1use crate::{
2 clipboard::{get_clipboard_provider, ClipboardProvider},
2 clipboard::{get_clipboard_provider, ClipboardProvider},
3 graphics::{CursorKind, Rect},
3 graphics::{CursorKind, Rect},
4+ info::Info,
4 theme::{self, Theme},
5 theme::{self, Theme},
5 tree::Tree,
6 tree::Tree,
6 Document, DocumentId, RegisterSelection, View, ViewId,
7 Document, DocumentId, RegisterSelection, View, ViewId,
@@ -32,6 +33,7 @@ pub struct Editor {
32 pub syn_loader: Arc<syntax::Loader>,
33 pub syn_loader: Arc<syntax::Loader>,
33 pub theme_loader: Arc<theme::Loader>,
34 pub theme_loader: Arc<theme::Loader>,
34
35
36+ pub autoinfo: Option<Info>,
35 pub status_msg: Option<(String, Severity)>,
37 pub status_msg: Option<(String, Severity)>,
36}
38}
37
39
@@ -64,6 +66,7 @@ impl Editor {
64 theme_loader: themes,
66 theme_loader: themes,
65 registers: Registers::default(),
67 registers: Registers::default(),
66 clipboard_provider: get_clipboard_provider(),
68 clipboard_provider: get_clipboard_provider(),
69+ autoinfo: None,
67 status_msg: None,
70 status_msg: None,
68 }
71 }
69 }
72 }
helix-view/src/info.rsnew file+51
@@ -0,0 +1,51 @@
1+use crate::input::KeyEvent;
2+use std::fmt::Write;
3+use unicode_width::UnicodeWidthStr;
4+
5+#[derive(Debug)]
6+/// Info box used in editor. Rendering logic will be in other crate.
7+pub struct Info {
8+ /// Title kept as static str for now.
9+ pub title: &'static str,
10+ /// Text body, should contains newline.
11+ pub text: String,
12+ /// Body width.
13+ pub width: u16,
14+ /// Body height.
15+ pub height: u16,
16+}
17+
18+impl Info {
19+ pub fn key(title: &'static str, body: Vec<(Vec<KeyEvent>, &'static str)>) -> Info {
20+ let keymaps_width: u16 = body
21+ .iter()
22+ .map(|r| r.0.iter().map(|e| e.width() as u16 + 2).sum::<u16>() - 2)
23+ .max()
24+ .unwrap();
25+ let mut text = String::new();
26+ let mut width = 0;
27+ let height = body.len() as u16;
28+ for (mut keyevents, desc) in body {
29+ let keyevent = keyevents.remove(0);
30+ let mut left = keymaps_width - keyevent.width() as u16;
31+ write!(text, "{}", keyevent).ok();
32+ for keyevent in keyevents {
33+ write!(text, ", {}", keyevent).ok();
34+ left -= 2 + keyevent.width() as u16;
35+ }
36+ for _ in 0..left {
37+ text.push(' ');
38+ }
39+ if keymaps_width + 2 + (desc.width() as u16) > width {
40+ width = keymaps_width + 2 + desc.width() as u16;
41+ }
42+ writeln!(text, " {}", &desc).ok();
43+ }
44+ Info {
45+ title,
46+ text,
47+ width,
48+ height,
49+ }
50+ }
51+}
helix-view/src/input.rs+120−44
@@ -13,6 +13,32 @@ pub struct KeyEvent {
13 pub modifiers: KeyModifiers,
13 pub modifiers: KeyModifiers,
14}
14}
15
15
16+pub(crate) mod keys {
17+ pub(crate) const BACKSPACE: &str = "backspace";
18+ pub(crate) const ENTER: &str = "ret";
19+ pub(crate) const LEFT: &str = "left";
20+ pub(crate) const RIGHT: &str = "right";
21+ pub(crate) const UP: &str = "up";
22+ pub(crate) const DOWN: &str = "down";
23+ pub(crate) const HOME: &str = "home";
24+ pub(crate) const END: &str = "end";
25+ pub(crate) const PAGEUP: &str = "pageup";
26+ pub(crate) const PAGEDOWN: &str = "pagedown";
27+ pub(crate) const TAB: &str = "tab";
28+ pub(crate) const BACKTAB: &str = "backtab";
29+ pub(crate) const DELETE: &str = "del";
30+ pub(crate) const INSERT: &str = "ins";
31+ pub(crate) const NULL: &str = "null";
32+ pub(crate) const ESC: &str = "esc";
33+ pub(crate) const SPACE: &str = "space";
34+ pub(crate) const LESS_THAN: &str = "lt";
35+ pub(crate) const GREATER_THAN: &str = "gt";
36+ pub(crate) const PLUS: &str = "plus";
37+ pub(crate) const MINUS: &str = "minus";
38+ pub(crate) const SEMICOLON: &str = "semicolon";
39+ pub(crate) const PERCENT: &str = "percent";
40+}
41+
16impl fmt::Display for KeyEvent {
42impl fmt::Display for KeyEvent {
17 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result {
43 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result {
18 f.write_fmt(format_args!(
44 f.write_fmt(format_args!(
@@ -34,28 +60,29 @@ impl fmt::Display for KeyEvent {
34 },
60 },
35 ))?;
61 ))?;
36 match self.code {
62 match self.code {
37− KeyCode::Backspace => f.write_str("backspace")?,
63+ KeyCode::Backspace => f.write_str(keys::BACKSPACE)?,
38− KeyCode::Enter => f.write_str("ret")?,
64+ KeyCode::Enter => f.write_str(keys::ENTER)?,
39− KeyCode::Left => f.write_str("left")?,
65+ KeyCode::Left => f.write_str(keys::LEFT)?,
40− KeyCode::Right => f.write_str("right")?,
66+ KeyCode::Right => f.write_str(keys::RIGHT)?,
41− KeyCode::Up => f.write_str("up")?,
67+ KeyCode::Up => f.write_str(keys::UP)?,
42− KeyCode::Down => f.write_str("down")?,
68+ KeyCode::Down => f.write_str(keys::DOWN)?,
43− KeyCode::Home => f.write_str("home")?,
69+ KeyCode::Home => f.write_str(keys::HOME)?,
44− KeyCode::End => f.write_str("end")?,
70+ KeyCode::End => f.write_str(keys::END)?,
45− KeyCode::PageUp => f.write_str("pageup")?,
71+ KeyCode::PageUp => f.write_str(keys::PAGEUP)?,
46− KeyCode::PageDown => f.write_str("pagedown")?,
72+ KeyCode::PageDown => f.write_str(keys::PAGEDOWN)?,
47− KeyCode::Tab => f.write_str("tab")?,
73+ KeyCode::Tab => f.write_str(keys::TAB)?,
48− KeyCode::BackTab => f.write_str("backtab")?,
74+ KeyCode::BackTab => f.write_str(keys::BACKTAB)?,
49− KeyCode::Delete => f.write_str("del")?,
75+ KeyCode::Delete => f.write_str(keys::DELETE)?,
50− KeyCode::Insert => f.write_str("ins")?,
76+ KeyCode::Insert => f.write_str(keys::INSERT)?,
51− KeyCode::Null => f.write_str("null")?,
77+ KeyCode::Null => f.write_str(keys::NULL)?,
52− KeyCode::Esc => f.write_str("esc")?,
78+ KeyCode::Esc => f.write_str(keys::ESC)?,
79+ KeyCode::Char(' ') => f.write_str(keys::SPACE)?,
53− KeyCode::Char('<') => f.write_str("lt")?,
80+ KeyCode::Char('<') => f.write_str(keys::LESS_THAN)?,
54− KeyCode::Char('>') => f.write_str("gt")?,
81+ KeyCode::Char('>') => f.write_str(keys::GREATER_THAN)?,
55− KeyCode::Char('+') => f.write_str("plus")?,
82+ KeyCode::Char('+') => f.write_str(keys::PLUS)?,
56− KeyCode::Char('-') => f.write_str("minus")?,
83+ KeyCode::Char('-') => f.write_str(keys::MINUS)?,
57− KeyCode::Char(';') => f.write_str("semicolon")?,
84+ KeyCode::Char(';') => f.write_str(keys::SEMICOLON)?,
58− KeyCode::Char('%') => f.write_str("percent")?,
85+ KeyCode::Char('%') => f.write_str(keys::PERCENT)?,
59 KeyCode::F(i) => f.write_fmt(format_args!("F{}", i))?,
86 KeyCode::F(i) => f.write_fmt(format_args!("F{}", i))?,
60 KeyCode::Char(c) => f.write_fmt(format_args!("{}", c))?,
87 KeyCode::Char(c) => f.write_fmt(format_args!("{}", c))?,
61 };
88 };
@@ -63,34 +90,83 @@ impl fmt::Display for KeyEvent {
63 }
90 }
64}
91}
65
92
93+impl unicode_width::UnicodeWidthStr for KeyEvent {
94+ fn width(&self) -> usize {
95+ use unicode_width::UnicodeWidthChar;
96+ let mut width = match self.code {
97+ KeyCode::Backspace => keys::BACKSPACE.len(),
98+ KeyCode::Enter => keys::ENTER.len(),
99+ KeyCode::Left => keys::LEFT.len(),
100+ KeyCode::Right => keys::RIGHT.len(),
101+ KeyCode::Up => keys::UP.len(),
102+ KeyCode::Down => keys::DOWN.len(),
103+ KeyCode::Home => keys::HOME.len(),
104+ KeyCode::End => keys::END.len(),
105+ KeyCode::PageUp => keys::PAGEUP.len(),
106+ KeyCode::PageDown => keys::PAGEDOWN.len(),
107+ KeyCode::Tab => keys::TAB.len(),
108+ KeyCode::BackTab => keys::BACKTAB.len(),
109+ KeyCode::Delete => keys::DELETE.len(),
110+ KeyCode::Insert => keys::INSERT.len(),
111+ KeyCode::Null => keys::NULL.len(),
112+ KeyCode::Esc => keys::ESC.len(),
113+ KeyCode::Char(' ') => keys::SPACE.len(),
114+ KeyCode::Char('<') => keys::LESS_THAN.len(),
115+ KeyCode::Char('>') => keys::GREATER_THAN.len(),
116+ KeyCode::Char('+') => keys::PLUS.len(),
117+ KeyCode::Char('-') => keys::MINUS.len(),
118+ KeyCode::Char(';') => keys::SEMICOLON.len(),
119+ KeyCode::Char('%') => keys::PERCENT.len(),
120+ KeyCode::F(1..=9) => 2,
121+ KeyCode::F(_) => 3,
122+ KeyCode::Char(c) => c.width().unwrap_or(0),
123+ };
124+ if self.modifiers.contains(KeyModifiers::SHIFT) {
125+ width += 2;
126+ }
127+ if self.modifiers.contains(KeyModifiers::ALT) {
128+ width += 2;
129+ }
130+ if self.modifiers.contains(KeyModifiers::CONTROL) {
131+ width += 2;
132+ }
133+ width
134+ }
135+
136+ fn width_cjk(&self) -> usize {
137+ self.width()
138+ }
139+}
140+
66impl std::str::FromStr for KeyEvent {
141impl std::str::FromStr for KeyEvent {
67 type Err = Error;
142 type Err = Error;
68
143
69 fn from_str(s: &str) -> Result<Self, Self::Err> {
144 fn from_str(s: &str) -> Result<Self, Self::Err> {
70 let mut tokens: Vec<_> = s.split('-').collect();
145 let mut tokens: Vec<_> = s.split('-').collect();
71 let code = match tokens.pop().ok_or_else(|| anyhow!("Missing key code"))? {
146 let code = match tokens.pop().ok_or_else(|| anyhow!("Missing key code"))? {
72− "backspace" => KeyCode::Backspace,
147+ keys::BACKSPACE => KeyCode::Backspace,
73− "space" => KeyCode::Char(' '),
74− "ret" => KeyCode::Enter,
148+ keys::ENTER => KeyCode::Enter,
75− "lt" => KeyCode::Char('<'),
76− "gt" => KeyCode::Char('>'),
77− "plus" => KeyCode::Char('+'),
78− "minus" => KeyCode::Char('-'),
79− "semicolon" => KeyCode::Char(';'),
80− "percent" => KeyCode::Char('%'),
81− "left" => KeyCode::Left,
149+ keys::LEFT => KeyCode::Left,
82− "right" => KeyCode::Right,
150+ keys::RIGHT => KeyCode::Right,
151+ keys::UP => KeyCode::Up,
83− "up" => KeyCode::Down,
152+ keys::DOWN => KeyCode::Down,
84− "home" => KeyCode::Home,
153+ keys::HOME => KeyCode::Home,
85− "end" => KeyCode::End,
154+ keys::END => KeyCode::End,
86− "pageup" => KeyCode::PageUp,
155+ keys::PAGEUP => KeyCode::PageUp,
87− "pagedown" => KeyCode::PageDown,
156+ keys::PAGEDOWN => KeyCode::PageDown,
88− "tab" => KeyCode::Tab,
157+ keys::TAB => KeyCode::Tab,
89− "backtab" => KeyCode::BackTab,
158+ keys::BACKTAB => KeyCode::BackTab,
90− "del" => KeyCode::Delete,
159+ keys::DELETE => KeyCode::Delete,
91− "ins" => KeyCode::Insert,
160+ keys::INSERT => KeyCode::Insert,
92− "null" => KeyCode::Null,
161+ keys::NULL => KeyCode::Null,
93− "esc" => KeyCode::Esc,
162+ keys::ESC => KeyCode::Esc,
163+ keys::SPACE => KeyCode::Char(' '),
164+ keys::LESS_THAN => KeyCode::Char('<'),
165+ keys::GREATER_THAN => KeyCode::Char('>'),
166+ keys::PLUS => KeyCode::Char('+'),
167+ keys::MINUS => KeyCode::Char('-'),
168+ keys::SEMICOLON => KeyCode::Char(';'),
169+ keys::PERCENT => KeyCode::Char('%'),
94 single if single.len() == 1 => KeyCode::Char(single.chars().next().unwrap()),
170 single if single.len() == 1 => KeyCode::Char(single.chars().next().unwrap()),
95 function if function.len() > 1 && function.starts_with('F') => {
171 function if function.len() > 1 && function.starts_with('F') => {
96 let function: String = function.chars().skip(1).collect();
172 let function: String = function.chars().skip(1).collect();
helix-view/src/lib.rs+1
@@ -5,6 +5,7 @@ pub mod clipboard;
5pub mod document;
5pub mod document;
6pub mod editor;
6pub mod editor;
7pub mod graphics;
7pub mod graphics;
8+pub mod info;
8pub mod input;
9pub mod input;
9pub mod keyboard;
10pub mod keyboard;
10pub mod register_selection;
11pub mod register_selection;