Нужна помощь с использованием ncurses для разбивки на выходные команды в моем пользовательском интерфейсе командной строки - PullRequest
0 голосов
/ 04 февраля 2019

Мне нужен простой пейджер для вывода команд CLI.Я хочу иметь возможность прокручивать вверх / вниз в выводе, либо одну целую страницу за раз, либо построчно.

Я посмотрел на «менее» исходный код, но он был слишком сложным, чтобыПомоги мне.Поэтому я сам начал писать простую.До сих пор я писал вывод команды в файл.затем прочитайте файл построчно и запишите в окно ncurses.Когда я достигаю нижней части окна, я жду, пока пользователь нажмет клавишу, затем очистлю экран и напишу новую страницу и так далее.В результате получается что-то вроде команды «more».

Вот простой код, который я использую:

int print()
{
    FILE *fp;
    ssize_t read;
    int row, col, x, y;
    char *line = NULL;
    char c;
    size_t len;

    initscr();
    getmaxyx(stdscr, row, col);

    fp = fopen("path_to_output_file", "r");

    if (!fp)
    {
        printf("Failed to open CLI output file.\n");
        return -1;
    }

    while ((read = getline(&line, &len, fp)) != -1)
    {
        getyx(stdscr, y, x);

        if (y == (row - 1))
        {
            printw("Press Any Key to continue...");
            c = getch();

            if (c == 'q')
            {
                break;
            }

            clear();
            move(0, 0);
        }

        printw(line);
        refresh();
    }

    fclose(fp);
    getch();
    endwin();

    return 0
}

Теперь мне нужна помощь, чтобы найти идею реализации обратной прокрутки для перемещения вверх на однустраница / строка в выводе.Как мне пройти по файлу и распечатать окно строк в ncurses, чтобы получить желаемый результат.

Кроме этого, любая идея по улучшению моего простого пейджера приветствуется ...

1 Ответ

0 голосов
/ 05 февраля 2019

Несмотря на то, что вы уже работаете над этим, вот реализация обратных движений, которая использует fseek() для сохранения смещений начала (физических / оконных) строк, собранных во время чтения строк:

    …
    keypad(stdscr, TRUE);   // enable returning function key tokens
    long offset, *pos = NULL, lineno = 0;
    char buffer[col+1];
    TABSIZE = 1;
    do
    {   y = 0;
        long topline = lineno;
        while (offset = ftell(fp), line = fgets(buffer, sizeof buffer, fp))
        {
            pos = realloc(pos, (lineno+1) * sizeof *pos);   if (!pos) exit(1);
            pos[lineno++] = offset; // save offset of current line
            addstr(line);
            getyx(stdscr, y, x);
            if (y == row-1)
                break;
        }
        printw("Press [upward arrow] or [Page Up] or any key to continue...");
        int c = getch();
        if (c == KEY_UP)    // Up arrow
            fseek(fp, pos[lineno = topline>1 ? topline-1 : 0], SEEK_SET);
        else
        if (c == KEY_PPAGE) // Previous page
            fseek(fp, pos[lineno = topline>=row ? topline-row+1 : 0], SEEK_SET);
        else
        if (c == 'q' || !line)
            break;

        clear();
        move(0, 0);
    } while (1);

    fclose(fp);
    endwin();
    …

В качестве простого подхода к решению проблемы с вкладками, я установил TABSIZE на 1.

...