From c57d9a2a65725dce8632bea6e539517f6b5e8f7d Mon Sep 17 00:00:00 2001 From: Phil Jones Date: Thu, 23 Jun 2022 13:59:23 +0100 Subject: Add tofi-run symlink. Invoking 'tofi' now acts like dmenu, expecting newline-separated options on stdin. Also fix history file handling and add an option to disable it. --- src/config.c | 2 ++ src/entry_backend/pango.c | 1 - src/history.c | 6 ++++- src/main.c | 63 +++++++++++++++++++++++++++++++++++------------ src/tofi.h | 1 + 5 files changed, 55 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/config.c b/src/config.c index ab6aa32..81f3f2a 100644 --- a/src/config.c +++ b/src/config.c @@ -275,6 +275,8 @@ bool parse_option(struct tofi *tofi, const char *filename, size_t lineno, const tofi->window.entry.horizontal = parse_bool(filename, lineno, value, &err); } else if (strcasecmp(option, "hide-cursor") == 0) { tofi->hide_cursor = parse_bool(filename, lineno, value, &err); + } else if (strcasecmp(option, "history") == 0) { + tofi->use_history = parse_bool(filename, lineno, value, &err); } else { PARSE_ERROR(filename, lineno, "Unknown option \"%s\"\n", option); err = true; diff --git a/src/entry_backend/pango.c b/src/entry_backend/pango.c index 38b8a02..990ce55 100644 --- a/src/entry_backend/pango.c +++ b/src/entry_backend/pango.c @@ -1,5 +1,4 @@ #include -#include #include #include #include "../entry.h" diff --git a/src/history.c b/src/history.c index 4438b5d..99edf79 100644 --- a/src/history.c +++ b/src/history.c @@ -66,11 +66,14 @@ struct history history_load() return vec; } + errno = 0; if (fseek(histfile, 0, SEEK_END) != 0) { log_error("Error seeking in history file: %s.\n", strerror(errno)); fclose(histfile); return vec; } + + errno = 0; size_t len = ftell(histfile); if (fseek(histfile, 0, SEEK_SET) != 0) { log_error("Error seeking in history file: %s.\n", strerror(errno)); @@ -78,8 +81,9 @@ struct history history_load() return vec; } + errno = 0; char *buf = xmalloc(len); - if (fread(buf, 1, len, histfile) != 0) { + if (fread(buf, 1, len, histfile) != len) { log_error("Error reading history file: %s.\n", strerror(errno)); fclose(histfile); return vec; diff --git a/src/main.c b/src/main.c index e4b2d2d..2523022 100644 --- a/src/main.c +++ b/src/main.c @@ -587,10 +587,11 @@ static void usage() " --margin-left Offset from left of screen.\n" " --margin-right Offset from right of screen.\n" " --hide-cursor Hide the cursor.\n" +" --history Sort results by number of usages.\n" ); } -static int parse_args(struct tofi *tofi, int argc, char *argv[]) +static void parse_args(struct tofi *tofi, int argc, char *argv[]) { /* Option parsing with getopt. */ const struct option long_options[] = { @@ -620,6 +621,7 @@ static int parse_args(struct tofi *tofi, int argc, char *argv[]) {"margin-right", required_argument, NULL, 0}, {"layout-horizontal", required_argument, NULL, 0}, {"hide-cursor", required_argument, NULL, 0}, + {"history", required_argument, NULL, 0}, {NULL, 0, NULL, 0} }; const char *short_options = ":hc:"; @@ -669,7 +671,11 @@ static int parse_args(struct tofi *tofi, int argc, char *argv[]) opt = getopt_long(argc, argv, short_options, long_options, &option_index); } - return optind; + if (optind < argc) { + log_error("Unexpected non-option argument '%s'.\n", argv[optind]); + usage(); + exit(EXIT_FAILURE); + } } int main(int argc, char *argv[]) @@ -708,17 +714,9 @@ int main(int argc, char *argv[]) | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT, + .use_history = true, }; - log_debug("Generating command list.\n"); - log_indent(); - tofi.window.entry.history = history_load(); - tofi.window.entry.commands = compgen_cached(); - compgen_history_sort(&tofi.window.entry.commands, &tofi.window.entry.history); - tofi.window.entry.results = string_vec_copy(&tofi.window.entry.commands); - log_unindent(); - log_debug("Command list generated.\n"); - /* * Initial Wayland & XKB setup. @@ -770,6 +768,35 @@ int main(int argc, char *argv[]) */ parse_args(&tofi, argc, argv); + /* + * If we were invoked as tofi-run, generate the command list. + * Otherwise, just read standard input. + */ + if (strstr(argv[0], "-run")) { + log_debug("Generating command list.\n"); + log_indent(); + tofi.window.entry.commands = compgen_cached(); + log_unindent(); + log_debug("Command list generated.\n"); + } else { + char *line = NULL; + size_t n = 0; + tofi.window.entry.commands = string_vec_create(); + while (getline(&line, &n, stdin) != -1) { + char *c = strchr(line, '\n'); + if (c) { + *c = '\0'; + } + string_vec_add(&tofi.window.entry.commands, line); + } + free(line); + } + if (tofi.use_history) { + tofi.window.entry.history = history_load(); + compgen_history_sort(&tofi.window.entry.commands, &tofi.window.entry.history); + } + tofi.window.entry.results = string_vec_copy(&tofi.window.entry.commands); + /* * Next, we create the Wayland surface, which takes on the * layer shell role. @@ -901,10 +928,12 @@ int main(int argc, char *argv[]) if (tofi.window.entry.results.count > 0) { uint32_t selection = tofi.window.entry.selection; printf("%s\n", tofi.window.entry.results.buf[selection]); - history_add( - &tofi.window.entry.history, - tofi.window.entry.results.buf[selection]); - history_save(&tofi.window.entry.history); + if (tofi.use_history) { + history_add( + &tofi.window.entry.history, + tofi.window.entry.results.buf[selection]); + history_save(&tofi.window.entry.history); + } break; } } @@ -938,7 +967,9 @@ int main(int argc, char *argv[]) wl_registry_destroy(tofi.wl_registry); string_vec_destroy(&tofi.window.entry.commands); string_vec_destroy(&tofi.window.entry.results); - history_destroy(&tofi.window.entry.history); + if (tofi.use_history) { + history_destroy(&tofi.window.entry.history); + } #endif /* * For release builds, skip straight to display disconnection and quit. diff --git a/src/tofi.h b/src/tofi.h index be4e750..1323bd4 100644 --- a/src/tofi.h +++ b/src/tofi.h @@ -50,6 +50,7 @@ struct tofi { /* Options */ int8_t anchor; bool hide_cursor; + bool use_history; }; #endif /* CLIENT_H */ -- cgit v1.2.3