summaryrefslogtreecommitdiff
path: root/more.c
diff options
context:
space:
mode:
Diffstat (limited to 'more.c')
-rw-r--r--more.c107
1 files changed, 65 insertions, 42 deletions
diff --git a/more.c b/more.c
index 108f70b..8b67540 100644
--- a/more.c
+++ b/more.c
@@ -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;