Skip to content

Commit

Permalink
Add infobox
Browse files Browse the repository at this point in the history
  • Loading branch information
pickfire committed Jun 28, 2021
1 parent 82fc28a commit 37524f4
Show file tree
Hide file tree
Showing 11 changed files with 296 additions and 78 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

105 changes: 81 additions & 24 deletions helix-term/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use helix_core::{

use helix_view::{
document::{IndentStyle, Mode},
info::Info,
input::KeyEvent,
keyboard::KeyCode,
view::{View, PADDING},
Expand All @@ -32,6 +33,7 @@ use movement::Movement;

use crate::{
compositor::{self, Callback, Component, Compositor},
key,
ui::{self, Completion, Picker, Popup, Prompt, PromptEvent},
};

Expand Down Expand Up @@ -3284,33 +3286,88 @@ fn select_register(cx: &mut Context) {
})
}

fn space_mode(cx: &mut Context) {
cx.on_next_key(move |cx, event| {
if let KeyEvent {
code: KeyCode::Char(ch),
..
} = event
{
// TODO: temporarily show SPC in the mode list
match ch {
'f' => file_picker(cx),
'b' => buffer_picker(cx),
's' => symbol_picker(cx),
'w' => window_mode(cx),
'y' => yank_joined_to_clipboard(cx),
'Y' => yank_main_selection_to_clipboard(cx),
'p' => paste_clipboard_after(cx),
'P' => paste_clipboard_before(cx),
'R' => replace_selections_with_clipboard(cx),
// ' ' => toggle_alternate_buffer(cx),
// TODO: temporary since space mode took its old key
' ' => keep_primary_selection(cx),
_ => (),
}
macro_rules! mode_info {
// TODO: how to use one expr for both pat and expr?
// TODO: how to use replaced function name as str at compile time?
// TODO: extend to support multiple keys, but first solve the other two
{$name:literal, $cx:expr, $($key:expr => $func:expr; $funcs:literal),+,} => {
mode_info! {
$name, $cx,
$($key; $key => $func; $funcs,)+
}
})
};
{$name:literal, $cx:expr, $($key:expr; $keyp:pat => $func:expr; $funcs:literal),+,} => {
$cx.editor.autoinfo = Some(Info::key(
$name,
vec![
$(
(vec![$key], $funcs),
)+
],
));
$cx.on_next_key(move |cx, event| {
match event {
$(
$keyp => $func(cx),
)+
_ => {}
}
})
}
}

fn space_mode(cx: &mut Context) {
mode_info! {
"space mode", cx,
key!('f'); key!('f') => file_picker; "file picker",
key!('b'); key!('b') => buffer_picker; "buffer picker",
key!('s'); key!('s') => symbol_picker; "symbol picker",
key!('w'); key!('w') => window_mode; "window mode",
key!('y'); key!('y') => yank_joined_to_clipboard; "yank joined to clipboard",
key!('Y'); key!('Y') => yank_main_selection_to_clipboard; "yank main selection to clipboard",
key!('p'); key!('p') => paste_clipboard_after; "paste clipboard after",
key!('P'); key!('P') => paste_clipboard_before; "paste clipboard before",
key!('R'); key!('R') => replace_selections_with_clipboard; "replace selections with clipboard",
key!(' '); key!(' ') => keep_primary_selection; "keep primary selection",
}
}

// TODO: generated, delete it later
// fn space_mode(cx: &mut Context) {
// cx.editor.autoinfo = Some(Info::key(
// "space",
// vec![
// (vec![key!('f')], "file picker"),
// (vec![key!('b')], "buffer picker"),
// (vec![key!('s')], "symbol picker"),
// (vec![key!('w')], "window mode"),
// (vec![key!('y')], "yank joined to clipboard"),
// (vec![key!('Y')], "yank main selection to clipboard"),
// (vec![key!('p')], "paste clipboard after"),
// (vec![key!('P')], "paste clipboard before"),
// (vec![key!('R')], "replace selections with clipboard"),
// (vec![key!(' ')], "keep primary selection"),
// ],
// ));
// cx.on_next_key(move |cx, event| {
// match event {
// key!('f') => file_picker(cx),
// key!('b') => buffer_picker(cx),
// key!('s') => symbol_picker(cx),
// key!('w') => window_mode(cx),
// key!('y') => yank_joined_to_clipboard(cx),
// key!('Y') => yank_main_selection_to_clipboard(cx),
// key!('p') => paste_clipboard_after(cx),
// key!('P') => paste_clipboard_before(cx),
// key!('R') => replace_selections_with_clipboard(cx),
// // key!(' ') => toggle_alternate_buffer(cx),
// // TODO: temporary since space mode took its old key
// key!(' ') => keep_primary_selection(cx),
// _ => {}
// }
// })
// }

fn view_mode(cx: &mut Context) {
cx.on_next_key(move |cx, event| {
if let KeyEvent {
Expand Down
16 changes: 8 additions & 8 deletions helix-term/src/keymap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,32 +109,32 @@ use std::{
macro_rules! key {
($key:ident) => {
KeyEvent {
code: KeyCode::$key,
modifiers: KeyModifiers::NONE,
code: helix_view::keyboard::KeyCode::$key,
modifiers: helix_view::keyboard::KeyModifiers::NONE,
}
};
($($ch:tt)*) => {
KeyEvent {
code: KeyCode::Char($($ch)*),
modifiers: KeyModifiers::NONE,
code: helix_view::keyboard::KeyCode::Char($($ch)*),
modifiers: helix_view::keyboard::KeyModifiers::NONE,
}
};
}

macro_rules! ctrl {
($($ch:tt)*) => {
KeyEvent {
code: KeyCode::Char($($ch)*),
modifiers: KeyModifiers::CONTROL,
code: helix_view::keyboard::KeyCode::Char($($ch)*),
modifiers: helix_view::keyboard::KeyModifiers::CONTROL,
}
};
}

macro_rules! alt {
($($ch:tt)*) => {
KeyEvent {
code: KeyCode::Char($($ch)*),
modifiers: KeyModifiers::ALT,
code: helix_view::keyboard::KeyCode::Char($($ch)*),
modifiers: helix_view::keyboard::KeyModifiers::ALT,
}
};
}
Expand Down
7 changes: 5 additions & 2 deletions helix-term/src/ui/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,10 @@ impl Component for EditorView {
self.render_view(doc, view, area, surface, &cx.editor.theme, is_focused);
}

if let Some(info) = std::mem::take(&mut cx.editor.autoinfo) {
info.render(area, surface, cx);
}

// render status msg
if let Some((status_msg, severity)) = &cx.editor.status_msg {
use helix_view::editor::Severity;
Expand All @@ -740,8 +744,7 @@ impl Component for EditorView {
}

if let Some(completion) = &self.completion {
completion.render(area, surface, cx)
// render completion here
completion.render(area, surface, cx);
}
}

Expand Down
24 changes: 24 additions & 0 deletions helix-term/src/ui/info.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use crate::compositor::{Component, Context};
use helix_view::graphics::{Margin, Rect, Style};
use helix_view::info::Info;
use tui::buffer::Buffer as Surface;
use tui::widgets::{Block, Borders, Widget};

impl Component for Info {
fn render(&self, viewport: Rect, surface: &mut Surface, cx: &mut Context) {
let block = Block::default().title(self.title).borders(Borders::ALL);
let Info { width, height, .. } = self;
let (w, h) = (*width + 2, *height + 2);
// -2 to subtract command line + statusline. a bit of a hack, because of splits.
let area = Rect::new(viewport.width - w, viewport.height - h - 2, w, h);
let margin = Margin {
vertical: 1,
horizontal: 1,
};
let Rect { x, y, .. } = area.inner(&margin);
for (y, line) in (y..).zip(self.text.lines()) {
surface.set_string(x, y, line, Style::default());
}
block.render(area, surface);
}
}
1 change: 1 addition & 0 deletions helix-term/src/ui/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod completion;
mod editor;
mod info;
mod markdown;
mod menu;
mod picker;
Expand Down
1 change: 1 addition & 0 deletions helix-view/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ slotmap = "1"

encoding_rs = "0.8"
chardetng = "0.1"
unicode-width = "0.1"

serde = { version = "1.0", features = ["derive"] }
toml = "0.5"
Expand Down
3 changes: 3 additions & 0 deletions helix-view/src/editor.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::{
clipboard::{get_clipboard_provider, ClipboardProvider},
graphics::{CursorKind, Rect},
info::Info,
theme::{self, Theme},
tree::Tree,
Document, DocumentId, RegisterSelection, View, ViewId,
Expand Down Expand Up @@ -32,6 +33,7 @@ pub struct Editor {
pub syn_loader: Arc<syntax::Loader>,
pub theme_loader: Arc<theme::Loader>,

pub autoinfo: Option<Info>,
pub status_msg: Option<(String, Severity)>,
}

Expand Down Expand Up @@ -64,6 +66,7 @@ impl Editor {
theme_loader: themes,
registers: Registers::default(),
clipboard_provider: get_clipboard_provider(),
autoinfo: None,
status_msg: None,
}
}
Expand Down
51 changes: 51 additions & 0 deletions helix-view/src/info.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use crate::input::KeyEvent;
use std::fmt::Write;
use unicode_width::UnicodeWidthStr;

#[derive(Debug)]
/// Info box used in editor. Rendering logic will be in other crate.
pub struct Info {
/// Title kept as static str for now.
pub title: &'static str,
/// Text body, should contains newline.
pub text: String,
/// Body width.
pub width: u16,
/// Body height.
pub height: u16,
}

impl Info {
pub fn key(title: &'static str, body: Vec<(Vec<KeyEvent>, &'static str)>) -> Info {
let keymaps_width: u16 = body
.iter()
.map(|r| r.0.iter().map(|e| e.width() as u16 + 2).sum::<u16>() - 2)
.max()
.unwrap();
let mut text = String::new();
let mut width = 0;
let height = body.len() as u16;
for (mut keyevents, desc) in body {
let keyevent = keyevents.remove(0);
let mut left = keymaps_width - keyevent.width() as u16;
write!(text, "{}", keyevent).ok();
for keyevent in keyevents {
write!(text, ", {}", keyevent).ok();
left -= 2 + keyevent.width() as u16;
}
for _ in 0..left {
text.push(' ');
}
if keymaps_width + 2 + (desc.width() as u16) > width {
width = keymaps_width + 2 + desc.width() as u16;
}
writeln!(text, " {}", &desc).ok();
}
Info {
title,
text,
width,
height,
}
}
}
Loading

0 comments on commit 37524f4

Please sign in to comment.