From 0b4e6ec74846189b71b4547a3b7c73585de3ade3 Mon Sep 17 00:00:00 2001 From: Daniel Poulin Date: Sun, 20 Feb 2022 17:40:25 -0500 Subject: [PATCH 1/9] Show infobox to hint textobjects with `mi` and `ma` --- helix-term/src/commands.rs | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 3839cbe6a0e2..59e62e9977d1 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -5353,6 +5353,7 @@ fn select_textobject_inner(cx: &mut Context) { fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) { let count = cx.count(); + cx.on_next_key(move |cx, event| { if let Some(ch) = event.char() { let textobject = move |editor: &mut Editor| { @@ -5400,9 +5401,33 @@ fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) { doc.set_selection(view.id, selection); }; textobject(cx.editor); + cx.editor.autoinfo = None; cx.editor.last_motion = Some(Motion(Box::new(textobject))); } - }) + }); + + if let Some(title) = match objtype { + textobject::TextObject::Inside => Some("Match inside"), + textobject::TextObject::Around => Some("Match around"), + textobject::TextObject::Movement => None, + } { + let help_text = vec![ + ("w", "Word"), + ("W", "WORD"), + ("c", "Class (tree-sitter)"), + ("f", "Function (tree-sitter)"), + ("p", "Parameter (tree-sitter)"), + ("m", "Matching delimiter under cursor"), + ]; + + cx.editor.autoinfo = Some(Info::new( + title, + help_text + .into_iter() + .map(|(col1, col2)| (col1.to_string(), col2.to_string())) + .collect(), + )); + }; } fn surround_add(cx: &mut Context) { From 1d9345b3c64e53fc9ae5136db49a7395f9d72c98 Mon Sep 17 00:00:00 2001 From: Daniel Poulin Date: Sun, 20 Feb 2022 19:36:06 -0500 Subject: [PATCH 2/9] 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. --- helix-term/src/commands.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 59e62e9977d1..14edaebf0f7c 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -5418,6 +5418,7 @@ fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) { ("f", "Function (tree-sitter)"), ("p", "Parameter (tree-sitter)"), ("m", "Matching delimiter under cursor"), + (" ", "Any opening or closing pair character"), ]; cx.editor.autoinfo = Some(Info::new( From d6b4d63e08dea434901f57b2d1a4b4e83b135435 Mon Sep 17 00:00:00 2001 From: Daniel Poulin Date: Sun, 20 Feb 2022 23:23:04 -0500 Subject: [PATCH 3/9] Don't allocate a vec for the static help text --- helix-term/src/commands.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 14edaebf0f7c..52b7c6cbf353 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -5411,7 +5411,7 @@ fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) { textobject::TextObject::Around => Some("Match around"), textobject::TextObject::Movement => None, } { - let help_text = vec![ + let help_text = [ ("w", "Word"), ("W", "WORD"), ("c", "Class (tree-sitter)"), From b7ccb67c0fbdd78b1437e7d3bb02c7e51746ac47 Mon Sep 17 00:00:00 2001 From: Daniel Poulin Date: Sun, 20 Feb 2022 23:46:53 -0500 Subject: [PATCH 4/9] Fix bug where `mi` would swallow next input and persist infobox --- helix-term/src/commands.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 52b7c6cbf353..2580ecff2a96 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -5355,6 +5355,7 @@ fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) { let count = cx.count(); cx.on_next_key(move |cx, event| { + cx.editor.autoinfo = None; if let Some(ch) = event.char() { let textobject = move |editor: &mut Editor| { let (view, doc) = current!(editor); @@ -5401,7 +5402,6 @@ fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) { doc.set_selection(view.id, selection); }; textobject(cx.editor); - cx.editor.autoinfo = None; cx.editor.last_motion = Some(Motion(Box::new(textobject))); } }); From c7f8e7892d98daecf0502e6b2faaa16cfc003e2e Mon Sep 17 00:00:00 2001 From: Daniel Poulin Date: Sun, 20 Feb 2022 23:50:22 -0500 Subject: [PATCH 5/9] Better help text for arbitrary pair matching in textobject selection --- helix-term/src/commands.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 2580ecff2a96..c03387d007e5 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -5418,7 +5418,7 @@ fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) { ("f", "Function (tree-sitter)"), ("p", "Parameter (tree-sitter)"), ("m", "Matching delimiter under cursor"), - (" ", "Any opening or closing pair character"), + (" ", "... or any ascii character acting as a pair"), ]; cx.editor.autoinfo = Some(Info::new( From 8d14a100b3278b5e7d81531908f62c935af73bdd Mon Sep 17 00:00:00 2001 From: Daniel Poulin Date: Mon, 21 Feb 2022 00:22:36 -0500 Subject: [PATCH 6/9] 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. --- helix-term/src/commands.rs | 8 +++++--- helix-term/src/ui/editor.rs | 3 +++ helix-view/src/editor.rs | 2 ++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index c03387d007e5..55ce58313e68 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -5356,6 +5356,7 @@ fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) { cx.on_next_key(move |cx, event| { cx.editor.autoinfo = None; + cx.editor.pseudo_pending = None; if let Some(ch) = event.char() { let textobject = move |editor: &mut Editor| { let (view, doc) = current!(editor); @@ -5406,9 +5407,9 @@ fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) { } }); - if let Some(title) = match objtype { - textobject::TextObject::Inside => Some("Match inside"), - textobject::TextObject::Around => Some("Match around"), + if let Some((title, abbrev)) = match objtype { + textobject::TextObject::Inside => Some(("Match inside", "mi")), + textobject::TextObject::Around => Some(("Match around", "ma")), textobject::TextObject::Movement => None, } { let help_text = [ @@ -5428,6 +5429,7 @@ fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) { .map(|(col1, col2)| (col1.to_string(), col2.to_string())) .collect(), )); + cx.editor.pseudo_pending = Some(abbrev.to_string()); }; } diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index 29552b67758d..e6122a19c9c8 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -1211,6 +1211,9 @@ impl Component for EditorView { disp.push_str(&s); } } + if let Some(pseudo_pending) = &cx.editor.pseudo_pending { + disp.push_str(&*pseudo_pending) + } let style = cx.editor.theme.get("ui.text"); let macro_width = if cx.editor.macro_recording.is_some() { 3 diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 85d9be67b275..3a2a9af8df15 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -299,6 +299,7 @@ pub struct Editor { pub idle_timer: Pin>, pub last_motion: Option, + pub pseudo_pending: Option, pub exit_code: i32, } @@ -346,6 +347,7 @@ impl Editor { autoinfo: None, idle_timer: Box::pin(sleep(config.idle_timeout)), last_motion: None, + pseudo_pending: None, config, auto_pairs, exit_code: 0, From a59f407c5cb65b554185fcfcf0af43bbaaad01f6 Mon Sep 17 00:00:00 2001 From: Daniel Poulin Date: Sun, 27 Feb 2022 09:12:13 -0500 Subject: [PATCH 7/9] Return early on anything other than `mi` and `ma` for autoinfo --- helix-term/src/commands.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 55ce58313e68..752877278e39 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -5410,7 +5410,7 @@ fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) { if let Some((title, abbrev)) = match objtype { textobject::TextObject::Inside => Some(("Match inside", "mi")), textobject::TextObject::Around => Some(("Match around", "ma")), - textobject::TextObject::Movement => None, + _ => return, } { let help_text = [ ("w", "Word"), From 5a817bc6ef0c32c73f919e496e8eb7da55d25baf Mon Sep 17 00:00:00 2001 From: Daniel Poulin Date: Sun, 27 Feb 2022 09:13:23 -0500 Subject: [PATCH 8/9] Remove "ascii" from help text with `mi` and `ma` --- helix-term/src/commands.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 752877278e39..315bd9814890 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -5419,7 +5419,7 @@ fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) { ("f", "Function (tree-sitter)"), ("p", "Parameter (tree-sitter)"), ("m", "Matching delimiter under cursor"), - (" ", "... or any ascii character acting as a pair"), + (" ", "... or any character acting as a pair"), ]; cx.editor.autoinfo = Some(Info::new( From 0b30b525c3363e6dca702741d35096b1846ad055 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Tue, 1 Mar 2022 10:17:21 +0900 Subject: [PATCH 9/9] Update helix-term/src/ui/editor.rs --- helix-term/src/ui/editor.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index e6122a19c9c8..064c74ee098f 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -1212,7 +1212,7 @@ impl Component for EditorView { } } if let Some(pseudo_pending) = &cx.editor.pseudo_pending { - disp.push_str(&*pseudo_pending) + disp.push_str(pseudo_pending.as_str()) } let style = cx.editor.theme.get("ui.text"); let macro_width = if cx.editor.macro_recording.is_some() {