diff options
author | Jakob Kaivo <jkk@ung.org> | 2022-04-18 19:12:52 -0400 |
---|---|---|
committer | Jakob Kaivo <jkk@ung.org> | 2022-04-18 19:12:52 -0400 |
commit | 1fa82850d87a0f5526153655a2368c46ea447a90 (patch) | |
tree | 5ffd8c628a4a221b93cd68b36ec82b6e182bd314 /more.c | |
parent | 344424ffafe5e3b310b5595d897579544abdb90d (diff) |
switch to curses
Diffstat (limited to 'more.c')
-rw-r--r-- | more.c | 107 |
1 files changed, 65 insertions, 42 deletions
@@ -1,9 +1,11 @@ #define _XOPEN_SOURCE 700 +#include <curses.h> #include <ctype.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <term.h> #include <unistd.h> #include "more.h" @@ -19,22 +21,23 @@ enum { CTRL_U = 0x15, }; -void refresh(const struct more_tty *mt, struct more_file *mf) +void man_refresh(struct more_file *mf) { - for (size_t i = mf->topline; i < mf->topline + mt->lines; i++) { + for (size_t i = mf->topline; i < mf->topline + LINES - 1; i++) { /* FIXME: account for long lines */ if (more_getline(mf, i) == -1) { break; } - printf("%s", mf->buf); + printw("%s", mf->buf); } } -void scroll(const struct more_tty *mt, struct more_file *mf, int count, int multiple) +void man_scroll(struct more_file *mf, int count, int multiple) { int by = count ? count * multiple : multiple; + scrl(by); if (by < 0) { if ((size_t)(-by) > mf->topline) { @@ -42,36 +45,38 @@ void scroll(const struct more_tty *mt, struct more_file *mf, int count, int mult } else { mf->topline += by; } - refresh(mt, mf); + man_refresh(mf); } else while (by-- > 0) { /* FIXME: account for long lines here, too */ mf->topline++; - if (more_getline(mf, mf->topline + mt->lines + 1) < 0) { + if (more_getline(mf, mf->topline + LINES + 1) < 0) { break; } - printf("%s", mf->buf); + printw("%s", mf->buf); } + + refresh(); } -void mark(const struct more_tty *mt, struct more_file *mf) +void mark(struct more_file *mf) { - int c = fgetc(mt->tty); + int c = getch(); if (islower(c)) { mf->mark[c - 'a'] = mf->topline; } } -void jump(const struct more_tty *mt, struct more_file *mf) +void jump(struct more_file *mf) { - int c = fgetc(mt->tty); + int c = getch(); if (islower(c)) { mf->topline = mf->mark[c - 'a']; - refresh(mt, mf); + man_refresh(mf); } } -int more(const struct more_tty *mt, const char *path) +static int more(const char *path) { struct more_file mf = more_open(path); @@ -80,11 +85,11 @@ int more(const struct more_tty *mt, const char *path) return 1; } - refresh(mt, &mf); + man_refresh(&mf); int count = 0; while (mf.f) { - int c = fgetc(mt->tty); + int c = getch(); switch (c) { case EOF: @@ -93,50 +98,50 @@ int more(const struct more_tty *mt, const char *path) case 'h': //show_help(); - printf("Help!"); + printw("Help!"); break; case 'f': case CTRL_F: if (count == 0) { - count = mt->lines; + count = LINES; } - scroll(mt, &mf, count, 1); + man_scroll(&mf, count, 1); break; case 'b': case CTRL_B: if (count == 0) { - count = mt->lines; + count = LINES; } - scroll(mt, &mf, count, -1); + man_scroll(&mf, count, -1); break; case ' ': - count = count ? count : mt->lines; + count = count ? count : LINES; /* FALLTHRU */ case 'j': case '\n': - scroll(mt, &mf, count, 1); + man_scroll(&mf, count, 1); break; case 'k': - scroll(mt, &mf, count, -1); + man_scroll(&mf, count, -1); break; case 'd': case CTRL_D: - scroll(mt, &mf, count, mt->lines / 2); + man_scroll(&mf, count, LINES / 2); break; case 's': count = count ? count : 1; - scroll(mt, &mf, mt->lines + count, 1); + man_scroll(&mf, LINES + count, 1); break; case 'u': case CTRL_U: - scroll(mt, &mf, count, -mt->lines / 2); + man_scroll(&mf, count, -LINES / 2); break; case 'G': @@ -145,7 +150,7 @@ int more(const struct more_tty *mt, const char *path) } /* FALLTHRU */ case 'g': - scroll(mt, &mf, count - mf.topline, 1); + man_scroll(&mf, count - mf.topline, 1); break; case 'R': @@ -153,15 +158,15 @@ int more(const struct more_tty *mt, const char *path) /* FALLTHRU */ case 'r': case CTRL_L: - refresh(mt, &mf); + man_refresh(&mf); break; case 'm': - mark(mt, &mf); + mark(&mf); break; case '\'': - jump(mt, &mf); + jump(&mf); break; case '/': @@ -181,9 +186,13 @@ int more(const struct more_tty *mt, const char *path) break; case ':': { - fputc(c, mt->tty); - int c2 = fgetc(mt->tty); - fprintf(mt->tty, "\b \b"); + addch(c); + echo(); + int c2 = getch(); + noecho(); + + printw("\b \b"); + switch (c2) { case 'e': // examine(); @@ -215,11 +224,11 @@ int more(const struct more_tty *mt, const char *path) case '=': case CTRL_G: - printf("%s; File %d/%d; Line %zd; Byte %zd/%zd; %zd%%", path, 0, 0, mf.topline, mf.bytepos[mf.topline], mf.nbytes, 100 * mf.bytepos[mf.topline] / mf.nbytes); + printw("%s; File %d/%d; Line %zd; Byte %zd/%zd; %zd%%", path, 0, 0, mf.topline, mf.bytepos[mf.topline], mf.nbytes, 100 * mf.bytepos[mf.topline] / mf.nbytes); break; case 'Z': - if (fgetc(mt->tty) != 'Z') { + if (getch() != 'Z') { break; } /* FALLTHRU */ @@ -245,6 +254,8 @@ int more(const struct more_tty *mt, const char *path) if (!isdigit(c)) { count = 0; } + + refresh(); } more_close(&mf); @@ -332,6 +343,11 @@ static int more_cat(const char *path, void (*loop)(FILE *)) return 0; } +static void more_exit(void) +{ + endwin(); +} + int main(int argc, char *argv[]) { int c; @@ -341,7 +357,6 @@ int main(int argc, char *argv[]) int ignorecase = 0; int compressempty = 0; int backspace = 1; - int lines = 0; adjust_args(&argc, &argv); @@ -368,7 +383,7 @@ int main(int argc, char *argv[]) break; case 'n': - lines = atoi(optarg); + setenv("LINES", optarg, 1); break; case 'p': @@ -393,16 +408,25 @@ int main(int argc, char *argv[]) return ret; } - struct more_tty mt = more_open_tty(lines); - if (optind >= argc) { - more(&mt, "-"); + more("-"); + } + + initscr(); + cbreak(); + noecho(); + scrollok(stdscr, TRUE); + + atexit(more_exit); + + if (clear) { + clear(); } int min = optind; int max = argc - 1; while (optind < argc) { - int next = more(&mt, argv[optind]); + int next = more(argv[optind]); optind += next; if (optind < min) { optind = min; @@ -412,7 +436,6 @@ int main(int argc, char *argv[]) } } - (void)clear; (void)fastexit; (void)ignorecase; (void)backspace; |