Skip to content

Commit

Permalink
Merge pull request #76 from lotabout/issue-70
Browse files Browse the repository at this point in the history
fix #70: accept multiple values for most options
  • Loading branch information
lotabout authored Jan 18, 2018
2 parents 7c5a539 + 6fbe8b7 commit 224af6e
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 42 deletions.
17 changes: 12 additions & 5 deletions src/curses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -536,9 +536,12 @@ impl Curses {

// parse the option of window height of skim

let min_height = options.value_of("min-height").map(|x| x.parse::<u16>().unwrap_or(10)).unwrap();
let min_height = options.values_of("min-height")
.and_then(|vals| vals.last())
.map(|x| x.parse::<u16>().unwrap_or(10)).unwrap();
let no_height = options.is_present("no-height");
let height = options.value_of("height").map(Curses::parse_margin_string).unwrap();
let height = options.values_of("height").and_then(|vals| vals.last())
.map(Curses::parse_margin_string).unwrap();

let height = if no_height {Margin::Percent(100)} else {height};

Expand Down Expand Up @@ -582,12 +585,16 @@ impl Curses {
};

// parse options for margin
let margins = options.value_of("margin").map(Curses::parse_margin).unwrap();
let margins = options.values_of("margin").and_then(|vals| vals.last())
.map(Curses::parse_margin).unwrap();
let (margin_top, margin_right, margin_bottom, margin_left) = margins;

// parse options for preview window
let preview_cmd_exist = options.is_present("preview");
let (preview_direction, preview_size, preview_wrap, preview_shown) = options.value_of("preview-window").map(Curses::parse_preview).unwrap();
let (preview_direction, preview_size, preview_wrap, preview_shown) = options.values_of("preview-window")
.and_then(|vals| vals.last())
.map(Curses::parse_preview)
.unwrap();
let mut ret = Curses {
term: Some(term),
top: 0,
Expand Down Expand Up @@ -916,7 +923,7 @@ pub struct ColorTheme {
impl ColorTheme {
pub fn init_from_options(options: &ArgMatches) {
// register
let theme = if let Some(color) = options.value_of("color") {
let theme = if let Some(color) = options.values_of("color").and_then(|vals| vals.last()) {
ColorTheme::from_options(color)
} else {
ColorTheme::dark256()
Expand Down
48 changes: 24 additions & 24 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,47 +181,47 @@ fn real_main() -> i32 {
.arg(Arg::with_name("bind").long("bind").short("b").multiple(true).takes_value(true))
.arg(Arg::with_name("multi").long("multi").short("m"))
.arg(Arg::with_name("no-multi").long("no-multi"))
.arg(Arg::with_name("prompt").long("prompt").short("p").takes_value(true).default_value("> "))
.arg(Arg::with_name("cmd-prompt").long("cmd-prompt").takes_value(true).default_value("c> "))
.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"))
.arg(Arg::with_name("tiebreak").long("tiebreak").short("t").multiple(true).takes_value(true))
.arg(Arg::with_name("ansi").long("ansi"))
.arg(Arg::with_name("exact").long("exact").short("e"))
.arg(Arg::with_name("cmd").long("cmd").short("cmd").takes_value(true))
.arg(Arg::with_name("cmd").long("cmd").short("cmd").multiple(true).takes_value(true))
.arg(Arg::with_name("interactive").long("interactive").short("i"))
.arg(Arg::with_name("query").long("query").short("q").takes_value(true))
.arg(Arg::with_name("cmd-query").long("cmd-query").takes_value(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"))
.arg(Arg::with_name("delimiter").long("delimiter").short("d").takes_value(true))
.arg(Arg::with_name("nth").long("nth").short("n").takes_value(true))
.arg(Arg::with_name("with-nth").long("with-nth").takes_value(true))
.arg(Arg::with_name("replstr").short("I").takes_value(true))
.arg(Arg::with_name("color").long("color").takes_value(true))
.arg(Arg::with_name("margin").long("margin").takes_value(true).default_value("0,0,0,0"))
.arg(Arg::with_name("min-height").long("min-height").takes_value(true).default_value("10"))
.arg(Arg::with_name("height").long("height").takes_value(true).default_value("100%"))
.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"))
.arg(Arg::with_name("preview").long("preview").takes_value(true))
.arg(Arg::with_name("preview-window").long("preview-window").takes_value(true).default_value("right:50%"))
.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"))
.arg(Arg::with_name("algorithm").long("algo").takes_value(true).default_value(""))

.arg(Arg::with_name("algorithm").long("algo").multiple(true).takes_value(true).default_value(""))
.arg(Arg::with_name("literal").long("literal"))
.arg(Arg::with_name("no-mouse").long("no-mouse"))

.arg(Arg::with_name("cycle").long("cycle"))
.arg(Arg::with_name("no-hscroll").long("no-hscroll"))
.arg(Arg::with_name("hscroll-off").long("hscroll-off").takes_value(true).default_value("10"))
.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"))
.arg(Arg::with_name("jump-labels").long("jump-labels").takes_value(true).default_value("abcdefghijklmnopqrstuvwxyz"))
.arg(Arg::with_name("jump-labels").long("jump-labels").multiple(true).takes_value(true).default_value("abcdefghijklmnopqrstuvwxyz"))
.arg(Arg::with_name("border").long("border"))
.arg(Arg::with_name("inline-info").long("inline-info"))
.arg(Arg::with_name("header").long("header").takes_value(true).default_value(""))
.arg(Arg::with_name("header-lines").long("header-lines").takes_value(true).default_value("1"))
.arg(Arg::with_name("tabstop").long("tabstop").takes_value(true).default_value("8"))
.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("1"))
.arg(Arg::with_name("tabstop").long("tabstop").multiple(true).takes_value(true).default_value("8"))
.arg(Arg::with_name("no-bold").long("no-bold"))
.arg(Arg::with_name("history").long("history").takes_value(true).default_value(""))
.arg(Arg::with_name("history-size").long("history-size").takes_value(true).default_value("500"))
.arg(Arg::with_name("history").long("history").multiple(true).takes_value(true).default_value(""))
.arg(Arg::with_name("history-size").long("history-size").multiple(true).takes_value(true).default_value("500"))
.arg(Arg::with_name("print-query").long("print-query"))
.arg(Arg::with_name("print-cmd").long("print-cmd"))
.arg(Arg::with_name("read0").long("read0"))
Expand Down
8 changes: 4 additions & 4 deletions src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,15 +110,15 @@ impl Model {
self.reverse = true;
}

if let Some(preview_cmd) = options.value_of("preview") {
if let Some(preview_cmd) = options.values_of("preview").and_then(|vals| vals.last()) {
self.preview_cmd = Some(preview_cmd.to_string());
}

if let Some(preview_window) = options.value_of("preview-window") {
if let Some(preview_window) = options.values_of("preview-window").and_then(|vals| vals.last()) {
self.preview_hidden = preview_window.find("hidden").is_some();
}

if let Some(delimiter) = options.value_of("delimiter") {
if let Some(delimiter) = options.values_of("delimiter").and_then(|vals| vals.last()) {
self.delimiter = Regex::new(delimiter)
.unwrap_or_else(|_| Regex::new(r"[ \t\n]+").unwrap());
}
Expand All @@ -139,7 +139,7 @@ impl Model {
self.no_hscroll = true;
}

if let Some(tabstop_str) = options.value_of("tabstop") {
if let Some(tabstop_str) = options.values_of("tabstop").and_then(|vals| vals.last()) {
let tabstop = tabstop_str.parse::<usize>().unwrap_or(8);
self.tabstop = max(1, tabstop);
}
Expand Down
14 changes: 8 additions & 6 deletions src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,31 +61,33 @@ impl Query {
}

pub fn parse_options(&mut self, options: &ArgMatches) {
if let Some(base_cmd) = options.value_of("cmd") {
// some options accept multiple values, thus take the last one

if let Some(base_cmd) = options.values_of("cmd").and_then(|vals| vals.last()) {
self.base_cmd = base_cmd.to_string();
}

if let Some(query) = options.value_of("query") {
if let Some(query) = options.values_of("query").and_then(|vals| vals.last()) {
self.query_before = query.chars().collect();
}

if let Some(cmd_query) = options.value_of("cmd-query") {
if let Some(cmd_query) = options.values_of("cmd-query").and_then(|vals| vals.last()) {
self.cmd_before = cmd_query.chars().collect();
}

if let Some(replstr) = options.value_of("replstr") {
if let Some(replstr) = options.values_of("replstr").and_then(|vals| vals.last()) {
self.replstr = replstr.to_string();
}

if options.is_present("interactive") {
self.mode = QueryMode::CMD;
}

if let Some(query_prompt) = options.value_of("prompt") {
if let Some(query_prompt) = options.values_of("prompt").and_then(|vals| vals.last()) {
self.query_prompt = query_prompt.to_string();
}

if let Some(cmd_prompt) = options.value_of("cmd-prompt") {
if let Some(cmd_prompt) = options.values_of("cmd-prompt").and_then(|vals| vals.last()) {
self.cmd_prompt = cmd_prompt.to_string();
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,20 @@ impl ReaderOption {
self.use_ansi_color = true;
}

if let Some(delimiter) = options.value_of("delimiter") {
if let Some(delimiter) = options.values_of("delimiter").and_then(|vals| vals.last()) {
self.delimiter = Regex::new(&(".*?".to_string() + delimiter))
.unwrap_or_else(|_| Regex::new(r".*?[\t ]").unwrap());
}

if let Some(transform_fields) = options.value_of("with-nth") {
if let Some(transform_fields) = options.values_of("with-nth").and_then(|vals| vals.last()) {
self.transform_fields = transform_fields.split(',')
.filter_map(|string| {
parse_range(string)
})
.collect();
}

if let Some(matching_fields) = options.value_of("nth") {
if let Some(matching_fields) = options.values_of("nth").and_then(|vals| vals.last()) {
self.matching_fields = matching_fields.split(',')
.filter_map(|string| {
parse_range(string)
Expand Down
76 changes: 76 additions & 0 deletions test/test_skim.py
Original file line number Diff line number Diff line change
Expand Up @@ -570,5 +570,81 @@ def test_reserved_options(self):
self.tmux.until(lambda lines: lines[-1].startswith('>'))
self.tmux.send_keys(Key('Enter'))

def test_multiple_option_values_should_be_accepted(self):
# normally we'll put some default options to SKIM_DEFAULT_OPTIONS and override it in command
# line. this test will ensure multiple values are accepted.

self.tmux.send_keys(f"echo -e 'a\\nb' | {self.sk('--bind=ctrl-a:cancel --bind ctrl-b:cancel')}", Key('Enter'))
self.tmux.until(lambda lines: lines[-1].startswith('>'))
self.tmux.send_keys(Key('Enter'))

self.tmux.send_keys(f"echo -e 'a\\nb' | {self.sk('--prompt a --prompt b -p c')}", Key('Enter'))
self.tmux.until(lambda lines: lines[-1].startswith('c'))
self.tmux.send_keys(Key('Enter'))

self.tmux.send_keys(f"echo -e 'a\\nb' | {self.sk('-i --cmd-prompt a --cmd-prompt b')}", Key('Enter'))
self.tmux.until(lambda lines: lines[-1].startswith('b'))
self.tmux.send_keys(Key('Enter'))

self.tmux.send_keys(f"echo -e 'a\\nb' | {self.sk('--expect=ctrl-a --expect=ctrl-v')}", Key('Enter'))
self.tmux.until(lambda lines: lines[-1].startswith('>'))
self.tmux.send_keys(Key('Enter'))

self.tmux.send_keys(f"echo -e 'a\\nb' | {self.sk('--tiebreak=index --tiebreak=score')}", Key('Enter'))
self.tmux.until(lambda lines: lines[-1].startswith('>'))
self.tmux.send_keys(Key('Enter'))

self.tmux.send_keys(f"echo -e 'a\\nb' | {self.sk('--cmd asdf --cmd find')}", Key('Enter'))
self.tmux.until(lambda lines: lines[-1].startswith('>'))
self.tmux.send_keys(Key('Enter'))

self.tmux.send_keys(f"echo -e 'a\\nb' | {self.sk('--query asdf -q xyz')}", Key('Enter'))
self.tmux.until(lambda lines: lines[-1].startswith('> xyz'))
self.tmux.send_keys(Key('Enter'))

self.tmux.send_keys(f"echo -e 'a\\nb' | {self.sk('-i --cmd-query asdf --cmd-query xyz')}", Key('Enter'))
self.tmux.until(lambda lines: lines[-1].startswith('c> xyz'))
self.tmux.send_keys(Key('Enter'))

self.tmux.send_keys(f"echo -e 'a\\nb' | {self.sk('--delimiter , --delimiter . -d ,')}", Key('Enter'))
self.tmux.until(lambda lines: lines[-1].startswith('>'))
self.tmux.send_keys(Key('Enter'))

self.tmux.send_keys(f"echo -e 'a\\nb' | {self.sk('--nth 1,2 --nth=1,3 -n 1,3')}", Key('Enter'))
self.tmux.until(lambda lines: lines[-1].startswith('>'))
self.tmux.send_keys(Key('Enter'))

self.tmux.send_keys(f"echo -e 'a\\nb' | {self.sk('--with-nth 1,2 --with-nth=1,3')}", Key('Enter'))
self.tmux.until(lambda lines: lines[-1].startswith('>'))
self.tmux.send_keys(Key('Enter'))

self.tmux.send_keys(f"echo -e 'a\\nb' | {self.sk('-I {} -I XX')}", Key('Enter'))
self.tmux.until(lambda lines: lines[-1].startswith('>'))
self.tmux.send_keys(Key('Enter'))

self.tmux.send_keys(f"echo -e 'a\\nb' | {self.sk('--color base --color light')}", Key('Enter'))
self.tmux.until(lambda lines: lines[-1].startswith('>'))
self.tmux.send_keys(Key('Enter'))

self.tmux.send_keys(f"echo -e 'a\\nb' | {self.sk('--margin 30% --margin 0')}", Key('Enter'))
self.tmux.until(lambda lines: lines[-1].startswith('>'))
self.tmux.send_keys(Key('Enter'))

self.tmux.send_keys(f"echo -e 'a\\nb' | {self.sk('--min-height 30% --min-height 10')}", Key('Enter'))
self.tmux.until(lambda lines: lines[-1].startswith('>'))
self.tmux.send_keys(Key('Enter'))

self.tmux.send_keys(f"echo -e 'a\\nb' | {self.sk('--height 30% --height 10')}", Key('Enter'))
self.tmux.until(lambda lines: lines[-1].startswith('>'))
self.tmux.send_keys(Key('Enter'))

self.tmux.send_keys(f"""echo -e 'a\\nb' | {self.sk('--preview "ls {}" --preview "cat {}"')}""", Key('Enter'))
self.tmux.until(lambda lines: lines[-1].startswith('>'))
self.tmux.send_keys(Key('Enter'))

self.tmux.send_keys(f"echo -e 'a\\nb' | {self.sk('--preview-window up --preview-window down')}", Key('Enter'))
self.tmux.until(lambda lines: lines[-1].startswith('>'))
self.tmux.send_keys(Key('Enter'))

if __name__ == '__main__':
unittest.main()

0 comments on commit 224af6e

Please sign in to comment.