clean up selection & fix crash when copying last line

This commit is contained in:
Crispy 2023-03-04 13:20:24 +01:00
parent 2d49302d0a
commit f41c23bbf8
2 changed files with 30 additions and 31 deletions

View file

@ -12,8 +12,8 @@ use std::{
vec, vec,
}; };
use crate::clipboard::Clipboard;
use crate::util::read_line; use crate::util::read_line;
use crate::{clipboard::Clipboard, util::RangeConverter};
const TAB_SIZE: usize = 4; const TAB_SIZE: usize = 4;
@ -328,30 +328,41 @@ impl Editor {
} }
} }
fn copy(&mut self) { fn selection(&self) -> Option<Range<usize>> {
let cursor = self.char_index(); let cursor = self.char_index();
let range = if let Some(marker) = self.marker { if let Some(marker) = self.marker {
marker.min(cursor)..(marker.max(cursor) + 1) Some(marker.min(cursor)..(marker.max(cursor)))
} else { } else {
self.current_line().as_inclusive() None
}; }
let text = self.text[range].to_owned(); }
fn selection_or_line(&self) -> Range<usize> {
self.selection().unwrap_or(self.current_line().clone())
}
fn copy(&mut self) {
let range = self.selection_or_line();
let mut text = self.text[range].to_owned();
if self.marker.is_none() {
text += "\n";
}
self.clipboard.set(text); self.clipboard.set(text);
self.marker = None;
} }
fn cut(&mut self) { fn cut(&mut self) {
let cursor = self.char_index(); let range = self.selection_or_line();
let range = if let Some(marker) = self.marker { let start = range.start;
marker.min(cursor)..(marker.max(cursor) + 1) let mut end = range.end;
} else { let mut text = self.text[range].to_owned();
self.current_line().as_inclusive() if self.marker.is_none() {
}; text += "\n";
let text = self.text[range.clone()].to_owned(); end += 1;
}
self.clipboard.set(text); self.clipboard.set(text);
self.text = self.text[..range.start].to_owned() + &self.text[range.end..]; self.text = self.text[..start].to_owned() + &self.text[end..];
self.find_lines(); self.find_lines();
self.move_to_byte(range.start); self.move_to_byte(start);
self.marker = None; self.marker = None;
} }
@ -363,6 +374,7 @@ impl Editor {
self.text.insert_str(cursor, &new_text); self.text.insert_str(cursor, &new_text);
self.find_lines(); self.find_lines();
self.move_to_byte(end_pos); self.move_to_byte(end_pos);
self.marker = None;
} }
/// Byte position of current character. May be text.len if cursor is at the end of the file /// Byte position of current character. May be text.len if cursor is at the end of the file

View file

@ -3,10 +3,7 @@ use crossterm::{
event::{self, Event, KeyCode}, event::{self, Event, KeyCode},
queue, terminal, queue, terminal,
}; };
use std::{ use std::io::{stdout, Write};
io::{stdout, Write},
ops::Range,
};
pub fn read_line(prompt: &str) -> Option<String> { pub fn read_line(prompt: &str) -> Option<String> {
let mut response = String::new(); let mut response = String::new();
@ -35,13 +32,3 @@ pub fn read_line(prompt: &str) -> Option<String> {
} }
Some(response.trim().into()) Some(response.trim().into())
} }
pub trait RangeConverter {
fn as_inclusive(&self) -> Range<usize>;
}
impl RangeConverter for Range<usize> {
fn as_inclusive(&self) -> Range<usize> {
self.start..(self.end + 1)
}
}