summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--src/fzy.c133
-rw-r--r--src/options.c104
-rw-r--r--src/options.h12
4 files changed, 142 insertions, 109 deletions
diff --git a/Makefile b/Makefile
index f4e3db7..6d5e742 100644
--- a/Makefile
+++ b/Makefile
@@ -11,7 +11,7 @@ INSTALL=install
INSTALL_PROGRAM=$(INSTALL)
INSTALL_DATA=${INSTALL} -m 644
-OBJECTS=src/fzy.o src/match.o src/tty.o src/choices.o
+OBJECTS=src/fzy.o src/match.o src/tty.o src/choices.o src/options.o
TESTOBJECTS=test/fzytest.c src/match.o src/choices.o
all: fzy
diff --git a/src/fzy.c b/src/fzy.c
index f5470fd..28dc7a6 100644
--- a/src/fzy.c
+++ b/src/fzy.c
@@ -2,21 +2,16 @@
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
-#include <getopt.h>
#include <limits.h>
#include "match.h"
#include "tty.h"
#include "choices.h"
+#include "options.h"
#include "../config.h"
-static int flag_show_scores = 0;
-
-static size_t num_lines = 10;
-static size_t scrolloff = 1;
-
-static const char *prompt = "> ";
+options_t options;
#define SEARCH_SIZE_MAX 4096
static char search[SEARCH_SIZE_MAX + 1] = {0};
@@ -24,7 +19,7 @@ static char search[SEARCH_SIZE_MAX + 1] = {0};
static void clear(tty_t *tty) {
tty_setcol(tty, 0);
size_t line = 0;
- while (line++ < num_lines) {
+ while (line++ < options.num_lines) {
tty_newline(tty);
}
tty_clearline(tty);
@@ -42,7 +37,7 @@ static void draw_match(tty_t *tty, const char *choice, int selected) {
size_t maxwidth = tty_getwidth(tty);
- if (flag_show_scores)
+ if (options.show_scores)
tty_printf(tty, "(%5.2f) ", score);
if (selected)
@@ -66,16 +61,17 @@ static void draw_match(tty_t *tty, const char *choice, int selected) {
}
static void draw(tty_t *tty, choices_t *choices) {
+ unsigned int num_lines = options.num_lines;
size_t start = 0;
size_t current_selection = choices->selection;
- if (current_selection + scrolloff >= num_lines) {
- start = current_selection + scrolloff - num_lines + 1;
+ if (current_selection + options.scrolloff >= num_lines) {
+ start = current_selection + options.scrolloff - num_lines + 1;
if (start + num_lines >= choices_available(choices)) {
start = choices_available(choices) - num_lines;
}
}
tty_setcol(tty, 0);
- tty_printf(tty, "%s%s", prompt, search);
+ tty_printf(tty, "%s%s", options.prompt, search);
tty_clearline(tty);
for (size_t i = start; i < start + num_lines; i++) {
tty_printf(tty, "\n");
@@ -86,7 +82,7 @@ static void draw(tty_t *tty, choices_t *choices) {
}
}
tty_moveup(tty, num_lines);
- tty_setcol(tty, strlen(prompt) + strlen(search));
+ tty_setcol(tty, strlen(options.prompt) + strlen(search));
tty_flush(tty);
}
@@ -167,119 +163,40 @@ static void run(tty_t *tty, choices_t *choices) {
} while (1);
}
-static const char *usage_str =
- ""
- "Usage: fzy [OPTION]...\n"
- " -l, --lines=LINES Specify how many lines of results to show (default 10)\n"
- " -p, --prompt=PROMPT Input prompt (default '> ')\n"
- " -q, --query=QUERY Use QUERY as the initial search string\n"
- " -e, --show-matches=QUERY Output the sorted matches of QUERY\n"
- " -t, --tty=TTY Specify file to use as TTY device (default /dev/tty)\n"
- " -s, --show-scores Show the scores of each match\n"
- " -h, --help Display this help and exit\n"
- " -v, --version Output version information and exit\n";
-
-static void usage(const char *argv0) {
- fprintf(stderr, usage_str, argv0);
-}
-
-static struct option longopts[] = {{"show-matches", required_argument, NULL, 'e'},
- {"query", required_argument, NULL, 'q'},
- {"lines", required_argument, NULL, 'l'},
- {"tty", required_argument, NULL, 't'},
- {"prompt", required_argument, NULL, 'p'},
- {"show-scores", no_argument, NULL, 's'},
- {"version", no_argument, NULL, 'v'},
- {"benchmark", optional_argument, NULL, 'b'},
- {"help", no_argument, NULL, 'h'},
- {NULL, 0, NULL, 0}};
-
int main(int argc, char *argv[]) {
- int benchmark = 0;
- const char *filter = NULL;
- const char *tty_filename = "/dev/tty";
- char c;
- while ((c = getopt_long(argc, argv, "vhse:q:l:t:p:", longopts, NULL)) != -1) {
- switch (c) {
- case 'v':
- printf("%s " VERSION " (c) 2014 John Hawthorn\n", argv[0]);
- exit(EXIT_SUCCESS);
- case 's':
- flag_show_scores = 1;
- break;
- case 'q':
- strncpy(search, optarg, SEARCH_SIZE_MAX);
- break;
- case 'e':
- filter = optarg;
- break;
- case 'b':
- if (optarg) {
- if (sscanf(optarg, "%d", &benchmark) != 1) {
- usage(argv[0]);
- exit(EXIT_FAILURE);
- }
- } else {
- benchmark = 100;
- }
- break;
- case 't':
- tty_filename = optarg;
- break;
- case 'p':
- prompt = optarg;
- break;
- case 'l': {
- int l;
- if (!strcmp(optarg, "max")) {
- l = INT_MAX;
- } else if (sscanf(optarg, "%d", &l) != 1 || l < 3) {
- fprintf(stderr, "Invalid format for --lines: %s\n", optarg);
- fprintf(stderr, "Must be integer in range 3..\n");
- usage(argv[0]);
- exit(EXIT_FAILURE);
- }
- num_lines = l;
- } break;
- case 'h':
- default:
- usage(argv[0]);
- exit(EXIT_SUCCESS);
- }
- }
- if (optind != argc) {
- usage(argv[0]);
- exit(EXIT_FAILURE);
- }
+ options_parse(&options, argc, argv);
choices_t choices;
choices_init(&choices);
choices_fread(&choices, stdin);
- if (benchmark) {
- if (!filter) {
+ if (options.benchmark) {
+ if (!options.filter) {
fprintf(stderr, "Must specify -e/--show-matches with --benchmark\n");
exit(EXIT_FAILURE);
}
- for (int i = 0; i < benchmark; i++)
- choices_search(&choices, filter);
- } else if (filter) {
- choices_search(&choices, filter);
+ for (int i = 0; i < options.benchmark; i++)
+ choices_search(&choices, options.filter);
+ } else if (options.filter) {
+ choices_search(&choices, options.filter);
for (size_t i = 0; i < choices_available(&choices); i++) {
- if (flag_show_scores)
+ if (options.show_scores)
printf("%f\t", choices_getscore(&choices, i));
printf("%s\n", choices_get(&choices, i));
}
} else {
/* interactive */
tty_t tty;
- tty_init(&tty, tty_filename);
+ tty_init(&tty, options.tty_filename);
+
+ if (options.num_lines > choices.size)
+ options.num_lines = choices.size;
- if (num_lines > choices.size)
- num_lines = choices.size;
+ if (options.num_lines + 1 > tty_getheight(&tty))
+ options.num_lines = tty_getheight(&tty) - 1;
- if (num_lines + 1 > tty_getheight(&tty))
- num_lines = tty_getheight(&tty) - 1;
+ if (options.init_search)
+ strncpy(search, options.init_search, SEARCH_SIZE_MAX);
run(&tty, &choices);
}
diff --git a/src/options.c b/src/options.c
new file mode 100644
index 0000000..3150ead
--- /dev/null
+++ b/src/options.c
@@ -0,0 +1,104 @@
+#include <getopt.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "options.h"
+
+static const char *usage_str =
+ ""
+ "Usage: fzy [OPTION]...\n"
+ " -l, --lines=LINES Specify how many lines of results to show (default 10)\n"
+ " -p, --prompt=PROMPT Input prompt (default '> ')\n"
+ " -q, --query=QUERY Use QUERY as the initial search string\n"
+ " -e, --show-matches=QUERY Output the sorted matches of QUERY\n"
+ " -t, --tty=TTY Specify file to use as TTY device (default /dev/tty)\n"
+ " -s, --show-scores Show the scores of each match\n"
+ " -h, --help Display this help and exit\n"
+ " -v, --version Output version information and exit\n";
+
+static void usage(const char *argv0) {
+ fprintf(stderr, usage_str, argv0);
+}
+
+static struct option longopts[] = {{"show-matches", required_argument, NULL, 'e'},
+ {"query", required_argument, NULL, 'q'},
+ {"lines", required_argument, NULL, 'l'},
+ {"tty", required_argument, NULL, 't'},
+ {"prompt", required_argument, NULL, 'p'},
+ {"show-scores", no_argument, NULL, 's'},
+ {"version", no_argument, NULL, 'v'},
+ {"benchmark", optional_argument, NULL, 'b'},
+ {"help", no_argument, NULL, 'h'},
+ {NULL, 0, NULL, 0}};
+
+void options_set_defaults(options_t *options) {
+ /* set defaults */
+ options->benchmark = 0;
+ options->filter = NULL;
+ options->init_search = NULL;
+ options->tty_filename = "/dev/tty";
+ options->show_scores = 0;
+ options->num_lines = 10;
+ options->scrolloff = 1;
+ options->prompt = "> ";
+}
+
+void options_parse(options_t *options, int argc, char *argv[]) {
+ options_set_defaults(options);
+
+ char c;
+ while ((c = getopt_long(argc, argv, "vhse:q:l:t:p:", longopts, NULL)) != -1) {
+ switch (c) {
+ case 'v':
+ printf("%s " VERSION " (c) 2014 John Hawthorn\n", argv[0]);
+ exit(EXIT_SUCCESS);
+ case 's':
+ options->show_scores = 1;
+ break;
+ case 'q':
+ options->init_search = optarg;
+ break;
+ case 'e':
+ options->filter = optarg;
+ break;
+ case 'b':
+ if (optarg) {
+ if (sscanf(optarg, "%d", &options->benchmark) != 1) {
+ usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+ } else {
+ options->benchmark = 100;
+ }
+ break;
+ case 't':
+ options->tty_filename = optarg;
+ break;
+ case 'p':
+ options->prompt = optarg;
+ break;
+ case 'l': {
+ int l;
+ if (!strcmp(optarg, "max")) {
+ l = INT_MAX;
+ } else if (sscanf(optarg, "%d", &l) != 1 || l < 3) {
+ fprintf(stderr, "Invalid format for --lines: %s\n", optarg);
+ fprintf(stderr, "Must be integer in range 3..\n");
+ usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+ options->num_lines = l;
+ } break;
+ case 'h':
+ default:
+ usage(argv[0]);
+ exit(EXIT_SUCCESS);
+ }
+ }
+ if (optind != argc) {
+ usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+}
diff --git a/src/options.h b/src/options.h
new file mode 100644
index 0000000..e19e292
--- /dev/null
+++ b/src/options.h
@@ -0,0 +1,12 @@
+typedef struct {
+ int benchmark;
+ const char *filter;
+ const char *init_search;
+ const char *tty_filename;
+ int show_scores;
+ unsigned int num_lines;
+ unsigned int scrolloff;
+ const char *prompt;
+} options_t;
+
+void options_parse(options_t *options, int argc, char *argv[]);