Show infobox to hint textobjects with `mi` and `ma` (#1686)

* Show infobox to hint textobjects with `mi` and `ma`

* Add note to infobox than any pair of characters will work too

The wording could probably be a little more clear, but I wanted to
keep it short but still accurate.

* Don't allocate a vec for the static help text

* Fix bug where `mi<esc>` would swallow next input and persist infobox

* Better help text for arbitrary pair matching in textobject selection

* Add way to add fake pending key data below status, use with `mi`/`ma`

This is a bit hacky as it makes use of global state which will end
up managed in multiple places, but has precedent in the way autoinfo
works. There should probably be a bigger refactor to handle this
kind of state better.

* Return early on anything other than `mi` and `ma` for autoinfo

* Remove "ascii" from help text with `mi` and `ma`

* Update helix-term/src/ui/editor.rs

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
pull/1640/head
Daniel S Poulin 3 years ago committed by GitHub
parent bdbf423876
commit b13d44156c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -5353,7 +5353,10 @@ fn select_textobject_inner(cx: &mut Context) {
fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) { fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) {
let count = cx.count(); let count = cx.count();
cx.on_next_key(move |cx, event| { cx.on_next_key(move |cx, event| {
cx.editor.autoinfo = None;
cx.editor.pseudo_pending = None;
if let Some(ch) = event.char() { if let Some(ch) = event.char() {
let textobject = move |editor: &mut Editor| { let textobject = move |editor: &mut Editor| {
let (view, doc) = current!(editor); let (view, doc) = current!(editor);
@ -5402,7 +5405,32 @@ fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) {
textobject(cx.editor); textobject(cx.editor);
cx.editor.last_motion = Some(Motion(Box::new(textobject))); cx.editor.last_motion = Some(Motion(Box::new(textobject)));
} }
}) });
if let Some((title, abbrev)) = match objtype {
textobject::TextObject::Inside => Some(("Match inside", "mi")),
textobject::TextObject::Around => Some(("Match around", "ma")),
_ => return,
} {
let help_text = [
("w", "Word"),
("W", "WORD"),
("c", "Class (tree-sitter)"),
("f", "Function (tree-sitter)"),
("p", "Parameter (tree-sitter)"),
("m", "Matching delimiter under cursor"),
(" ", "... or any character acting as a pair"),
];
cx.editor.autoinfo = Some(Info::new(
title,
help_text
.into_iter()
.map(|(col1, col2)| (col1.to_string(), col2.to_string()))
.collect(),
));
cx.editor.pseudo_pending = Some(abbrev.to_string());
};
} }
fn surround_add(cx: &mut Context) { fn surround_add(cx: &mut Context) {

@ -1211,6 +1211,9 @@ impl Component for EditorView {
disp.push_str(&s); disp.push_str(&s);
} }
} }
if let Some(pseudo_pending) = &cx.editor.pseudo_pending {
disp.push_str(pseudo_pending.as_str())
}
let style = cx.editor.theme.get("ui.text"); let style = cx.editor.theme.get("ui.text");
let macro_width = if cx.editor.macro_recording.is_some() { let macro_width = if cx.editor.macro_recording.is_some() {
3 3

@ -299,6 +299,7 @@ pub struct Editor {
pub idle_timer: Pin<Box<Sleep>>, pub idle_timer: Pin<Box<Sleep>>,
pub last_motion: Option<Motion>, pub last_motion: Option<Motion>,
pub pseudo_pending: Option<String>,
pub exit_code: i32, pub exit_code: i32,
} }
@ -346,6 +347,7 @@ impl Editor {
autoinfo: 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,
pseudo_pending: None,
config, config,
auto_pairs, auto_pairs,
exit_code: 0, exit_code: 0,

Loading…
Cancel
Save