Clipboard graceful handling (#712)

* Gracefully handled lack of system clipboard

If the `system_clipboard` feature is enabled, but we failed to
initialize the `SystemClipboard`, default to `LocalClipboard` instead of
panicking.

* Remove `eprintln!()` when failing to access system clipboard
This commit is contained in:
Antoine Büsch 2024-01-23 20:25:28 +11:00 committed by GitHub
parent ede2defbfe
commit 7d08fc8d29
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 18 additions and 14 deletions

View File

@ -56,21 +56,26 @@ pub use system_clipboard::SystemClipboard;
#[cfg(feature = "system_clipboard")] #[cfg(feature = "system_clipboard")]
/// Helper to get a clipboard based on the `system_clipboard` feature flag: /// Helper to get a clipboard based on the `system_clipboard` feature flag:
/// ///
/// Enabled -> [`SystemClipboard`], which talks to the system /// Enabled -> [`SystemClipboard`], which talks to the system. If the system clipboard can't be
/// accessed, it will default to [`LocalClipboard`].
/// ///
/// Disabled -> [`LocalClipboard`], which supports cutting and pasting limited to the [`crate::Reedline`] instance /// Disabled -> [`LocalClipboard`], which supports cutting and pasting limited to the [`crate::Reedline`] instance
pub fn get_default_clipboard() -> SystemClipboard { pub fn get_default_clipboard() -> Box<dyn Clipboard> {
SystemClipboard::new() SystemClipboard::new().map_or_else(
|_e| Box::new(LocalClipboard::new()) as Box<dyn Clipboard>,
|cb| Box::new(cb),
)
} }
#[cfg(not(feature = "system_clipboard"))] #[cfg(not(feature = "system_clipboard"))]
/// Helper to get a clipboard based on the `system_clipboard` feature flag: /// Helper to get a clipboard based on the `system_clipboard` feature flag:
/// ///
/// Enabled -> `SystemClipboard`, which talks to the system /// Enabled -> `SystemClipboard`, which talks to the system. If the system clipboard can't be
/// accessed, it will default to [`LocalClipboard`].
/// ///
/// Disabled -> [`LocalClipboard`], which supports cutting and pasting limited to the [`crate::Reedline`] instance /// Disabled -> [`LocalClipboard`], which supports cutting and pasting limited to the [`crate::Reedline`] instance
pub fn get_default_clipboard() -> LocalClipboard { pub fn get_default_clipboard() -> Box<dyn Clipboard> {
LocalClipboard::new() Box::new(LocalClipboard::new())
} }
#[cfg(feature = "system_clipboard")] #[cfg(feature = "system_clipboard")]
@ -78,7 +83,7 @@ mod system_clipboard {
use super::*; use super::*;
use arboard::Clipboard as Arboard; use arboard::Clipboard as Arboard;
/// Wrapper around [`clipboard`](https://docs.rs/clipboard) crate /// Wrapper around [`arboard`](https://docs.rs/arboard) crate
/// ///
/// Requires that the feature `system_clipboard` is enabled /// Requires that the feature `system_clipboard` is enabled
pub struct SystemClipboard { pub struct SystemClipboard {
@ -88,13 +93,12 @@ mod system_clipboard {
} }
impl SystemClipboard { impl SystemClipboard {
pub fn new() -> Self { pub fn new() -> Result<Self, arboard::Error> {
let cb = Arboard::new().unwrap(); Ok(SystemClipboard {
SystemClipboard { cb: Arboard::new()?,
cb,
local_copy: String::new(), local_copy: String::new(),
mode: ClipboardMode::Normal, mode: ClipboardMode::Normal,
} })
} }
} }
@ -120,7 +124,7 @@ mod system_clipboard {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::{get_default_clipboard, Clipboard, ClipboardMode}; use super::{get_default_clipboard, ClipboardMode};
#[test] #[test]
fn reads_back() { fn reads_back() {
let mut cb = get_default_clipboard(); let mut cb = get_default_clipboard();

View File

@ -18,7 +18,7 @@ impl Default for Editor {
fn default() -> Self { fn default() -> Self {
Editor { Editor {
line_buffer: LineBuffer::new(), line_buffer: LineBuffer::new(),
cut_buffer: Box::new(get_default_clipboard()), cut_buffer: get_default_clipboard(),
edit_stack: EditStack::new(), edit_stack: EditStack::new(),
last_undo_behavior: UndoBehavior::CreateUndoPoint, last_undo_behavior: UndoBehavior::CreateUndoPoint,
selection_anchor: None, selection_anchor: None,