diff --git a/src/ui.rs b/src/ui.rs index a881674..e8d8124 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -14,9 +14,7 @@ mod action; mod mode; mod view; -pub use self::action::Action; -pub use self::mode::Mode; -pub use self::view::View; +pub use self::{action::Action, mode::Mode, view::View}; use crate::{ bookmarks, color, @@ -188,7 +186,7 @@ impl UI { if url.contains("://") && !url.starts_with("gopher://") { self.dirty = true; return if self.confirm(&format!("Open external URL? {}", url)) { - open_external(url) + utils::open_external(url) } else { Ok(()) }; @@ -627,7 +625,7 @@ impl UI { 'y' => { if let Some(page) = self.views.get(self.focused) { let url = page.url(); - copy_to_clipboard(&url)?; + utils::copy_to_clipboard(&url)?; let msg = format!("Copied {} to clipboard.", url); self.set_status(&msg); } @@ -652,38 +650,3 @@ impl Drop for UI { out.flush().expect(ERR_STDOUT); } } - -fn copy_to_clipboard(data: &str) -> Result<()> { - spawn_os_clipboard().and_then(|mut child| { - let child_stdin = child.stdin.as_mut().unwrap(); - child_stdin.write_all(data.as_bytes()) - }) -} - -fn spawn_os_clipboard() -> Result { - if cfg!(target_os = "macos") { - process::Command::new("pbcopy") - .stdin(Stdio::piped()) - .spawn() - } else { - process::Command::new("xclip") - .args(&["-sel", "clip"]) - .stdin(Stdio::piped()) - .spawn() - } -} - -// runs the `open` shell command -fn open_external(url: &str) -> Result<()> { - let output = process::Command::new("open").arg(url).output()?; - if output.stderr.is_empty() { - Ok(()) - } else { - Err(error!( - "`open` error: {}", - String::from_utf8(output.stderr) - .unwrap_or_else(|_| "?".into()) - .trim_end() - )) - } -} diff --git a/src/utils.rs b/src/utils.rs index c157aa9..41d84bf 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,4 +1,8 @@ //! Helper functions and macros. +use std::{ + io::{Result, Write}, + process::{self, Stdio}, +}; /// Debug macro that appends a line to `phetch.log`. /// Useful for printf-style debugging - add your `log!()` calls, @@ -49,3 +53,38 @@ pub fn human_bytes(bytes: usize) -> String { format!("{}{}", count, tag) } + +/// Copies data to the system clipboard, if possible. +/// Uses `pbcopy` on macOS or `xclip -sel clip` on Linux. +pub fn copy_to_clipboard(data: &str) -> Result<()> { + #[cfg(target_os = "macos")] + let mut cmd = process::Command::new("pbcopy"); + #[cfg(not(target_os = "macos"))] + let mut cmd = process::Command::new("xclip").args(&["-sel", "clip"]); + + cmd.stdin(Stdio::piped()).spawn().and_then(|mut child| { + let child_stdin = child.stdin.as_mut().unwrap(); + child_stdin.write_all(data.as_bytes()) + }) +} + +/// Used to open non-Gopher URLs. +/// Runs `open` command on macOS or `xdg-open` on Linux. +pub fn open_external(url: &str) -> Result<()> { + #[cfg(target_os = "macos")] + let cmd = "open"; + #[cfg(not(target_os = "macos"))] + let cmd = "xdg-open"; + + let output = process::Command::new(cmd).arg(url).output()?; + if output.stderr.is_empty() { + Ok(()) + } else { + Err(error!( + "`open` error: {}", + String::from_utf8(output.stderr) + .unwrap_or_else(|_| "?".into()) + .trim_end() + )) + } +}