on master help sign in
Automatically track pseudo-pending text (#4077)
6cca737Michael Davis
helix-term/src/commands.rs+33−45
@@ -1091,27 +1091,18 @@ fn extend_next_long_word_end(cx: &mut Context) {
1091 extend_word_impl(cx, movement::move_next_long_word_end)
1091 extend_word_impl(cx, movement::move_next_long_word_end)
1092}
1092}
1093
1093
1094−fn will_find_char<F>(
1094+fn will_find_char<F>(cx: &mut Context, search_fn: F, inclusive: bool, extend: bool)
1095− cx: &mut Context,
1096− search_fn: F,
1097− inclusive: bool,
1098− extend: bool,
1099− pseudo_pending: &str,
1100−) where
1095+where
1101 F: Fn(RopeSlice, char, usize, usize, bool) -> Option<usize> + 'static,
1096 F: Fn(RopeSlice, char, usize, usize, bool) -> Option<usize> + 'static,
1102{
1097{
1103 // TODO: count is reset to 1 before next key so we move it into the closure here.
1098 // TODO: count is reset to 1 before next key so we move it into the closure here.
1104 // Would be nice to carry over.
1099 // Would be nice to carry over.
1105 let count = cx.count();
1100 let count = cx.count();
1106
1101
1107− cx.editor.pseudo_pending = Some(pseudo_pending.to_string());
1108−
1109 // need to wait for next key
1102 // need to wait for next key
1110 // TODO: should this be done by grapheme rather than char? For example,
1103 // TODO: should this be done by grapheme rather than char? For example,
1111 // we can't properly handle the line-ending CRLF case here in terms of char.
1104 // we can't properly handle the line-ending CRLF case here in terms of char.
1112 cx.on_next_key(move |cx, event| {
1105 cx.on_next_key(move |cx, event| {
1113− cx.editor.pseudo_pending = None;
1114−
1115 let ch = match event {
1106 let ch = match event {
1116 KeyEvent {
1107 KeyEvent {
1117 code: KeyCode::Enter,
1108 code: KeyCode::Enter,
@@ -1214,35 +1205,35 @@ fn find_prev_char_impl(
1214}
1205}
1215
1206
1216fn find_till_char(cx: &mut Context) {
1207fn find_till_char(cx: &mut Context) {
1217− will_find_char(cx, find_next_char_impl, false, false, "t")
1208+ will_find_char(cx, find_next_char_impl, false, false)
1218}
1209}
1219
1210
1220fn find_next_char(cx: &mut Context) {
1211fn find_next_char(cx: &mut Context) {
1221− will_find_char(cx, find_next_char_impl, true, false, "f")
1212+ will_find_char(cx, find_next_char_impl, true, false)
1222}
1213}
1223
1214
1224fn extend_till_char(cx: &mut Context) {
1215fn extend_till_char(cx: &mut Context) {
1225− will_find_char(cx, find_next_char_impl, false, true, "t")
1216+ will_find_char(cx, find_next_char_impl, false, true)
1226}
1217}
1227
1218
1228fn extend_next_char(cx: &mut Context) {
1219fn extend_next_char(cx: &mut Context) {
1229− will_find_char(cx, find_next_char_impl, true, true, "f")
1220+ will_find_char(cx, find_next_char_impl, true, true)
1230}
1221}
1231
1222
1232fn till_prev_char(cx: &mut Context) {
1223fn till_prev_char(cx: &mut Context) {
1233− will_find_char(cx, find_prev_char_impl, false, false, "T")
1224+ will_find_char(cx, find_prev_char_impl, false, false)
1234}
1225}
1235
1226
1236fn find_prev_char(cx: &mut Context) {
1227fn find_prev_char(cx: &mut Context) {
1237− will_find_char(cx, find_prev_char_impl, true, false, "F")
1228+ will_find_char(cx, find_prev_char_impl, true, false)
1238}
1229}
1239
1230
1240fn extend_till_prev_char(cx: &mut Context) {
1231fn extend_till_prev_char(cx: &mut Context) {
1241− will_find_char(cx, find_prev_char_impl, false, true, "T")
1232+ will_find_char(cx, find_prev_char_impl, false, true)
1242}
1233}
1243
1234
1244fn extend_prev_char(cx: &mut Context) {
1235fn extend_prev_char(cx: &mut Context) {
1245− will_find_char(cx, find_prev_char_impl, true, true, "F")
1236+ will_find_char(cx, find_prev_char_impl, true, true)
1246}
1237}
1247
1238
1248fn repeat_last_motion(cx: &mut Context) {
1239fn repeat_last_motion(cx: &mut Context) {
@@ -4392,7 +4383,6 @@ fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) {
4392
4383
4393 cx.on_next_key(move |cx, event| {
4384 cx.on_next_key(move |cx, event| {
4394 cx.editor.autoinfo = None;
4385 cx.editor.autoinfo = None;
4395− cx.editor.pseudo_pending = None;
4396 if let Some(ch) = event.char() {
4386 if let Some(ch) = event.char() {
4397 let textobject = move |editor: &mut Editor| {
4387 let textobject = move |editor: &mut Editor| {
4398 let (view, doc) = current!(editor);
4388 let (view, doc) = current!(editor);
@@ -4441,33 +4431,31 @@ fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) {
4441 }
4431 }
4442 });
4432 });
4443
4433
4444− if let Some((title, abbrev)) = match objtype {
4434+ let title = match objtype {
4445− textobject::TextObject::Inside => Some(("Match inside", "mi")),
4435+ textobject::TextObject::Inside => "Match inside",
4446− textobject::TextObject::Around => Some(("Match around", "ma")),
4436+ textobject::TextObject::Around => "Match around",
4447 _ => return,
4437 _ => return,
4448− } {
4449− let help_text = [
4450− ("w", "Word"),
4451− ("W", "WORD"),
4452− ("p", "Paragraph"),
4453− ("c", "Class (tree-sitter)"),
4454− ("f", "Function (tree-sitter)"),
4455− ("a", "Argument/parameter (tree-sitter)"),
4456− ("o", "Comment (tree-sitter)"),
4457− ("t", "Test (tree-sitter)"),
4458− ("m", "Closest surrounding pair to cursor"),
4459− (" ", "... or any character acting as a pair"),
4460− ];
4461−
4462− cx.editor.autoinfo = Some(Info::new(
4463− title,
4464− help_text
4465− .into_iter()
4466− .map(|(col1, col2)| (col1.to_string(), col2.to_string()))
4467− .collect(),
4468− ));
4469− cx.editor.pseudo_pending = Some(abbrev.to_string());
4470 };
4438 };
4439+ let help_text = [
4440+ ("w", "Word"),
4441+ ("W", "WORD"),
4442+ ("p", "Paragraph"),
4443+ ("c", "Class (tree-sitter)"),
4444+ ("f", "Function (tree-sitter)"),
4445+ ("a", "Argument/parameter (tree-sitter)"),
4446+ ("o", "Comment (tree-sitter)"),
4447+ ("t", "Test (tree-sitter)"),
4448+ ("m", "Closest surrounding pair to cursor"),
4449+ (" ", "... or any character acting as a pair"),
4450+ ];
4451+
4452+ cx.editor.autoinfo = Some(Info::new(
4453+ title,
4454+ help_text
4455+ .into_iter()
4456+ .map(|(col1, col2)| (col1.to_string(), col2.to_string()))
4457+ .collect(),
4458+ ));
4471}
4459}
4472
4460
4473fn surround_add(cx: &mut Context) {
4461fn surround_add(cx: &mut Context) {
helix-term/src/ui/editor.rs+10−2
@@ -33,6 +33,7 @@ use super::statusline;
33pub struct EditorView {
33pub struct EditorView {
34 pub keymaps: Keymaps,
34 pub keymaps: Keymaps,
35 on_next_key: Option<Box<dyn FnOnce(&mut commands::Context, KeyEvent)>>,
35 on_next_key: Option<Box<dyn FnOnce(&mut commands::Context, KeyEvent)>>,
36+ pseudo_pending: Vec<KeyEvent>,
36 last_insert: (commands::MappableCommand, Vec<InsertEvent>),
37 last_insert: (commands::MappableCommand, Vec<InsertEvent>),
37 pub(crate) completion: Option<Completion>,
38 pub(crate) completion: Option<Completion>,
38 spinners: ProgressSpinners,
39 spinners: ProgressSpinners,
@@ -56,6 +57,7 @@ impl EditorView {
56 Self {
57 Self {
57 keymaps,
58 keymaps,
58 on_next_key: None,
59 on_next_key: None,
60+ pseudo_pending: Vec::new(),
59 last_insert: (commands::MappableCommand::normal_mode, Vec::new()),
61 last_insert: (commands::MappableCommand::normal_mode, Vec::new()),
60 completion: None,
62 completion: None,
61 spinners: ProgressSpinners::default(),
63 spinners: ProgressSpinners::default(),
@@ -839,6 +841,7 @@ impl EditorView {
839 event: KeyEvent,
841 event: KeyEvent,
840 ) -> Option<KeymapResult> {
842 ) -> Option<KeymapResult> {
841 let mut last_mode = mode;
843 let mut last_mode = mode;
844+ self.pseudo_pending.extend(self.keymaps.pending());
842 let key_result = self.keymaps.get(mode, event);
845 let key_result = self.keymaps.get(mode, event);
843 cxt.editor.autoinfo = self.keymaps.sticky().map(|node| node.infobox());
846 cxt.editor.autoinfo = self.keymaps.sticky().map(|node| node.infobox());
844
847
@@ -1316,6 +1319,11 @@ impl Component for EditorView {
1316 }
1319 }
1317
1320
1318 self.on_next_key = cx.on_next_key_callback.take();
1321 self.on_next_key = cx.on_next_key_callback.take();
1322+ match self.on_next_key {
1323+ Some(_) => self.pseudo_pending.push(key),
1324+ None => self.pseudo_pending.clear(),
1325+ }
1326+
1319 // appease borrowck
1327 // appease borrowck
1320 let callback = cx.callback.take();
1328 let callback = cx.callback.take();
1321
1329
@@ -1416,8 +1424,8 @@ impl Component for EditorView {
1416 for key in self.keymaps.pending() {
1424 for key in self.keymaps.pending() {
1417 disp.push_str(&key.key_sequence_format());
1425 disp.push_str(&key.key_sequence_format());
1418 }
1426 }
1419− if let Some(pseudo_pending) = &cx.editor.pseudo_pending {
1427+ for key in &self.pseudo_pending {
1420− disp.push_str(pseudo_pending.as_str())
1428+ disp.push_str(&key.key_sequence_format());
1421 }
1429 }
1422 let style = cx.editor.theme.get("ui.text");
1430 let style = cx.editor.theme.get("ui.text");
1423 let macro_width = if cx.editor.macro_recording.is_some() {
1431 let macro_width = if cx.editor.macro_recording.is_some() {
helix-view/src/editor.rs−2
@@ -677,7 +677,6 @@ pub struct Editor {
677
677
678 pub idle_timer: Pin<Box<Sleep>>,
678 pub idle_timer: Pin<Box<Sleep>>,
679 pub last_motion: Option<Motion>,
679 pub last_motion: Option<Motion>,
680− pub pseudo_pending: Option<String>,
681
680
682 pub last_completion: Option<CompleteAction>,
681 pub last_completion: Option<CompleteAction>,
683
682
@@ -758,7 +757,6 @@ impl Editor {
758 idle_timer: Box::pin(sleep(conf.idle_timeout)),
757 idle_timer: Box::pin(sleep(conf.idle_timeout)),
759 last_motion: None,
758 last_motion: None,
760 last_completion: None,
759 last_completion: None,
761− pseudo_pending: None,
762 config,
760 config,
763 auto_pairs,
761 auto_pairs,
764 exit_code: 0,
762 exit_code: 0,