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 5f2e561edb8bf36c8a19ec32e0a83abde936be34
   DIR parent b1d593674e9619d39191b87c769d8caf9723bc0e
   URI Author: Quentin Rameau <quinq@fifth.space>
       Date:   Fri, 30 Jun 2017 16:59:37 +0200
       
       Move UI specific code to it's own file
       
       Diffstat:
         M Makefile                            |       6 +++++-
         A common.h                            |      24 ++++++++++++++++++++++++
         M config.mk                           |       7 +++++--
         M sacc.c                              |     147 +------------------------------
         A ui_txt.c                            |     128 +++++++++++++++++++++++++++++++
       
       5 files changed, 165 insertions(+), 147 deletions(-)
       ---
   DIR diff --git a/Makefile b/Makefile
       t@@ -5,11 +5,15 @@
        include config.mk
        
        BIN = sacc
       +OBJ = $(BIN:=.o) ui_$(UI).o
        
        all: $(BIN)
        
       +$(BIN): config.mk $(OBJ)
       +        $(CC) $(OBJ) $(SACCLDFLAGS) -o $@
       +
        clean:
       -        rm -f $(BIN)
       +        rm -f $(BIN) $(OBJ)
        
        install:
                mkdir -p $(PREFIX)/bin/
   DIR diff --git a/common.h b/common.h
       t@@ -0,0 +1,24 @@
       +typedef struct item Item;
       +typedef struct dir Dir;
       +
       +struct item {
       +        char type;
       +        char *username;
       +        char *selector;
       +        char *host;
       +        char *port;
       +        char *raw;
       +        size_t printoff;
       +        Item *entry;
       +        Dir  *dir;
       +};
       +
       +struct dir {
       +        Item **items;
       +        size_t nitems;
       +};
       +
       +void die(const char *fmt, ...);
       +void display(Item *item);
       +Item *selectitem(Item *entry);
       +const char *typedisplay(char t);
   DIR diff --git a/config.mk b/config.mk
       t@@ -1,9 +1,12 @@
        # Install paths
        PREFIX = /usr/local
        
       +# UI type, txt
       +UI=txt
       +
        # Stock FLAGS
        SACCCFLAGS = -D_POSIX_C_SOURCE=200809L $(CFLAGS)
        SACCLDFLAGS = $(LDFLAGS)
        
       -.c:
       -        $(CC) -o $@ $(SACCCFLAGS) $(SACCLDFLAGS) $<
       +.c.o:
       +        $(CC) $(SACCCFLAGS) -c $<
   DIR diff --git a/sacc.c b/sacc.c
       t@@ -6,33 +6,13 @@
        #include <stdlib.h>
        #include <string.h>
        #include <stropts.h>
       -#include <termios.h> /* ifdef BSD */
        #include <unistd.h>
       -#include <sys/ioctl.h>
        #include <sys/socket.h>
        #include <sys/types.h>
        
       -typedef struct item Item;
       -typedef struct dir Dir;
       -
       -struct item {
       -        char type;
       -        char *username;
       -        char *selector;
       -        char *host;
       -        char *port;
       -        char *raw;
       -        size_t printoff;
       -        Item *entry;
       -        Dir  *dir;
       -};
       -
       -struct dir {
       -        Item **items;
       -        size_t nitems;
       -};
       +#include "common.h"
        
       -static void
       +void
        die(const char *fmt, ...)
        {
                va_list arg;
       t@@ -90,33 +70,7 @@ usage(void)
                die("usage: sacc URL");
        }
        
       -static void
       -help(void)
       -{
       -        puts("Commands:\n"
       -             "N = [1-9]...: browse item N.\n"
       -             "0: browse previous item.\n"
       -             "n: show next page.\n"
       -             "p: show previous page.\n"
       -             "!: refetch failed item.\n"
       -             "^D, q: quit.\n"
       -             "h: this help.");
       -}
       -
       -static int
       -termlines(void)
       -{
       -        struct winsize ws;
       -
       -        if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0) {
       -                die("Could not get terminal resolution: %s",
       -                    strerror(errno));
       -        }
       -
       -        return ws.ws_row-1;
       -}
       -
       -static const char *
       +const char *
        typedisplay(char t)
        {
                switch (t) {
       t@@ -159,41 +113,6 @@ typedisplay(char t)
                }
        }
        
       -static void
       -display(Item *item)
       -{
       -        Item **items;
       -        size_t i, lines, nitems;
       -        int ndigits;
       -
       -        if (item->type > '1')
       -                return;
       -
       -        switch (item->type) {
       -        case '0':
       -                puts(item->raw);
       -                break;
       -        case '1':
       -                items = item->dir->items;
       -                nitems = item->dir->nitems;
       -                lines = item->printoff + termlines();
       -                ndigits = (nitems < 10) ? 1 : (nitems < 100) ? 2 : 3;
       -
       -                for (i = item->printoff; i < nitems && i < lines; ++i) {
       -                        if (item = items[i]) {
       -                                printf("%*d %-4s%c %s\n", ndigits, i+1,
       -                                       item->type != 'i' ?
       -                                       typedisplay(item->type) : "",
       -                                       item->type > '1' ? '|' : '+',
       -                                       items[i]->username);
       -                        } else {
       -                                printf("%*d  !! |\n", ndigits, i+1);
       -                        }
       -                }
       -                break;
       -        }
       -}
       -
        static char *
        pickfield(char **raw, char sep)
        {
       t@@ -411,66 +330,6 @@ dig(Item *entry, Item *item)
                return 1;
        }
        
       -static Item *
       -selectitem(Item *entry)
       -{
       -        char buf[BUFSIZ], nl;
       -        Item *hole;
       -        int item, nitems, lines;
       -
       -        nitems = entry->dir ? entry->dir->nitems : 0;
       -
       -        do {
       -                printf("%d items (h for help): ", nitems);
       -
       -                if (!fgets(buf, sizeof(buf), stdin)) {
       -                        putchar('\n');
       -                        return NULL;
       -                }
       -                if (!strcmp(buf, "q\n"))
       -                        return NULL;
       -
       -                if (!strcmp(buf, "n\n")) {
       -                        lines = termlines();
       -                        if (lines < entry->dir->nitems - entry->printoff &&
       -                            lines < (size_t)-1 - entry->printoff)
       -                                entry->printoff += lines;
       -                        return entry;
       -                }
       -                if (!strcmp(buf, "p\n")) {
       -                        lines = termlines();
       -                        if (lines <= entry->printoff)
       -                                entry->printoff -= lines;
       -                        else
       -                                entry->printoff = 0;
       -                        return entry;
       -                }
       -
       -                if (!strcmp(buf, "!\n")) {
       -                        if (entry->raw)
       -                                continue;
       -                        return entry;
       -                }
       -
       -                item = -1;
       -                if (!strcmp(buf, "h\n")) {
       -                        help();
       -                        continue;
       -                }
       -                if (*buf < '0' || *buf > '9')
       -                        continue;
       -
       -                nl = '\0';
       -                if (sscanf(buf, "%d%c", &item, &nl) != 2 || nl != '\n')
       -                        item = -1;
       -        } while (item < 0 || item > nitems);
       -
       -        if (item > 0)
       -                return entry->dir->items[item-1];
       -
       -        return entry->entry;
       -}
       -
        static void
        delve(Item *hole)
        {
   DIR diff --git a/ui_txt.c b/ui_txt.c
       t@@ -0,0 +1,128 @@
       +#include <errno.h>
       +#include <stdio.h>
       +#include <string.h>
       +#include <termios.h>
       +#include <sys/ioctl.h>
       +#include <sys/types.h>
       +
       +#include "common.h"
       +
       +void
       +help(void)
       +{
       +        puts("Commands:\n"
       +             "N = [1-9]...: browse item N.\n"
       +             "0: browse previous item.\n"
       +             "n: show next page.\n"
       +             "p: show previous page.\n"
       +             "!: refetch failed item.\n"
       +             "^D, q: quit.\n"
       +             "h: this help.");
       +}
       +
       +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;
       +}
       +
       +void
       +display(Item *item)
       +{
       +        Item **items;
       +        size_t i, lines, nitems;
       +        int ndigits;
       +
       +        if (item->type > '1')
       +                return;
       +
       +        switch (item->type) {
       +        case '0':
       +                puts(item->raw);
       +                break;
       +        case '1':
       +                items = item->dir->items;
       +                nitems = item->dir->nitems;
       +                lines = item->printoff + termlines();
       +                ndigits = (nitems < 10) ? 1 : (nitems < 100) ? 2 : 3;
       +
       +                for (i = item->printoff; i < nitems && i < lines; ++i) {
       +                        if (item = items[i]) {
       +                                printf("%*d %-4s%c %s\n", ndigits, i+1,
       +                                       item->type != 'i' ?
       +                                       typedisplay(item->type) : "",
       +                                       item->type > '1' ? '|' : '+',
       +                                       items[i]->username);
       +                        } else {
       +                                printf("%*d  !! |\n", ndigits, i+1);
       +                        }
       +                }
       +                break;
       +        }
       +}
       +
       +Item *
       +selectitem(Item *entry)
       +{
       +        char buf[BUFSIZ], nl;
       +        int item, nitems, lines;
       +
       +        nitems = entry->dir ? entry->dir->nitems : 0;
       +
       +        do {
       +                printf("%d items (h for help): ", nitems);
       +
       +                if (!fgets(buf, sizeof(buf), stdin)) {
       +                        putchar('\n');
       +                        return NULL;
       +                }
       +                if (!strcmp(buf, "q\n"))
       +                        return NULL;
       +
       +                if (!strcmp(buf, "n\n")) {
       +                        lines = termlines();
       +                        if (lines < entry->dir->nitems - entry->printoff &&
       +                            lines < (size_t)-1 - entry->printoff)
       +                                entry->printoff += lines;
       +                        return entry;
       +                }
       +                if (!strcmp(buf, "p\n")) {
       +                        lines = termlines();
       +                        if (lines <= entry->printoff)
       +                                entry->printoff -= lines;
       +                        else
       +                                entry->printoff = 0;
       +                        return entry;
       +                }
       +
       +                if (!strcmp(buf, "!\n")) {
       +                        if (entry->raw)
       +                                continue;
       +                        return entry;
       +                }
       +
       +                item = -1;
       +                if (!strcmp(buf, "h\n")) {
       +                        help();
       +                        continue;
       +                }
       +                if (*buf < '0' || *buf > '9')
       +                        continue;
       +
       +                nl = '\0';
       +                if (sscanf(buf, "%d%c", &item, &nl) != 2 || nl != '\n')
       +                        item = -1;
       +        } while (item < 0 || item > nitems);
       +
       +        if (item > 0)
       +                return entry->dir->items[item-1];
       +
       +        return entry->entry;
       +}