Added basic clipboard support
This commit is contained in:
parent
c5e61823f8
commit
cec0ae50e5
5 changed files with 168 additions and 2 deletions
86
Cargo.lock
generated
86
Cargo.lock
generated
|
|
@ -83,6 +83,12 @@ version = "2.4.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
|
checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "block"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.2.27"
|
version = "1.2.27"
|
||||||
|
|
@ -152,6 +158,28 @@ version = "0.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1"
|
checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clipboard"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "25a904646c0340239dcf7c51677b33928bf24fdf424b79a57909c0109075b2e7"
|
||||||
|
dependencies = [
|
||||||
|
"clipboard-win",
|
||||||
|
"objc",
|
||||||
|
"objc-foundation",
|
||||||
|
"objc_id",
|
||||||
|
"x11-clipboard",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clipboard-win"
|
||||||
|
version = "2.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e3a093d6fed558e5fe24c3dfc85a68bb68f1c824f440d3ba5aca189e2998786b"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "colorchoice"
|
name = "colorchoice"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
|
|
@ -234,6 +262,15 @@ version = "0.4.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "malloc_buf"
|
||||||
|
version = "0.0.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.7.5"
|
version = "2.7.5"
|
||||||
|
|
@ -252,6 +289,35 @@ dependencies = [
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "objc"
|
||||||
|
version = "0.2.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
|
||||||
|
dependencies = [
|
||||||
|
"malloc_buf",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "objc-foundation"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9"
|
||||||
|
dependencies = [
|
||||||
|
"block",
|
||||||
|
"objc",
|
||||||
|
"objc_id",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "objc_id"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b"
|
||||||
|
dependencies = [
|
||||||
|
"objc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot"
|
name = "parking_lot"
|
||||||
version = "0.12.1"
|
version = "0.12.1"
|
||||||
|
|
@ -648,12 +714,32 @@ version = "0.52.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
|
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "x11-clipboard"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "89bd49c06c9eb5d98e6ba6536cf64ac9f7ee3a009b2f53996d405b3944f6bcea"
|
||||||
|
dependencies = [
|
||||||
|
"xcb",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "xcb"
|
||||||
|
version = "0.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5e917a3f24142e9ff8be2414e36c649d47d6cc2ba81f16201cdef96e533e02de"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"log",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zte"
|
name = "zte"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chumsky",
|
"chumsky",
|
||||||
"clap",
|
"clap",
|
||||||
|
"clipboard",
|
||||||
"crossterm",
|
"crossterm",
|
||||||
"slotmap",
|
"slotmap",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ crossterm = "0.27"
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
chumsky = { version = "0.10.1", features = ["pratt"] }
|
chumsky = { version = "0.10.1", features = ["pratt"] }
|
||||||
unicode-display-width = "0.3.0"
|
unicode-display-width = "0.3.0"
|
||||||
|
clipboard = "0.5.0"
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
opt-level = 2
|
opt-level = 2
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,9 @@ pub enum Action {
|
||||||
Mouse(MouseAction, [isize; 2], bool), // (action, pos, is_ctrl)
|
Mouse(MouseAction, [isize; 2], bool), // (action, pos, is_ctrl)
|
||||||
Undo,
|
Undo,
|
||||||
Redo,
|
Redo,
|
||||||
|
Copy,
|
||||||
|
Cut,
|
||||||
|
Paste,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// How far should movement go?
|
/// How far should movement go?
|
||||||
|
|
@ -429,7 +432,7 @@ impl RawEvent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_undo_redo(&self) -> Option<Action> {
|
pub fn to_edit(&self) -> Option<Action> {
|
||||||
match &self.0 {
|
match &self.0 {
|
||||||
TerminalEvent::Key(KeyEvent {
|
TerminalEvent::Key(KeyEvent {
|
||||||
code: KeyCode::Char('z'),
|
code: KeyCode::Char('z'),
|
||||||
|
|
@ -443,6 +446,24 @@ impl RawEvent {
|
||||||
kind: KeyEventKind::Press,
|
kind: KeyEventKind::Press,
|
||||||
..
|
..
|
||||||
}) => Some(Action::Redo),
|
}) => Some(Action::Redo),
|
||||||
|
TerminalEvent::Key(KeyEvent {
|
||||||
|
code: KeyCode::Char('c'),
|
||||||
|
modifiers: KeyModifiers::CONTROL,
|
||||||
|
kind: KeyEventKind::Press,
|
||||||
|
..
|
||||||
|
}) => Some(Action::Copy),
|
||||||
|
TerminalEvent::Key(KeyEvent {
|
||||||
|
code: KeyCode::Char('x'),
|
||||||
|
modifiers: KeyModifiers::CONTROL,
|
||||||
|
kind: KeyEventKind::Press,
|
||||||
|
..
|
||||||
|
}) => Some(Action::Cut),
|
||||||
|
TerminalEvent::Key(KeyEvent {
|
||||||
|
code: KeyCode::Char('v'),
|
||||||
|
modifiers: KeyModifiers::CONTROL,
|
||||||
|
kind: KeyEventKind::Press,
|
||||||
|
..
|
||||||
|
}) => Some(Action::Paste),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
34
src/state.rs
34
src/state.rs
|
|
@ -3,6 +3,7 @@ use crate::{
|
||||||
highlight::{Highlighter, Highlights},
|
highlight::{Highlighter, Highlights},
|
||||||
theme,
|
theme,
|
||||||
};
|
};
|
||||||
|
use clipboard::{ClipboardContext, ClipboardProvider};
|
||||||
use slotmap::{HopSlotMap, new_key_type};
|
use slotmap::{HopSlotMap, new_key_type};
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
|
|
@ -734,6 +735,39 @@ impl Buffer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn copy(&mut self, cursor_id: CursorId) -> bool {
|
||||||
|
let Some(cursor) = self.cursors.get(cursor_id) else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
if let Some(text) = cursor.selection().and_then(|s| self.text.chars().get(s))
|
||||||
|
&& ClipboardContext::new()
|
||||||
|
.and_then(|mut ctx| ctx.set_contents(text.iter().copied().collect()))
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cut(&mut self, cursor_id: CursorId) -> bool {
|
||||||
|
if self.copy(cursor_id) {
|
||||||
|
self.backspace(cursor_id);
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn paste(&mut self, cursor_id: CursorId) -> bool {
|
||||||
|
if let Ok(s) = ClipboardContext::new().and_then(|mut ctx| ctx.get_contents()) {
|
||||||
|
self.enter(cursor_id, s.chars());
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn start_session(&mut self) -> CursorId {
|
pub fn start_session(&mut self) -> CursorId {
|
||||||
self.cursors.insert(Cursor::default())
|
self.cursors.insert(Cursor::default())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ impl Input {
|
||||||
.or_else(|| e.to_select_all())
|
.or_else(|| e.to_select_all())
|
||||||
.or_else(|| e.to_indent())
|
.or_else(|| e.to_indent())
|
||||||
.or_else(|| e.to_mouse(self.last_area))
|
.or_else(|| e.to_mouse(self.last_area))
|
||||||
.or_else(|| e.to_undo_redo())
|
.or_else(|| e.to_edit())
|
||||||
}) {
|
}) {
|
||||||
Some(Action::Char(c)) => {
|
Some(Action::Char(c)) => {
|
||||||
if c == '\x08' {
|
if c == '\x08' {
|
||||||
|
|
@ -164,6 +164,30 @@ impl Input {
|
||||||
Ok(Resp::handled(Some(Event::Bell)))
|
Ok(Resp::handled(Some(Event::Bell)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some(Action::Copy) => {
|
||||||
|
if buffer.copy(cursor_id) {
|
||||||
|
self.refocus(buffer, cursor_id);
|
||||||
|
Ok(Resp::handled(None))
|
||||||
|
} else {
|
||||||
|
Ok(Resp::handled(Some(Event::Bell)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(Action::Cut) => {
|
||||||
|
if buffer.cut(cursor_id) {
|
||||||
|
self.refocus(buffer, cursor_id);
|
||||||
|
Ok(Resp::handled(None))
|
||||||
|
} else {
|
||||||
|
Ok(Resp::handled(Some(Event::Bell)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(Action::Paste) => {
|
||||||
|
if buffer.paste(cursor_id) {
|
||||||
|
self.refocus(buffer, cursor_id);
|
||||||
|
Ok(Resp::handled(None))
|
||||||
|
} else {
|
||||||
|
Ok(Resp::handled(Some(Event::Bell)))
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => Err(event),
|
_ => Err(event),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue