在ncurses中实现文本滚动的推荐方法是什么?

我正试图实现一个ncurses应用程序文本滚动像less。 推荐的方法是什么?

以下是我所知道的:

  1. 您可以使用scroll向上或向下移动文本缓冲区1行。 但是,如果向下滚动,则最终会有一个空白行,如果向上滚动,则最下面会有一个空白行,必须重新绘制。
  2. Ncurses为你做wordwrap,当我不得不在第一步中确定我要重画哪一行时,弄乱了我的math。

我想我可以自己重新实现wordwrap,并保留所有后包装行的数组,但这似乎是一个常见的问题,所以可能有更好的方法。

我在ncurses方面还不是很有经验,所以我不知道所有的库函数,但是保持一个双向链接的文本行列表可以工作。 这里是一个较less的原始克隆:

 #include <ncurses.h> #include <stdlib.h> #define MAXLEN 128 typedef struct Line { char contents[MAXLEN]; struct Line *prev, *next; } Line; Line *head, *curr; int nr_lines; int curr_line; int term_rows, term_cols; void load(const char *filename); void draw(Line *l); int main(int argc, char **argv) { if (argc == 1) { fputs("less: No file to open\n", stderr); return 1; } initscr(); noecho(); keypad(stdscr, TRUE); // for KEY_UP, KEY_DOWN getmaxyx(stdscr, term_rows, term_cols); addstr("Reading text...\n"); load(argv[1]); curr = head; curr_line = 0; draw(curr); int ch; while ((ch = getch()) != EOF && ch != 'q') { if (ch == KEY_UP && curr->prev != NULL) { curr_line--; curr = curr->prev; } else if (ch == KEY_DOWN && curr->next != NULL && curr_line + term_rows < nr_lines) { curr_line++; curr = curr->next; } draw(curr); } endwin(); return 0; } void load(const char *filename) { FILE *fp = fopen(filename, "r"); Line *lp; head = malloc(sizeof(Line)); head->prev = head->next = NULL; curr = head; while (fgets(curr->contents, MAXLEN, fp)) { lp = malloc(sizeof(Line)); lp->prev = curr; curr->next = lp; curr = lp; nr_lines++; } curr->next = NULL; } void draw(Line *l) { int i; clear(); for (i = 0; i < term_rows && l != NULL; i++, l = l->next) addstr(l->contents); } 

我不知道这将如何处理超过128个字符的行,但这是一个不同的解决scheme不同的问题。

至于文字换行,如果你不需要保留原来的文本格式,你可以从文件中读取长长的行。

ncurses只知道当前的屏幕。 当屏幕滚动时,ncurses不会跟踪任何离开屏幕的文本。 您的terminal可能有一个回滚缓冲区,但是这与ncurses无关,并且curses无法查看terminal的回滚缓冲区。

我希望如果你需要滚动的话,你需要跟踪你当前在文件中的位置。

我不认为ncurses做了自动换行,你怎么做换行?