URI: 
       added a -t / -b option to set the menu at the top / bottom of the screen - 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 0bf49abb280f7bdbc6e13f12a84a844e119061db
   DIR parent 1035fe68e4071585215a146fd1d31a914534c89d
  HTML Author: Josuah Demangeonā  ā µ <mail@josuah.net>
       Date:   Fri, 31 Mar 2017 19:24:39 +0200
       
       added a -t / -b option to set the menu at the top / bottom of the screen
       
       Diffstat:
         M iomenu.1                            |       6 ++++++
         M iomenu.c                            |      61 +++++++++++++++++++++----------
       
       2 files changed, 48 insertions(+), 19 deletions(-)
       ---
   DIR diff --git a/iomenu.1 b/iomenu.1
       @@ -11,6 +11,8 @@
        .
        .Nm
        .Op Fl l Ar lines
       +.Op Fl b
       +.Op Fl t
        .
        .Sh DESCRIPTION
        .
       @@ -31,6 +33,10 @@ the items are displayed in an horizontal list.
        Otherwise, in a vertical list of at most
        .Ar lines
        lines.
       +.
       +.It Fl t / 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
       @@ -27,7 +27,7 @@ static int       current = 0, offset = 0, prev = 0, next = 0;
        static int       linec = 0,      matchc = 0;
        static wchar_t **linev = NULL, **matchv = NULL;
        static wchar_t   input[BUFSIZ], formatted[BUFSIZ * 8];
       -static int       opt_l = 0;
       +static int       opt_l = 0, opt_tb = 0;
        
        
        static void
       @@ -59,18 +59,50 @@ set_terminal(void)
        {
                struct termios new;
        
       +        /* get window size */
       +        if (ioctl(tty_fd, TIOCGWINSZ, &ws) < 0)
       +                die("ioctl");
       +
       +        /* save cursor postition */
       +        fputws(L"\033[s", stderr);
       +
       +        /* put cursor at the top / bottom */
       +        switch (opt_tb) {
       +        case 't': fputws(L"\033[H", stderr);                        break;
       +        case 'b': fwprintf(stderr, L"\033[%dH", ws.ws_row - opt_l); break;
       +        }
       +
       +        /* save attributes to `termios` */
                if (tcgetattr(tty_fd, &termios) < 0 || tcgetattr(tty_fd, &new) < 0) {
                        perror("tcgetattr");
                        exit(EXIT_FAILURE);
                }
        
       +        /* change to raw mode */
                new.c_lflag &= ~(ICANON | ECHO | IGNBRK);
       -
                tcsetattr(tty_fd, TCSANOW, &new);
        }
        
        
        static void
       +reset_terminal(void)
       +{
       +        extern struct termios termios;
       +        extern struct winsize ws;
       +
       +        /* clear terminal */
       +        for (int i = 0; i < opt_l + 1; i++)
       +                fputws(L"\r\033[K\n", stderr);
       +
       +        /* reset cursor position */
       +        fputws(L"\033[u", stderr);
       +
       +        /* set terminal back to normal mode */
       +        tcsetattr(tty_fd, TCSANOW, &termios);
       +}
       +
       +
       +static void
        read_lines(void)
        {
                wchar_t buffer[BUFSIZ];
       @@ -215,9 +247,6 @@ print_screen(void)
        {
                int count;
        
       -        if (ioctl(tty_fd, TIOCGWINSZ, &ws) < 0)
       -                die("ioctl");
       -
                count = MIN(opt_l, ws.ws_row - 2);
        
                fputws(L"\r\033[K", stderr);
       @@ -239,15 +268,6 @@ print_screen(void)
        }
        
        
       -static void
       -clear(int lines)
       -{
       -        for (int i = 0; i < lines + 1; i++)
       -                fputws(L"\r\033[K\n", stderr);
       -        fwprintf(stderr, L"\033[%dA", lines + 1);
       -}
       -
       -
        static int
        match_line(wchar_t *line, wchar_t **tokv, int tokc)
        {
       @@ -340,7 +360,6 @@ input_key(void)
                switch (key) {
        
                case CONTROL('C'):
       -                clear(opt_l);
                        return EXIT_FAILURE;
        
                case CONTROL('U'):
       @@ -399,6 +418,7 @@ input_get(void)
        
                input[0] = '\0';
        
       +        print_screen();
                while ((exit_code = input_key()) == CONTINUE)
                        print_screen();
        
       @@ -431,6 +451,10 @@ main(int argc, char *argv[])
                                if (++i >= argc || sscanf(argv[i], "%d", &opt_l) <= 0)
                                        usage();
                                break;
       +
       +                case 't': opt_tb = 't'; break;
       +                case 'b': opt_tb = 'b'; break;
       +
                        default:
                                usage();
                        }
       @@ -442,15 +466,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);
       -
                set_terminal();
        
       -        print_screen();
       +        /* main loop */
                exit_code = input_get();
        
       -        tcsetattr(tty_fd, TCSANOW, &termios);
       -        clear(opt_l);
       +        reset_terminal();
                close(tty_fd);
       +
                free_all();
        
                return exit_code;