on master help sign in
Readline style insert mode (#1039)

* readline style insert mode * update keymap.md * don't save change history in insert mode * Revert "don't save change history in insert mode" This reverts commit cb47f946d7fb62ceda68e7d1692a3914d0be7762. * don't affect register and history in insert mode * add insert_register * don't call exit_select_mode in insert mode * avoid set_selection * avoid duplicated current!

commit46d9ae2b62f5b8494c527e0f8475509ce5fad095 authorBob <QiBaobin@users.noreply.github.com> dateMon 15 Nov 2021, 23:31 (5 years ago) parentc638b6b
4 files changed+114−9
book/src/keymap.md+23−7 helix-term/src/commands.rs+65−2 helix-term/src/keymap.rs+17 helix-term/src/ui/prompt.rs+9
book/src/keymap.md+23−7
@@ -243,11 +243,26 @@ Mappings in the style of [vim-unimpaired](https://github.com/tpope/vim-unimpaire
243243
244244## Insert Mode
245245
246−| Key | Description | Command |
247−| ----- | ----------- | ------- |
248−| `Escape` | Switch to normal mode | `normal_mode` |
249−| `Ctrl-x` | Autocomplete | `completion` |
250−| `Ctrl-w` | Delete previous word | `delete_word_backward` |
246+| Key | Description | Command |
247+| ----- | ----------- | ------- |
248+| `Escape` | Switch to normal mode | `normal_mode` |
249+| `Ctrl-x` | Autocomplete | `completion` |
250+| `Ctrl-r` | Insert a register content | `insert_register` |
251+| `Ctrl-w` | Delete previous word | `delete_word_backward` |
252+| `Alt-d` | Delete next word | `delete_word_forward` |
253+| `Alt-b`, `Alt-Left` | Backward a word | `move_prev_word_end` |
254+| `Ctrl-b`, `Left` | Backward a char | `move_char_left` |
255+| `Alt-f`, `Alt-Right` | Forward a word | `move_next_word_start` |
256+| `Ctrl-f`, `Right` | Forward a char | `move_char_right` |
257+| `Ctrl-e`, `End` | move to line end | `goto_line_end_newline` |
258+| `Ctrl-a`, `Home` | move to line start | `goto_line_start` |
259+| `Ctrl-w` | delete previous word | `delete_word_backwar` |
260+| `Ctrl-u` | delete to start of line | `kill_to_line_start` |
261+| `Ctrl-k` | delete to end of line | `kill_to_line_end` |
262+| `backspace`, `Ctrl-h` | delete previous char | `delete_char_backward` |
263+| `delete`, `Ctrl-d` | delete previous char | `delete_char_forward` |
264+| `Ctrl-p`, `Up` | move to previous line | `move_line_up` |
265+| `Ctrl-n`, `Down` | move to next line | `move_line_down` |
251266
252267## Select / extend mode
253268
@@ -285,6 +300,7 @@ Keys to use within prompt, Remapping currently not supported.
285300| `Ctrl-e`, `End` | Move prompt end |
286301| `Ctrl-a`, `Home` | Move prompt start |
287302| `Ctrl-w` | Delete previous word |
303+| `Alt-d` | Delete next word |
288304| `Ctrl-u` | Delete to start of line |
289305| `Ctrl-k` | Delete to end of line |
290306| `backspace`, `Ctrl-h` | Delete previous char |
@@ -292,7 +308,7 @@ Keys to use within prompt, Remapping currently not supported.
292308| `Ctrl-s` | Insert a word under doc cursor, may be changed to Ctrl-r Ctrl-w later |
293309| `Ctrl-p`, `Up` | Select previous history |
294310| `Ctrl-n`, `Down` | Select next history |
295−| `Tab` | Select next completion item |
296−| `BackTab` | Select previous completion item |
311+| `Tab` | Select next completion item |
312+| `BackTab` | Select previous completion item |
297313| `Enter` | Open selected |
298314
helix-term/src/commands.rs+65−2
@@ -187,6 +187,7 @@ impl Command {
187187 copy_selection_on_prev_line, "Copy selection on previous line",
188188 move_next_word_start, "Move to beginning of next word",
189189 move_prev_word_start, "Move to beginning of previous word",
190+ move_prev_word_end, "Move to end of previous word",
190191 move_next_word_end, "Move to end of next word",
191192 move_next_long_word_start, "Move to beginning of next long word",
192193 move_prev_long_word_start, "Move to beginning of previous long word",
@@ -284,6 +285,9 @@ impl Command {
284285 delete_char_backward, "Delete previous char",
285286 delete_char_forward, "Delete next char",
286287 delete_word_backward, "Delete previous word",
288+ delete_word_forward, "Delete next word",
289+ kill_to_line_start, "Delete content till the start of the line",
290+ kill_to_line_end, "Delete content till the end of the line",
287291 undo, "Undo change",
288292 redo, "Redo change",
289293 earlier, "Move backward in history",
@@ -330,6 +334,7 @@ impl Command {
330334 wclose, "Close window",
331335 wonly, "Current window only",
332336 select_register, "Select register",
337+ insert_register, "Insert register",
333338 align_view_middle, "Align view middle",
334339 align_view_top, "Align view top",
335340 align_view_center, "Align view center",
@@ -572,6 +577,29 @@ fn extend_to_line_start(cx: &mut Context) {
572577 goto_line_start_impl(view, doc, Movement::Extend)
573578}
574579
580+fn kill_to_line_start(cx: &mut Context) {
581+ let (view, doc) = current!(cx.editor);
582+ let text = doc.text().slice(..);
583+
584+ let selection = doc.selection(view.id).clone().transform(|range| {
585+ let line = range.cursor_line(text);
586+ range.put_cursor(text, text.line_to_char(line), true)
587+ });
588+ delete_selection_insert_mode(doc, view, &selection);
589+}
590+
591+fn kill_to_line_end(cx: &mut Context) {
592+ let (view, doc) = current!(cx.editor);
593+ let text = doc.text().slice(..);
594+
595+ let selection = doc.selection(view.id).clone().transform(|range| {
596+ let line = range.cursor_line(text);
597+ let pos = line_end_char_index(&text, line);
598+ range.put_cursor(text, pos, true)
599+ });
600+ delete_selection_insert_mode(doc, view, &selection);
601+}
602+
575603fn goto_first_nonwhitespace(cx: &mut Context) {
576604 let (view, doc) = current!(cx.editor);
577605 let text = doc.text().slice(..);
@@ -684,6 +712,10 @@ fn move_prev_word_start(cx: &mut Context) {
684712 move_word_impl(cx, movement::move_prev_word_start)
685713}
686714
715+fn move_prev_word_end(cx: &mut Context) {
716+ move_word_impl(cx, movement::move_prev_word_end)
717+}
718+
687719fn move_next_word_end(cx: &mut Context) {
688720 move_word_impl(cx, movement::move_next_word_end)
689721}
@@ -1586,6 +1618,17 @@ fn delete_selection_impl(reg: &mut Register, doc: &mut Document, view_id: ViewId
15861618 doc.apply(&transaction, view_id);
15871619}
15881620
1621+#[inline]
1622+fn delete_selection_insert_mode(doc: &mut Document, view: &View, selection: &Selection) {
1623+ let view_id = view.id;
1624+
1625+ // then delete
1626+ let transaction = Transaction::change_by_selection(doc.text(), selection, |range| {
1627+ (range.from(), range.to(), None)
1628+ });
1629+ doc.apply(&transaction, view_id);
1630+}
1631+
15891632fn delete_selection(cx: &mut Context) {
15901633 let reg_name = cx.register.unwrap_or('"');
15911634 let (view, doc) = current!(cx.editor);
@@ -4010,8 +4053,19 @@ pub mod insert {
40104053 .selection(view.id)
40114054 .clone()
40124055 .transform(|range| movement::move_prev_word_start(text, range, count));
4013− doc.set_selection(view.id, selection);
4014− delete_selection(cx)
4056+ delete_selection_insert_mode(doc, view, &selection);
4057+ }
4058+
4059+ pub fn delete_word_forward(cx: &mut Context) {
4060+ let count = cx.count();
4061+ let (view, doc) = current!(cx.editor);
4062+ let text = doc.text().slice(..);
4063+
4064+ let selection = doc
4065+ .selection(view.id)
4066+ .clone()
4067+ .transform(|range| movement::move_next_word_start(text, range, count));
4068+ delete_selection_insert_mode(doc, view, &selection);
40154069 }
40164070}
40174071
@@ -4973,6 +5027,15 @@ fn select_register(cx: &mut Context) {
49735027 })
49745028}
49755029
5030+fn insert_register(cx: &mut Context) {
5031+ cx.on_next_key(move |cx, event| {
5032+ if let Some(ch) = event.char() {
5033+ cx.editor.selected_register = Some(ch);
5034+ paste_before(cx);
5035+ }
5036+ })
5037+}
5038+
49765039fn align_view_top(cx: &mut Context) {
49775040 let (view, doc) = current!(cx.editor);
49785041 align_view(doc, view, Align::Top);
helix-term/src/keymap.rs+17
@@ -731,21 +731,38 @@ impl Default for Keymaps {
731731 "esc" => normal_mode,
732732
733733 "backspace" => delete_char_backward,
734+ "C-h" => delete_char_backward,
734735 "del" => delete_char_forward,
736+ "C-d" => delete_char_forward,
735737 "ret" => insert_newline,
736738 "tab" => insert_tab,
737739 "C-w" => delete_word_backward,
740+ "A-d" => delete_word_forward,
738741
739742 "left" => move_char_left,
743+ "C-b" => move_char_left,
740744 "down" => move_line_down,
745+ "C-n" => move_line_down,
741746 "up" => move_line_up,
747+ "C-p" => move_line_up,
742748 "right" => move_char_right,
749+ "C-f" => move_char_right,
750+ "A-b" => move_prev_word_end,
751+ "A-left" => move_prev_word_end,
752+ "A-f" => move_next_word_start,
753+ "A-right" => move_next_word_start,
743754 "pageup" => page_up,
744755 "pagedown" => page_down,
745756 "home" => goto_line_start,
757+ "C-a" => goto_line_start,
746758 "end" => goto_line_end_newline,
759+ "C-e" => goto_line_end_newline,
760+
761+ "C-k" => kill_to_line_end,
762+ "C-u" => kill_to_line_start,
747763
748764 "C-x" => completion,
765+ "C-r" => insert_register,
749766 });
750767 Keymaps(hashmap!(
751768 Mode::Normal => Keymap::new(normal),
helix-term/src/ui/prompt.rs+9
@@ -231,6 +231,14 @@ impl Prompt {
231231 self.completion = (self.completion_fn)(&self.line);
232232 }
233233
234+ pub fn delete_word_forwards(&mut self) {
235+ let pos = self.eval_movement(Movement::ForwardWord(1));
236+ self.line.replace_range(self.cursor..pos, "");
237+
238+ self.exit_selection();
239+ self.completion = (self.completion_fn)(&self.line);
240+ }
241+
234242 pub fn kill_to_start_of_line(&mut self) {
235243 let pos = self.eval_movement(Movement::StartOfLine);
236244 self.line.replace_range(pos..self.cursor, "");
@@ -435,6 +443,7 @@ impl Component for Prompt {
435443 ctrl!('e') | key!(End) => self.move_end(),
436444 ctrl!('a') | key!(Home) => self.move_start(),
437445 ctrl!('w') => self.delete_word_backwards(),
446+ alt!('d') => self.delete_word_forwards(),
438447 ctrl!('k') => self.kill_to_end_of_line(),
439448 ctrl!('u') => self.kill_to_start_of_line(),
440449 ctrl!('h') | key!(Backspace) => {