split main argument parsing in another function - iomenu - interactive terminal-based selection menu HTML git clone git://bitreich.org/iomenu git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/iomenu DIR Log DIR Files DIR Refs DIR Tags DIR README DIR LICENSE --- DIR commit 33e51a893ff428e83faf59b5116dde88e3f83c50 DIR parent abf6f97c75cc29af910c1031397854c40b5c5f09 HTML Author: Josuah Demangeon <josuah.demangeon@gandi.net> Date: Mon, 21 Aug 2017 02:48:22 +0200 split main argument parsing in another function Diffstat: M iomenu.c | 149 ++++++++++++++----------------- 1 file changed, 69 insertions(+), 80 deletions(-) --- DIR diff --git a/iomenu.c b/iomenu.c @@ -27,7 +27,7 @@ static int opt[128]; static char *prompt = ""; static void -free_all(void) +freelines(void) { if (linev) { for (; linec > 0; linec--) @@ -43,18 +43,18 @@ die(const char *s) { tcsetattr(ttyfd, TCSANOW, &termios); close(ttyfd); - free_all(); + freelines(); perror(s); exit(EXIT_FAILURE); } static void -set_terminal(void) +setterminal(void) { struct termios new; /* save cursor postition */ - fputs("\033[s", stderr); + fputs("\x1b[s", stderr); /* save attributes to `termios` */ if (tcgetattr(ttyfd, &termios) < 0 || tcgetattr(ttyfd, &new) < 0) { @@ -68,23 +68,23 @@ set_terminal(void) } static void -reset_terminal(void) +resetterminal(void) { int i; /* clear terminal */ for (i = 0; i < opt['l'] + 1; i++) - fputs("\r\033[K\n", stderr); + fputs("\r\x1b[K\n", stderr); /* reset cursor position */ - fputs("\033[u", stderr); + fputs("\x1b[u", stderr); /* set terminal back to normal mode */ tcsetattr(ttyfd, TCSANOW, &termios); } static void -read_lines(void) +readlines(void) { char buffer[BUFSIZ]; int size = 1 << 6; @@ -96,7 +96,7 @@ read_lines(void) linev[0] = matchv[0] = NULL; - /* read the file into an array of lines */ + /* read the file into an array of lines as the lines never change */ for (; fgets(buffer, sizeof buffer, stdin); linec++, matchc++) { int len = strlen(buffer); @@ -145,62 +145,60 @@ format(char *str, int cols) } static void -print_lines(int count) +printlines(int count) { int printed = 0, i = current / count * count; while (printed < count && i < matchc) { - char *s = format(matchv[i], ws.ws_col - 1); if (opt['#'] && matchv[i][0] == '#') { - fprintf(stderr, "\n\033[1m\033[K %s\033[m", s); + char *s = format(matchv[i], ws.ws_col); + fprintf(stderr, "\n\x1b[1m\x1b[K%s\x1b[m", s + 1); + } else if (i == current) { - fprintf(stderr, "\n\033[30;47m\033[K %s\033[m", s); + char *s = format(matchv[i], ws.ws_col - 3); + fprintf(stderr, "\n\x1b[30;47m\x1b[K %s\x1b[m", s); + } else { - fprintf(stderr, "\n\033[K %s\033[m", s); + char *s = format(matchv[i], ws.ws_col - 3); + fprintf(stderr, "\n\x1b[K %s", s); } i++; printed++; } while (printed++ < count) - fputs("\n\033[K", stderr); + fputs("\n\x1b[K", stderr); } static void -print_screen(void) +printscreen(void) { int cols = ws.ws_col - 1, i; int count = MIN(opt['l'], ws.ws_row - 1); - fputs("\r\033[K", stderr); + fputs("\r\x1b[K", stderr); - /* items */ - print_lines(count); - fprintf(stderr, "\033[%dA", count); + printlines(count); + fprintf(stderr, "\x1b[%dA\r", count); - fputs("\r", stderr); - - /* prompt */ if (*prompt) { format(prompt, cols); - fputs("\033[30;47m ", stderr); + fputs("\x1b[30;47m ", stderr); for (i = 0; formatted[i]; i++) fputc(formatted[i], stderr); - fputs(" \033[m", stderr); + fputs(" \x1b[m", stderr); cols -= strlen(formatted) + 1; } fputc(' ', stderr); - - /* input */ fputs(format(input, cols), stderr); fflush(stderr); } static int -match_line(char *line, char **tokv, int tokc) +matchline(char *line, char **tokv, int tokc) { if (opt['#'] && line[0] == '#') return 2; @@ -213,7 +211,7 @@ match_line(char *line, char **tokv, int tokc) } static void -move_line(signed int n) +move(signed int n) { int i; @@ -226,7 +224,7 @@ move_line(signed int n) } static void -filter_lines(void) +filter(void) { char **tokv = NULL, *s, buffer[sizeof (input)]; int tokc = 0, n = 0, i; @@ -249,17 +247,17 @@ filter_lines(void) matchc = 0; for (i = 0; i < linec; i++) - if (match_line(linev[i], tokv, tokc)) + if (matchline(linev[i], tokv, tokc)) matchv[matchc++] = linev[i]; free(tokv); if (opt['#'] && matchv[current][0] == '#') - move_line(+1); + move(+1); } static void -remove_word_input() +removeword() { int len = strlen(input) - 1, i; @@ -270,11 +268,11 @@ remove_word_input() for (i = len; i >= 0 && !isspace(input[i]); i--) input[i] = '\0'; - filter_lines(); + filter(); } static void -add_character(char key) +addchar(char key) { int len = strlen(input); @@ -283,11 +281,11 @@ add_character(char key) input[len + 1] = '\0'; } - filter_lines(); + filter(); } static void -print_selection(void) +printselection(void) { /* header */ if (opt['#']) { @@ -310,11 +308,11 @@ print_selection(void) puts(matchv[current]); } - fputs("\r\033[K", stderr); + fputs("\r\x1b[K", stderr); } static int -input_key(void) +key(void) { int key = fgetc(stdin); @@ -326,81 +324,63 @@ top: case CONTROL('U'): input[0] = '\0'; - filter_lines(); + filter(); break; case CONTROL('W'): - remove_word_input(); + removeword(); break; case 127: case CONTROL('H'): /* backspace */ input[strlen(input) - 1] = '\0'; - filter_lines(); + filter(); break; case CONTROL('N'): - move_line(+1); + move(+1); break; case CONTROL('P'): - move_line(-1); + move(-1); break; case CONTROL('V'): - move_line(ws.ws_row - 1); + move(ws.ws_row - 1); break; case ALT('v'): - move_line(-ws.ws_row + 1); + move(-ws.ws_row + 1); break; case CONTROL('I'): /* tab */ if (linec > 0) strcpy(input, matchv[current]); - filter_lines(); + filter(); break; case CONTROL('J'): /* enter */ case CONTROL('M'): - print_selection(); + printselection(); return EXIT_SUCCESS; - case 033: /* escape / alt */ + case 0x1b: /* escape / alt */ key = ALT(fgetc(stdin)); goto top; default: - add_character((char) key); + addchar((char) key); } return CONTINUE; } -/* - * Listen for the user input and call the appropriate functions. - */ -static int -input_get(void) -{ - int exit_code; - - input[0] = '\0'; - - while ((exit_code = input_key()) == CONTINUE) - print_screen(); - - tcsetattr(ttyfd, TCSANOW, &termios); - - return exit_code; -} - static void sigwinch() { if (ioctl(ttyfd, TIOCGWINSZ, &ws) < 0) die("ioctl"); - print_screen(); + printscreen(); signal(SIGWINCH, sigwinch); } @@ -412,11 +392,9 @@ usage(void) exit(EXIT_FAILURE); } -int -main(int argc, char *argv[]) +static void +parseopt(int argc, char *argv[]) { - int exit_code; - memset(opt, 0, 128 * sizeof (int)); opt['l'] = 255; @@ -446,22 +424,33 @@ main(int argc, char *argv[]) usage(); } } +} - setlocale(LC_ALL, ""); - read_lines(); - filter_lines(); +int +main(int argc, char *argv[]) +{ + int exitcode; + + parseopt(argc, argv); + + readlines(); + filter(); if (!freopen("/dev/tty", "r", stdin) || !freopen("/dev/tty", "w", stderr)) die("freopen"); ttyfd = open("/dev/tty", O_RDWR); - set_terminal(); + setterminal(); sigwinch(); - exit_code = input_get(); /* main loop */ - reset_terminal(); + + input[0] = '\0'; + while ((exitcode = key()) == CONTINUE) + printscreen(); + + resetterminal(); close(ttyfd); - freeall(); + freelines(); return exitcode; }