mirror of
https://github.com/TaKO8Ki/gobang
synced 2024-10-31 03:20:33 +00:00
Use command for clipboard instead of copypasta (#36)
* use copy command instead of copypasta * remove a step for installing dependencies * rename copy_string to copy_to_clipboard
This commit is contained in:
parent
5da6b1b796
commit
d493f46875
5
.github/workflows/ci.yml
vendored
5
.github/workflows/ci.yml
vendored
@ -83,10 +83,5 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
path: target
|
path: target
|
||||||
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}
|
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}
|
||||||
- name: Install dependencies
|
|
||||||
if: runner.os == 'Linux'
|
|
||||||
run: |
|
|
||||||
sudo apt-get install libxcb-xkb-dev
|
|
||||||
sudo apt install libxcb-composite0-dev
|
|
||||||
- name: Run Tests
|
- name: Run Tests
|
||||||
run: cargo test --workspace -- --skip=e2e --color always
|
run: cargo test --workspace -- --skip=e2e --color always
|
||||||
|
32
Cargo.lock
generated
32
Cargo.lock
generated
@ -220,7 +220,6 @@ dependencies = [
|
|||||||
"objc",
|
"objc",
|
||||||
"objc-foundation",
|
"objc-foundation",
|
||||||
"objc_id",
|
"objc_id",
|
||||||
"x11-clipboard",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -556,6 +555,7 @@ dependencies = [
|
|||||||
"toml",
|
"toml",
|
||||||
"tui",
|
"tui",
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
|
"which",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1869,6 +1869,17 @@ dependencies = [
|
|||||||
"webpki",
|
"webpki",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "which"
|
||||||
|
version = "4.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ea187a8ef279bc014ec368c27a920da2024d2a711109bfbe3440585d5cf27ad9"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
"lazy_static",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "whoami"
|
name = "whoami"
|
||||||
version = "1.1.2"
|
version = "1.1.2"
|
||||||
@ -1929,25 +1940,6 @@ version = "0.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214"
|
checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "x11-clipboard"
|
|
||||||
version = "0.5.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b397ace6e980510de59a4fe3d4c758dffab231d6d747ce9fa1aba6b6035d5f32"
|
|
||||||
dependencies = [
|
|
||||||
"xcb",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "xcb"
|
|
||||||
version = "0.9.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "62056f63138b39116f82a540c983cc11f1c90cd70b3d492a70c25eaa50bd22a6"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"log",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zeroize"
|
name = "zeroize"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
|
@ -36,8 +36,5 @@ async-trait = "0.1.50"
|
|||||||
itertools = "0.10.0"
|
itertools = "0.10.0"
|
||||||
rust_decimal = "1.15"
|
rust_decimal = "1.15"
|
||||||
|
|
||||||
[target.'cfg(any(target_os = "macos", windows))'.dependencies]
|
[target.'cfg(all(target_family="unix",not(target_os="macos")))'.dependencies]
|
||||||
copypasta = { version = "0.7.0", default-features = false }
|
which = "4.1"
|
||||||
|
|
||||||
[target.'cfg(not(any(target_os = "macos", windows)))'.dependencies]
|
|
||||||
copypasta = { version = "0.7.0", features = ["x11"], default-features = false }
|
|
||||||
|
@ -31,7 +31,7 @@ impl DatabaseTreeItems {
|
|||||||
item.set_collapsed(false);
|
item.set_collapsed(false);
|
||||||
item
|
item
|
||||||
} else {
|
} else {
|
||||||
let mut item = item.clone();
|
let mut item = item;
|
||||||
item.show();
|
item.show();
|
||||||
item
|
item
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::clipboard::Clipboard;
|
use crate::clipboard::copy_to_clipboard;
|
||||||
use crate::components::{CommandInfo, Component as _, DrawableComponent as _, EventState};
|
use crate::components::{CommandInfo, Component as _, DrawableComponent as _, EventState};
|
||||||
use crate::database::{MySqlPool, Pool, PostgresPool, RECORDS_LIMIT_PER_PAGE};
|
use crate::database::{MySqlPool, Pool, PostgresPool, RECORDS_LIMIT_PER_PAGE};
|
||||||
use crate::event::Key;
|
use crate::event::Key;
|
||||||
@ -31,7 +31,6 @@ pub struct App {
|
|||||||
databases: DatabasesComponent,
|
databases: DatabasesComponent,
|
||||||
connections: ConnectionsComponent,
|
connections: ConnectionsComponent,
|
||||||
table_status: TableStatusComponent,
|
table_status: TableStatusComponent,
|
||||||
clipboard: Clipboard,
|
|
||||||
pool: Option<Box<dyn Pool>>,
|
pool: Option<Box<dyn Pool>>,
|
||||||
pub config: Config,
|
pub config: Config,
|
||||||
pub error: ErrorComponent,
|
pub error: ErrorComponent,
|
||||||
@ -50,7 +49,6 @@ impl App {
|
|||||||
table_status: TableStatusComponent::default(),
|
table_status: TableStatusComponent::default(),
|
||||||
error: ErrorComponent::new(config.key_config),
|
error: ErrorComponent::new(config.key_config),
|
||||||
focus: Focus::ConnectionList,
|
focus: Focus::ConnectionList,
|
||||||
clipboard: Clipboard::new(),
|
|
||||||
pool: None,
|
pool: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -262,7 +260,7 @@ impl App {
|
|||||||
|
|
||||||
if key == self.config.key_config.copy {
|
if key == self.config.key_config.copy {
|
||||||
if let Some(text) = self.record_table.table.selected_cells() {
|
if let Some(text) = self.record_table.table.selected_cells() {
|
||||||
self.clipboard.store(text)
|
copy_to_clipboard(text.as_str())?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,7 +310,7 @@ impl App {
|
|||||||
|
|
||||||
if key == self.config.key_config.copy {
|
if key == self.config.key_config.copy {
|
||||||
if let Some(text) = self.structure_table.selected_cells() {
|
if let Some(text) = self.structure_table.selected_cells() {
|
||||||
self.clipboard.store(text)
|
copy_to_clipboard(text.as_str())?
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
116
src/clipboard.rs
116
src/clipboard.rs
@ -1,68 +1,68 @@
|
|||||||
use copypasta::ClipboardContext;
|
use anyhow::{anyhow, Result};
|
||||||
use copypasta::ClipboardProvider;
|
#[cfg(all(target_family = "unix", not(target_os = "macos")))]
|
||||||
|
use std::ffi::OsStr;
|
||||||
|
use std::io::Write;
|
||||||
|
use std::process::{Command, Stdio};
|
||||||
|
|
||||||
pub struct Clipboard {
|
fn execute_copy_command(command: Command, text: &str) -> Result<()> {
|
||||||
clipboard: Box<dyn ClipboardProvider>,
|
let mut command = command;
|
||||||
selection: Option<Box<dyn ClipboardProvider>>,
|
|
||||||
|
let mut process = command
|
||||||
|
.stdin(Stdio::piped())
|
||||||
|
.stdout(Stdio::null())
|
||||||
|
.spawn()
|
||||||
|
.map_err(|e| anyhow!("`{:?}`: {}", command, e))?;
|
||||||
|
|
||||||
|
process
|
||||||
|
.stdin
|
||||||
|
.as_mut()
|
||||||
|
.ok_or_else(|| anyhow!("`{:?}`", command))?
|
||||||
|
.write_all(text.as_bytes())
|
||||||
|
.map_err(|e| anyhow!("`{:?}`: {}", command, e))?;
|
||||||
|
|
||||||
|
process
|
||||||
|
.wait()
|
||||||
|
.map_err(|e| anyhow!("`{:?}`: {}", command, e))?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clipboard {
|
#[cfg(all(target_family = "unix", not(target_os = "macos")))]
|
||||||
pub fn new() -> Self {
|
fn gen_command(path: impl AsRef<OsStr>, xclip_syntax: bool) -> Command {
|
||||||
Self::default()
|
let mut c = Command::new(path);
|
||||||
|
if xclip_syntax {
|
||||||
|
c.arg("-selection");
|
||||||
|
c.arg("clipboard");
|
||||||
|
} else {
|
||||||
|
c.arg("--clipboard");
|
||||||
}
|
}
|
||||||
|
c
|
||||||
// #[cfg(any(test, not(any(target_os = "macos", windows))))]
|
|
||||||
// pub fn new_nop() -> Self {
|
|
||||||
// Self {
|
|
||||||
// clipboard: Box::new(NopClipboardContext::new().unwrap()),
|
|
||||||
// selection: None,
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Clipboard {
|
#[cfg(all(target_family = "unix", not(target_os = "macos")))]
|
||||||
fn default() -> Self {
|
pub fn copy_to_clipboard(string: &str) -> Result<()> {
|
||||||
return Self {
|
use std::path::PathBuf;
|
||||||
clipboard: Box::new(ClipboardContext::new().unwrap()),
|
use which::which;
|
||||||
selection: None,
|
let (path, xclip_syntax) = which("xclip").ok().map_or_else(
|
||||||
};
|
|| {
|
||||||
|
(
|
||||||
|
which("xsel").ok().unwrap_or_else(|| PathBuf::from("xsel")),
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|path| (path, true),
|
||||||
|
);
|
||||||
|
|
||||||
// #[cfg(target_os = "linux")]
|
let cmd = gen_command(path, xclip_syntax);
|
||||||
// return Self {
|
execute_copy_command(cmd, string)
|
||||||
// clipboard: Box::new(ClipboardContext::new().unwrap()),
|
|
||||||
// selection: Some(Box::new(
|
|
||||||
// X11ClipboardContext::<X11SelectionClipboard>::new().unwrap(),
|
|
||||||
// )),
|
|
||||||
// };
|
|
||||||
|
|
||||||
// #[cfg(not(any(target_os = "macos", windows)))]
|
|
||||||
// return Self::new_nop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clipboard {
|
#[cfg(target_os = "macos")]
|
||||||
pub fn store(&mut self, text: impl Into<String>) {
|
pub fn copy_to_clipboard(string: &str) -> Result<()> {
|
||||||
let clipboard = match &mut self.selection {
|
execute_copy_command(Command::new("pbcopy"), string)
|
||||||
Some(provider) => provider,
|
}
|
||||||
None => &mut self.clipboard,
|
|
||||||
};
|
#[cfg(windows)]
|
||||||
|
pub fn copy_to_clipboard(string: &str) -> Result<()> {
|
||||||
clipboard.set_contents(text.into()).unwrap_or_else(|err| {
|
execute_copy_command(Command::new("clip"), string)
|
||||||
panic!("Unable to store text in clipboard: {}", err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn _load(&mut self) -> String {
|
|
||||||
let clipboard = match &mut self.selection {
|
|
||||||
Some(provider) => provider,
|
|
||||||
None => &mut self.clipboard,
|
|
||||||
};
|
|
||||||
|
|
||||||
match clipboard.get_contents() {
|
|
||||||
Err(err) => {
|
|
||||||
panic!("Unable to load text from clipboard: {}", err);
|
|
||||||
}
|
|
||||||
Ok(text) => text,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -265,7 +265,7 @@ fn convert_column_value_to_string(row: &PgRow, column: &PgColumn) -> anyhow::Res
|
|||||||
}
|
}
|
||||||
if let Ok(value) = row.try_get(column_name) {
|
if let Ok(value) = row.try_get(column_name) {
|
||||||
let value: Option<Vec<String>> = value;
|
let value: Option<Vec<String>> = value;
|
||||||
return Ok(value.map_or("NULL".to_string(), |v| v.join(",").to_string()));
|
return Ok(value.map_or("NULL".to_string(), |v| v.join(",")));
|
||||||
}
|
}
|
||||||
Err(anyhow::anyhow!(
|
Err(anyhow::anyhow!(
|
||||||
"column type not implemented: `{}` {}",
|
"column type not implemented: `{}` {}",
|
||||||
|
Loading…
Reference in New Issue
Block a user