summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hawthorn <john@hawthorn.email>2019-08-16 01:17:40 -0700
committerGitHub <noreply@github.com>2019-08-16 01:17:40 -0700
commitb7ff1a61a845253fb090126c6cd9f29f028b66e6 (patch)
tree5a3662fb7b40386a686e5cdd0d5a0f8adef7f549
parenta318e00e30df4056c78ff4edf38376feb4d57dab (diff)
parent79e48082f579f6c02a55b7cff81ecee1c4127b29 (diff)
Merge pull request #121 from jhawthorn/read-null
Add -0/--read-null
-rw-r--r--src/choices.c7
-rw-r--r--src/choices.h2
-rw-r--r--src/fzy.c8
-rw-r--r--src/options.c26
-rw-r--r--src/options.h1
-rw-r--r--src/tty.c4
-rw-r--r--src/tty.h1
-rw-r--r--src/tty_interface.c6
-rw-r--r--test/acceptance/acceptance_test.rb1
9 files changed, 37 insertions, 19 deletions
diff --git a/src/choices.c b/src/choices.c
index a8c24b6..fe2f80b 100644
--- a/src/choices.c
+++ b/src/choices.c
@@ -46,7 +46,7 @@ static void *safe_realloc(void *buffer, size_t size) {
return buffer;
}
-void choices_fread(choices_t *c, FILE *file) {
+void choices_fread(choices_t *c, FILE *file, char input_delimiter) {
/* Save current position for parsing later */
size_t buffer_start = c->buffer_size;
@@ -72,9 +72,10 @@ void choices_fread(choices_t *c, FILE *file) {
*/
/* Tokenize input and add to choices */
+ const char *line_end = c->buffer + c->buffer_size;
char *line = c->buffer + buffer_start;
do {
- char *nl = strchr(line, '\n');
+ char *nl = strchr(line, input_delimiter);
if (nl)
*nl++ = '\0';
@@ -83,7 +84,7 @@ void choices_fread(choices_t *c, FILE *file) {
choices_add(c, line);
line = nl;
- } while (line);
+ } while (line && line < line_end);
}
static void choices_resize(choices_t *c, size_t new_capacity) {
diff --git a/src/choices.h b/src/choices.h
index e8a598b..925478e 100644
--- a/src/choices.h
+++ b/src/choices.h
@@ -28,7 +28,7 @@ typedef struct {
} choices_t;
void choices_init(choices_t *c, options_t *options);
-void choices_fread(choices_t *c, FILE *file);
+void choices_fread(choices_t *c, FILE *file, char input_delimiter);
void choices_destroy(choices_t *c);
void choices_add(choices_t *c, const char *choice);
size_t choices_available(choices_t *c);
diff --git a/src/fzy.c b/src/fzy.c
index 6b9aa5a..c2e5600 100644
--- a/src/fzy.c
+++ b/src/fzy.c
@@ -27,11 +27,11 @@ int main(int argc, char *argv[]) {
fprintf(stderr, "Must specify -e/--show-matches with --benchmark\n");
exit(EXIT_FAILURE);
}
- choices_fread(&choices, stdin);
+ choices_fread(&choices, stdin, options.input_delimiter);
for (int i = 0; i < options.benchmark; i++)
choices_search(&choices, options.filter);
} else if (options.filter) {
- choices_fread(&choices, stdin);
+ choices_fread(&choices, stdin, options.input_delimiter);
choices_search(&choices, options.filter);
for (size_t i = 0; i < choices_available(&choices); i++) {
if (options.show_scores)
@@ -42,13 +42,13 @@ int main(int argc, char *argv[]) {
/* interactive */
if (isatty(STDIN_FILENO))
- choices_fread(&choices, stdin);
+ choices_fread(&choices, stdin, options.input_delimiter);
tty_t tty;
tty_init(&tty, options.tty_filename);
if (!isatty(STDIN_FILENO))
- choices_fread(&choices, stdin);
+ choices_fread(&choices, stdin, options.input_delimiter);
if (options.num_lines > choices.size)
options.num_lines = choices.size;
diff --git a/src/options.c b/src/options.c
index 7e4d414..58f8fa0 100644
--- a/src/options.c
+++ b/src/options.c
@@ -17,6 +17,7 @@ static const char *usage_str =
" -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"
+ " -0, --read-null Read input delimited by ASCII NUL characters\n"
" -j, --workers NUM Use NUM workers for searching. (default is # of CPUs)\n"
" -h, --help Display this help and exit\n"
" -v, --version Output version information and exit\n";
@@ -31,6 +32,7 @@ static struct option longopts[] = {{"show-matches", required_argument, NULL, 'e'
{"tty", required_argument, NULL, 't'},
{"prompt", required_argument, NULL, 'p'},
{"show-scores", no_argument, NULL, 's'},
+ {"read-null", no_argument, NULL, '0'},
{"version", no_argument, NULL, 'v'},
{"benchmark", optional_argument, NULL, 'b'},
{"workers", required_argument, NULL, 'j'},
@@ -39,22 +41,23 @@ static struct option longopts[] = {{"show-matches", required_argument, NULL, 'e'
void options_init(options_t *options) {
/* set defaults */
- options->benchmark = 0;
- options->filter = NULL;
- options->init_search = NULL;
- options->show_scores = 0;
- options->scrolloff = 1;
- options->tty_filename = DEFAULT_TTY;
- options->num_lines = DEFAULT_NUM_LINES;
- options->prompt = DEFAULT_PROMPT;
- options->workers = DEFAULT_WORKERS;
+ options->benchmark = 0;
+ options->filter = NULL;
+ options->init_search = NULL;
+ options->show_scores = 0;
+ options->scrolloff = 1;
+ options->tty_filename = DEFAULT_TTY;
+ options->num_lines = DEFAULT_NUM_LINES;
+ options->prompt = DEFAULT_PROMPT;
+ options->workers = DEFAULT_WORKERS;
+ options->input_delimiter = '\n';
}
void options_parse(options_t *options, int argc, char *argv[]) {
options_init(options);
int c;
- while ((c = getopt_long(argc, argv, "vhse:q:l:t:p:j:", longopts, NULL)) != -1) {
+ while ((c = getopt_long(argc, argv, "vhs0e:q:l:t:p:j:", longopts, NULL)) != -1) {
switch (c) {
case 'v':
printf("%s " VERSION " © 2014-2018 John Hawthorn\n", argv[0]);
@@ -62,6 +65,9 @@ void options_parse(options_t *options, int argc, char *argv[]) {
case 's':
options->show_scores = 1;
break;
+ case '0':
+ options->input_delimiter = '\0';
+ break;
case 'q':
options->init_search = optarg;
break;
diff --git a/src/options.h b/src/options.h
index 01a43fd..6098a64 100644
--- a/src/options.h
+++ b/src/options.h
@@ -11,6 +11,7 @@ typedef struct {
unsigned int scrolloff;
const char *prompt;
unsigned int workers;
+ char input_delimiter;
} options_t;
void options_init(options_t *options);
diff --git a/src/tty.c b/src/tty.c
index f8de9f5..733477e 100644
--- a/src/tty.c
+++ b/src/tty.c
@@ -184,6 +184,10 @@ void tty_printf(tty_t *tty, const char *fmt, ...) {
va_end(args);
}
+void tty_putc(tty_t *tty, char c) {
+ fputc(c, tty->fout);
+}
+
void tty_flush(tty_t *tty) {
fflush(tty->fout);
}
diff --git a/src/tty.h b/src/tty.h
index 6c73a6e..013360e 100644
--- a/src/tty.h
+++ b/src/tty.h
@@ -51,6 +51,7 @@ void tty_moveup(tty_t *tty, int i);
void tty_setcol(tty_t *tty, int col);
void tty_printf(tty_t *tty, const char *fmt, ...);
+void tty_putc(tty_t *tty, char c);
void tty_flush(tty_t *tty);
size_t tty_getwidth(tty_t *tty);
diff --git a/src/tty_interface.c b/src/tty_interface.c
index f366a23..225f33a 100644
--- a/src/tty_interface.c
+++ b/src/tty_interface.c
@@ -65,7 +65,11 @@ static void draw_match(tty_interface_t *state, const char *choice, int selected)
} else {
tty_setfg(tty, TTY_COLOR_NORMAL);
}
- tty_printf(tty, "%c", choice[i]);
+ if (choice[i] == '\n') {
+ tty_putc(tty, ' ');
+ } else {
+ tty_printf(tty, "%c", choice[i]);
+ }
}
tty_setwrap(tty);
tty_setnormal(tty);
diff --git a/test/acceptance/acceptance_test.rb b/test/acceptance/acceptance_test.rb
index 52c6af0..ba3ec01 100644
--- a/test/acceptance/acceptance_test.rb
+++ b/test/acceptance/acceptance_test.rb
@@ -456,6 +456,7 @@ Usage: fzy [OPTION]...
-e, --show-matches=QUERY Output the sorted matches of QUERY
-t, --tty=TTY Specify file to use as TTY device (default /dev/tty)
-s, --show-scores Show the scores of each match
+ -0, --read-null Read input delimited by ASCII NUL characters
-j, --workers NUM Use NUM workers for searching. (default is # of CPUs)
-h, --help Display this help and exit
-v, --version Output version information and exit