summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@ung.org>2022-04-18 20:18:28 -0400
committerJakob Kaivo <jkk@ung.org>2022-04-18 20:18:28 -0400
commite7b5a5613219363afdf9b0c4270ce6263c34d4fe (patch)
treeaca72a5a3c35fc518e3fe5121825c7a77e40ea53
parent42ae813b3ec2d6faf123083e4a74172347632c8f (diff)
use separate status line window for better :e and such
-rw-r--r--more.c75
1 files changed, 54 insertions, 21 deletions
diff --git a/more.c b/more.c
index e1a1b9b..8db2d87 100644
--- a/more.c
+++ b/more.c
@@ -8,11 +8,14 @@
#include <string.h>
#include <term.h>
#include <unistd.h>
+#include <wordexp.h>
#include "more.h"
static int more_clear = 0;
static int retval = 0;
+static WINDOW *more_win = NULL;
+static WINDOW *more_status = NULL;
enum {
CTRL_B = 0x02,
@@ -25,48 +28,47 @@ enum {
static void more_refresh(struct more_file *mf)
{
- for (size_t i = mf->topline; i < mf->topline + LINES - 1; i++) {
+ for (size_t i = mf->topline; i < mf->topline + LINES; i++) {
/* FIXME: account for long lines */
if (more_getline(mf, i) == -1) {
break;
}
- printw("%s", mf->buf);
+ wprintw(more_win, "%s", mf->buf);
}
}
static void more_scroll(struct more_file *mf, int count, int multiple)
{
int by = count ? count * multiple : multiple;
+
if (abs(by) >= LINES && more_clear) {
clear();
}
if (by < 0) {
- scrl(by);
+ wscrl(more_win, by);
if ((size_t)(-by) > mf->topline) {
mf->topline = 0;
} else {
mf->topline += by;
}
more_refresh(mf);
- } else while (by-- > 0) {
+ } else while (by-- >= 0) {
/* FIXME: account for long lines here, too */
mf->topline++;
if (more_getline(mf, mf->topline + LINES - 1) < 0) {
break;
}
- printw("%s", mf->buf);
+ wprintw(more_win, "%s", mf->buf);
}
-
- refresh();
}
static void mark(struct more_file *mf)
{
- int c = getch();
+ int c = wgetch(more_status);
if (islower(c)) {
mf->mark[c - 'a'] = mf->topline;
}
@@ -74,7 +76,7 @@ static void mark(struct more_file *mf)
static void jump(struct more_file *mf)
{
- int c = getch();
+ int c = wgetch(more_status);
if (islower(c)) {
mf->topline = mf->mark[c - 'a'];
more_refresh(mf);
@@ -83,14 +85,38 @@ static void jump(struct more_file *mf)
static struct more_file more_examine(struct more_file *mf)
{
- printw("e ");
- refresh();
+ wprintw(more_status, "e");
echo();
char filename[1024];
- getnstr(filename, sizeof(filename));
+ wgetnstr(more_status, filename, sizeof(filename));
noecho();
+ wclear(more_status);
+
+ wordexp_t we = { 0 };
+ if (wordexp(filename, &we, WRDE_NOCMD) != 0) {
+ wprintw(more_status, "couldn't expand %s", filename);
+ return *mf;
+ }
+
+ if (we.we_wordc == 0) {
+ return *mf;
+ }
+
+ strcpy(filename, we.we_wordv[0]);
+ wordfree(&we);
+
+ if (we.we_wordc > 1) {
+ wprintw(more_status, "not opening multiple files");
+ return *mf;
+ }
+
+ if (!strcmp(filename, "#")) {
+ strcpy(filename, mf->path);
+ }
+
struct more_file ret = more_open(filename);
if (ret.f == NULL) {
+ wprintw(more_status, "%s: %s", filename, strerror(errno));
return *mf;
}
@@ -109,10 +135,13 @@ static int more(const char *path)
}
more_refresh(&mf);
+ wrefresh(more_win);
int count = 0;
while (mf.f) {
- int c = getch();
+ wmove(more_status, 0, 0);
+ int c = wgetch(more_status);
+ wclear(more_status);
switch (c) {
case EOF:
@@ -121,7 +150,7 @@ static int more(const char *path)
case 'h':
//show_help();
- printw("Help!");
+ wprintw(more_status, "Help!");
break;
case 'f':
@@ -209,12 +238,12 @@ static int more(const char *path)
break;
case ':': {
- addch(c);
+ waddch(more_status, c);
echo();
- int c2 = getch();
+ int c2 = wgetch(more_status);
noecho();
- printw("\b \b");
+ wprintw(more_status, "\b \b");
switch (c2) {
case 'e':
@@ -247,11 +276,11 @@ static int more(const char *path)
case '=':
case CTRL_G:
- 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);
+ wprintw(more_status, "%s; File %d/%d; Line %zd; Byte %zd/%zd; %zd%%", mf.path, 0, 0, mf.topline, mf.bytepos[mf.topline], mf.nbytes, 100 * mf.bytepos[mf.topline] / mf.nbytes);
break;
case 'Z':
- if (getch() != 'Z') {
+ if (wgetch(more_status) != 'Z') {
break;
}
/* FALLTHRU */
@@ -278,7 +307,7 @@ static int more(const char *path)
count = 0;
}
- refresh();
+ wrefresh(more_win);
}
more_close(&mf);
@@ -438,7 +467,11 @@ int main(int argc, char *argv[])
initscr();
cbreak();
noecho();
- scrollok(stdscr, TRUE);
+
+ more_win = newwin(LINES - 1, 0, 0, 0);
+ scrollok(more_win, TRUE);
+ more_status = newwin(1, 0, LINES - 1, 0);
+ touchwin(stdscr);
atexit(more_exit);