Re: [dev] I wrote a pager

From: Greg Reagle <greg.reagle_AT_umbc.edu>
Date: Fri, 16 Sep 2016 23:16:04 -0400

Thanks to all who gave feedback. I made a few enhancements. Hopefully
they're not bloat. I think it has significantly better functionality
for only several more SLOC. Once again, looking for feedback. Also, do
you suckless maintainers want to put this into sbase?

It tries to get the size of the screen from environment variables LINES
and COLUMNS and from ioctl() which overrides environment variables.

It keeps track of lines longer than screen width and compensates to not
overflow the screen; however it does so in a naive way of considering
every byte a column (printing character). This works well for ASCII
characters, but for utf8 is imperfect, but errs on the side of
displaying not enough per page rather than too much per page.

Someone asked about how it deals with binary files. It doesn't have any
particular algorithm for dealing with binary files. On my system
(Debian), it deals fine with binary files in that it doesn't
malfunction. It does make the terminal beep though (I guess from BELL
characters). It basically has the same behavior is cat-ing a binary
file on my system, but does it one page at a time.

#!/usr/bin/tcc -run
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
int
main(int argc, char *argv[])
{
    unsigned short page_lines = 23, page_cols = 80;
        int line_count, col_count;
        int ch, env_num;
        char* env_string;
        FILE *tty;
    struct winsize ws;

        if (env_string = getenv("LINES")) {
                env_num = strtol(env_string, NULL, 10);
                if (env_num > 0) page_lines = env_num - 1;
        }
        if (env_string = getenv("COLUMNS")) {
                env_num = strtol(env_string, NULL, 10);
                if (env_num > 0) page_cols = env_num;
        }
        if ((tty = fopen("/dev/tty", "r")) == NULL) {
                perror("Error opening /dev/tty");
                return(errno);
        }
    if (!ioctl(fileno(tty), TIOCGWINSZ, &ws)) {
                page_lines = ws.ws_row - 1;
                page_cols = ws.ws_col;
        }

        ch = getchar();
        for (line_count = 0, col_count = 1; ch != EOF; ++col_count) {
                putchar(ch);
                if (ch == '\n' || col_count >= page_cols) {
                        ++line_count;
                        col_count = 0;
                        if (line_count >= page_lines) {
                                while (fgetc(tty) != '\n') ;
                                line_count = 0;
                        }
                }
                ch = getchar();
        }
        fclose(tty);
        return(0);
}
Received on Sat Sep 17 2016 - 05:16:04 CEST

This archive was generated by hypermail 2.3.0 : Sat Sep 17 2016 - 05:24:13 CEST