Added support for page up and down with Ctrl/Alt + v - 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 422bb3cf75123ac36aed39c370de89dfbe55dd78 DIR parent e2db9fd49d5351986d5803604bed7e2680545621 HTML Author: Josuah Demangeon <josuah.demangeon@gandi.net> Date: Mon, 21 Aug 2017 09:04:18 +0200 Added support for page up and down with Ctrl/Alt + v Diffstat: M README | 34 ++++++++++++++++++------------- M iomenu.1 | 24 +++++++++++++++--------- M iomenu.c | 51 +++++++++++++++++++------------ 3 files changed, 66 insertions(+), 43 deletions(-) --- DIR diff --git a/README b/README @@ -1,7 +1,7 @@ -IOMENU(1) General Commands Manual IOMENU(1) +IOMENU(1) FreeBSD General Commands Manual IOMENU(1) NAME - iomenu – interactive selection menu + iomenu - interactive selection menu SYNOPSIS iomenu [-#] [-l lines] [-p prompt] @@ -22,28 +22,34 @@ DESCRIPTION -# If a line starts with #, iomenu will interprete it as a header, which always matches, and can not be printed. - Selection control + Selection keybindings An active selection is highlighted, and can be controlled with keybindings. - ^P, ^N Move selection to the previous/next item. + Ctrl + p, Ctrl + n + Move selection to the previous/next item. - ^M, ^J, Enter Print the selection to the standard output, and exit 0. + Ctrl + v Ns, Alt + v + Move one page up or down. - Input handling - As printable keys are entered, the selection is filtered to match every - word from the input. + Ctrl + m, Ctrl + j, Enter + Print the selection to the standard output, and exit 0. - ^H, Bakcspace Remove last character from current input. +Text input + As printable keys are entered, the lines are filtered to match each word + from the input. - ^W Remove last word from current input. + Ctrl + h, Bakcspace + Remove last character from current input. - ^U Remove the whole input string. + Ctrl + w Remove last word from current input. - ^I, Tab Fill the input with current selection. + Ctrl + u Remove the whole input string. + + Ctrl + i, Tab Fill the input with current selection. EXIT STATUS - The iomenu utility exits 0 on success, and >0 if an error occurs. + The iomenu utility exits 0 on success, and >0 if an error occurs. EXAMPLES Open a bookmark from a list in a text file: @@ -80,4 +86,4 @@ AUTORS iomenu was written from scratch by Josuah Demangeon <mail@josuah.net> with the help of dmenu(1) and vis-menu(1) as models. -Void Linux August 21, 2017 Void Linux +FreeBSD 11.0-RELEASE-p1 August 21, 2017 FreeBSD 11.0-RELEASE-p1 DIR diff --git a/iomenu.1 b/iomenu.1 @@ -54,36 +54,42 @@ will interprete it as a header, which always matches, and can not be printed. . . -.Ss Selection control +.Ss Selection keybindings . An active selection is highlighted, and can be controlled with keybindings. .Bl -tag -width XXXXXXXXXXXXXXX . -.It Ic ^P Ns , Ic ^N +.It Ic Ctrl + p Ns , Ic Ctrl + n Move selection to the previous/next item. . -.It Ic ^M Ns , Ic ^J Ns , Ic Enter +.It Ic Ctrl + v Ns, Ic Alt + v +Move one page up or down. +. +.It Ic Ctrl + m Ns , Ic Ctrl + j Ns , Ic Enter Print the selection to the standard output, and exit 0. . .El . -.Ss Input handling . -As printable keys are entered, the selection is filtered to match every +.Sh Text input +. +As printable keys are entered, the lines are filtered to match each word from the input. +. .Bl -tag -width XXXXXXXXXXXXXXX . -.It Ic ^H Ns , Ic Bakcspace +.It Ic Ctrl + h Ns , Ic Bakcspace Remove last character from current input. . -.It Ic ^W +.It Ic Ctrl + w Remove last word from current input. . -.It Ic ^U +.It Ic Ctrl + u Remove the whole input string. . -.It Ic ^I Ns , Ic Tab +.It Ic Ctrl + i Ns , Ic Tab Fill the input with current selection. +. .El . . DIR diff --git a/iomenu.c b/iomenu.c @@ -18,13 +18,13 @@ static struct winsize ws; static struct termios termios; -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[128]; -static char *prompt = ""; +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[128], rows = 0; +static char *prompt = ""; static void freelines(void) @@ -145,11 +145,11 @@ format(char *str, int cols) } static void -printlines(int count) +printlines(void) { - int printed = 0, i = current / count * count; + int printed = 0, i = current - current % rows; - while (printed < count && i < matchc) { + while (printed < rows && i < matchc) { char *s = format(matchv[i], ws.ws_col - 1); @@ -163,7 +163,7 @@ printlines(int count) i++; printed++; } - while (printed++ < count) + while (printed++ < rows) fputs("\n\033[K", stderr); } @@ -171,12 +171,11 @@ static void printscreen(void) { int cols = ws.ws_col - 1; - int count = MIN(opt['l'], ws.ws_row - 1); fputs("\r\033[K", stderr); - printlines(count); - fprintf(stderr, "\033[%dA\r", count); + printlines(); + fprintf(stderr, "\033[%dA\r", rows); if (*prompt) { format(prompt, cols - 2); @@ -204,11 +203,11 @@ matchline(char *line, char **tokv, int tokc) } static void -move(signed int n) +move(signed int sign) { int i; - for (i = current + n; 0 <= i && i < matchc; i += n) { + for (i = current + sign; 0 <= i && i < matchc; i += sign) { if (!opt['#'] || matchv[i][0] != '#') { current = i; break; @@ -217,6 +216,18 @@ move(signed int n) } static void +movepg(signed int sign) +{ + int i = current - current % rows + rows * sign; + + if (0 > i || i > matchc) + return; + + current = i - 1; + move(+1); +} + +static void filter(void) { char **tokv = NULL, *s, buffer[sizeof (input)]; @@ -280,7 +291,6 @@ addchar(char key) static void printselection(void) { - /* header */ if (opt['#']) { char **match = matchv + current; @@ -294,7 +304,6 @@ printselection(void) putchar('\t'); } - /* input or selection */ if (matchc == 0 || (opt['#'] && matchv[current][0] == '#')) { puts(input); } else { @@ -339,11 +348,11 @@ top: break; case CONTROL('V'): - move(ws.ws_row - 1); + movepg(+1); break; case ALT('v'): - move(-ws.ws_row + 1); + movepg(-1); break; case CONTROL('I'): /* tab */ @@ -373,6 +382,8 @@ sigwinch() { if (ioctl(ttyfd, TIOCGWINSZ, &ws) < 0) die("ioctl"); + + rows = MIN(opt['l'], ws.ws_row - 1); printscreen(); signal(SIGWINCH, sigwinch);