diff --git a/Cargo.lock b/Cargo.lock index cbc67be4..162676eb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,6 +20,54 @@ dependencies = [ "libc", ] +[[package]] +name = "anstream" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" + +[[package]] +name = "anstyle-parse" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +dependencies = [ + "anstyle", + "windows-sys", +] + [[package]] name = "arrayvec" version = "0.7.2" @@ -90,29 +138,31 @@ dependencies = [ [[package]] name = "clap" -version = "3.2.22" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86447ad904c7fb335a790c9d7fe3d0d971dc523b8ccd1561a520de9a85302750" +checksum = "b230ab84b0ffdf890d5a10abdbc8b83ae1c4918275daea1ab8801f71536b2651" dependencies = [ - "atty", - "bitflags", - "clap_lex", - "indexmap", - "once_cell", - "strsim", - "termcolor", - "textwrap", + "clap_builder", ] [[package]] -name = "clap_lex" -version = "0.2.4" +name = "clap_builder" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" dependencies = [ - "os_str_bytes", + "anstream", + "anstyle", + "clap_lex", + "strsim 0.11.0", ] +[[package]] +name = "clap_lex" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" + [[package]] name = "codespan-reporting" version = "0.11.1" @@ -123,6 +173,12 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + [[package]] name = "core-foundation-sys" version = "0.8.3" @@ -260,7 +316,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim", + "strsim 0.10.0", "syn", ] @@ -382,12 +438,6 @@ dependencies = [ "wasi 0.11.0+wasi-snapshot-preview1", ] -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - [[package]] name = "hermit-abi" version = "0.1.19" @@ -433,16 +483,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" -[[package]] -name = "indexmap" -version = "1.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" -dependencies = [ - "autocfg", - "hashbrown", -] - [[package]] name = "js-sys" version = "0.3.60" @@ -566,12 +606,6 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" -[[package]] -name = "os_str_bytes" -version = "6.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff" - [[package]] name = "pin-utils" version = "0.1.0" @@ -580,9 +614,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" dependencies = [ "unicode-ident", ] @@ -683,7 +717,7 @@ checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" [[package]] name = "skim" -version = "0.10.4" +version = "0.10.5" dependencies = [ "atty", "beef", @@ -714,6 +748,12 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strsim" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" + [[package]] name = "syn" version = "1.0.103" @@ -745,12 +785,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "textwrap" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "949517c0cf1bf4ee812e2e07e08ab448e3ae0d23472aee8a06c985f0c8815b16" - [[package]] name = "thiserror" version = "1.0.37" @@ -838,9 +872,9 @@ checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" [[package]] name = "utf8parse" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936e4b492acfd135421d8dca4b1aa80a7bfc26e702ef3af710e0752684df5372" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "vte" @@ -959,3 +993,69 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" diff --git a/Cargo.toml b/Cargo.toml index 60299a3b..da9cb629 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "skim" -version = "0.10.4" +version = "0.10.5" authors = ["Zhang Jinzhou "] description = "Fuzzy Finder in rust!" documentation = "https://docs.rs/skim" @@ -29,7 +29,7 @@ unicode-width = "0.1.9" log = "0.4.17" env_logger = { version = "0.9.0", optional = true } time = "0.3.13" -clap = { version = "3.2.22", optional = true, features = ["cargo"] } +clap = { version = "4.5.2", optional = true, features = ["cargo"] } tuikit = "0.5.0" vte = "0.11.0" fuzzy-matcher = "0.3.7" diff --git a/src/bin/main.rs b/src/bin/main.rs index dff7e421..fb6a9599 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -7,12 +7,14 @@ extern crate shlex; extern crate skim; extern crate time; +use clap::parser::ValuesRef; +use clap::{crate_version, Arg, ArgAction, ArgMatches, Command}; use derive_builder::Builder; + use std::env; use std::fs::File; use std::io::{BufRead, BufReader, BufWriter, Write}; -use clap::{crate_version, App, Arg, ArgMatches}; use skim::prelude::*; const USAGE: &str = " @@ -167,82 +169,80 @@ fn real_main() -> Result { //------------------------------------------------------------------------------ // parse options - let opts = App::new("sk") + let opts = Command::new("sk") .author("Jinzhou Zhang") .version(crate_version!()) - .arg(Arg::with_name("help").long("help").short('h')) - .arg(Arg::with_name("bind").long("bind").short('b').multiple(true).takes_value(true)) - .arg(Arg::with_name("multi").long("multi").short('m').multiple(true)) - .arg(Arg::with_name("no-multi").long("no-multi").multiple(true)) - .arg(Arg::with_name("prompt").long("prompt").short('p').multiple(true).takes_value(true).default_value("> ")) - .arg(Arg::with_name("cmd-prompt").long("cmd-prompt").multiple(true).takes_value(true).default_value("c> ")) - .arg(Arg::with_name("expect").long("expect").multiple(true).takes_value(true)) - .arg(Arg::with_name("tac").long("tac").multiple(true)) - .arg(Arg::with_name("tiebreak").long("tiebreak").short('t').multiple(true).takes_value(true)) - .arg(Arg::with_name("ansi").long("ansi").multiple(true)) - .arg(Arg::with_name("exact").long("exact").short('e').multiple(true)) - .arg(Arg::with_name("cmd").long("cmd").short('c').multiple(true).takes_value(true)) - .arg(Arg::with_name("interactive").long("interactive").short('i').multiple(true)) - .arg(Arg::with_name("query").long("query").short('q').multiple(true).takes_value(true)) - .arg(Arg::with_name("cmd-query").long("cmd-query").multiple(true).takes_value(true)) - .arg(Arg::with_name("regex").long("regex").multiple(true)) - .arg(Arg::with_name("delimiter").long("delimiter").short('d').multiple(true).takes_value(true)) - .arg(Arg::with_name("nth").long("nth").short('n').multiple(true).takes_value(true)) - .arg(Arg::with_name("with-nth").long("with-nth").multiple(true).takes_value(true)) - .arg(Arg::with_name("replstr").short('I').multiple(true).takes_value(true)) - .arg(Arg::with_name("color").long("color").multiple(true).takes_value(true)) - .arg(Arg::with_name("margin").long("margin").multiple(true).takes_value(true).default_value("0,0,0,0")) - .arg(Arg::with_name("min-height").long("min-height").multiple(true).takes_value(true).default_value("10")) - .arg(Arg::with_name("height").long("height").multiple(true).takes_value(true).default_value("100%")) - .arg(Arg::with_name("no-height").long("no-height").multiple(true)) - .arg(Arg::with_name("no-clear").long("no-clear").multiple(true)) - .arg(Arg::with_name("no-clear-start").long("no-clear-start").multiple(true)) - .arg(Arg::with_name("no-mouse").long("no-mouse").multiple(true)) - .arg(Arg::with_name("preview").long("preview").multiple(true).takes_value(true)) - .arg(Arg::with_name("preview-window").long("preview-window").multiple(true).takes_value(true).default_value("right:50%")) - .arg(Arg::with_name("reverse").long("reverse").multiple(true)) - - .arg(Arg::with_name("algorithm").long("algo").multiple(true).takes_value(true).default_value("skim_v2")) - .arg(Arg::with_name("case").long("case").multiple(true).takes_value(true).default_value("smart")) - .arg(Arg::with_name("literal").long("literal").multiple(true)) - .arg(Arg::with_name("cycle").long("cycle").multiple(true)) - .arg(Arg::with_name("no-hscroll").long("no-hscroll").multiple(true)) - .arg(Arg::with_name("hscroll-off").long("hscroll-off").multiple(true).takes_value(true).default_value("10")) - .arg(Arg::with_name("filepath-word").long("filepath-word").multiple(true)) - .arg(Arg::with_name("jump-labels").long("jump-labels").multiple(true).takes_value(true).default_value("abcdefghijklmnopqrstuvwxyz")) - .arg(Arg::with_name("border").long("border").multiple(true)) - .arg(Arg::with_name("inline-info").long("inline-info").multiple(true)) - .arg(Arg::with_name("header").long("header").multiple(true).takes_value(true).default_value("")) - .arg(Arg::with_name("header-lines").long("header-lines").multiple(true).takes_value(true).default_value("0")) - .arg(Arg::with_name("tabstop").long("tabstop").multiple(true).takes_value(true).default_value("8")) - .arg(Arg::with_name("no-bold").long("no-bold").multiple(true)) - .arg(Arg::with_name("history").long("history").multiple(true).takes_value(true)) - .arg(Arg::with_name("cmd-history").long("cmd-history").multiple(true).takes_value(true)) - .arg(Arg::with_name("history-size").long("history-size").multiple(true).takes_value(true).default_value("1000")) - .arg(Arg::with_name("cmd-history-size").long("cmd-history-size").multiple(true).takes_value(true).default_value("1000")) - .arg(Arg::with_name("print-query").long("print-query").multiple(true)) - .arg(Arg::with_name("print-cmd").long("print-cmd").multiple(true)) - .arg(Arg::with_name("print-score").long("print-score").multiple(true)) - .arg(Arg::with_name("read0").long("read0").multiple(true)) - .arg(Arg::with_name("print0").long("print0").multiple(true)) - .arg(Arg::with_name("sync").long("sync").multiple(true)) - .arg(Arg::with_name("extended").long("extended").short('x').multiple(true)) - .arg(Arg::with_name("no-sort").long("no-sort").multiple(true)) - .arg(Arg::with_name("select-1").long("select-1").short('1').multiple(true)) - .arg(Arg::with_name("exit-0").long("exit-0").short('0').multiple(true)) - .arg(Arg::with_name("filter").long("filter").short('f').takes_value(true).multiple(true)) - .arg(Arg::with_name("layout").long("layout").multiple(true).takes_value(true).default_value("default")) - .arg(Arg::with_name("keep-right").long("keep-right").multiple(true)) - .arg(Arg::with_name("skip-to-pattern").long("skip-to-pattern").multiple(true).takes_value(true).default_value("")) - .arg(Arg::with_name("pre-select-n").long("pre-select-n").multiple(true).takes_value(true).default_value("0")) - .arg(Arg::with_name("pre-select-pat").long("pre-select-pat").multiple(true).takes_value(true).default_value("")) - .arg(Arg::with_name("pre-select-items").long("pre-select-items").multiple(true).takes_value(true)) - .arg(Arg::with_name("pre-select-file").long("pre-select-file").multiple(true).takes_value(true).default_value("")) - .arg(Arg::with_name("no-clear-if-empty").long("no-clear-if-empty").multiple(true)) - .arg(Arg::with_name("show-cmd-error").long("show-cmd-error").multiple(true)) + .arg(Arg::new("bind").long("bind").short('b').action(ArgAction::Append)) + .arg(Arg::new("multi").long("multi").short('m').action(ArgAction::Count)) + .arg(Arg::new("no-multi").long("no-multi").action(ArgAction::Count)) + .arg(Arg::new("prompt").long("prompt").short('p').action(ArgAction::Append).default_value("> ")) + .arg(Arg::new("cmd-prompt").long("cmd-prompt").action(ArgAction::Append).default_value("c> ")) + .arg(Arg::new("expect").long("expect").action(ArgAction::Append)) + .arg(Arg::new("tac").long("tac").action(ArgAction::Count)) + .arg(Arg::new("tiebreak").long("tiebreak").short('t').action(ArgAction::Append)) + .arg(Arg::new("ansi").long("ansi").action(ArgAction::Count)) + .arg(Arg::new("exact").long("exact").short('e').action(ArgAction::Count)) + .arg(Arg::new("cmd").long("cmd").short('c').action(ArgAction::Append)) + .arg(Arg::new("interactive").long("interactive").short('i').action(ArgAction::Count)) + .arg(Arg::new("query").long("query").short('q').action(ArgAction::Append)) + .arg(Arg::new("cmd-query").long("cmd-query").action(ArgAction::Append)) + .arg(Arg::new("regex").long("regex").action(ArgAction::Count)) + .arg(Arg::new("delimiter").long("delimiter").short('d').action(ArgAction::Append)) + .arg(Arg::new("nth").long("nth").short('n').action(ArgAction::Append).allow_hyphen_values(true)) + .arg(Arg::new("with-nth").long("with-nth").action(ArgAction::Append).allow_hyphen_values(true)) + .arg(Arg::new("replstr").short('I').action(ArgAction::Append)) + .arg(Arg::new("color").long("color").action(ArgAction::Append)) + .arg(Arg::new("margin").long("margin").action(ArgAction::Append).default_value("0,0,0,0")) + .arg(Arg::new("min-height").long("min-height").action(ArgAction::Append).default_value("10")) + .arg(Arg::new("height").long("height").action(ArgAction::Append).default_value("100%")) + .arg(Arg::new("no-height").long("no-height").action(ArgAction::Count)) + .arg(Arg::new("no-clear").long("no-clear").action(ArgAction::Count)) + .arg(Arg::new("no-clear-start").long("no-clear-start").action(ArgAction::Count)) + .arg(Arg::new("no-mouse").long("no-mouse").action(ArgAction::Count)) + .arg(Arg::new("preview").long("preview").action(ArgAction::Append)) + .arg(Arg::new("preview-window").long("preview-window").action(ArgAction::Append).default_value("right:50%")) + .arg(Arg::new("reverse").long("reverse").action(ArgAction::Count)) + .arg(Arg::new("algorithm").long("algo").action(ArgAction::Append).default_value("skim_v2")) + .arg(Arg::new("case").long("case").action(ArgAction::Append).default_value("smart")) + .arg(Arg::new("literal").long("literal").action(ArgAction::Count)) + .arg(Arg::new("cycle").long("cycle").action(ArgAction::Count)) + .arg(Arg::new("no-hscroll").long("no-hscroll").action(ArgAction::Count)) + .arg(Arg::new("hscroll-off").long("hscroll-off").action(ArgAction::Append).default_value("10")) + .arg(Arg::new("filepath-word").long("filepath-word").action(ArgAction::Count)) + .arg(Arg::new("jump-labels").long("jump-labels").action(ArgAction::Append).default_value("abcdefghijklmnopqrstuvwxyz")) + .arg(Arg::new("border").long("border").action(ArgAction::Count)) + .arg(Arg::new("inline-info").long("inline-info").action(ArgAction::Count)) + .arg(Arg::new("header").long("header").action(ArgAction::Append).default_value("")) + .arg(Arg::new("header-lines").long("header-lines").action(ArgAction::Append).default_value("0")) + .arg(Arg::new("tabstop").long("tabstop").action(ArgAction::Append).default_value("8")) + .arg(Arg::new("no-bold").long("no-bold").action(ArgAction::Count)) + .arg(Arg::new("history").long("history").action(ArgAction::Append)) + .arg(Arg::new("cmd-history").long("cmd-history").action(ArgAction::Append)) + .arg(Arg::new("history-size").long("history-size").action(ArgAction::Append).default_value("1000")) + .arg(Arg::new("cmd-history-size").long("cmd-history-size").action(ArgAction::Append).default_value("1000")) + .arg(Arg::new("print-query").long("print-query").action(ArgAction::Count)) + .arg(Arg::new("print-cmd").long("print-cmd").action(ArgAction::Count)) + .arg(Arg::new("print-score").long("print-score").action(ArgAction::Count)) + .arg(Arg::new("read0").long("read0").action(ArgAction::Count)) + .arg(Arg::new("print0").long("print0").action(ArgAction::Count)) + .arg(Arg::new("sync").long("sync").action(ArgAction::Count)) + .arg(Arg::new("extended").long("extended").short('x').action(ArgAction::Count)) + .arg(Arg::new("no-sort").long("no-sort").action(ArgAction::Count)) + .arg(Arg::new("select-1").long("select-1").short('1').action(ArgAction::Count)) + .arg(Arg::new("exit-0").long("exit-0").short('0').action(ArgAction::Count)) + .arg(Arg::new("filter").long("filter").short('f').action(ArgAction::Append)) + .arg(Arg::new("layout").long("layout").action(ArgAction::Append).default_value("default")) + .arg(Arg::new("keep-right").long("keep-right").action(ArgAction::Count)) + .arg(Arg::new("skip-to-pattern").long("skip-to-pattern").action(ArgAction::Append).default_value("")) + .arg(Arg::new("pre-select-n").long("pre-select-n").action(ArgAction::Append).default_value("0")) + .arg(Arg::new("pre-select-pat").long("pre-select-pat").action(ArgAction::Append).default_value("")) + .arg(Arg::new("pre-select-items").long("pre-select-items").action(ArgAction::Append)) + .arg(Arg::new("pre-select-file").long("pre-select-file").action(ArgAction::Append).default_value("")) + .arg(Arg::new("no-clear-if-empty").long("no-clear-if-empty").action(ArgAction::Count)) + .arg(Arg::new("show-cmd-error").long("show-cmd-error").action(ArgAction::Count)) .get_matches_from(args); - if opts.is_present("help") { + if opts.contains_id("help") { write!(stdout, "{}", USAGE)?; return Ok(0); } @@ -250,18 +250,18 @@ fn real_main() -> Result { //------------------------------------------------------------------------------ let mut options = parse_options(&opts); - let preview_window_joined = opts.values_of("preview-window").map(|x| x.collect::>().join(":")); + let preview_window_joined = values_of(&opts, "preview-window").map(|x| x.join(":")); options.preview_window = preview_window_joined.as_deref(); //------------------------------------------------------------------------------ // initialize collector let item_reader_option = SkimItemReaderOption::default() - .ansi(opts.is_present("ansi")) - .delimiter(opts.values_of("delimiter").and_then(|vals| vals.last()).unwrap_or("")) - .with_nth(opts.values_of("with-nth").and_then(|vals| vals.last()).unwrap_or("")) - .nth(opts.values_of("nth").and_then(|vals| vals.last()).unwrap_or("")) - .read0(opts.is_present("read0")) - .show_error(opts.is_present("show-cmd-error")) + .ansi(is_present(&opts, "ansi")) + .delimiter(last_of(&opts, "delimiter").unwrap_or("")) + .with_nth(last_of(&opts, "with-nth").unwrap_or("")) + .nth(last_of(&opts, "nth").unwrap_or("")) + .read0(is_present(&opts, "read0")) + .show_error(is_present(&opts,"show-cmd-error")) .build(); let cmd_collector = Rc::new(RefCell::new(SkimItemReader::new(item_reader_option))); @@ -269,8 +269,8 @@ fn real_main() -> Result { //------------------------------------------------------------------------------ // read in the history file - let fz_query_histories = opts.values_of("history").and_then(|vals| vals.last()); - let cmd_query_histories = opts.values_of("cmd-history").and_then(|vals| vals.last()); + let fz_query_histories = last_of(&opts, "history"); + let cmd_query_histories = last_of(&opts, "cmd-history"); let query_history = fz_query_histories.and_then(|filename| read_file_lines(filename).ok()).unwrap_or_default(); let cmd_history = cmd_query_histories.and_then(|filename| read_file_lines(filename).ok()).unwrap_or_default(); @@ -283,10 +283,10 @@ fn real_main() -> Result { //------------------------------------------------------------------------------ // handle pre-selection options - let pre_select_n: Option = opts.values_of("pre-select-n").and_then(|vals| vals.last()).and_then(|s| s.parse().ok()); - let pre_select_pat = opts.values_of("pre-select-pat").and_then(|vals| vals.last()); - let pre_select_items: Option> = opts.values_of("pre-select-items").map(|vals| vals.flat_map(|m|m.split('\n')).map(|s|s.to_string()).collect()); - let pre_select_file = opts.values_of("pre-select-file").and_then(|vals| vals.last()); + let pre_select_n: Option = last_of(&opts, "pre-select-n").and_then(|s| s.parse().ok()); + let pre_select_pat = last_of(&opts, "pre-select-pat"); + let pre_select_items: Option> = opts.get_many::("pre-select-items").map(|vals| vals.flat_map(|m| m.split('\n')).map(|s|s.to_string()).collect()); + let pre_select_file = last_of(&opts, "pre-select-file"); if pre_select_n.is_some() || pre_select_pat.is_some() || pre_select_items.is_some() || pre_select_file.is_some() { let first_n = pre_select_n.unwrap_or(0); @@ -306,10 +306,10 @@ fn real_main() -> Result { //------------------------------------------------------------------------------ let bin_options = BinOptionsBuilder::default() - .filter(opts.values_of("filter").and_then(|vals| vals.last())) - .print_query(opts.is_present("print-query")) - .print_cmd(opts.is_present("print-cmd")) - .output_ending(if opts.is_present("print0") { "\0" } else { "\n" }) + .filter(last_of(&opts, "filter")) + .print_query(is_present(&opts, "print-query")) + .print_cmd(is_present(&opts, "print-cmd")) + .output_ending(if is_present(&opts, "print0") { "\0" } else { "\n" }) .build() .expect(""); @@ -324,7 +324,7 @@ fn real_main() -> Result { //------------------------------------------------------------------------------ // filter mode - if opts.is_present("filter") { + if values_of(&opts, "filter").is_some() { return filter(&bin_options, &options, rx_item); } @@ -350,7 +350,7 @@ fn real_main() -> Result { write!(stdout, "{}{}", output.cmd, bin_options.output_ending)?; } - if opts.is_present("expect") { + if values_of(&opts, "expect").is_some() { match output.final_event { Event::EvActAccept(Some(accept_key)) => { write!(stdout, "{}{}", accept_key, bin_options.output_ending)?; @@ -369,14 +369,14 @@ fn real_main() -> Result { //------------------------------------------------------------------------------ // write the history with latest item if let Some(file) = fz_query_histories { - let limit = opts.values_of("history-size").and_then(|vals| vals.last()) + let limit = last_of(&opts, "history-size") .and_then(|size| size.parse::().ok()) .unwrap_or(DEFAULT_HISTORY_SIZE); write_history_to_file(&query_history, &output.query, limit, file)?; } if let Some(file) = cmd_query_histories { - let limit = opts.values_of("cmd-history-size").and_then(|vals| vals.last()) + let limit = last_of(&opts, "cmd-history-size") .and_then(|size| size.parse::().ok()) .unwrap_or(DEFAULT_HISTORY_SIZE); write_history_to_file(&cmd_history, &output.cmd, limit, file)?; @@ -387,72 +387,58 @@ fn real_main() -> Result { fn parse_options(options: &ArgMatches) -> SkimOptions<'_> { SkimOptionsBuilder::default() - .color(options.values_of("color").and_then(|vals| vals.last())) - .min_height(options.values_of("min-height").and_then(|vals| vals.last())) - .no_height(options.is_present("no-height")) - .height(options.values_of("height").and_then(|vals| vals.last())) - .margin(options.values_of("margin").and_then(|vals| vals.last())) - .preview(options.values_of("preview").and_then(|vals| vals.last())) - .cmd(options.values_of("cmd").and_then(|vals| vals.last())) - .query(options.values_of("query").and_then(|vals| vals.last())) - .cmd_query(options.values_of("cmd-query").and_then(|vals| vals.last())) - .interactive(options.is_present("interactive")) - .prompt(options.values_of("prompt").and_then(|vals| vals.last())) - .cmd_prompt(options.values_of("cmd-prompt").and_then(|vals| vals.last())) - .bind( - options - .values_of("bind") - .map(|x| x.collect::>()) - .unwrap_or_default(), - ) - .expect(options.values_of("expect").map(|x| x.collect::>().join(","))) - .multi(if options.is_present("no-multi") { + .color(last_of(options, "color")) + .min_height(last_of(options, "min-height")) + .no_height(is_present(options, "no-height")) + .height(last_of(options, "height")) + .margin(last_of(options, "margin")) + .preview(last_of(options, "preview")) + .cmd(last_of(options, "cmd")) + .query(last_of(options, "query")) + .cmd_query(last_of(options, "cmd-query")) + .interactive(is_present(options, "interactive")) + .prompt(last_of(options, "prompt")) + .cmd_prompt(last_of(options, "cmd-prompt")) + .bind(values_of(options, "bind").unwrap_or_default()) + .expect(values_of(options, "expect").map(|x| x.join(","))) + .multi(if is_present(options, "no-multi") { false } else { - options.is_present("multi") + is_present(options, "multi") }) - .layout(options.values_of("layout").and_then(|vals| vals.last()).unwrap_or("")) - .reverse(options.is_present("reverse")) - .no_hscroll(options.is_present("no-hscroll")) - .no_mouse(options.is_present("no-mouse")) - .no_clear(options.is_present("no-clear")) - .no_clear_start(options.is_present("no-clear-start")) - .tabstop(options.values_of("tabstop").and_then(|vals| vals.last())) - .tiebreak(options.values_of("tiebreak").map(|x| x.collect::>().join(","))) - .tac(options.is_present("tac")) - .nosort(options.is_present("no-sort")) - .exact(options.is_present("exact")) - .regex(options.is_present("regex")) - .delimiter(options.values_of("delimiter").and_then(|vals| vals.last())) - .inline_info(options.is_present("inline-info")) - .header(options.values_of("header").and_then(|vals| vals.last())) + .layout(last_of(options, "layout").unwrap_or("")) + .reverse(is_present(options, "reverse")) + .no_hscroll(is_present(options, "no-hscroll")) + .no_mouse(is_present(options, "no-mouse")) + .no_clear(is_present(options, "no-clear")) + .no_clear_start(is_present(options, "no-clear-start")) + .tabstop(last_of(options, "tabstop")) + .tiebreak(values_of(options, "tiebreak").map(|x| x.join(","))) + .tac(is_present(options, "tac")) + .nosort(is_present(options, "no-sort")) + .exact(is_present(options, "exact")) + .regex(is_present(options, "regex")) + .delimiter(last_of(options, "delimiter")) + .inline_info(is_present(options, "inline-info")) + .header(last_of(options, "header")) .header_lines( - options - .values_of("header-lines") - .and_then(|vals| vals.last()) + last_of(options, "header-lines") .map(|s| s.parse::().unwrap_or(0)) .unwrap_or(0), ) - .layout(options.values_of("layout").and_then(|vals| vals.last()).unwrap_or("")) - .algorithm(FuzzyAlgorithm::of( - options.values_of("algorithm").and_then(|vals| vals.last()).unwrap(), - )) - .case(match options.value_of("case") { + .layout(last_of(options, "layout").unwrap_or("")) + .algorithm(FuzzyAlgorithm::of(last_of(options, "algorithm").unwrap())) + .case(match last_of(options, "case") { Some("smart") => CaseMatching::Smart, Some("ignore") => CaseMatching::Ignore, _ => CaseMatching::Respect, }) - .keep_right(options.is_present("keep-right")) - .skip_to_pattern( - options - .values_of("skip-to-pattern") - .and_then(|vals| vals.last()) - .unwrap_or(""), - ) - .select1(options.is_present("select-1")) - .exit0(options.is_present("exit-0")) - .sync(options.is_present("sync")) - .no_clear_if_empty(options.is_present("no-clear-if-empty")) + .keep_right(is_present(options, "keep-right")) + .skip_to_pattern(last_of(options, "skip-to-pattern").unwrap_or("")) + .select1(is_present(options, "select-1")) + .exit0(is_present(options, "exit-0")) + .sync(is_present(options, "sync")) + .no_clear_if_empty(is_present(options, "no-clear-if-empty")) .build() .unwrap() } @@ -556,3 +542,18 @@ pub fn filter( Ok(if num_matched == 0 { 1 } else { 0 }) } + +fn last_of<'a>(matches: &'a ArgMatches, id: &str) -> Option<&'a str> { + matches + .get_many::(id) + .and_then(ValuesRef::last) + .map(String::as_str) +} + +fn values_of<'a>(matches: &'a ArgMatches, id: &str) -> Option> { + matches.get_many::(id).map(|x| x.map(|x| x.as_str()).collect()) +} + +fn is_present(matches: &ArgMatches, id: &str) -> bool { + matches.get_count(id) > 0 +}