add clipboard
This commit is contained in:
parent
59b45f57c3
commit
5ece5b7198
3 changed files with 98 additions and 8 deletions
42
src/clipboard.rs
Normal file
42
src/clipboard.rs
Normal 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;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
19
src/main.rs
19
src/main.rs
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue