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!
This commit is contained in:
parent
c638b6b60e
commit
46d9ae2b62
4 changed files with 114 additions and 9 deletions
|
@ -243,11 +243,26 @@ Mappings in the style of [vim-unimpaired](https://github.com/tpope/vim-unimpaire
|
||||||
|
|
||||||
## Insert Mode
|
## Insert Mode
|
||||||
|
|
||||||
| Key | Description | Command |
|
| Key | Description | Command |
|
||||||
| ----- | ----------- | ------- |
|
| ----- | ----------- | ------- |
|
||||||
| `Escape` | Switch to normal mode | `normal_mode` |
|
| `Escape` | Switch to normal mode | `normal_mode` |
|
||||||
| `Ctrl-x` | Autocomplete | `completion` |
|
| `Ctrl-x` | Autocomplete | `completion` |
|
||||||
| `Ctrl-w` | Delete previous word | `delete_word_backward` |
|
| `Ctrl-r` | Insert a register content | `insert_register` |
|
||||||
|
| `Ctrl-w` | Delete previous word | `delete_word_backward` |
|
||||||
|
| `Alt-d` | Delete next word | `delete_word_forward` |
|
||||||
|
| `Alt-b`, `Alt-Left` | Backward a word | `move_prev_word_end` |
|
||||||
|
| `Ctrl-b`, `Left` | Backward a char | `move_char_left` |
|
||||||
|
| `Alt-f`, `Alt-Right` | Forward a word | `move_next_word_start` |
|
||||||
|
| `Ctrl-f`, `Right` | Forward a char | `move_char_right` |
|
||||||
|
| `Ctrl-e`, `End` | move to line end | `goto_line_end_newline` |
|
||||||
|
| `Ctrl-a`, `Home` | move to line start | `goto_line_start` |
|
||||||
|
| `Ctrl-w` | delete previous word | `delete_word_backwar` |
|
||||||
|
| `Ctrl-u` | delete to start of line | `kill_to_line_start` |
|
||||||
|
| `Ctrl-k` | delete to end of line | `kill_to_line_end` |
|
||||||
|
| `backspace`, `Ctrl-h` | delete previous char | `delete_char_backward` |
|
||||||
|
| `delete`, `Ctrl-d` | delete previous char | `delete_char_forward` |
|
||||||
|
| `Ctrl-p`, `Up` | move to previous line | `move_line_up` |
|
||||||
|
| `Ctrl-n`, `Down` | move to next line | `move_line_down` |
|
||||||
|
|
||||||
## Select / extend mode
|
## Select / extend mode
|
||||||
|
|
||||||
|
@ -285,6 +300,7 @@ Keys to use within prompt, Remapping currently not supported.
|
||||||
| `Ctrl-e`, `End` | Move prompt end |
|
| `Ctrl-e`, `End` | Move prompt end |
|
||||||
| `Ctrl-a`, `Home` | Move prompt start |
|
| `Ctrl-a`, `Home` | Move prompt start |
|
||||||
| `Ctrl-w` | Delete previous word |
|
| `Ctrl-w` | Delete previous word |
|
||||||
|
| `Alt-d` | Delete next word |
|
||||||
| `Ctrl-u` | Delete to start of line |
|
| `Ctrl-u` | Delete to start of line |
|
||||||
| `Ctrl-k` | Delete to end of line |
|
| `Ctrl-k` | Delete to end of line |
|
||||||
| `backspace`, `Ctrl-h` | Delete previous char |
|
| `backspace`, `Ctrl-h` | Delete previous char |
|
||||||
|
@ -292,7 +308,7 @@ Keys to use within prompt, Remapping currently not supported.
|
||||||
| `Ctrl-s` | Insert a word under doc cursor, may be changed to Ctrl-r Ctrl-w later |
|
| `Ctrl-s` | Insert a word under doc cursor, may be changed to Ctrl-r Ctrl-w later |
|
||||||
| `Ctrl-p`, `Up` | Select previous history |
|
| `Ctrl-p`, `Up` | Select previous history |
|
||||||
| `Ctrl-n`, `Down` | Select next history |
|
| `Ctrl-n`, `Down` | Select next history |
|
||||||
| `Tab` | Select next completion item |
|
| `Tab` | Select next completion item |
|
||||||
| `BackTab` | Select previous completion item |
|
| `BackTab` | Select previous completion item |
|
||||||
| `Enter` | Open selected |
|
| `Enter` | Open selected |
|
||||||
|
|
||||||
|
|
|
@ -187,6 +187,7 @@ impl Command {
|
||||||
copy_selection_on_prev_line, "Copy selection on previous line",
|
copy_selection_on_prev_line, "Copy selection on previous line",
|
||||||
move_next_word_start, "Move to beginning of next word",
|
move_next_word_start, "Move to beginning of next word",
|
||||||
move_prev_word_start, "Move to beginning of previous word",
|
move_prev_word_start, "Move to beginning of previous word",
|
||||||
|
move_prev_word_end, "Move to end of previous word",
|
||||||
move_next_word_end, "Move to end of next word",
|
move_next_word_end, "Move to end of next word",
|
||||||
move_next_long_word_start, "Move to beginning of next long word",
|
move_next_long_word_start, "Move to beginning of next long word",
|
||||||
move_prev_long_word_start, "Move to beginning of previous long word",
|
move_prev_long_word_start, "Move to beginning of previous long word",
|
||||||
|
@ -284,6 +285,9 @@ impl Command {
|
||||||
delete_char_backward, "Delete previous char",
|
delete_char_backward, "Delete previous char",
|
||||||
delete_char_forward, "Delete next char",
|
delete_char_forward, "Delete next char",
|
||||||
delete_word_backward, "Delete previous word",
|
delete_word_backward, "Delete previous word",
|
||||||
|
delete_word_forward, "Delete next word",
|
||||||
|
kill_to_line_start, "Delete content till the start of the line",
|
||||||
|
kill_to_line_end, "Delete content till the end of the line",
|
||||||
undo, "Undo change",
|
undo, "Undo change",
|
||||||
redo, "Redo change",
|
redo, "Redo change",
|
||||||
earlier, "Move backward in history",
|
earlier, "Move backward in history",
|
||||||
|
@ -330,6 +334,7 @@ impl Command {
|
||||||
wclose, "Close window",
|
wclose, "Close window",
|
||||||
wonly, "Current window only",
|
wonly, "Current window only",
|
||||||
select_register, "Select register",
|
select_register, "Select register",
|
||||||
|
insert_register, "Insert register",
|
||||||
align_view_middle, "Align view middle",
|
align_view_middle, "Align view middle",
|
||||||
align_view_top, "Align view top",
|
align_view_top, "Align view top",
|
||||||
align_view_center, "Align view center",
|
align_view_center, "Align view center",
|
||||||
|
@ -572,6 +577,29 @@ fn extend_to_line_start(cx: &mut Context) {
|
||||||
goto_line_start_impl(view, doc, Movement::Extend)
|
goto_line_start_impl(view, doc, Movement::Extend)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn kill_to_line_start(cx: &mut Context) {
|
||||||
|
let (view, doc) = current!(cx.editor);
|
||||||
|
let text = doc.text().slice(..);
|
||||||
|
|
||||||
|
let selection = doc.selection(view.id).clone().transform(|range| {
|
||||||
|
let line = range.cursor_line(text);
|
||||||
|
range.put_cursor(text, text.line_to_char(line), true)
|
||||||
|
});
|
||||||
|
delete_selection_insert_mode(doc, view, &selection);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn kill_to_line_end(cx: &mut Context) {
|
||||||
|
let (view, doc) = current!(cx.editor);
|
||||||
|
let text = doc.text().slice(..);
|
||||||
|
|
||||||
|
let selection = doc.selection(view.id).clone().transform(|range| {
|
||||||
|
let line = range.cursor_line(text);
|
||||||
|
let pos = line_end_char_index(&text, line);
|
||||||
|
range.put_cursor(text, pos, true)
|
||||||
|
});
|
||||||
|
delete_selection_insert_mode(doc, view, &selection);
|
||||||
|
}
|
||||||
|
|
||||||
fn goto_first_nonwhitespace(cx: &mut Context) {
|
fn goto_first_nonwhitespace(cx: &mut Context) {
|
||||||
let (view, doc) = current!(cx.editor);
|
let (view, doc) = current!(cx.editor);
|
||||||
let text = doc.text().slice(..);
|
let text = doc.text().slice(..);
|
||||||
|
@ -684,6 +712,10 @@ fn move_prev_word_start(cx: &mut Context) {
|
||||||
move_word_impl(cx, movement::move_prev_word_start)
|
move_word_impl(cx, movement::move_prev_word_start)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn move_prev_word_end(cx: &mut Context) {
|
||||||
|
move_word_impl(cx, movement::move_prev_word_end)
|
||||||
|
}
|
||||||
|
|
||||||
fn move_next_word_end(cx: &mut Context) {
|
fn move_next_word_end(cx: &mut Context) {
|
||||||
move_word_impl(cx, movement::move_next_word_end)
|
move_word_impl(cx, movement::move_next_word_end)
|
||||||
}
|
}
|
||||||
|
@ -1586,6 +1618,17 @@ fn delete_selection_impl(reg: &mut Register, doc: &mut Document, view_id: ViewId
|
||||||
doc.apply(&transaction, view_id);
|
doc.apply(&transaction, view_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn delete_selection_insert_mode(doc: &mut Document, view: &View, selection: &Selection) {
|
||||||
|
let view_id = view.id;
|
||||||
|
|
||||||
|
// then delete
|
||||||
|
let transaction = Transaction::change_by_selection(doc.text(), selection, |range| {
|
||||||
|
(range.from(), range.to(), None)
|
||||||
|
});
|
||||||
|
doc.apply(&transaction, view_id);
|
||||||
|
}
|
||||||
|
|
||||||
fn delete_selection(cx: &mut Context) {
|
fn delete_selection(cx: &mut Context) {
|
||||||
let reg_name = cx.register.unwrap_or('"');
|
let reg_name = cx.register.unwrap_or('"');
|
||||||
let (view, doc) = current!(cx.editor);
|
let (view, doc) = current!(cx.editor);
|
||||||
|
@ -4010,8 +4053,19 @@ pub mod insert {
|
||||||
.selection(view.id)
|
.selection(view.id)
|
||||||
.clone()
|
.clone()
|
||||||
.transform(|range| movement::move_prev_word_start(text, range, count));
|
.transform(|range| movement::move_prev_word_start(text, range, count));
|
||||||
doc.set_selection(view.id, selection);
|
delete_selection_insert_mode(doc, view, &selection);
|
||||||
delete_selection(cx)
|
}
|
||||||
|
|
||||||
|
pub fn delete_word_forward(cx: &mut Context) {
|
||||||
|
let count = cx.count();
|
||||||
|
let (view, doc) = current!(cx.editor);
|
||||||
|
let text = doc.text().slice(..);
|
||||||
|
|
||||||
|
let selection = doc
|
||||||
|
.selection(view.id)
|
||||||
|
.clone()
|
||||||
|
.transform(|range| movement::move_next_word_start(text, range, count));
|
||||||
|
delete_selection_insert_mode(doc, view, &selection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4973,6 +5027,15 @@ fn select_register(cx: &mut Context) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn insert_register(cx: &mut Context) {
|
||||||
|
cx.on_next_key(move |cx, event| {
|
||||||
|
if let Some(ch) = event.char() {
|
||||||
|
cx.editor.selected_register = Some(ch);
|
||||||
|
paste_before(cx);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn align_view_top(cx: &mut Context) {
|
fn align_view_top(cx: &mut Context) {
|
||||||
let (view, doc) = current!(cx.editor);
|
let (view, doc) = current!(cx.editor);
|
||||||
align_view(doc, view, Align::Top);
|
align_view(doc, view, Align::Top);
|
||||||
|
|
|
@ -731,21 +731,38 @@ impl Default for Keymaps {
|
||||||
"esc" => normal_mode,
|
"esc" => normal_mode,
|
||||||
|
|
||||||
"backspace" => delete_char_backward,
|
"backspace" => delete_char_backward,
|
||||||
|
"C-h" => delete_char_backward,
|
||||||
"del" => delete_char_forward,
|
"del" => delete_char_forward,
|
||||||
|
"C-d" => delete_char_forward,
|
||||||
"ret" => insert_newline,
|
"ret" => insert_newline,
|
||||||
"tab" => insert_tab,
|
"tab" => insert_tab,
|
||||||
"C-w" => delete_word_backward,
|
"C-w" => delete_word_backward,
|
||||||
|
"A-d" => delete_word_forward,
|
||||||
|
|
||||||
"left" => move_char_left,
|
"left" => move_char_left,
|
||||||
|
"C-b" => move_char_left,
|
||||||
"down" => move_line_down,
|
"down" => move_line_down,
|
||||||
|
"C-n" => move_line_down,
|
||||||
"up" => move_line_up,
|
"up" => move_line_up,
|
||||||
|
"C-p" => move_line_up,
|
||||||
"right" => move_char_right,
|
"right" => move_char_right,
|
||||||
|
"C-f" => move_char_right,
|
||||||
|
"A-b" => move_prev_word_end,
|
||||||
|
"A-left" => move_prev_word_end,
|
||||||
|
"A-f" => move_next_word_start,
|
||||||
|
"A-right" => move_next_word_start,
|
||||||
"pageup" => page_up,
|
"pageup" => page_up,
|
||||||
"pagedown" => page_down,
|
"pagedown" => page_down,
|
||||||
"home" => goto_line_start,
|
"home" => goto_line_start,
|
||||||
|
"C-a" => goto_line_start,
|
||||||
"end" => goto_line_end_newline,
|
"end" => goto_line_end_newline,
|
||||||
|
"C-e" => goto_line_end_newline,
|
||||||
|
|
||||||
|
"C-k" => kill_to_line_end,
|
||||||
|
"C-u" => kill_to_line_start,
|
||||||
|
|
||||||
"C-x" => completion,
|
"C-x" => completion,
|
||||||
|
"C-r" => insert_register,
|
||||||
});
|
});
|
||||||
Keymaps(hashmap!(
|
Keymaps(hashmap!(
|
||||||
Mode::Normal => Keymap::new(normal),
|
Mode::Normal => Keymap::new(normal),
|
||||||
|
|
|
@ -231,6 +231,14 @@ impl Prompt {
|
||||||
self.completion = (self.completion_fn)(&self.line);
|
self.completion = (self.completion_fn)(&self.line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn delete_word_forwards(&mut self) {
|
||||||
|
let pos = self.eval_movement(Movement::ForwardWord(1));
|
||||||
|
self.line.replace_range(self.cursor..pos, "");
|
||||||
|
|
||||||
|
self.exit_selection();
|
||||||
|
self.completion = (self.completion_fn)(&self.line);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn kill_to_start_of_line(&mut self) {
|
pub fn kill_to_start_of_line(&mut self) {
|
||||||
let pos = self.eval_movement(Movement::StartOfLine);
|
let pos = self.eval_movement(Movement::StartOfLine);
|
||||||
self.line.replace_range(pos..self.cursor, "");
|
self.line.replace_range(pos..self.cursor, "");
|
||||||
|
@ -435,6 +443,7 @@ impl Component for Prompt {
|
||||||
ctrl!('e') | key!(End) => self.move_end(),
|
ctrl!('e') | key!(End) => self.move_end(),
|
||||||
ctrl!('a') | key!(Home) => self.move_start(),
|
ctrl!('a') | key!(Home) => self.move_start(),
|
||||||
ctrl!('w') => self.delete_word_backwards(),
|
ctrl!('w') => self.delete_word_backwards(),
|
||||||
|
alt!('d') => self.delete_word_forwards(),
|
||||||
ctrl!('k') => self.kill_to_end_of_line(),
|
ctrl!('k') => self.kill_to_end_of_line(),
|
||||||
ctrl!('u') => self.kill_to_start_of_line(),
|
ctrl!('u') => self.kill_to_start_of_line(),
|
||||||
ctrl!('h') | key!(Backspace) => {
|
ctrl!('h') | key!(Backspace) => {
|
||||||
|
|
Loading…
Add table
Reference in a new issue