Select new pasted text in normal mode only (#4824)

d6323b7cbc changed the behavior of paste
to select the newly inserted text. This is preferrable in normal mode
because it's useful to be able to act on the new text. This behavior
is worse for insert or select mode though:

* In insert mode, the cursor ends up on the last character of the newly
  selected text, so further typing inserts text before the last
  character.
* In select mode, the current selection is replaced with the new text
  selection which doesn't extend the current selection. With this
  change, the selection is extended to include the new text.

This aligns the behavior more closely with Kakoune, but it's
coincidental instead of intentional: Kakoune doesn't implement
bracketed paste (AFAIK) which causes this behavior in insert mode,
and Kakoune doesn't have a select mode.
pull/4834/head
Michael Davis 2 years ago committed by GitHub
parent 2f9ca3840a
commit bbde897ac3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -3467,7 +3467,14 @@ enum Paste {
Cursor, Cursor,
} }
fn paste_impl(values: &[String], doc: &mut Document, view: &mut View, action: Paste, count: usize) { fn paste_impl(
values: &[String],
doc: &mut Document,
view: &mut View,
action: Paste,
count: usize,
mode: Mode,
) {
if values.is_empty() { if values.is_empty() {
return; return;
} }
@ -3499,7 +3506,7 @@ fn paste_impl(values: &[String], doc: &mut Document, view: &mut View, action: Pa
let mut offset = 0; let mut offset = 0;
let mut ranges = SmallVec::with_capacity(selection.len()); let mut ranges = SmallVec::with_capacity(selection.len());
let transaction = Transaction::change_by_selection(text, selection, |range| { let mut transaction = Transaction::change_by_selection(text, selection, |range| {
let pos = match (action, linewise) { let pos = match (action, linewise) {
// paste linewise before // paste linewise before
(Paste::Before, true) => text.line_to_char(text.char_to_line(range.from())), (Paste::Before, true) => text.line_to_char(text.char_to_line(range.from())),
@ -3531,7 +3538,9 @@ fn paste_impl(values: &[String], doc: &mut Document, view: &mut View, action: Pa
(pos, pos, value) (pos, pos, value)
}); });
let transaction = transaction.with_selection(Selection::new(ranges, selection.primary_index())); if mode == Mode::Normal {
transaction = transaction.with_selection(Selection::new(ranges, selection.primary_index()));
}
apply_transaction(&transaction, doc, view); apply_transaction(&transaction, doc, view);
} }
@ -3543,7 +3552,7 @@ pub(crate) fn paste_bracketed_value(cx: &mut Context, contents: String) {
Mode::Normal => Paste::Before, Mode::Normal => Paste::Before,
}; };
let (view, doc) = current!(cx.editor); let (view, doc) = current!(cx.editor);
paste_impl(&[contents], doc, view, paste, count); paste_impl(&[contents], doc, view, paste, count, cx.editor.mode);
} }
fn paste_clipboard_impl( fn paste_clipboard_impl(
@ -3555,7 +3564,7 @@ fn paste_clipboard_impl(
let (view, doc) = current!(editor); let (view, doc) = current!(editor);
match editor.clipboard_provider.get_contents(clipboard_type) { match editor.clipboard_provider.get_contents(clipboard_type) {
Ok(contents) => { Ok(contents) => {
paste_impl(&[contents], doc, view, action, count); paste_impl(&[contents], doc, view, action, count, editor.mode);
Ok(()) Ok(())
} }
Err(e) => Err(e.context("Couldn't get system clipboard contents")), Err(e) => Err(e.context("Couldn't get system clipboard contents")),
@ -3674,7 +3683,7 @@ fn paste(cx: &mut Context, pos: Paste) {
let registers = &mut cx.editor.registers; let registers = &mut cx.editor.registers;
if let Some(values) = registers.read(reg_name) { if let Some(values) = registers.read(reg_name) {
paste_impl(values, doc, view, pos, count); paste_impl(values, doc, view, pos, count, cx.editor.mode);
} }
} }

Loading…
Cancel
Save