mptre / pick

A fuzzy search tool for the command-line

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Silently pass through on single choice/match

avivey opened this issue · comments

Hi, I have a feature suggestion:

If the input is only one option, pass it silently and don't go interactive.

My use case: I have a shortcut for git ls-files | grep $@ | xargs less, which basically finds a file by name and displays it. Obviously this is a little awkward if the grep matches multiple files, so I'd like to replace grep with pick, but only pop up a menu if there's actually more than one result to pick from.

I guess this can also make sense if -q is supplied and exactly one result is matched.

What do you think?

#!/bin/sh

filter ()
{
	FILTER="$( awk '
		BEGIN	{ n = 0 }
		/'$1'/	{ print $0; n++ }
		END	{ exit n }'
	)"

	[ $? -gt 1 ] && { echo "$FILTER" | pick; } || echo "$FILTER"
}

git ls-files | filter "$1" | xargs less
diff --git a/pick.c b/pick.c
index 9a3f422..354c98b 100644
--- a/pick.c
+++ b/pick.c
@@ -107,6 +107,7 @@ main(int argc, char *argv[])
        const struct choice     *choice;
        char                    *input;
        int                      c;
+       int                      one_choice = 0;
        int                      output_description = 0;
        int                      rc = 0;
 
@@ -115,8 +116,11 @@ main(int argc, char *argv[])
        if (pledge("stdio tty rpath wpath cpath", NULL) == -1)
                err(1, "pledge");
 
-       while ((c = getopt(argc, argv, "dhoq:KSvxX")) != -1)
+       while ((c = getopt(argc, argv, "1dhoq:KSvxX")) != -1)
                switch (c) {
+               case '1':
+                       one_choice = 1;
+                       break;
                case 'd':
                        descriptions = 1;
                        break;
@@ -165,13 +169,17 @@ main(int argc, char *argv[])
        }
 
        input = get_choices();
-       tty_init(1);
+       if (one_choice && choices.length == 1)
+               choice = &choices.v[0];
+       else {
+               tty_init(1);
 
-       if (pledge("stdio tty", NULL) == -1)
-               err(1, "pledge");
+               if (pledge("stdio tty", NULL) == -1)
+                       err(1, "pledge");
 
-       choice = selected_choice();
-       tty_restore(1);
+               choice = selected_choice();
+               tty_restore(1);
+       }
        if (choice != NULL) {
                printf("%s\n", choice->string);
                if (output_description)
@@ -190,11 +198,12 @@ main(int argc, char *argv[])
 __dead void
 usage(int status)
 {
-       fprintf(stderr, "usage: pick [-hvKS] [-d [-o]] [-x | -X] [-q query]\n"
+       fprintf(stderr, "usage: pick [-hvKS] [-1] [-d [-o]] [-x | -X] [-q query]\n"
            "    -h          output this help message and exit\n"
            "    -v          output the version and exit\n"
            "    -K          disable toggling of keypad transmit mode\n"
            "    -S          disable sorting\n"
+           "    -1          disable selection if there is only one choice\n"
            "    -d          read and display descriptions\n"
            "    -o          output description of selected on exit\n"
            "    -x          enable alternate screen\n"
git ls-files | grep "$1" | pick -1 | xargs less

Plenty of alternatives at this point, closing for now.