Revert "Remove our complex clipboard logic, use clipboard-ext crate instead"
This reverts commit 8bfe173a18
.
This commit is contained in:
parent
5b088610dd
commit
5f21b87937
7 changed files with 283 additions and 28 deletions
15
Cargo.lock
generated
15
Cargo.lock
generated
|
@ -253,17 +253,6 @@ dependencies = [
|
||||||
"x11-clipboard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"x11-clipboard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "clipboard-ext"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"clipboard 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"which 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"x11-clipboard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clipboard-win"
|
name = "clipboard-win"
|
||||||
version = "2.2.0"
|
version = "2.2.0"
|
||||||
|
@ -600,7 +589,7 @@ dependencies = [
|
||||||
"chbs 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"chbs 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"clipboard-ext 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"clipboard 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"colored 1.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"colored 1.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"derive_builder 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"derive_builder 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"directories 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"directories 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -623,6 +612,7 @@ dependencies = [
|
||||||
"toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"urlshortener 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"urlshortener 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"version-compare 0.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"version-compare 0.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"which 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2734,7 +2724,6 @@ dependencies = [
|
||||||
"checksum chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01"
|
"checksum chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01"
|
||||||
"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
|
"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
|
||||||
"checksum clipboard 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "25a904646c0340239dcf7c51677b33928bf24fdf424b79a57909c0109075b2e7"
|
"checksum clipboard 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "25a904646c0340239dcf7c51677b33928bf24fdf424b79a57909c0109075b2e7"
|
||||||
"checksum clipboard-ext 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2513f2e8ada5da8d9a368f764092cd35eeb4e0c2d56fc43948c2962645324b22"
|
|
||||||
"checksum clipboard-win 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e3a093d6fed558e5fe24c3dfc85a68bb68f1c824f440d3ba5aca189e2998786b"
|
"checksum clipboard-win 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e3a093d6fed558e5fe24c3dfc85a68bb68f1c824f440d3ba5aca189e2998786b"
|
||||||
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||||
"checksum colored 1.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8815e2ab78f3a59928fc32e141fbeece88320a240e43f47b2fd64ea3a88a5b3d"
|
"checksum colored 1.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8815e2ab78f3a59928fc32e141fbeece88320a240e43f47b2fd64ea3a88a5b3d"
|
||||||
|
|
17
Cargo.toml
17
Cargo.toml
|
@ -28,6 +28,7 @@ exclude = [
|
||||||
"/SECURITY.md",
|
"/SECURITY.md",
|
||||||
]
|
]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
build = "build.rs"
|
||||||
|
|
||||||
[package.metadata.deb]
|
[package.metadata.deb]
|
||||||
section = "utility"
|
section = "utility"
|
||||||
|
@ -71,7 +72,7 @@ default = [
|
||||||
archive = ["tar"]
|
archive = ["tar"]
|
||||||
|
|
||||||
# Support for putting share URLs in clipboard
|
# Support for putting share URLs in clipboard
|
||||||
clipboard = ["clipboard-ext"]
|
clipboard = ["clip", "which"]
|
||||||
|
|
||||||
# Compile with file history support
|
# Compile with file history support
|
||||||
history = []
|
history = []
|
||||||
|
@ -94,11 +95,16 @@ infer-command = []
|
||||||
# Compile without colored output support
|
# Compile without colored output support
|
||||||
no-color = ["colored/no-color"]
|
no-color = ["colored/no-color"]
|
||||||
|
|
||||||
|
# Automatic using build.rs: use xclip/xsel binary method for clipboard support
|
||||||
|
clipboard-bin = ["clipboard"]
|
||||||
|
|
||||||
|
# Automatic using build.rs: use native clipboard crate for clipboard support
|
||||||
|
clipboard-crate = ["clipboard"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
chbs = "0.0.9"
|
chbs = "0.0.9"
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
clap = "2.33"
|
clap = "2.33"
|
||||||
clipboard-ext = { version = "0.1", optional = true }
|
|
||||||
colored = "1.9"
|
colored = "1.9"
|
||||||
derive_builder = "0.9"
|
derive_builder = "0.9"
|
||||||
directories = "2.0"
|
directories = "2.0"
|
||||||
|
@ -121,3 +127,10 @@ tempfile = "3"
|
||||||
toml = "0.5"
|
toml = "0.5"
|
||||||
urlshortener = { version = "2", optional = true }
|
urlshortener = { version = "2", optional = true }
|
||||||
version-compare = "0.0.10"
|
version-compare = "0.0.10"
|
||||||
|
|
||||||
|
[target.'cfg(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd", target_os = "netbsd"))'.dependencies]
|
||||||
|
which = { version = "3.1", optional = true }
|
||||||
|
|
||||||
|
[target.'cfg(not(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd", target_os = "netbsd")))'.dependencies]
|
||||||
|
# Aliased to clip to prevent name collision with clipboard feature
|
||||||
|
clip = { version = "0.5", optional = true, package = "clipboard" }
|
||||||
|
|
|
@ -574,8 +574,8 @@ Some environment variables may be set at compile time to tweak some defaults.
|
||||||
|
|
||||||
| Variable | Description |
|
| Variable | Description |
|
||||||
| :----------- | :------------------------------------------------------------------------- |
|
| :----------- | :------------------------------------------------------------------------- |
|
||||||
| `XCLIP_PATH` | Set fixed `xclip` binary path when using `clipboard` (Linux, *BSD) |
|
| `XCLIP_PATH` | Set fixed `xclip` binary path when using `clipboard-bin` (Linux, *BSD) |
|
||||||
| `XSEL_PATH` | Set fixed `xsel` binary path when using `clipboard` (Linux, *BSD) |
|
| `XSEL_PATH` | Set fixed `xsel` binary path when using `clipboard-bin` (Linux, *BSD) |
|
||||||
|
|
||||||
At this time, no configuration or _dotfile_ file support is available.
|
At this time, no configuration or _dotfile_ file support is available.
|
||||||
This will be something added in a later release.
|
This will be something added in a later release.
|
||||||
|
|
37
build.rs
Normal file
37
build.rs
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
fn main() {
|
||||||
|
#[cfg(all(
|
||||||
|
feature = "clipboard",
|
||||||
|
any(
|
||||||
|
target_os = "linux",
|
||||||
|
target_os = "freebsd",
|
||||||
|
target_os = "dragonfly",
|
||||||
|
target_os = "openbsd",
|
||||||
|
target_os = "netbsd",
|
||||||
|
)
|
||||||
|
))]
|
||||||
|
{
|
||||||
|
// Select clipboard binary method
|
||||||
|
#[cfg(not(feature = "clipboard-crate"))]
|
||||||
|
println!("cargo:rustc-cfg=feature=\"clipboard-bin\"");
|
||||||
|
|
||||||
|
// xclip and xsel paths are inserted at compile time
|
||||||
|
println!("cargo:rerun-if-env-changed=XCLIP_PATH");
|
||||||
|
println!("cargo:rerun-if-env-changed=XSEL_PATH");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(all(
|
||||||
|
feature = "clipboard",
|
||||||
|
not(any(
|
||||||
|
target_os = "linux",
|
||||||
|
target_os = "freebsd",
|
||||||
|
target_os = "dragonfly",
|
||||||
|
target_os = "openbsd",
|
||||||
|
target_os = "netbsd",
|
||||||
|
))
|
||||||
|
))]
|
||||||
|
{
|
||||||
|
// Select clipboard crate method
|
||||||
|
#[cfg(not(feature = "clipboard-bin"))]
|
||||||
|
println!("cargo:rustc-cfg=feature=\"clipboard-crate\"");
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,8 @@ use prettytable::{format::FormatBuilder, Cell, Row, Table};
|
||||||
use crate::client::to_duration;
|
use crate::client::to_duration;
|
||||||
use crate::cmd::matcher::{debug::DebugMatcher, main::MainMatcher, Matcher};
|
use crate::cmd::matcher::{debug::DebugMatcher, main::MainMatcher, Matcher};
|
||||||
use crate::error::ActionError;
|
use crate::error::ActionError;
|
||||||
|
#[cfg(feature = "clipboard-bin")]
|
||||||
|
use crate::util::ClipboardType;
|
||||||
use crate::util::{api_version_list, features_list, format_bool, format_duration};
|
use crate::util::{api_version_list, features_list, format_bool, format_duration};
|
||||||
|
|
||||||
/// A file debug action.
|
/// A file debug action.
|
||||||
|
@ -96,6 +98,13 @@ impl<'a> Debug<'a> {
|
||||||
Cell::new(&api_version_list().join(", ")),
|
Cell::new(&api_version_list().join(", ")),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
|
// Clipboard information
|
||||||
|
#[cfg(feature = "clipboard-bin")]
|
||||||
|
table.add_row(Row::new(vec![
|
||||||
|
Cell::new("Clipboard:"),
|
||||||
|
Cell::new(&format!("{}", ClipboardType::select())),
|
||||||
|
]));
|
||||||
|
|
||||||
// Show whether quiet is used
|
// Show whether quiet is used
|
||||||
table.add_row(Row::new(vec![
|
table.add_row(Row::new(vec![
|
||||||
Cell::new("Quiet:"),
|
Cell::new("Quiet:"),
|
||||||
|
|
|
@ -444,10 +444,9 @@ impl<'a> Upload<'a> {
|
||||||
{
|
{
|
||||||
if let Some(copy_mode) = matcher_upload.copy() {
|
if let Some(copy_mode) = matcher_upload.copy() {
|
||||||
if let Err(err) = set_clipboard(copy_mode.build(url.as_str())) {
|
if let Err(err) = set_clipboard(copy_mode.build(url.as_str())) {
|
||||||
print_error_msg(format!(
|
print_error(
|
||||||
"failed to copy the share link to the clipboard, ignoring: {}",
|
err.context("failed to copy the share link to the clipboard, ignoring"),
|
||||||
err,
|
);
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
222
src/util.rs
222
src/util.rs
|
@ -1,28 +1,38 @@
|
||||||
|
#[cfg(feature = "clipboard-crate")]
|
||||||
|
extern crate clip;
|
||||||
extern crate colored;
|
extern crate colored;
|
||||||
extern crate directories;
|
extern crate directories;
|
||||||
extern crate fs2;
|
extern crate fs2;
|
||||||
extern crate open;
|
extern crate open;
|
||||||
extern crate regex;
|
extern crate regex;
|
||||||
|
#[cfg(feature = "clipboard-bin")]
|
||||||
|
extern crate which;
|
||||||
|
|
||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
use std::env::{self, current_exe, var_os};
|
use std::env::{self, current_exe, var_os};
|
||||||
#[cfg(feature = "clipboard")]
|
|
||||||
use std::error::Error as StdError;
|
|
||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
|
#[cfg(feature = "clipboard")]
|
||||||
|
use std::fmt;
|
||||||
use std::fmt::{Debug, Display};
|
use std::fmt::{Debug, Display};
|
||||||
|
#[cfg(feature = "clipboard-bin")]
|
||||||
|
use std::io::ErrorKind as IoErrorKind;
|
||||||
use std::io::{stderr, stdin, Error as IoError, Write};
|
use std::io::{stderr, stdin, Error as IoError, Write};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::{exit, ExitStatus};
|
use std::process::{exit, ExitStatus};
|
||||||
|
#[cfg(feature = "clipboard-bin")]
|
||||||
|
use std::process::{Command, Stdio};
|
||||||
|
|
||||||
|
#[cfg(feature = "clipboard-crate")]
|
||||||
|
use self::clip::{ClipboardContext, ClipboardProvider};
|
||||||
use self::colored::*;
|
use self::colored::*;
|
||||||
#[cfg(feature = "history")]
|
#[cfg(feature = "history")]
|
||||||
use self::directories::ProjectDirs;
|
use self::directories::ProjectDirs;
|
||||||
use self::fs2::available_space;
|
use self::fs2::available_space;
|
||||||
use chrono::Duration;
|
use chrono::Duration;
|
||||||
#[cfg(feature = "clipboard")]
|
|
||||||
use clipboard_ext::{prelude::*, x11_bin::ClipboardContext};
|
|
||||||
use failure::{err_msg, Fail};
|
use failure::{err_msg, Fail};
|
||||||
|
#[cfg(feature = "clipboard-crate")]
|
||||||
|
use failure::{Compat, Error};
|
||||||
use ffsend_api::{
|
use ffsend_api::{
|
||||||
api::request::{ensure_success, ResponseError},
|
api::request::{ensure_success, ResponseError},
|
||||||
client::Client,
|
client::Client,
|
||||||
|
@ -31,6 +41,8 @@ use ffsend_api::{
|
||||||
};
|
};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use rpassword::prompt_password_stderr;
|
use rpassword::prompt_password_stderr;
|
||||||
|
#[cfg(feature = "clipboard-bin")]
|
||||||
|
use which::which;
|
||||||
|
|
||||||
use crate::cmd::matcher::MainMatcher;
|
use crate::cmd::matcher::MainMatcher;
|
||||||
|
|
||||||
|
@ -291,10 +303,202 @@ pub fn open_path(path: &str) -> Result<ExitStatus, IoError> {
|
||||||
open::that(path)
|
open::that(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the clipboard of the user to the given `contents` string.
|
/// Set the clipboard of the user to the given `content` string.
|
||||||
#[cfg(feature = "clipboard")]
|
#[cfg(feature = "clipboard")]
|
||||||
pub fn set_clipboard(contents: String) -> Result<(), Box<dyn StdError>> {
|
pub fn set_clipboard(content: String) -> Result<(), ClipboardError> {
|
||||||
Ok(ClipboardContext::new()?.set_contents(contents)?)
|
ClipboardType::select().set(content)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Clipboard management enum.
|
||||||
|
///
|
||||||
|
/// Defines which method of setting the clipboard is used.
|
||||||
|
/// Invoke `ClipboardType::select()` to select the best variant to use determined at runtime.
|
||||||
|
///
|
||||||
|
/// Usually, the `Native` variant is used. However, on Linux system a different variant will be
|
||||||
|
/// selected which will call a system binary to set the clipboard. This must be done because the
|
||||||
|
/// native clipboard interface only has a lifetime of the application. This means that the
|
||||||
|
/// clipboard is instantly cleared as soon as this application quits, which is always immediately.
|
||||||
|
/// This limitation is due to security reasons as defined by X11. The alternative binaries we set
|
||||||
|
/// the clipboard with spawn a daemon in the background to keep the clipboad alive until it's
|
||||||
|
/// flushed.
|
||||||
|
#[cfg(feature = "clipboard")]
|
||||||
|
#[derive(Clone, Eq, PartialEq)]
|
||||||
|
pub enum ClipboardType {
|
||||||
|
/// Native operating system clipboard.
|
||||||
|
#[cfg(feature = "clipboard-crate")]
|
||||||
|
Native,
|
||||||
|
|
||||||
|
/// Manage clipboard through `xclip` on Linux.
|
||||||
|
///
|
||||||
|
/// May contain a binary path if specified at compile time through the `XCLIP_PATH` variable.
|
||||||
|
#[cfg(feature = "clipboard-bin")]
|
||||||
|
Xclip(Option<String>),
|
||||||
|
|
||||||
|
/// Manage clipboard through `xsel` on Linux.
|
||||||
|
///
|
||||||
|
/// May contain a binary path if specified at compile time through the `XSEL_PATH` variable.
|
||||||
|
#[cfg(feature = "clipboard-bin")]
|
||||||
|
Xsel(Option<String>),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "clipboard")]
|
||||||
|
impl ClipboardType {
|
||||||
|
/// Select the clipboard type to use, depending on the runtime system.
|
||||||
|
pub fn select() -> Self {
|
||||||
|
#[cfg(feature = "clipboard-crate")]
|
||||||
|
{
|
||||||
|
ClipboardType::Native
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "clipboard-bin")]
|
||||||
|
{
|
||||||
|
if let Some(path) = option_env!("XCLIP_PATH") {
|
||||||
|
ClipboardType::Xclip(Some(path.to_owned()))
|
||||||
|
} else if let Some(path) = option_env!("XSEL_PATH") {
|
||||||
|
ClipboardType::Xsel(Some(path.to_owned()))
|
||||||
|
} else if which("xclip").is_ok() {
|
||||||
|
ClipboardType::Xclip(None)
|
||||||
|
} else if which("xsel").is_ok() {
|
||||||
|
ClipboardType::Xsel(None)
|
||||||
|
} else {
|
||||||
|
// TODO: should we error here instead, as no clipboard binary was found?
|
||||||
|
ClipboardType::Xclip(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set clipboard contents through the selected clipboard type.
|
||||||
|
pub fn set(&self, content: String) -> Result<(), ClipboardError> {
|
||||||
|
match self {
|
||||||
|
#[cfg(feature = "clipboard-crate")]
|
||||||
|
ClipboardType::Native => Self::native_set(content),
|
||||||
|
#[cfg(feature = "clipboard-bin")]
|
||||||
|
ClipboardType::Xclip(path) => Self::xclip_set(path.clone(), &content),
|
||||||
|
#[cfg(feature = "clipboard-bin")]
|
||||||
|
ClipboardType::Xsel(path) => Self::xsel_set(path.clone(), &content),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the clipboard through a native interface.
|
||||||
|
///
|
||||||
|
/// This is used on non-Linux systems.
|
||||||
|
#[cfg(feature = "clipboard-crate")]
|
||||||
|
fn native_set(content: String) -> Result<(), ClipboardError> {
|
||||||
|
ClipboardProvider::new()
|
||||||
|
.and_then(|mut context: ClipboardContext| context.set_contents(content))
|
||||||
|
.map_err(|err| format_err!("{}", err).compat())
|
||||||
|
.map_err(ClipboardError::Native)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "clipboard-bin")]
|
||||||
|
fn xclip_set(path: Option<String>, content: &str) -> Result<(), ClipboardError> {
|
||||||
|
Self::sys_cmd_set(
|
||||||
|
"xclip",
|
||||||
|
Command::new(path.unwrap_or_else(|| "xclip".into()))
|
||||||
|
.arg("-sel")
|
||||||
|
.arg("clip"),
|
||||||
|
content,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "clipboard-bin")]
|
||||||
|
fn xsel_set(path: Option<String>, content: &str) -> Result<(), ClipboardError> {
|
||||||
|
Self::sys_cmd_set(
|
||||||
|
"xsel",
|
||||||
|
Command::new(path.unwrap_or_else(|| "xsel".into())).arg("--clipboard"),
|
||||||
|
content,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "clipboard-bin")]
|
||||||
|
fn sys_cmd_set(
|
||||||
|
bin: &'static str,
|
||||||
|
command: &mut Command,
|
||||||
|
content: &str,
|
||||||
|
) -> Result<(), ClipboardError> {
|
||||||
|
// Spawn the command process for setting the clipboard
|
||||||
|
let mut process = match command.stdin(Stdio::piped()).stdout(Stdio::null()).spawn() {
|
||||||
|
Ok(process) => process,
|
||||||
|
Err(err) => {
|
||||||
|
return Err(match err.kind() {
|
||||||
|
IoErrorKind::NotFound => ClipboardError::NoBinary,
|
||||||
|
_ => ClipboardError::BinaryIo(bin, err),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Write the contents to the xclip process
|
||||||
|
process
|
||||||
|
.stdin
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.write_all(content.as_bytes())
|
||||||
|
.map_err(|err| ClipboardError::BinaryIo(bin, err))?;
|
||||||
|
|
||||||
|
// Wait for xclip to exit
|
||||||
|
let status = process
|
||||||
|
.wait()
|
||||||
|
.map_err(|err| ClipboardError::BinaryIo(bin, err))?;
|
||||||
|
if !status.success() {
|
||||||
|
return Err(ClipboardError::BinaryStatus(
|
||||||
|
bin,
|
||||||
|
status.code().unwrap_or(0),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "clipboard")]
|
||||||
|
impl fmt::Display for ClipboardType {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
#[cfg(feature = "clipboard-crate")]
|
||||||
|
ClipboardType::Native => write!(f, "native"),
|
||||||
|
#[cfg(feature = "clipboard-bin")]
|
||||||
|
ClipboardType::Xclip(path) => match path {
|
||||||
|
None => write!(f, "xclip"),
|
||||||
|
Some(path) => write!(f, "xclip ({})", path),
|
||||||
|
},
|
||||||
|
#[cfg(feature = "clipboard-bin")]
|
||||||
|
ClipboardType::Xsel(path) => match path {
|
||||||
|
None => write!(f, "xsel"),
|
||||||
|
Some(path) => write!(f, "xsel ({})", path),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "clipboard")]
|
||||||
|
#[derive(Debug, Fail)]
|
||||||
|
pub enum ClipboardError {
|
||||||
|
/// A generic error occurred while setting the clipboard contents.
|
||||||
|
///
|
||||||
|
/// This is for non-Linux systems, using a native clipboard interface.
|
||||||
|
#[cfg(feature = "clipboard-crate")]
|
||||||
|
#[fail(display = "failed to access clipboard")]
|
||||||
|
Native(#[cause] Compat<Error>),
|
||||||
|
|
||||||
|
/// The `xclip` or `xsel` binary could not be found on the system, required for clipboard support.
|
||||||
|
#[cfg(feature = "clipboard-bin")]
|
||||||
|
#[fail(display = "failed to access clipboard, xclip or xsel is not installed")]
|
||||||
|
NoBinary,
|
||||||
|
|
||||||
|
/// An error occurred while using `xclip` or `xsel` to set the clipboard contents.
|
||||||
|
/// This problem probably occurred when starting, or while piping the clipboard contents to
|
||||||
|
/// the process.
|
||||||
|
#[cfg(feature = "clipboard-bin")]
|
||||||
|
#[fail(display = "failed to access clipboard using {}", _0)]
|
||||||
|
BinaryIo(&'static str, #[cause] IoError),
|
||||||
|
|
||||||
|
/// `xclip` or `xsel` unexpectetly exited with a non-successful status code.
|
||||||
|
#[cfg(feature = "clipboard-bin")]
|
||||||
|
#[fail(
|
||||||
|
display = "failed to use clipboard, {} exited with status code {}",
|
||||||
|
_0, _1
|
||||||
|
)]
|
||||||
|
BinaryStatus(&'static str, i32),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check for an emtpy password in the given `password`.
|
/// Check for an emtpy password in the given `password`.
|
||||||
|
@ -845,6 +1049,10 @@ pub fn features_list() -> Vec<&'static str> {
|
||||||
features.push("archive");
|
features.push("archive");
|
||||||
#[cfg(feature = "clipboard")]
|
#[cfg(feature = "clipboard")]
|
||||||
features.push("clipboard");
|
features.push("clipboard");
|
||||||
|
#[cfg(feature = "clipboard-bin")]
|
||||||
|
features.push("clipboard-bin");
|
||||||
|
#[cfg(feature = "clipboard-crate")]
|
||||||
|
features.push("clipboard-crate");
|
||||||
#[cfg(feature = "history")]
|
#[cfg(feature = "history")]
|
||||||
features.push("history");
|
features.push("history");
|
||||||
#[cfg(feature = "qrcode")]
|
#[cfg(feature = "qrcode")]
|
||||||
|
|
Loading…
Reference in a new issue