diff --git a/src/bin/copyrat.rs b/src/bin/copyrat.rs index 011e336..5a3f565 100644 --- a/src/bin/copyrat.rs +++ b/src/bin/copyrat.rs @@ -1,6 +1,4 @@ use clap::Clap; -use std::fs::OpenOptions; -use std::io::prelude::*; use std::io::{self, Read}; use copyrat::{config::basic, run, ui::Selection}; @@ -25,19 +23,5 @@ fn main() { } let Selection { text, .. } = selection.unwrap(); - - // Write output to a target_path if provided, else print to original stdout. - match opt.target_path { - None => println!("{}", text), - Some(target) => { - let mut file = OpenOptions::new() - .create(true) - .truncate(true) - .write(true) - .open(target) - .expect("Unable to open the target file"); - - file.write_all(text.as_bytes()).unwrap(); - } - } + println!("{}", text); } diff --git a/src/config/basic.rs b/src/config/basic.rs index c42a117..3859d6e 100644 --- a/src/config/basic.rs +++ b/src/config/basic.rs @@ -1,6 +1,4 @@ use clap::Clap; -use std::collections::HashMap; -use std::path; use std::str::FromStr; use crate::{ @@ -46,6 +44,10 @@ pub struct Config { #[clap(short, long)] pub unique_hint: bool, + /// Move focus back to first/last match. + #[clap(short = 'w', long)] + pub focus_wrap_around: bool, + #[clap(flatten)] pub colors: ui::colors::UiColors, @@ -53,10 +55,6 @@ pub struct Config { #[clap(long, arg_enum, default_value = "leading")] pub hint_alignment: ui::HintAlignment, - /// Move focus back to first/last match. - #[clap(long)] - pub focus_wrap_around: bool, - /// Optional hint styling. /// /// Underline or surround the hint for increased visibility. @@ -68,10 +66,6 @@ pub struct Config { #[clap(long, default_value = "{}", parse(try_from_str = parse_chars))] pub hint_surroundings: (char, char), - - /// Optional target path where to store the selected matches. - #[clap(short = 'o', long = "output", parse(from_os_str))] - pub target_path: Option, } /// Type introduced due to parsing limitation, @@ -100,53 +94,10 @@ impl FromStr for HintStyleArg { /// Try to parse a `&str` into a tuple of `char`s. fn parse_chars(src: &str) -> Result<(char, char), error::ParseError> { - if src.len() != 2 { + if src.chars().count() != 2 { return Err(error::ParseError::ExpectedSurroundingPair); } let chars: Vec = src.chars().collect(); Ok((chars[0], chars[1])) } - -impl Config { - /// Try parsing provided options, and update self with the valid values. - pub fn merge_map( - &mut self, - options: &HashMap, - ) -> Result<(), error::ParseError> { - for (name, value) in options { - match name.as_ref() { - "@copyrat-alphabet" => { - self.alphabet = alphabet::parse_alphabet(value)?; - } - "@copyrat-pattern-name" => { - self.named_patterns = vec![regexes::parse_pattern_name(value)?] - } - "@copyrat-custom-pattern" => self.custom_patterns = vec![String::from(value)], - "@copyrat-reverse" => { - self.reverse = value.parse::()?; - } - "@copyrat-unique-hint" => { - self.unique_hint = value.parse::()?; - } - - "@copyrat-match-fg" => self.colors.match_fg = ui::colors::parse_color(value)?, - "@copyrat-match-bg" => self.colors.match_bg = ui::colors::parse_color(value)?, - "@copyrat-focused-fg" => self.colors.focused_fg = ui::colors::parse_color(value)?, - "@copyrat-focused-bg" => self.colors.focused_bg = ui::colors::parse_color(value)?, - "@copyrat-hint-fg" => self.colors.hint_fg = ui::colors::parse_color(value)?, - "@copyrat-hint-bg" => self.colors.hint_bg = ui::colors::parse_color(value)?, - - "@copyrat-hint-alignment" => { - self.hint_alignment = ui::HintAlignment::from_str(&value)? - } - "@copyrat-hint-style" => self.hint_style = Some(HintStyleArg::from_str(&value)?), - - // Ignore unknown options. - _ => (), - } - } - - Ok(()) - } -} diff --git a/src/config/tmux_bridge.rs b/src/config/tmux_bridge.rs index d4e329f..de9cb01 100644 --- a/src/config/tmux_bridge.rs +++ b/src/config/tmux_bridge.rs @@ -3,8 +3,12 @@ use std::collections::HashMap; use std::str::FromStr; use super::basic; -use crate::comm::tmux; -use crate::error; +use crate::{ + comm::tmux, + error, + textbuf::{alphabet, regexes}, + ui, +}; /// Main configuration, parsed from command line. #[derive(Clap, Debug)] @@ -16,15 +20,15 @@ pub struct Config { /// However, you should consider reading them from the config file (the /// default option) as this saves both a command call (about 10ms) and a /// Regex compilation. - #[clap(long)] - pub ignore_options_from_tmux: bool, + #[clap(short = 'n', long)] + pub ignore_tmux_options: bool, - /// Name of the copyrat temporary window. + /// Name of the copyrat temporary Tmux window. /// /// Copyrat is launched in a temporary window of that name. The only pane /// in this temp window gets swapped with the current active one for /// in-place searching, then swapped back and killed after we exit. - #[clap(long, default_value = "[copyrat]")] + #[clap(short = 'W', long, default_value = "[copyrat]")] pub window_name: String, /// Capture visible area or entire pane history. @@ -47,31 +51,60 @@ impl Config { pub fn initialize() -> Result { let mut config = Config::parse(); - if !config.ignore_options_from_tmux { + if !config.ignore_tmux_options { let tmux_options: HashMap = tmux::get_options("@copyrat-")?; // Override default values with those coming from tmux. - config.merge_map(&tmux_options)?; - } + let wrapped = &mut config.basic_config; - Ok(config) - } - /// Try parsing provided options, and update self with the valid values. - /// Unknown options are simply ignored. - pub fn merge_map( - &mut self, - options: &HashMap, - ) -> Result<(), error::ParseError> { - for (name, value) in options { - if let "@copyrat-capture" = name.as_ref() { - self.capture_region = CaptureRegion::from_str(&value)?; + for (name, value) in &tmux_options { + match name.as_ref() { + "@copyrat-capture" => config.capture_region = CaptureRegion::from_str(&value)?, + "@copyrat-alphabet" => { + wrapped.alphabet = alphabet::parse_alphabet(value)?; + } + "@copyrat-pattern-name" => { + wrapped.named_patterns = vec![regexes::parse_pattern_name(value)?] + } + "@copyrat-custom-pattern" => { + wrapped.custom_patterns = vec![String::from(value)] + } + "@copyrat-reverse" => { + wrapped.reverse = value.parse::()?; + } + "@copyrat-unique-hint" => { + wrapped.unique_hint = value.parse::()?; + } + + "@copyrat-match-fg" => { + wrapped.colors.match_fg = ui::colors::parse_color(value)? + } + "@copyrat-match-bg" => { + wrapped.colors.match_bg = ui::colors::parse_color(value)? + } + "@copyrat-focused-fg" => { + wrapped.colors.focused_fg = ui::colors::parse_color(value)? + } + "@copyrat-focused-bg" => { + wrapped.colors.focused_bg = ui::colors::parse_color(value)? + } + "@copyrat-hint-fg" => wrapped.colors.hint_fg = ui::colors::parse_color(value)?, + "@copyrat-hint-bg" => wrapped.colors.hint_bg = ui::colors::parse_color(value)?, + + "@copyrat-hint-alignment" => { + wrapped.hint_alignment = ui::HintAlignment::from_str(&value)? + } + "@copyrat-hint-style" => { + wrapped.hint_style = Some(basic::HintStyleArg::from_str(&value)?) + } + + // Ignore unknown options. + _ => (), + } } } - // Pass the call to cli_options. - self.basic_config.merge_map(options)?; - - Ok(()) + Ok(config) } } diff --git a/src/ui/colors.rs b/src/ui/colors.rs index 19bf50e..daa8674 100644 --- a/src/ui/colors.rs +++ b/src/ui/colors.rs @@ -47,12 +47,13 @@ mod tests { } } -/// Holds color-related data, for clarity. +/// Holds color-related data. /// /// - `focus_*` colors are used to render the currently focused matched text. /// - `normal_*` colors are used to render other matched text. /// - `hint_*` colors are used to render the hints. #[derive(Clap, Debug)] +#[clap(about)] // Needed to avoid this doc comment to be used as overall `about`. pub struct UiColors { /// Foreground color for base text. #[clap(long, default_value = "bright-cyan", parse(try_from_str = parse_color))]