add clipboard

This commit is contained in:
Crispy 2023-03-01 22:16:10 +01:00
parent 59b45f57c3
commit 5ece5b7198
3 changed files with 98 additions and 8 deletions

42
src/clipboard.rs Normal file
View file

@ -0,0 +1,42 @@
use std::{cell::RefCell, rc::Rc};
#[derive(Clone)]
pub struct Clipboard {
clipboard: Rc<RefCell<Internal>>,
}
impl Clipboard {
pub fn new() -> Self {
Self {
clipboard: Rc::new(RefCell::new(Internal::new())),
}
}
pub fn get(&self) -> String {
self.clipboard.borrow().get().to_owned()
}
pub fn set(&mut self, text: String) {
self.clipboard.borrow_mut().set(text);
}
}
struct Internal {
contents: String,
}
impl Internal {
fn new() -> Self {
Self {
contents: String::new(),
}
}
fn get(&self) -> &str {
&self.contents
}
fn set(&mut self, text: String) {
self.contents = text;
}
}

View file

@ -11,6 +11,7 @@ use termion::{
terminal_size,
};
use crate::clipboard::Clipboard;
use crate::util::read_line;
const TAB_SIZE: usize = 4;
@ -21,6 +22,7 @@ pub struct Editor {
scroll: usize,
cursor: Cursor,
marker: Option<usize>,
clipboard: Clipboard,
path: Option<String>,
active: bool,
}
@ -35,7 +37,7 @@ struct Cursor {
type Line = Range<usize>;
impl Editor {
pub fn new(path: String) -> Self {
pub fn new(clipboard: Clipboard, path: String) -> Self {
let text = fs::read_to_string(&path).unwrap_or_default();
let mut this = Editor {
text,
@ -43,6 +45,7 @@ impl Editor {
scroll: 0,
cursor: Cursor { line: 0, column: 0 },
marker: None,
clipboard,
path: Some(path),
active: false,
};
@ -50,13 +53,14 @@ impl Editor {
this
}
pub fn new_empty() -> Self {
pub fn new_empty(clipboard: Clipboard) -> Self {
Editor {
text: String::new(),
lines: vec![0..0],
scroll: 0,
cursor: Cursor { line: 0, column: 0 },
marker: None,
clipboard,
path: None,
active: false,
}
@ -91,6 +95,9 @@ impl Editor {
Key::End => self.move_end(),
Key::Ctrl('s') => self.save(),
Key::Ctrl('p') => self.toggle_marker(),
Key::Ctrl('c') => self.copy(),
Key::Ctrl('x') => self.cut(),
Key::Ctrl('v') => self.paste(),
_ => (),
}
}
@ -129,7 +136,7 @@ impl Editor {
if char == '\t' {
print!("{:1$}", " ", TAB_SIZE);
} else {
print!("{}", char);
print!("{char}");
}
}
color_reset();
@ -272,6 +279,38 @@ impl Editor {
}
}
fn copy(&mut self) {
let cursor = self.char_index();
let range = if let Some(marker) = self.marker {
marker.min(cursor)..marker.max(cursor)
} else {
self.current_line().clone()
};
let text = self.text[range].to_owned();
self.clipboard.set(text);
}
fn cut(&mut self) {
let cursor = self.char_index();
let range = if let Some(marker) = self.marker {
marker.min(cursor)..marker.max(cursor)
} else {
self.current_line().clone()
};
let text = self.text[range.clone()].to_owned();
self.clipboard.set(text);
self.text = self.text[..range.start].to_owned() + &self.text[range.end..];
self.find_lines();
self.marker = None;
}
fn paste(&mut self) {
let cursor = self.char_index();
self.text.insert_str(cursor, &self.clipboard.get());
self.find_lines();
// TODO move cursor to end
}
/// Byte position of current character. May be text.len if cursor is at the end of the file
fn char_index(&self) -> usize {
self.current_line().start + self.cursor.column

View file

@ -11,8 +11,10 @@ use termion::{
raw::{IntoRawMode, RawTerminal},
};
mod clipboard;
mod editor;
mod util;
use clipboard::Clipboard;
use editor::Editor;
fn main() {
@ -22,18 +24,25 @@ fn main() {
struct Navigator {
editors: Vec<Editor>,
selected: Option<usize>,
path: String,
clipboard: Clipboard,
_term: RawTerminal<Stdout>,
}
impl Navigator {
fn new() -> Self {
let term = stdout().into_raw_mode().unwrap();
let editors = env::args().skip(1).map(Editor::new).collect();
let clipboard = Clipboard::new();
let mut editors: Vec<Editor> = env::args()
.skip(1)
.map(|path| Editor::new(clipboard.clone(), path))
.collect();
if editors.is_empty() {
editors.push(Editor::new_empty(clipboard.clone()));
}
Self {
editors,
selected: Some(0),
path: String::new(),
clipboard,
_term: term,
}
}
@ -72,7 +81,7 @@ impl Navigator {
for event in stdin().events().take(1).flatten() {
if let Event::Key(key) = event {
match key {
Key::Esc => self.quit(),
Key::Char('q') => self.quit(),
Key::Char('\n') => self.open_selected(),
Key::Ctrl('n') => self.new_editor(),
Key::Up => self.nav_up(),
@ -105,7 +114,7 @@ impl Navigator {
fn new_editor(&mut self) {
self.selected = Some(self.editors.len());
self.editors.push(Editor::new_empty());
self.editors.push(Editor::new_empty(self.clipboard.clone()));
self.open_selected();
}