visual mode deletions now properly yank deleted text into the selected register

This commit is contained in:
2026-02-20 12:18:34 -05:00
parent 88c0945e47
commit 13cf5cf032

View File

@@ -15,7 +15,7 @@ use crate::{
error::ShResult, error::ShResult,
term::{Style, Styled}, term::{Style, Styled},
}, },
prelude::*, prelude::*, prompt::readline::register::write_register,
}; };
const PUNCTUATION: [&str; 3] = ["?", "!", "."]; const PUNCTUATION: [&str; 3] = ["?", "!", "."];
@@ -562,9 +562,9 @@ impl LineBuf {
self.buffer.remove(idx); self.buffer.remove(idx);
self.update_graphemes(); self.update_graphemes();
} }
pub fn drain(&mut self, start: usize, end: usize) -> String { pub fn drain(&mut self, range: Range<usize>) -> String {
let start = start.max(0); let start = range.start.max(0);
let end = end.min(self.grapheme_indices().len()); let end = range.end.min(self.grapheme_indices().len());
let drained = if end == self.grapheme_indices().len() { let drained = if end == self.grapheme_indices().len() {
if start == self.grapheme_indices().len() { if start == self.grapheme_indices().len() {
return String::new(); return String::new();
@@ -579,6 +579,9 @@ impl LineBuf {
self.update_graphemes(); self.update_graphemes();
drained drained
} }
pub fn drain_inclusive(&mut self, range: RangeInclusive<usize>) -> String {
self.drain(*range.start()..range.end().saturating_add(1))
}
pub fn push(&mut self, ch: char) { pub fn push(&mut self, ch: char) {
self.buffer.push(ch); self.buffer.push(ch);
self.update_graphemes(); self.update_graphemes();
@@ -2389,7 +2392,7 @@ impl LineBuf {
.map(|c| c.to_string()) .map(|c| c.to_string())
.unwrap_or_default() .unwrap_or_default()
} else { } else {
let drained = self.drain(start, end); let drained = self.drain(start..end);
self.update_graphemes(); self.update_graphemes();
drained drained
}; };
@@ -2572,6 +2575,16 @@ impl LineBuf {
let Some(content) = register.read_from_register() else { let Some(content) = register.read_from_register() else {
return Ok(()); return Ok(());
}; };
if let Some(range) = self.select_range {
let register_text = self.drain_inclusive(range.0..=range.1);
write_register(None, register_text); // swap deleted text into register
self.insert_str_at(range.0, &content);
self.cursor.set(range.0 + content.chars().count());
self.select_range = None;
self.update_graphemes();
return Ok(());
}
let insert_idx = match anchor { let insert_idx = match anchor {
Anchor::After => self.cursor.ret_add(1), Anchor::After => self.cursor.ret_add(1),
Anchor::Before => self.cursor.get(), Anchor::Before => self.cursor.get(),