icleaner page next/prev and global window dimension property - iomenu - interactive terminal-based selection menu Err bitreich.org 70 hgit clone git://bitreich.org/iomenu git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/iomenu URL:git://bitreich.org/iomenu git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/iomenu bitreich.org 70 1Log /scm/iomenu/log.gph bitreich.org 70 1Files /scm/iomenu/files.gph bitreich.org 70 1Refs /scm/iomenu/refs.gph bitreich.org 70 1Tags /scm/iomenu/tag bitreich.org 70 1README /scm/iomenu/file/README.gph bitreich.org 70 1LICENSE /scm/iomenu/file/LICENSE.gph bitreich.org 70 i--- Err bitreich.org 70 1commit 62853eb76762d6adfac4bd5cbcc410e96ebc955f /scm/iomenu/commit/62853eb76762d6adfac4bd5cbcc410e96ebc955f.gph bitreich.org 70 1parent a74019ac53549e4017a2aa36bd377c1e0c2c9fc7 /scm/iomenu/commit/a74019ac53549e4017a2aa36bd377c1e0c2c9fc7.gph bitreich.org 70 hAuthor: Josuah Demangeonā  ā µ URL:mailto:mail@josuah.net bitreich.org 70 iDate: Sun, 19 Mar 2017 11:49:25 +0100 Err bitreich.org 70 i Err bitreich.org 70 icleaner page next/prev and global window dimension property Err bitreich.org 70 i Err bitreich.org 70 iDiffstat: Err bitreich.org 70 i M iomenu.c | 199 ++++++++++++++++--------------- Err bitreich.org 70 i Err bitreich.org 70 i1 file changed, 103 insertions(+), 96 deletions(-) Err bitreich.org 70 i--- Err bitreich.org 70 1diff --git a/iomenu.c b/iomenu.c /scm/iomenu/file/iomenu.c.gph bitreich.org 70 i@@ -17,15 +17,18 @@ Err bitreich.org 70 i #define MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i-char input[BUFSIZ]; Err bitreich.org 70 i-int current = 0, offset = 0, prev = 0, next = 0; Err bitreich.org 70 i-int linec = 0, matchc = 0; Err bitreich.org 70 i-char **linev = NULL, **matchv = NULL; Err bitreich.org 70 i-char *opt_prompt = ""; Err bitreich.org 70 i-int opt_lines = 0; Err bitreich.org 70 i+static struct winsize winsize; Err bitreich.org 70 i+static struct termios termios; Err bitreich.org 70 i Err bitreich.org 70 i+static char input[BUFSIZ]; Err bitreich.org 70 i+static int current = 0, offset = 0, prev = 0, next = 0; Err bitreich.org 70 i+static int linec = 0, matchc = 0; Err bitreich.org 70 i+static char **linev = NULL, **matchv = NULL; Err bitreich.org 70 i+static char *opt_prompt = ""; Err bitreich.org 70 i+static int opt_lines = 0; Err bitreich.org 70 i Err bitreich.org 70 i-void Err bitreich.org 70 i+ Err bitreich.org 70 i+static void Err bitreich.org 70 i free_v(char **v, int c) Err bitreich.org 70 i { Err bitreich.org 70 i for (; c > 0; c--) Err bitreich.org 70 i@@ -35,7 +38,7 @@ free_v(char **v, int c) Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i-void Err bitreich.org 70 i+static void Err bitreich.org 70 i die(const char *s) Err bitreich.org 70 i { Err bitreich.org 70 i /* tcsetattr(STDIN_FILENO, TCSANOW, &termio_old); */ Err bitreich.org 70 i@@ -44,25 +47,21 @@ die(const char *s) Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i-struct termios Err bitreich.org 70 i+static void Err bitreich.org 70 i set_terminal(int tty_fd) Err bitreich.org 70 i { Err bitreich.org 70 i- struct termios termio_old; Err bitreich.org 70 i- struct termios termio_new; Err bitreich.org 70 i- Err bitreich.org 70 i- if (tcgetattr(tty_fd, &termio_old) < 0) Err bitreich.org 70 i- die("Can not get terminal attributes with tcgetattr()."); Err bitreich.org 70 i- Err bitreich.org 70 i- termio_new = termio_old; Err bitreich.org 70 i- termio_new.c_lflag &= ~(ICANON | ECHO | IGNBRK); Err bitreich.org 70 i+ if (tcgetattr(tty_fd, &termios) < 0) { Err bitreich.org 70 i+ perror("tcgetattr"); Err bitreich.org 70 i+ exit(EXIT_FAILURE); Err bitreich.org 70 i+ } Err bitreich.org 70 i Err bitreich.org 70 i- tcsetattr(tty_fd, TCSANOW, &termio_new); Err bitreich.org 70 i+ termios.c_lflag &= ~(ICANON | ECHO | IGNBRK); Err bitreich.org 70 i Err bitreich.org 70 i- return termio_old; Err bitreich.org 70 i+ tcsetattr(tty_fd, TCSANOW, &termios); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i-void Err bitreich.org 70 i+static void Err bitreich.org 70 i read_lines(void) Err bitreich.org 70 i { Err bitreich.org 70 i char buffer[BUFSIZ]; Err bitreich.org 70 i@@ -99,7 +98,7 @@ read_lines(void) Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i-int Err bitreich.org 70 i+static int Err bitreich.org 70 i match_line(char *line, char **tokv, int tokc) Err bitreich.org 70 i { Err bitreich.org 70 i for (int i = 0; i < tokc; i++) Err bitreich.org 70 i@@ -110,38 +109,7 @@ match_line(char *line, char **tokv, int tokc) Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i-void Err bitreich.org 70 i-filter_lines(void) Err bitreich.org 70 i-{ Err bitreich.org 70 i- char **tokv = NULL, *s, buffer[sizeof (input)]; Err bitreich.org 70 i- int tokc = 0, n = 0; Err bitreich.org 70 i- Err bitreich.org 70 i- current = offset = prev = next = 0; Err bitreich.org 70 i- Err bitreich.org 70 i- /* tokenize input from space characters, this comes from dmenu */ Err bitreich.org 70 i- strcpy(buffer, input); Err bitreich.org 70 i- for (s = strtok(buffer, " "); s; s = strtok(NULL, " "), tokc++) { Err bitreich.org 70 i- Err bitreich.org 70 i- if (tokc >= n) { Err bitreich.org 70 i- tokv = realloc(tokv, ++n * sizeof (*tokv)); Err bitreich.org 70 i- Err bitreich.org 70 i- if (tokv == NULL) Err bitreich.org 70 i- die("realloc"); Err bitreich.org 70 i- } Err bitreich.org 70 i- Err bitreich.org 70 i- tokv[tokc] = s; Err bitreich.org 70 i- } Err bitreich.org 70 i- Err bitreich.org 70 i- matchc = 0; Err bitreich.org 70 i- for (int i = 0; i < linec; i++) Err bitreich.org 70 i- if (match_line(linev[i], tokv, tokc)) Err bitreich.org 70 i- matchv[matchc++] = linev[i]; Err bitreich.org 70 i- Err bitreich.org 70 i- free(tokv); Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i- Err bitreich.org 70 i-void Err bitreich.org 70 i+static void Err bitreich.org 70 i print_string(char *str, int current) Err bitreich.org 70 i { Err bitreich.org 70 i fputs(current ? "\033[30;47m" : "", stderr); Err bitreich.org 70 i@@ -150,8 +118,8 @@ print_string(char *str, int current) Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i-void Err bitreich.org 70 i-print_lines(int count, int cols) Err bitreich.org 70 i+static void Err bitreich.org 70 i+print_lines(int count) Err bitreich.org 70 i { Err bitreich.org 70 i int p = 0; /* amount of lines printed */ Err bitreich.org 70 i offset = current / count * count; Err bitreich.org 70 i@@ -166,86 +134,92 @@ print_lines(int count, int cols) Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i-void Err bitreich.org 70 i-update_pages(int pos, int cols) Err bitreich.org 70 i+static int Err bitreich.org 70 i+prev_page(int pos, int cols) Err bitreich.org 70 i { Err bitreich.org 70 i- int col; Err bitreich.org 70 i+ pos--; Err bitreich.org 70 i+ for (int col = 0; pos > 0; pos--) Err bitreich.org 70 i+ if ((col += strlen(matchv[pos]) + 2) > cols) Err bitreich.org 70 i+ return pos + 1; Err bitreich.org 70 i Err bitreich.org 70 i- for (prev = pos, col = 0; prev > 0; prev--) Err bitreich.org 70 i- if ((col += strlen(matchv[prev]) + 2) > cols) Err bitreich.org 70 i- break; Err bitreich.org 70 i+ return pos; Err bitreich.org 70 i+} Err bitreich.org 70 i Err bitreich.org 70 i- for (next = pos, col = 0; next <= matchc; next++) Err bitreich.org 70 i- if ((col += strlen(matchv[next]) + 2) > cols) Err bitreich.org 70 i- break; Err bitreich.org 70 i- next++; Err bitreich.org 70 i Err bitreich.org 70 i- next--; Err bitreich.org 70 i+static int Err bitreich.org 70 i+next_page(int pos, int cols) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ for (int col = 0; pos < matchc; pos++) Err bitreich.org 70 i+ if ((col += strlen(matchv[pos]) + 2) > cols) Err bitreich.org 70 i+ return pos - 1; Err bitreich.org 70 i+ Err bitreich.org 70 i+ return pos; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i-void Err bitreich.org 70 i-print_columns(int cols) Err bitreich.org 70 i+static void Err bitreich.org 70 i+print_columns(void) Err bitreich.org 70 i { Err bitreich.org 70 i if (current < offset) { Err bitreich.org 70 i+ next = offset; Err bitreich.org 70 i offset = prev; Err bitreich.org 70 i- update_pages(offset, cols - 30 - 1); Err bitreich.org 70 i+ prev = prev_page(offset, winsize.ws_col - 30 - 1); Err bitreich.org 70 i Err bitreich.org 70 i } else if (current >= next) { Err bitreich.org 70 i+ prev = offset; Err bitreich.org 70 i offset = next; Err bitreich.org 70 i- update_pages(offset, cols - 30 - 1); Err bitreich.org 70 i+ next = next_page(offset, winsize.ws_col - 30 - 1); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i+ fputs(offset > 0 ? "< " : " ", stderr); Err bitreich.org 70 i+ Err bitreich.org 70 i for (int i = offset; i < next && i < matchc; i++) Err bitreich.org 70 i print_string(matchv[i], i == current); Err bitreich.org 70 i Err bitreich.org 70 i- Err bitreich.org 70 i if (next < matchc) Err bitreich.org 70 i- fprintf(stderr, "\033[%dC>", cols); Err bitreich.org 70 i+ fprintf(stderr, "\033[%dC>", winsize.ws_col - 30); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i-void Err bitreich.org 70 i-print_prompt(int cols) Err bitreich.org 70 i+static void Err bitreich.org 70 i+print_prompt(void) Err bitreich.org 70 i { Err bitreich.org 70 i- int limit = opt_lines ? cols : 30; Err bitreich.org 70 i+ int limit = opt_lines ? winsize.ws_col : 30 - 2; Err bitreich.org 70 i Err bitreich.org 70 i fputc('\r', stderr); Err bitreich.org 70 i- for (int i = 0; i < limit - 2; i++) Err bitreich.org 70 i+ for (int i = 0; i < limit; i++) Err bitreich.org 70 i fputc(' ', stderr); Err bitreich.org 70 i Err bitreich.org 70 i- fputs(offset > 0 ? "< " : " ", stderr); Err bitreich.org 70 i- Err bitreich.org 70 i fprintf(stderr, "\r%s %s", opt_prompt, input); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i-void Err bitreich.org 70 i+static void Err bitreich.org 70 i print_screen(int tty_fd) Err bitreich.org 70 i { Err bitreich.org 70 i- struct winsize w; Err bitreich.org 70 i int count; Err bitreich.org 70 i Err bitreich.org 70 i- if (ioctl(tty_fd, TIOCGWINSZ, &w) < 0) Err bitreich.org 70 i- die("could not get terminal size"); Err bitreich.org 70 i+ if (ioctl(tty_fd, TIOCGWINSZ, &winsize) < 0) Err bitreich.org 70 i+ die("ioctl"); Err bitreich.org 70 i Err bitreich.org 70 i- count = MIN(opt_lines, w.ws_row - 2); Err bitreich.org 70 i+ count = MIN(opt_lines, winsize.ws_row - 2); Err bitreich.org 70 i Err bitreich.org 70 i fputs("\r\033[K", stderr); Err bitreich.org 70 i Err bitreich.org 70 i if (opt_lines) { Err bitreich.org 70 i- print_lines(count, w.ws_col); Err bitreich.org 70 i+ print_lines(count); Err bitreich.org 70 i fprintf(stderr, "\033[%dA", count + 1); Err bitreich.org 70 i+ Err bitreich.org 70 i } else { Err bitreich.org 70 i fputs("\033[30C", stderr); Err bitreich.org 70 i- print_columns(w.ws_col); Err bitreich.org 70 i+ print_columns(); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i- print_prompt(w.ws_col); Err bitreich.org 70 i+ print_prompt(); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i-void Err bitreich.org 70 i+static void Err bitreich.org 70 i print_clear(int lines) Err bitreich.org 70 i { Err bitreich.org 70 i for (int i = 0; i < lines + 1; i++) Err bitreich.org 70 i@@ -254,7 +228,40 @@ print_clear(int lines) Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i-void Err bitreich.org 70 i+static void Err bitreich.org 70 i+filter_lines(void) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ char **tokv = NULL, *s, buffer[sizeof (input)]; Err bitreich.org 70 i+ int tokc = 0, n = 0; Err bitreich.org 70 i+ Err bitreich.org 70 i+ current = offset = prev = next = 0; Err bitreich.org 70 i+ Err bitreich.org 70 i+ strcpy(buffer, input); Err bitreich.org 70 i+ Err bitreich.org 70 i+ for (s = strtok(buffer, " "); s; s = strtok(NULL, " "), tokc++) { Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (tokc >= n) { Err bitreich.org 70 i+ tokv = realloc(tokv, ++n * sizeof (*tokv)); Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (tokv == NULL) Err bitreich.org 70 i+ die("realloc"); Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ tokv[tokc] = s; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ matchc = 0; Err bitreich.org 70 i+ for (int i = 0; i < linec; i++) Err bitreich.org 70 i+ if (match_line(linev[i], tokv, tokc)) Err bitreich.org 70 i+ matchv[matchc++] = linev[i]; Err bitreich.org 70 i+ Err bitreich.org 70 i+ free(tokv); Err bitreich.org 70 i+ Err bitreich.org 70 i+ next = next_page(0, winsize.ws_col - 30 - 1); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+ Err bitreich.org 70 i+static void Err bitreich.org 70 i remove_word_input() Err bitreich.org 70 i { Err bitreich.org 70 i int len = strlen(input) - 1; Err bitreich.org 70 i@@ -270,7 +277,7 @@ remove_word_input() Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i-void Err bitreich.org 70 i+static void Err bitreich.org 70 i add_character(char key) Err bitreich.org 70 i { Err bitreich.org 70 i int len = strlen(input); Err bitreich.org 70 i@@ -287,7 +294,7 @@ add_character(char key) Err bitreich.org 70 i /* Err bitreich.org 70 i * Send the selection to stdout. Err bitreich.org 70 i */ Err bitreich.org 70 i-void Err bitreich.org 70 i+static void Err bitreich.org 70 i print_selection(void) Err bitreich.org 70 i { Err bitreich.org 70 i fputs("\r\033[K", stderr); Err bitreich.org 70 i@@ -303,7 +310,7 @@ print_selection(void) Err bitreich.org 70 i /* Err bitreich.org 70 i * Perform action associated with key Err bitreich.org 70 i */ Err bitreich.org 70 i-int Err bitreich.org 70 i+static int Err bitreich.org 70 i input_key(FILE *tty_fp) Err bitreich.org 70 i { Err bitreich.org 70 i char key = fgetc(tty_fp); Err bitreich.org 70 i@@ -359,20 +366,20 @@ input_key(FILE *tty_fp) Err bitreich.org 70 i /* Err bitreich.org 70 i * Listen for the user input and call the appropriate functions. Err bitreich.org 70 i */ Err bitreich.org 70 i-int Err bitreich.org 70 i+static int Err bitreich.org 70 i input_get(int tty_fd) Err bitreich.org 70 i { Err bitreich.org 70 i FILE *tty_fp = fopen("/dev/tty", "r"); Err bitreich.org 70 i int exit_code; Err bitreich.org 70 i- struct termios termio_old = set_terminal(tty_fd); Err bitreich.org 70 i Err bitreich.org 70 i input[0] = '\0'; Err bitreich.org 70 i Err bitreich.org 70 i+ set_terminal(tty_fd); Err bitreich.org 70 i+ Err bitreich.org 70 i while ((exit_code = input_key(tty_fp)) == CONTINUE) Err bitreich.org 70 i print_screen(tty_fd); Err bitreich.org 70 i Err bitreich.org 70 i- /* resets the terminal to the previous state. */ Err bitreich.org 70 i- tcsetattr(tty_fd, TCSANOW, &termio_old); Err bitreich.org 70 i+ set_terminal(tty_fd); Err bitreich.org 70 i Err bitreich.org 70 i fclose(tty_fp); Err bitreich.org 70 i Err bitreich.org 70 i@@ -380,7 +387,7 @@ input_get(int tty_fd) Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i-void Err bitreich.org 70 i+static void Err bitreich.org 70 i usage(void) Err bitreich.org 70 i { Err bitreich.org 70 i fputs("usage: iomenu [-l lines] [-p prompt]\n", stderr); Err bitreich.org 70 .