fix clipboard issues and edge cases

This commit is contained in:
Crispy 2023-03-03 23:38:33 +01:00
parent 1b3dc37623
commit f3f1c4de94
2 changed files with 34 additions and 8 deletions

View file

@ -11,8 +11,8 @@ use termion::{
terminal_size, terminal_size,
}; };
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;
@ -228,6 +228,15 @@ impl Editor {
self.ensure_char_boundary(); self.ensure_char_boundary();
} }
fn move_to_byte(&mut self, pos: usize) {
for (line_index, line) in self.lines.iter().enumerate() {
if (line.start..=line.end).contains(&pos) {
self.cursor.line = line_index;
self.cursor.column = pos - line.start;
}
}
}
fn toggle_marker(&mut self) { fn toggle_marker(&mut self) {
if self.marker.is_some() { if self.marker.is_some() {
self.marker = None; self.marker = None;
@ -290,34 +299,38 @@ impl Editor {
fn copy(&mut self) { fn copy(&mut self) {
let cursor = self.char_index(); let cursor = self.char_index();
let range = if let Some(marker) = self.marker { let range = if let Some(marker) = self.marker {
marker.min(cursor)..marker.max(cursor) marker.min(cursor)..(marker.max(cursor) + 1)
} else { } else {
self.current_line().clone() self.current_line().as_inclusive()
}; };
let text = self.text[range].to_owned(); let text = self.text[range].to_owned();
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 cursor = self.char_index();
let range = if let Some(marker) = self.marker { let range = if let Some(marker) = self.marker {
marker.min(cursor)..marker.max(cursor) marker.min(cursor)..(marker.max(cursor) + 1)
} else { } else {
self.current_line().clone() self.current_line().as_inclusive()
}; };
let text = self.text[range.clone()].to_owned(); let text = self.text[range.clone()].to_owned();
self.clipboard.set(text); self.clipboard.set(text);
self.text = self.text[..range.start].to_owned() + &self.text[range.end..]; self.text = self.text[..range.start].to_owned() + &self.text[range.end..];
self.find_lines(); self.find_lines();
self.move_to_byte(range.start);
self.marker = None; self.marker = None;
} }
fn paste(&mut self) { fn paste(&mut self) {
self.unsaved_changes = true; self.unsaved_changes = true;
let cursor = self.char_index(); let cursor = self.char_index();
self.text.insert_str(cursor, &self.clipboard.get()); let new_text = self.clipboard.get();
let end_pos = cursor + new_text.len();
self.text.insert_str(cursor, &new_text);
self.find_lines(); self.find_lines();
// TODO move cursor to end self.move_to_byte(end_pos);
} }
/// 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

@ -1,4 +1,7 @@
use std::io::{stdin, stdout, Write}; use std::{
io::{stdin, stdout, Write},
ops::Range,
};
use termion::{ use termion::{
cursor, cursor,
event::{Event, Key}, event::{Event, Key},
@ -33,3 +36,13 @@ 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)
}
}