iiomenu.c: horizontal mode with -l 0 - 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 695c25f7dc0613e9aa3e9057b333ec22c0e580f9 /scm/iomenu/commit/695c25f7dc0613e9aa3e9057b333ec22c0e580f9.gph bitreich.org 70 1parent 5ac10691e817e4bfb903449a99614a1184d03a7e /scm/iomenu/commit/5ac10691e817e4bfb903449a99614a1184d03a7e.gph bitreich.org 70 hAuthor: Josuah Demangeon URL:mailto:josuah.demangeon@gandi.net bitreich.org 70 iDate: Sun, 3 Sep 2017 20:09:12 +0200 Err bitreich.org 70 i Err bitreich.org 70 iiomenu.c: horizontal mode with -l 0 Err bitreich.org 70 i Err bitreich.org 70 iDiffstat: Err bitreich.org 70 i M iomenu.c | 215 +++++++++++++++++++------------ Err bitreich.org 70 i Err bitreich.org 70 i1 file changed, 135 insertions(+), 80 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@@ -14,6 +14,7 @@ Err bitreich.org 70 i #include "utf8.h" Err bitreich.org 70 i Err bitreich.org 70 i #define CONTINUE 2 /* as opposed to EXIT_SUCCESS and EXIT_FAILURE */ Err bitreich.org 70 i+#define MARGIN 30 /* space for the input before the horizontal list */ Err bitreich.org 70 i Err bitreich.org 70 i #define CTL(char) (char ^ 0x40) Err bitreich.org 70 i #define ALT(char) (char + 0x80) Err bitreich.org 70 i@@ -53,6 +54,34 @@ die(const char *s) Err bitreich.org 70 i } Err bitreich.org 70 i 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+ int size = 0; Err bitreich.org 70 i+ size_t len; Err bitreich.org 70 i+ Err bitreich.org 70 i+ do { Err bitreich.org 70 i+ if (linec >= size) { Err bitreich.org 70 i+ size += BUFSIZ; Err bitreich.org 70 i+ linev = realloc(linev, sizeof (char **) * size); Err bitreich.org 70 i+ matchv = realloc(matchv, sizeof (char **) * size); Err bitreich.org 70 i+ if (!linev || !matchv) Err bitreich.org 70 i+ die("realloc"); Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ linev[linec] = malloc(LINE_MAX + 1); Err bitreich.org 70 i+ if (!(fgets(linev[linec], LINE_MAX, stdin))) { Err bitreich.org 70 i+ free(linev[linec]); Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ len = strlen(linev[linec]); Err bitreich.org 70 i+ if (len > 0 && linec[linev][len - 1] == '\n') Err bitreich.org 70 i+ linev[linec][len - 1] = '\0'; Err bitreich.org 70 i+ Err bitreich.org 70 i+ } while (++linec, ++matchc); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+static void Err bitreich.org 70 i set_terminal(void) Err bitreich.org 70 i { Err bitreich.org 70 i struct termios new; Err bitreich.org 70 i@@ -83,48 +112,73 @@ reset_terminal(void) Err bitreich.org 70 i /* reset cursor position */ Err bitreich.org 70 i fputs("\033[u", stderr); Err bitreich.org 70 i Err bitreich.org 70 i- /* set terminal back to normal mode */ Err bitreich.org 70 i tcsetattr(ttyfd, TCSANOW, &termios); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i-static void Err bitreich.org 70 i-read_lines(void) Err bitreich.org 70 i+static size_t Err bitreich.org 70 i+str_width(char *s) Err bitreich.org 70 i { Err bitreich.org 70 i- int size = 0; Err bitreich.org 70 i- size_t len; Err bitreich.org 70 i+ int width = 0; Err bitreich.org 70 i Err bitreich.org 70 i- do { Err bitreich.org 70 i- if (linec >= size) { Err bitreich.org 70 i- size += BUFSIZ; Err bitreich.org 70 i- linev = realloc(linev, sizeof (char **) * size); Err bitreich.org 70 i- matchv = realloc(matchv, sizeof (char **) * size); Err bitreich.org 70 i- if (!linev || !matchv) Err bitreich.org 70 i- die("realloc"); Err bitreich.org 70 i- } Err bitreich.org 70 i+ while (*s) { Err bitreich.org 70 i+ if (*s++ == '\t') Err bitreich.org 70 i+ width += (width + 7) % 8; Err bitreich.org 70 i+ else Err bitreich.org 70 i+ width++; Err bitreich.org 70 i+ } Err bitreich.org 70 i Err bitreich.org 70 i- linev[linec] = malloc(LINE_MAX + 1); Err bitreich.org 70 i- if (!(fgets(linev[linec], LINE_MAX, stdin))) { Err bitreich.org 70 i- free(linev[linec]); Err bitreich.org 70 i- break; Err bitreich.org 70 i- } Err bitreich.org 70 i+ return width; Err bitreich.org 70 i+} Err bitreich.org 70 i Err bitreich.org 70 i- len = strlen(linev[linec]); Err bitreich.org 70 i- if (len > 0 && linec[linev][len - 1] == '\n') Err bitreich.org 70 i- linev[linec][len - 1] = '\0'; 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 Err bitreich.org 70 i- } while (++linec, ++matchc); Err bitreich.org 70 i+ pos -= pos > 0 ? 1 : 0; Err bitreich.org 70 i+ for (col = 0; pos > 0; pos--) Err bitreich.org 70 i+ if ((col += str_width(matchv[pos]) + 2) > cols) Err bitreich.org 70 i+ return pos + 1; Err bitreich.org 70 i+ return pos; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i-static size_t Err bitreich.org 70 i-string_width(char *s) 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- int width = 0; Err bitreich.org 70 i+ int col; Err bitreich.org 70 i Err bitreich.org 70 i- while (*s) Err bitreich.org 70 i- if (*s++ == '\t') Err bitreich.org 70 i- width += (width + 7) % 8; Err bitreich.org 70 i+ for (col = 0; pos < matchc; pos++) Err bitreich.org 70 i+ if ((col += str_width(matchv[pos]) + 2) > cols) Err bitreich.org 70 i+ return pos; Err bitreich.org 70 i+ return pos; Err bitreich.org 70 i+} Err bitreich.org 70 i Err bitreich.org 70 i- return width; Err bitreich.org 70 i+static void Err bitreich.org 70 i+move(signed int sign) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ int i; Err bitreich.org 70 i+ Err bitreich.org 70 i+ for (i = current + sign; 0 <= i && i < matchc; i += sign) { Err bitreich.org 70 i+ if (!opt['#'] || matchv[i][0] != '#') { Err bitreich.org 70 i+ current = i; Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ } 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+move_page(signed int sign) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ int i = current - current % rows + rows * sign; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (!opt['l']) Err bitreich.org 70 i+ return; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (0 > i || i > matchc) Err bitreich.org 70 i+ return; Err bitreich.org 70 i+ Err bitreich.org 70 i+ current = i - 1; Err bitreich.org 70 i+ move(+1); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i static char * Err bitreich.org 70 i@@ -149,10 +203,10 @@ format(char *str, int cols) Err bitreich.org 70 i *fmt++ = *str++; Err bitreich.org 70 i col++; Err bitreich.org 70 i Err bitreich.org 70 i- } else { Err bitreich.org 70 i- *fmt++ = '?'; Err bitreich.org 70 i- col++; Err bitreich.org 70 i- str++; Err bitreich.org 70 i+ } else { Err bitreich.org 70 i+ *fmt++ = '?'; Err bitreich.org 70 i+ col++; Err bitreich.org 70 i+ str++; Err bitreich.org 70 i } Err bitreich.org 70 i } Err bitreich.org 70 i *fmt = '\0'; Err bitreich.org 70 i@@ -165,22 +219,51 @@ print_lines(void) Err bitreich.org 70 i { Err bitreich.org 70 i int printed = 0, i = current - current % rows; Err bitreich.org 70 i Err bitreich.org 70 i- while (printed < rows && i < matchc) { Err bitreich.org 70 i+ for (; printed < rows && i < matchc; i++, printed++) { Err bitreich.org 70 i+ fprintf(stderr, Err bitreich.org 70 i+ opt['#'] && matchv[i][0] == '#' ? Err bitreich.org 70 i+ "\n\033[1m\033[K %s\033[m" : Err bitreich.org 70 i+ i == current ? Err bitreich.org 70 i+ "\n\033[47;30m\033[K %s\033[m" : Err bitreich.org 70 i+ "\n\033[K %s", Err bitreich.org 70 i+ format(matchv[i], ws.ws_col - 1) Err bitreich.org 70 i+ ); Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ while (printed++ < rows) Err bitreich.org 70 i+ fputs("\n\033[K", stderr); Err bitreich.org 70 i+} Err bitreich.org 70 i Err bitreich.org 70 i- char *s = format(matchv[i], ws.ws_col - 1); Err bitreich.org 70 i+static void Err bitreich.org 70 i+print_segments(void) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ int i; Err bitreich.org 70 i Err bitreich.org 70 i- if (opt['#'] && matchv[i][0] == '#') Err bitreich.org 70 i- fprintf(stderr, "\n\033[1m\033[K %s\033[m", s); Err bitreich.org 70 i- else if (i == current) Err bitreich.org 70 i- fprintf(stderr, "\n\033[30;47m\033[K %s\033[m", s); Err bitreich.org 70 i- else Err bitreich.org 70 i- fprintf(stderr, "\n\033[K %s", s); Err bitreich.org 70 i+ if (current < offset) { Err bitreich.org 70 i+ next = offset; Err bitreich.org 70 i+ offset = prev_page(offset, ws.ws_col - MARGIN - 4); Err bitreich.org 70 i Err bitreich.org 70 i- i++; printed++; Err bitreich.org 70 i+ } else if (current >= next) { Err bitreich.org 70 i+ offset = next; Err bitreich.org 70 i+ next = next_page(offset, ws.ws_col - MARGIN - 4); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i- while (printed++ < rows) Err bitreich.org 70 i- fputs("\n\033[K", stderr); Err bitreich.org 70 i+ fprintf(stderr, "\r\033[K\033[%dC", MARGIN); Err bitreich.org 70 i+ fputs(offset > 0 ? "< " : " ", stderr); Err bitreich.org 70 i+ Err bitreich.org 70 i+ for (i = offset; i < next && i < matchc; i++) { Err bitreich.org 70 i+ fprintf(stderr, Err bitreich.org 70 i+ opt['#'] && matchv[i][0] == '#' ? "\033[1m %s \033[m" : Err bitreich.org 70 i+ i == current ? "\033[7m %s \033[m" : Err bitreich.org 70 i+ " %s ", Err bitreich.org 70 i+ format(matchv[i], ws.ws_col - 1) Err bitreich.org 70 i+ ); 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\b>", ws.ws_col - MARGIN); Err bitreich.org 70 i+ Err bitreich.org 70 i+ fputc('\r', stderr); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i static void Err bitreich.org 70 i@@ -188,10 +271,12 @@ print_screen(void) Err bitreich.org 70 i { Err bitreich.org 70 i int cols = ws.ws_col - 1; 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- print_lines(); Err bitreich.org 70 i- fprintf(stderr, "\033[%dA\r", rows); Err bitreich.org 70 i+ if (opt['l'] > 0) { Err bitreich.org 70 i+ print_lines(); Err bitreich.org 70 i+ fprintf(stderr, "\033[%dA\r", rows); Err bitreich.org 70 i+ } else { Err bitreich.org 70 i+ print_segments(); Err bitreich.org 70 i+ } Err bitreich.org 70 i Err bitreich.org 70 i if (*prompt) { Err bitreich.org 70 i format(prompt, cols - 2); Err bitreich.org 70 i@@ -219,34 +304,6 @@ match_line(char *line, char **tokv, int tokc) Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i static void Err bitreich.org 70 i-move(signed int sign) Err bitreich.org 70 i-{ Err bitreich.org 70 i- int i; Err bitreich.org 70 i- Err bitreich.org 70 i- for (i = current + sign; 0 <= i && i < matchc; i += sign) { Err bitreich.org 70 i- if (!opt['#'] || matchv[i][0] != '#') { Err bitreich.org 70 i- current = i; Err bitreich.org 70 i- break; Err bitreich.org 70 i- } 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-move_page(signed int sign) Err bitreich.org 70 i-{ Err bitreich.org 70 i- int i = current - current % rows + rows * sign; Err bitreich.org 70 i- Err bitreich.org 70 i- if (!opt['l']) Err bitreich.org 70 i- return; Err bitreich.org 70 i- Err bitreich.org 70 i- if (0 > i || i > matchc) Err bitreich.org 70 i- return; Err bitreich.org 70 i- Err bitreich.org 70 i- current = i - 1; Err bitreich.org 70 i- move(+1); Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-static void Err bitreich.org 70 i filter(void) Err bitreich.org 70 i { Err bitreich.org 70 i char **tokv = NULL, *s, buffer[sizeof (input)]; Err bitreich.org 70 i@@ -333,10 +390,8 @@ print_selection(void) Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i static int Err bitreich.org 70 i-key(void) Err bitreich.org 70 i+key(int key) Err bitreich.org 70 i { Err bitreich.org 70 i- int key = fgetc(stdin); Err bitreich.org 70 i- Err bitreich.org 70 i top: Err bitreich.org 70 i switch (key) { Err bitreich.org 70 i Err bitreich.org 70 i@@ -485,7 +540,7 @@ main(int argc, char *argv[]) Err bitreich.org 70 i sigwinch(); Err bitreich.org 70 i Err bitreich.org 70 i input[0] = '\0'; Err bitreich.org 70 i- while ((exit_code = key()) == CONTINUE) Err bitreich.org 70 i+ while ((exit_code = key(fgetc(stdin))) == CONTINUE) Err bitreich.org 70 i print_screen(); Err bitreich.org 70 i print_screen(); Err bitreich.org 70 i Err bitreich.org 70 .