Global clipboard with local fallback
This commit is contained in:
parent
35c5f0816b
commit
71a0a89f5f
5 changed files with 65 additions and 20 deletions
39
src/state.rs
39
src/state.rs
|
|
@ -733,14 +733,12 @@ impl Buffer {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn copy(&mut self, cursor_id: CursorId) -> bool {
|
||||
pub fn copy(&mut self, clipboard: &mut Clipboard, 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()
|
||||
&& clipboard.set(text.iter().copied().collect()).is_ok()
|
||||
{
|
||||
true
|
||||
} else {
|
||||
|
|
@ -748,8 +746,8 @@ impl Buffer {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn cut(&mut self, cursor_id: CursorId) -> bool {
|
||||
if self.copy(cursor_id) {
|
||||
pub fn cut(&mut self, clipboard: &mut Clipboard, cursor_id: CursorId) -> bool {
|
||||
if self.copy(clipboard, cursor_id) {
|
||||
self.backspace(cursor_id);
|
||||
true
|
||||
} else {
|
||||
|
|
@ -757,8 +755,8 @@ impl Buffer {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn paste(&mut self, cursor_id: CursorId) -> bool {
|
||||
if let Ok(s) = ClipboardContext::new().and_then(|mut ctx| ctx.get_contents()) {
|
||||
pub fn paste(&mut self, clipboard: &mut Clipboard, cursor_id: CursorId) -> bool {
|
||||
if let Ok(s) = clipboard.get() {
|
||||
self.enter(cursor_id, s.chars());
|
||||
true
|
||||
} else {
|
||||
|
|
@ -895,11 +893,33 @@ fn classify(c: char) -> Option<u8> {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct Clipboard {
|
||||
// If a global clipboard cannot be established, use a local clipboard instead
|
||||
ctx: Result<ClipboardContext, String>,
|
||||
}
|
||||
|
||||
impl Clipboard {
|
||||
fn get(&mut self) -> Result<String, ()> {
|
||||
match &mut self.ctx {
|
||||
Ok(ctx) => ctx.get_contents().map_err(|_| ()),
|
||||
Err(contents) => Ok(contents.clone()),
|
||||
}
|
||||
}
|
||||
|
||||
fn set(&mut self, text: String) -> Result<(), ()> {
|
||||
match &mut self.ctx {
|
||||
Ok(ctx) => ctx.set_contents(text).map_err(|_| ()),
|
||||
Err(contents) => Ok(*contents = text),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct State {
|
||||
pub buffers: HopSlotMap<BufferId, Buffer>,
|
||||
pub tick: u64,
|
||||
pub theme: theme::Theme,
|
||||
pub most_recent_counter: usize,
|
||||
pub clipboard: Clipboard,
|
||||
}
|
||||
|
||||
impl TryFrom<Args> for State {
|
||||
|
|
@ -910,6 +930,9 @@ impl TryFrom<Args> for State {
|
|||
tick: 0,
|
||||
theme: theme::Theme::default(),
|
||||
most_recent_counter: 0,
|
||||
clipboard: Clipboard {
|
||||
ctx: ClipboardContext::new().map_err(|_| String::new()),
|
||||
},
|
||||
};
|
||||
|
||||
if args.paths.is_empty() {
|
||||
|
|
|
|||
|
|
@ -153,7 +153,8 @@ impl Element for Doc {
|
|||
let Some(buffer) = state.buffers.get_mut(self.buffer) else {
|
||||
return Err(event);
|
||||
};
|
||||
self.input.handle(buffer, cursor_id, event)
|
||||
self.input
|
||||
.handle(&mut state.clipboard, buffer, cursor_id, event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -326,7 +327,12 @@ impl Finder {
|
|||
}
|
||||
_ => self
|
||||
.input
|
||||
.handle(&mut self.buffer, self.cursor_id, event)
|
||||
.handle(
|
||||
&mut state.clipboard,
|
||||
&mut self.buffer,
|
||||
self.cursor_id,
|
||||
event,
|
||||
)
|
||||
.map(Resp::into_can_end),
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use super::*;
|
||||
use crate::{
|
||||
state::{Buffer, CursorId},
|
||||
state::{Buffer, Clipboard, CursorId},
|
||||
terminal::CursorStyle,
|
||||
};
|
||||
|
||||
|
|
@ -56,6 +56,7 @@ impl Input {
|
|||
|
||||
pub fn handle(
|
||||
&mut self,
|
||||
clipboard: &mut Clipboard,
|
||||
buffer: &mut Buffer,
|
||||
cursor_id: CursorId,
|
||||
event: Event,
|
||||
|
|
@ -191,7 +192,7 @@ impl Input {
|
|||
}
|
||||
}
|
||||
Some(Action::Copy) => {
|
||||
if buffer.copy(cursor_id) {
|
||||
if buffer.copy(clipboard, cursor_id) {
|
||||
self.refocus(buffer, cursor_id);
|
||||
Ok(Resp::handled(None))
|
||||
} else {
|
||||
|
|
@ -199,7 +200,7 @@ impl Input {
|
|||
}
|
||||
}
|
||||
Some(Action::Cut) => {
|
||||
if buffer.cut(cursor_id) {
|
||||
if buffer.cut(clipboard, cursor_id) {
|
||||
self.refocus(buffer, cursor_id);
|
||||
Ok(Resp::handled(None))
|
||||
} else {
|
||||
|
|
@ -207,7 +208,7 @@ impl Input {
|
|||
}
|
||||
}
|
||||
Some(Action::Paste) => {
|
||||
if buffer.paste(cursor_id) {
|
||||
if buffer.paste(clipboard, cursor_id) {
|
||||
self.refocus(buffer, cursor_id);
|
||||
Ok(Resp::handled(None))
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -88,7 +88,12 @@ impl Element<()> for Prompt {
|
|||
},
|
||||
_ => self
|
||||
.input
|
||||
.handle(&mut self.buffer, self.cursor_id, event)
|
||||
.handle(
|
||||
&mut state.clipboard,
|
||||
&mut self.buffer,
|
||||
self.cursor_id,
|
||||
event,
|
||||
)
|
||||
.map(Resp::into_can_end),
|
||||
}
|
||||
}
|
||||
|
|
@ -231,7 +236,12 @@ impl Element<()> for Switcher {
|
|||
Err(event) => {
|
||||
let res = self
|
||||
.input
|
||||
.handle(&mut self.buffer, self.cursor_id, event)
|
||||
.handle(
|
||||
&mut state.clipboard,
|
||||
&mut self.buffer,
|
||||
self.cursor_id,
|
||||
event,
|
||||
)
|
||||
.map(Resp::into_can_end);
|
||||
// Score entries
|
||||
let filter = self.buffer.text.to_string();
|
||||
|
|
@ -416,12 +426,12 @@ impl Element<()> for Opener {
|
|||
Err(event) => {
|
||||
let res = match self
|
||||
.input
|
||||
.handle(&mut self.buffer, self.cursor_id, event)
|
||||
.handle(&mut state.clipboard, &mut self.buffer, self.cursor_id, event)
|
||||
.map(Resp::into_can_end)
|
||||
{
|
||||
Ok(x) => Ok(x),
|
||||
Err(event) => if let Some((buffer, cursor_id, input)) = &mut self.preview {
|
||||
input.handle(buffer, *cursor_id, event).map(Resp::into_can_end)
|
||||
input.handle(&mut state.clipboard, buffer, *cursor_id, event).map(Resp::into_can_end)
|
||||
} else {
|
||||
Err(event)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -130,14 +130,19 @@ impl Element<()> for Searcher {
|
|||
Err(event) => {
|
||||
let res = match self
|
||||
.input
|
||||
.handle(&mut self.buffer, self.cursor_id, event)
|
||||
.handle(
|
||||
&mut state.clipboard,
|
||||
&mut self.buffer,
|
||||
self.cursor_id,
|
||||
event,
|
||||
)
|
||||
.map(Resp::into_can_end)
|
||||
{
|
||||
Ok(x) => Ok(x),
|
||||
Err(event) => {
|
||||
if let Some((buffer, cursor_id, input, _)) = &mut self.preview {
|
||||
input
|
||||
.handle(buffer, *cursor_id, event)
|
||||
.handle(&mut state.clipboard, buffer, *cursor_id, event)
|
||||
.map(Resp::into_can_end)
|
||||
} else {
|
||||
Err(event)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue