Simplified the options. - iomenu - interactive terminal-based selection menu
(HTM) git clone git://bitreich.org/iomenu git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/iomenu
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) Tags
(DIR) README
(DIR) LICENSE
---
(DIR) commit f764d7df1ae0d98852309ebce4ed01bb25e0af38
(DIR) parent 6b29b825670b511f255ef2f8bbd19db35aa68c58
(HTM) Author: Josuah Demangeon <josuah.demangeon@gandi.net>
Date: Mon, 21 Aug 2017 02:05:47 +0200
Simplified the options.
Diffstat:
M iomenu.1 | 13 +++----------
M iomenu.c | 137 +++++++++----------------------
2 files changed, 42 insertions(+), 108 deletions(-)
---
(DIR) diff --git a/iomenu.1 b/iomenu.1
@@ -1,4 +1,4 @@
-.Dd mar 19, 2017
+.Dd aug 21, 2017
.Dt IOMENU 1
.Os
.
@@ -14,9 +14,7 @@
.
.
.Nm
-.Op Fl t
-.Op Fl b
-.Op Fl s
+.Op Fl #
.Op Fl l Ar lines
.Op Fl p Ar prompt
.
@@ -48,18 +46,13 @@ lines.
Set the prompt to display at the beginning of the input to
.Ar prompt .
.
-.It Fl s
+.It Fl #
If a line starts with
.Li # ,
.Nm
will interprete it as a header, which always matches, and can not be
printed.
.
-.It Fl t Ns / Ns Fl b
-Print the menu at the top / bottom rather than at current cursor
-position.
-Reset the cursor postition afterward.
-.El
.
.Ss Selection control
.
(DIR) diff --git a/iomenu.c b/iomenu.c
@@ -10,25 +10,21 @@
#include <sys/ioctl.h>
-
#define CONTINUE 2 /* as opposed to EXIT_SUCCESS and EXIT_FAILURE */
#define CONTROL(char) (char ^ 0x40)
#define ALT(char) (char + 0x80)
#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
-
static struct winsize ws;
static struct termios termios;
-int tty_fd;
-
-static int current = 0, offset = 0, prev = 0, next = 0;
+static int ttyfd;
+static int current = 0, offset = 0, prev = 0, next = 0;
static int linec = 0, matchc = 0;
static char **linev = NULL, **matchv = NULL;
-static char input[BUFSIZ], formatted[BUFSIZ * 8];
-static int opt_tb = 0, opt_l = 255, opt_h = 0;
-static char *argv0, *opt_p = "", opt_s = '\0';
-
+static char input[BUFSIZ], formatted[BUFSIZ * 8];
+static int opt[128];
+static char *prompt = "";
static void
free_all(void)
@@ -42,18 +38,16 @@ free_all(void)
free(matchv);
}
-
static void
die(const char *s)
{
- tcsetattr(tty_fd, TCSANOW, &termios);
- close(tty_fd);
+ tcsetattr(ttyfd, TCSANOW, &termios);
+ close(ttyfd);
free_all();
perror(s);
exit(EXIT_FAILURE);
}
-
static void
set_terminal(void)
{
@@ -62,44 +56,33 @@ set_terminal(void)
/* save cursor postition */
fputs("\033[s", stderr);
- /* put cursor at the top / bottom */
- switch (opt_tb) {
- case 't': fputs("\033[H", stderr); break;
- case 'b': fprintf(stderr, "\033[%dH", ws.ws_row - opt_l); break;
- }
-
/* save attributes to `termios` */
- if (tcgetattr(tty_fd, &termios) < 0 || tcgetattr(tty_fd, &new) < 0) {
+ if (tcgetattr(ttyfd, &termios) < 0 || tcgetattr(ttyfd, &new) < 0) {
perror("tcgetattr");
exit(EXIT_FAILURE);
}
/* change to raw mode */
new.c_lflag &= ~(ICANON | ECHO | IGNBRK);
- tcsetattr(tty_fd, TCSANOW, &new);
+ tcsetattr(ttyfd, TCSANOW, &new);
}
-
static void
reset_terminal(void)
{
- extern struct termios termios;
- extern struct winsize ws;
-
int i;
/* clear terminal */
- for (i = 0; i < opt_l + 1; i++)
+ for (i = 0; i < opt['l'] + 1; i++)
fputs("\r\033[K\n", stderr);
/* reset cursor position */
fputs("\033[u", stderr);
/* set terminal back to normal mode */
- tcsetattr(tty_fd, TCSANOW, &termios);
+ tcsetattr(ttyfd, TCSANOW, &termios);
}
-
static void
read_lines(void)
{
@@ -136,12 +119,9 @@ read_lines(void)
}
}
-
static char *
format(char *str, int cols)
{
- extern char formatted[BUFSIZ * 8];
-
int i, j;
for (i = j = 0; str[i] && j < cols; i++) {
@@ -164,19 +144,15 @@ format(char *str, int cols)
return formatted;
}
-
static void
print_lines(int count)
{
- extern int opt_l;
- extern char opt_s;
-
int printed = 0, i = current / count * count;
while (printed < count && i < matchc) {
char *s = format(matchv[i], ws.ws_col - 1);
- if (opt_s && matchv[i][0] == opt_s) {
+ if (opt['#'] && matchv[i][0] == '#') {
fprintf(stderr, "\n\033[1m\033[K %s\033[m", s);
} else if (i == current) {
fprintf(stderr, "\n\033[30;47m\033[K %s\033[m", s);
@@ -191,14 +167,11 @@ print_lines(int count)
fputs("\n\033[K", stderr);
}
-
static void
print_screen(void)
{
- extern char formatted[BUFSIZ * 8];
-
int cols = ws.ws_col - 1, i;
- int count = MIN(opt_l, ws.ws_row - 1);
+ int count = MIN(opt['l'], ws.ws_row - 1);
fputs("\r\033[K", stderr);
@@ -209,8 +182,8 @@ print_screen(void)
fputs("\r", stderr);
/* prompt */
- if (opt_p[0] != '\0') {
- format(opt_p, cols);
+ if (*prompt) {
+ format(prompt, cols);
fputs("\033[30;47m ", stderr);
for (i = 0; formatted[i]; i++)
fputc(formatted[i], stderr);
@@ -226,11 +199,10 @@ print_screen(void)
fflush(stderr);
}
-
static int
match_line(char *line, char **tokv, int tokc)
{
- if (opt_s && line[0] == opt_s)
+ if (opt['#'] && line[0] == '#')
return 2;
while (tokc-- > 0)
@@ -240,24 +212,19 @@ match_line(char *line, char **tokv, int tokc)
return 1;
}
-
static void
move_line(signed int n)
{
- extern int current;
- extern char **matchv;
-
int i;
for (i = current + n; 0 <= i && i < matchc; i += n) {
- if (!opt_s || matchv[i][0] != opt_s) {
+ if (!opt['#'] || matchv[i][0] != '#') {
current = i;
break;
}
}
}
-
static void
filter_lines(void)
{
@@ -287,11 +254,10 @@ filter_lines(void)
free(tokv);
- if (opt_s && matchv[current][0] == opt_s)
+ if (opt['#'] && matchv[current][0] == '#')
move_line(+1);
}
-
static void
remove_word_input()
{
@@ -307,7 +273,6 @@ remove_word_input()
filter_lines();
}
-
static void
add_character(char key)
{
@@ -321,19 +286,15 @@ add_character(char key)
filter_lines();
}
-
static void
print_selection(void)
{
- extern int current;
- extern char **matchv, input[BUFSIZ];
-
/* header */
- if (opt_h && opt_s) {
+ if (opt['#']) {
char **match = matchv + current;
while (--match >= matchv) {
- if ((*match)[0] == opt_s) {
+ if ((*match)[0] == '#') {
fputs(*match, stdout);
break;
}
@@ -343,7 +304,7 @@ print_selection(void)
}
/* input or selection */
- if (matchc == 0 || (opt_s && matchv[current][0] == opt_s)) {
+ if (matchc == 0 || (opt['#'] && matchv[current][0] == '#')) {
puts(input);
} else {
puts(matchv[current]);
@@ -352,7 +313,6 @@ print_selection(void)
fputs("\r\033[K", stderr);
}
-
static int
input_key(void)
{
@@ -407,11 +367,8 @@ top:
return EXIT_SUCCESS;
case 033: /* escape / alt */
- if (fgetc(stdin) == 'v') {
- key = ALT('v');
- goto top;
- }
- break;
+ key = ALT(fgetc(stdin));
+ goto top;
default:
add_character((char) key);
@@ -420,7 +377,6 @@ top:
return CONTINUE;
}
-
/*
* Listen for the user input and call the appropriate functions.
*/
@@ -434,71 +390,56 @@ input_get(void)
while ((exit_code = input_key()) == CONTINUE)
print_screen();
- tcsetattr(tty_fd, TCSANOW, &termios);
+ tcsetattr(ttyfd, TCSANOW, &termios);
return exit_code;
}
-
static void
sigwinch()
{
- extern struct winsize ws;
-
- /* get window size */
- if (ioctl(tty_fd, TIOCGWINSZ, &ws) < 0)
+ if (ioctl(ttyfd, TIOCGWINSZ, &ws) < 0)
die("ioctl");
-
print_screen();
signal(SIGWINCH, sigwinch);
}
-
static void
usage(void)
{
- fprintf(stderr, "%s [-b] [-t] [-s] [-l lines] [-p prompt]\n", argv0);
-
+ fputs("iomenu [-#] [-l lines] [-p prompt]\n", stderr);
exit(EXIT_FAILURE);
}
-
int
main(int argc, char *argv[])
{
- extern char *opt_p, *argv0;
- extern int opt_l;
-
int exit_code;
- for (argv0 = argv[0], argv++, argc--; argc > 0; argv++, argc--) {
+ memset(opt, 0, 128 * sizeof (int));
+
+ opt['l'] = 255;
+ for (argv++, argc--; argc > 0; argv++, argc--) {
if (argv[0][0] != '-')
usage();
switch ((*argv)[1]) {
case 'l':
argv++; argc--;
- if (argc == 0 || sscanf(*argv, "%d", &opt_l) <= 0)
+ if (argc == 0 || sscanf(*argv, "%d", &opt['l']) <= 0)
usage();
break;
- case 't': opt_tb = 't'; break;
- case 'b': opt_tb = 'b'; break;
-
case 'p':
- argc--; argv++;
+ argv++; argc--;
if (argc == 0)
usage();
- opt_p = *argv;
- break;
-
- case 's':
- opt_s = '#';
+ prompt = *argv;
break;
- case 'h':
- opt_h = 1;
+ case '#':
+ opt['#'] = 1;
break;
default:
@@ -513,14 +454,14 @@ main(int argc, char *argv[])
if (!freopen("/dev/tty", "r", stdin) ||
!freopen("/dev/tty", "w", stderr))
die("freopen");
- tty_fd = open("/dev/tty", O_RDWR);
+ ttyfd = open("/dev/tty", O_RDWR);
set_terminal();
sigwinch();
exit_code = input_get(); /* main loop */
reset_terminal();
- close(tty_fd);
- free_all();
+ close(ttyfd);
+ freeall();
- return exit_code;
+ return exitcode;
}