Re: [dev] I wrote a pager
Suckless is not about being so small that any task, even stupidly useless like this one suddenly sucks less because of linecount.
Re: [dev] I wrote a pager
On Sat, Sep 17, 2016, at 12:55 PM, pranomes...@gmail.com wrote: > Maybe I'm a bit late for the party, but I think that > https://arcetera.moe/git/pg/log.html > could be another alternative for a suckless pager. > > Possible advantages: more features, like scrolling back and going to the > beginning/end of the > file (some might argue that this is something the terminal multiplexer is > for, I disagree), and > applying numerical multipliers to commands. Searching is planned. > > Possible disadvantages: does not deal with arbitrary length lines or > files, uses queue.h and > malloc for each line for saving the file contents (which is kinda slow) > and is overall still > a bit buggy. > > But basically, this pager seems suckless too. What is your opinion on > this? Six times bigger (307 lines versus 49 lines) and slow and buggy? No thank you. In any case, it looks like the suckless maintainers think that paging should be done inside the terminal (tmux/dvtm).
Re: [dev] I wrote a pager
On Sat, Sep 17, 2016, at 01:09 PM, hiro wrote: > a suckless pager would be provided by the terminal. Good point. I hadn't thought of that when I was trying stali. Stali has dvtm! Even still, I think that it would be nice for sbase to have a pager and I think that the one I wrote is pretty suckless.
Re: [dev] I wrote a pager
you might also just want to fix your tmux or dvtm or whatever you use to organize your virtual terminals in your virtual terminals.
Re: [dev] I wrote a pager
a suckless pager would be provided by the terminal.
Re: [dev] I wrote a pager
Greg Reagle wrote: > 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 > #include > #include > #include > 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); > } Maybe I'm a bit late for the party, but I think that https://arcetera.moe/git/pg/log.html could be another alternative for a suckless pager. Possible advantages: more features, like scrolling back and going to the beginning/end of the file (some might argue that this is something the terminal multiplexer is for, I disagree), and applying numerical multipliers to commands. Searching is planned. Possible disadvantages: does not deal with arbitrary length lines or files, uses queue.h and malloc for each line for saving the file contents (which is kinda slow) and is overall still a bit buggy. But basically, this pager seems suckless too. What is your opinion on this? Greetings, pranomostro
Re: [dev] I wrote a pager
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 #include #include #include 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); }
Re: [dev] I wrote a pager
On Fri, Sep 16, 2016, at 04:10 PM, Martin Kühne wrote: > a few gripes: > > atoi: personally I prefer strtol and range-checks on the result and/or > errno. > getenv(LINES) is a start, but you might also want to offer > ioctl(TIOCGWINSZ) where available. > always NULL-check the return value of getenv. Thanks for your feedback. As far as I understand it, this code char *lines = getenv("LINES"); int page_size = lines ? atoi(lines) : 24; does indeed check the return value of getenv. I don't know why it would segfault. > what does your pager do on binary input and unexpected things? does it > filter ansi escape sequences? These are good questions. I'll look into it and get back to you. What do you think appropriate behavior for binary input would be? It is a pager so it is not supposed to be used on binary input. It could abort or it could just ignore are two ideas off the top of my head. > how does it treat lines wider than the screen width, and how does that > influence the line count calculation? It does not take into account long longer than screen width, so in those cases the output will scroll off the screen. Perhaps I'll add that feature. Thanks for good suggestions.
Re: [dev] I wrote a pager - errno
On Fri, Sep 16, 2016, at 12:26 PM, u...@netbeisser.de wrote: > > #include > > #include > > > > int main() > > { > > const int page_size = 22; > > int count = 0; > > int ch; > > FILE *tty; > > > > if ((tty = fopen("/dev/tty", "a+")) == NULL) > > return(errno); > > > > ch = getchar(); > > while (ch != EOF) { > > putchar(ch); > > if (ch == '\n') { > > ++count; > > if (count >= page_size) { > > fgetc(tty); > > count = 0; > > } > > } > > ch = getchar(); > > } > > fclose(tty); > > } > > hm, do you really need errno ? Well, I don't know. Like I wrote, I am not an expert C programmer. I could just return a value of 1, but the user might be interested to know what the error was.
Re: [dev] I wrote a pager
On Fri, Sep 16, 2016, at 12:25 PM, u...@netbeisser.de wrote: > Thank you Greg for writing such a fantastic pager. It is very primitive, so I don't know whether you're being sincere or sarcastic. > I could increase lines > however to something more than 22. I chose 22 because a VT100 terminal is 80x24, and one line is used for the user input. It is also the number of lines per page in the plan 9 pager (called "p"). I might make it a little more sophisticated by calculating how many lines are on the screen, but only if it can be done in a portable and simple way.
Re: [dev] I wrote a pager
a few gripes: atoi: personally I prefer strtol and range-checks on the result and/or errno. getenv(LINES) is a start, but you might also want to offer ioctl(TIOCGWINSZ) where available. always NULL-check the return value of getenv. what does your pager do on binary input and unexpected things? does it filter ansi escape sequences? how does it treat lines wider than the screen width, and how does that influence the line count calculation? cheers! mar77i
Re: [dev] I wrote a pager
Can you elaborate? On Fri, Sep 16, 2016 at 2:41 PM, Teodoro Santoni wrote: > Hi, > > 2016-09-16 17:40 GMT, Evan Gates : >> On Fri, Sep 16, 2016 at 9:25 AM, wrote >>> Thank you Greg for writing such a fantastic pager. I could increase lines >>> however to something more than 22. >> >> char *lines = getenv("LINES"); >> int page_size = lines ? atoi(lines) : 24; >> >> > > May segfail under rc and dash. >
Re: [dev] I wrote a pager
Hi, 2016-09-16 17:40 GMT, Evan Gates : > On Fri, Sep 16, 2016 at 9:25 AM, wrote >> Thank you Greg for writing such a fantastic pager. I could increase lines >> however to something more than 22. > > char *lines = getenv("LINES"); > int page_size = lines ? atoi(lines) : 24; > > May segfail under rc and dash.
Re: [dev] I wrote a pager
On Fri, Sep 16, 2016 at 9:25 AM, wrote > Thank you Greg for writing such a fantastic pager. I could increase lines > however to something more than 22. char *lines = getenv("LINES"); int page_size = lines ? atoi(lines) : 24;
Re: [dev] I wrote a pager - errno
On Fri, Sep 16, 2016 at 11:43:37AM -0400, Greg Reagle wrote: > On Fri, Sep 16, 2016, at 10:01 AM, Greg Reagle wrote: > > Greetings. I am running stali in qemu and and it seems to lack a pager. > > Is it a goal of the suckless project to write a suckless pager for > > sbase? I see that plan9port already has a pager called "p". What about > > importing that into 9base? > > Since I know that code is king around here, I wrote a pager program. I > am not an expert C programmer, so I might have done some things wrong. > But I think it does a good job of being minimalist. > > What do you think? Would you like to put it into sbase or stali? If yes > then I can clone the sbase repo and submit a proper git patch. > > #include > #include > > int main() > { > const int page_size = 22; > int count = 0; > int ch; > FILE *tty; > > if ((tty = fopen("/dev/tty", "a+")) == NULL) > return(errno); > > ch = getchar(); > while (ch != EOF) { > putchar(ch); > if (ch == '\n') { > ++count; > if (count >= page_size) { > fgetc(tty); > count = 0; > } > } > ch = getchar(); > } > fclose(tty); > } hm, do you really need errno ?
Re: [dev] I wrote a pager
On Fri, Sep 16, 2016 at 11:43:37AM -0400, Greg Reagle wrote: > On Fri, Sep 16, 2016, at 10:01 AM, Greg Reagle wrote: > > Greetings. I am running stali in qemu and and it seems to lack a pager. > > Is it a goal of the suckless project to write a suckless pager for > > sbase? I see that plan9port already has a pager called "p". What about > > importing that into 9base? > > Since I know that code is king around here, I wrote a pager program. I > am not an expert C programmer, so I might have done some things wrong. > But I think it does a good job of being minimalist. > > What do you think? Would you like to put it into sbase or stali? If yes > then I can clone the sbase repo and submit a proper git patch. > > #include > #include > > int main() > { > const int page_size = 22; > int count = 0; > int ch; > FILE *tty; > > if ((tty = fopen("/dev/tty", "a+")) == NULL) > return(errno); > > ch = getchar(); > while (ch != EOF) { > putchar(ch); > if (ch == '\n') { > ++count; > if (count >= page_size) { > fgetc(tty); > count = 0; > } > } > ch = getchar(); > } > fclose(tty); > } Thank you Greg for writing such a fantastic pager. I could increase lines however to something more than 22. Keep teh suckless spirit alive ! Greetings Stefan