aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2019-11-01 14:43:06 +0100
committerBruce Hill <bruce@bruce-hill.com>2019-11-01 14:43:06 +0100
commitfedc1751fe89d1f547eb1d90614252b29e910492 (patch)
tree54faa7cca384259bbd5f2424d4987f0b8ec09897
parent00653d0b11e6ba2c4b975a904435eb9eaa714509 (diff)
Added a --read0 option and fixed up the documentation.
-rw-r--r--README.md2
-rw-r--r--ask.134
-rw-r--r--ask.c36
3 files changed, 48 insertions, 24 deletions
diff --git a/README.md b/README.md
index ece7021..c4d4fc3 100644
--- a/README.md
+++ b/README.md
@@ -32,5 +32,7 @@ Here's a simple program to move a file from the current directory:
`$XDG_DATA/ask/<name>.hist` (`~/.local/share/ask/<name>.hist` by default) for
use with up/down arrow keys. Maximum of 1000 entries are stored per log file.
+For the full set of command line options, run `man ./ask.1`.
+
## License
`ask` is released under the MIT License. See LICENSE for details.
diff --git a/ask.1 b/ask.1
index df05429..e00a549 100644
--- a/ask.1
+++ b/ask.1
@@ -5,16 +5,23 @@
ask \- A tiny command line tool for getting user input
.SH SYNOPSIS
.B ask
-[\fI-hPqvyn\fR]
-[\fI-q\fR |\fI--query=initial\fR]
-[[\fI-p\fR |\fI--prompt=\fR]\fIprompt \fR
-[\fIoptions...\fR]]
+[\fI-Q\fR|\fI--quickpick\fR]
+[\fI-P\fR|\fI--password\fR]
+[\fI-0\fR|\fI--read0\fR]
+[\fI-y\fR|\fI--yes\fR]
+[\fI-n\fR|\fI--no\fR]
+[(\fI-H \fR|\fI--history=\fR) name]
+[\fI-h\fR|\fI--help\fR]
+[\fI-v\fR|\fI--version\fR]
+[(\fI-q\fR |\fI--query=\fR) initial]
+[(\fI-p\fR |\fI--prompt=\fR) prompt]
+[\fIoptions...\fR]
.SH DESCRIPTION
\fBask\fR is a tiny console application that displays a prompt, gets user input
(with line editing and fuzzy finding functionality), and prints the result to
standard output
.SH OPTIONS
-.B \-q
+.B \-Q
.B \--quickpick
When used with fuzzy finding, as soon as exactly one match is found, exit and
print it.
@@ -23,6 +30,10 @@ print it.
.B \--password
Use password mode, which does not print user input as it's being typed.
+.B \-0
+.B \--read0
+Read input delineated by NULL bytes instead of newlines.
+
.B \-v
.B \--version
Print \fBask\fR's version and exit.
@@ -31,16 +42,21 @@ Print \fBask\fR's version and exit.
.B \--help
Print \fBask\fR's usage and exit.
-.B \-q
-.B \--query=
+.B \-q <query>
+.B \--query=<query>
If given, pre-populate the user input with this value.
-.B \-p
-.B \--prompt=
+.B \-p <prompt>
+.B \--prompt=<prompt>
If provided, display the given prompt in bold. If the \fI-p\fR and
\fI--prompt=\fR flags are not used, the first positional argument is used as
the prompt, or \fB"> "\fR if there are no positional arguments.
+.B \-H <file>
+.B \--history=<file>
+Use the given file as a history file. With a history file, you can browse
+previously selected values with the up/down arrow keys.
+
.B \-y
.B \--yes
Quickpick between "y" and "n" with "[Y/n]" appended to the prompt, exiting with
diff --git a/ask.c b/ask.c
index 87b4ac9..b3cad99 100644
--- a/ask.c
+++ b/ask.c
@@ -2,11 +2,12 @@
* Copyright 2019 Bruce Hill
* Released under the MIT License (see LICENSE for details)
* Usage: ask [-Q|--quickpick] [-y|--yes] [-n|--no] [-P|--password] [[-H |--history=]name]
- * [-v|--version] [-h|--help] [-q |--query=initial] [[-p |--prompt=]prompt [options...]]
+ * [-v|--version] [-h|--help] [-0|--read0] [-q |--query=initial] [[-p |--prompt=]prompt [options...]]
* --password: password mode
* --quickpick: quickpick mode (exit when only one option remains)
* --version: print version and exit
* --help: print usage and exit
+ * --read0: read input delimited by NULL bytes instead of newlines
* --query: initial value to pre-populate user input
* --prompt: use the given prompt (displayed in bold)
* --yes: append " [Y/n]" to the prompt, use quickpick mode,
@@ -28,7 +29,7 @@
#include "bterm.h"
-#define ASK_VERSION "0.3"
+#define ASK_VERSION "0.4"
#define LOWERCASE(c) ('A' <= (c) && (c) <= 'Z' ? ((c) + 'a' - 'A') : (c))
#define EQ(a, b) (case_sensitive ? (a) == (b) : LOWERCASE(a) == LOWERCASE(b))
#define PASSWORD "-\\|/"
@@ -373,20 +374,8 @@ int main(int argc, char *argv[])
int yes = 0, no = 0;
char *prompt = NULL, *query = NULL, *histname = NULL;
char **opts = NULL;
+ char delim = '\n';
size_t linescap = 0, linecap = 0;
- int nopts = 0;
- char *line = NULL;
- struct pollfd pfd = {STDIN_FILENO, POLLIN, 0};
- if (poll(&pfd, 1, 50) > 0) {
- while ((getline(&line, &linecap, stdin)) >= 0) {
- if ((size_t)nopts >= linescap)
- opts = memcheck(realloc(opts, (linescap += 100)*sizeof(char*)));
- if (!line[0]) continue;
- if (line[strlen(line)-1] == '\n')
- line[strlen(line)-1] = '\0';
- opts[nopts++] = memcheck(strdup(line));
- }
- }
int a;
for (a = 1; a < argc; a++) {
if (strcmp(argv[a], "-H") == 0) {
@@ -399,6 +388,7 @@ int main(int argc, char *argv[])
case 'Q': quickpick = 1; break;
case 'h': goto help_flag;
case 'v': goto version_flag;
+ case '0': delim = '\0'; break;
case 'y': yes = 1; quickpick = 1; break;
case 'n': no = 1; quickpick = 1; break;
}
@@ -407,6 +397,8 @@ int main(int argc, char *argv[])
prompt = argv[++a];
} else if (strcmp(argv[a], "-q") == 0) {
query = argv[++a];
+ } else if (strncmp(argv[a], "--read0", strlen("--read0")) == 0) {
+ delim = '\0';
} else if (strncmp(argv[a], "--prompt=", strlen("--prompt=")) == 0) {
prompt = &argv[a][strlen("--prompt=")];
} else if (strncmp(argv[a], "--query=", strlen("--query=")) == 0) {
@@ -437,6 +429,20 @@ int main(int argc, char *argv[])
}
if (!prompt && a < argc) prompt = argv[a++];
+ int nopts = 0;
+ char *line = NULL;
+ struct pollfd pfd = {STDIN_FILENO, POLLIN, 0};
+ if (poll(&pfd, 1, 50) > 0) {
+ while ((getdelim(&line, &linecap, delim, stdin)) >= 0) {
+ if ((size_t)nopts >= linescap)
+ opts = memcheck(realloc(opts, (linescap += 100)*sizeof(char*)));
+ if (!line[0]) continue;
+ if (line[strlen(line)-1] == '\n')
+ line[strlen(line)-1] = '\0';
+ opts[nopts++] = memcheck(strdup(line));
+ }
+ }
+
while (a < argc) {
if ((size_t)nopts >= linescap)
opts = memcheck(realloc(opts, (linescap += 100)*sizeof(char*)));