t* sacc + cursorline and uri preview
       
   URI git clone git://git.codevoid.de/sacc-sdk
   DIR Log
   DIR Files
   DIR Refs
   DIR LICENSE
       ---
   DIR commit 06da9e03ae2c5a92ad499d531a4bb0d3b48d2a9e
   DIR parent 6cd1427b61606300e7fcc7718863a0ad332908a6
   URI Author: Quentin Rameau <quinq@fifth.space>
       Date:   Mon,  3 Jul 2017 17:52:32 +0200
       
       Add a status line for screen ui and unify with text
       
       Diffstat:
         M ui_ti.c                             |      47 +++++++++++++++++++++++--------
         M ui_txt.c                            |      67 +++++++++++++++++++++----------
       
       2 files changed, 81 insertions(+), 33 deletions(-)
       ---
   DIR diff --git a/ui_ti.c b/ui_ti.c
       t@@ -27,6 +27,9 @@ uisetup(void)
                tcsetattr(0, TCSAFLUSH, &traw);
        
                setupterm(NULL, 1, NULL);
       +        putp(tparm(save_cursor));
       +        putp(tparm(change_scroll_region, 0, lines-2));
       +        putp(tparm(restore_cursor));
        }
        
        void
       t@@ -51,23 +54,40 @@ help(void)
                return;
        }
        
       +static void
       +displaystatus(Item *item)
       +{
       +        size_t nitems = item->dir->nitems;
       +
       +        putp(tparm(save_cursor));
       +
       +        putp(tparm(cursor_address, lines-1, 0));
       +        putp(tparm(enter_standout_mode));
       +        printf("%3d%%| %s:%s%s", nitems <= lines ? 100 :
       +               ((unsigned long long)item->printoff + lines) * 100 / nitems,
       +               item->host, item->port, item->selector);
       +        putp(tparm(exit_standout_mode));
       +
       +        putp(tparm(restore_cursor));
       +}
       +
        void
       -display(Item *item)
       +display(Item *entry)
        {
       -        Item **items;
       +        Item *item, **items;
                size_t i, curln, lastln, nitems, printoff;
        
       -        if (item->type != '1')
       +        if (entry->type != '1')
                        return;
        
                putp(tparm(clear_screen));
                putp(tparm(save_cursor));
        
       -        items = item->dir->items;
       -        nitems = item->dir->nitems;
       -        printoff = item->printoff;
       -        curln = item->curline;
       -        lastln = printoff + lines;
       +        items = entry->dir->items;
       +        nitems = entry->dir->nitems;
       +        printoff = entry->printoff;
       +        curln = entry->curline;
       +        lastln = printoff + lines-1; /* one off for status bar */
        
                for (i = printoff; i < nitems && i < lastln; ++i) {
                        if (item = items[i]) {
       t@@ -85,6 +105,7 @@ display(Item *item)
                }
        
                putp(tparm(restore_cursor));
       +        displaystatus(entry);
                fflush(stdout);
        }
        
       t@@ -93,6 +114,7 @@ movecurline(Item *item, int l)
        {
                size_t nitems;
                ssize_t curline, offline;
       +        int plines = lines-2;
        
                if (item->dir == NULL)
                        return;
       t@@ -106,11 +128,11 @@ movecurline(Item *item, int l)
                item->curline = curline;
        
                if (l > 0) {
       -                offline = item->printoff + lines;
       -                if (curline - item->printoff >= lines / 2 && offline < nitems) {
       +                offline = item->printoff + lines-1;
       +                if (curline - item->printoff >= plines / 2 && offline < nitems) {
                                putp(tparm(save_cursor));
        
       -                        putp(tparm(cursor_address, lines, 0));
       +                        putp(tparm(cursor_address, plines, 0));
                                putp(tparm(scroll_forward));
                                printitem(item->dir->items[offline]);
        
       t@@ -119,7 +141,7 @@ movecurline(Item *item, int l)
                        }
                } else {
                        offline = item->printoff + l;
       -                if (curline - offline <= lines / 2 && offline >= 0) {
       +                if (curline - offline <= plines / 2 && offline >= 0) {
                                putp(tparm(save_cursor));
        
                                putp(tparm(cursor_address, 0, 0));
       t@@ -136,6 +158,7 @@ movecurline(Item *item, int l)
                putp(tparm(enter_standout_mode));
                printitem(item->dir->items[curline]);
                putp(tparm(exit_standout_mode));
       +        displaystatus(item);
                fflush(stdout);
        }
        
   DIR diff --git a/ui_txt.c b/ui_txt.c
       t@@ -7,10 +7,30 @@
        
        #include "common.h"
        
       +int lines;
       +
       +static int
       +termlines(void)
       +{
       +        struct winsize ws;
       +
       +        if (ioctl(1, TIOCGWINSZ, &ws) < 0) {
       +                die("Could not get terminal resolution: %s",
       +                    strerror(errno));
       +        }
       +
       +        return ws.ws_row-1; /* one off for status bar */
       +}
       +
        void
       -uisetup(void) { return; }
       +uisetup(void) {
       +        lines = termlines();
       +}
       +
        void
       -uicleanup(void) { return; }
       +uicleanup(void) {
       +        return;
       +}
        
        void
        help(void)
       t@@ -26,44 +46,49 @@ help(void)
        }
        
        static int
       -termlines(void)
       +ndigits(size_t n)
        {
       -        struct winsize ws;
       +        return (n < 10) ? 1 : (n < 100) ? 2 : 3;
       +}
        
       -        if (ioctl(1, TIOCGWINSZ, &ws) < 0) {
       -                die("Could not get terminal resolution: %s",
       -                    strerror(errno));
       -        }
       +static void
       +printstatus(Item *item)
       +{
       +        size_t nitems = item->dir->nitems;
        
       -        return ws.ws_row-1;
       +        printf("%3d%%%*c %s:%s%s (h for help): ", nitems <= lines ? 100 :
       +               ((unsigned long long)item->printoff + lines) * 100 / nitems,
       +               ndigits(nitems)+2, '|', item->host, item->port, item->selector);
        }
        
        void
       -display(Item *item)
       +display(Item *entry)
        {
       -        Item **items;
       +        Item *item, **items;
                size_t i, lines, nitems;
       -        int ndigits;
       +        int nd;
        
       -        if (item->type != '1')
       +        if (entry->type != '1')
                        return;
        
       -        items = item->dir->items;
       -        nitems = item->dir->nitems;
       -        lines = item->printoff + termlines();
       -        ndigits = (nitems < 10) ? 1 : (nitems < 100) ? 2 : 3;
       +        items = entry->dir->items;
       +        nitems = entry->dir->nitems;
       +        lines = entry->printoff + termlines();
       +        nd = ndigits(nitems);
        
       -        for (i = item->printoff; i < nitems && i < lines; ++i) {
       +        for (i = entry->printoff; i < nitems && i < lines; ++i) {
                        if (item = items[i]) {
       -                        printf("%*d %-4s%c %s\n", ndigits, i+1,
       +                        printf("%*zu %-4s%c %s\n", nd, i+1,
                                       item->type != 'i' ?
                                       typedisplay(item->type) : "",
                                       item->type > '1' ? '|' : '+',
                                       items[i]->username);
                        } else {
       -                        printf("%*d  !! |\n", ndigits, i+1);
       +                        printf("%*zu  !! |\n", nd, i+1);
                        }
                }
       +
       +        fflush(stdout);
        }
        
        Item *
       t@@ -75,7 +100,7 @@ selectitem(Item *entry)
                nitems = entry->dir ? entry->dir->nitems : 0;
        
                do {
       -                printf("%d items (h for help): ", nitems);
       +                printstatus(entry);
                        fflush(stdout);
        
                        if (!fgets(buf, sizeof(buf), stdin)) {