troglobit / editline

A small replacement for GNU readline() for UNIX
https://troglobit.com/projects/editline/
Other
277 stars 56 forks source link

rl_point is always zero #55

Open okbob opened 3 years ago

okbob commented 3 years ago

I try to use alternative API

/* For wcwidth() */
#define _XOPEN_SOURCE 700

#include <locale.h>
#include <ncurses.h>
#include <editline/readline.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>

int kurzor;

static int      readline_proxy;
static bool     readline_proxy_is_valid = false;
char   *string = NULL;

/*
 * Zkopiruje znak z proxy do readline
 */
static int
readline_getc(FILE  *dummy)
{
    readline_proxy_is_valid = false;
    return readline_proxy;
}

/*
 * Touto funkci readline predava vysledek editace
 */
static void
readline_callback(char *line)
{
    free(string);
    string = NULL;

    if (line)
        string = strdup(line);

}

/*
 * Chceme mit zobrazeni ve vlastni rezii
 */
static void
readline_redisplay()
{
    /* do nothing here */
}

/*
 * Vrati (zobrazovaci) sirku retezce.
 */
static size_t
strnwidth(const char *s, size_t n)
{
    mbstate_t shift_state;
    wchar_t wc;
    size_t wc_len;
    size_t width = 0;
    size_t ch_width;

    memset(&shift_state, '\0', sizeof shift_state);

    for (size_t i = 0; i < n; i += wc_len)
    {
        wc_len = mbrtowc(&wc, s + i, MB_CUR_MAX, &shift_state);
        if (!wc_len)
            return width;

        if ((wc_len == (size_t) -1) || (wc_len == (size_t) -2))
            return width + strnlen(s + i, n - i);

        if (iswcntrl(wc))
            width += 2;
        else if ((ch_width = wcwidth(wc)) > 0)
            width += ch_width;
    }

    return width;
}

int
main()
{
    int     c = 0;
    bool    alt = false;
    char   *prompt = ": ";

    setlocale(LC_ALL, "");

    initscr();
    cbreak();
    noecho();

    /* ENTER neni \n */
    nonl();

    /*
     * readline vyzaduje neprekodovany vstup tj
     * vypnuty keypad a cteni vice bajtovych
     * znaku po bajtech (emuluje se binarni
     * cteni ze souboru v aktualnim kodovani)
     */
    keypad(stdscr, FALSE);

    /*
     * Instalace hooku - pokud se pouzije rl_getc_function,
     * tak by se mel VZDY pouzit i rl_input_available_hook.
     */
    rl_getc_function = readline_getc;
    rl_redisplay_function = readline_redisplay;

    /*
     * Nechceme obsluhu signalu v readline, a nechceme tab
     * complete (neni nakonfigurovano, hrozi pady.
     */
    rl_catch_signals = 0;
    rl_catch_sigwinch = 0;
    rl_inhibit_completion = 0;

    /* Zahajeni editace */
    rl_callback_handler_install(prompt, readline_callback);

    /* Vlozi vychozi (default) text */
    rl_insert_text("Editaci ukonci 2x stisk ESCAPE");

    while (1)
    {
        int     cursor_pos;

        clear();

        mvaddstr(10, 10, rl_prompt);
        addstr(rl_line_buffer);

        if (string)
        {
            mvaddstr(12, 6, "text: ");
            attron(A_REVERSE);
            addstr(string);
            attroff(A_REVERSE);
        }

        /* nastav kurzor */
        cursor_pos = strnwidth(rl_prompt, SIZE_MAX) +
                     strnwidth(rl_line_buffer, rl_point);
        move(10, 10 + cursor_pos);

        refresh();

        get_wch(&c);

        /* ignoruj tabelatory */
        if (c == '\t')
            continue;

        if (c == 27)
        {
            if (alt)
                break;
            else
                alt = true;
        }
        else
            alt = false;

        readline_proxy = c;
        readline_proxy_is_valid = true;

        /* posli echo readline, ze jsou nova data k precteni */
        rl_callback_read_char();
    }

    rl_callback_handler_remove();

    endwin();
}

I am able to build this example, but the variables rl_point and rl_end are always zero. Unfortunately editline doesn't decode cursor keys or other control keys.

Is this functionality supported? I try to use editline from ncurses application.

tested on FC34

Name         : editline
Version      : 1.17.1
Release      : 3.fc34
Architecture : x86_64
Size         : 28 k
Source       : editline-1.17.1-3.fc34.src.rpm
Repository   : fedora
Summary      : A small compatible replacement for readline
URL          : https://troglobit.com/projects/editline/
License      : HSRL
Description  : This is a line editing library for UNIX. It can be linked into almost
             : any program to provide command line editing and history. It is call
             : compatible with the FSF readline library, but is a fraction of the
             : size (and offers fewer features).
troglobit commented 3 years ago

The integration of the GNU readline compat APIs, like the custom callbacks, is in a very raw and limited state. I tested them at one point three years when I first attempted to include them. It's however not something I've prioritized, and reception for it has been non-existent, so I'm not surprised your example doesn't work.

Editline is a very limited library, but cursor keys does work, provided it is built with --enable-arrow-keys, which is the configure default.

okbob commented 3 years ago

čt 5. 8. 2021 v 18:24 odesílatel Joachim Wiberg @.***> napsal:

The integration of the GNU readline compat APIs, like the custom callbacks, is in a very raw and limited state. I tested them at one point three years when I first attempted to include them. It's however not something I've prioritized, and reception for it has been non-existent, so I'm not surprised your example doesn't work.

Editline is a very limited library, but cursor keys does work, provided it is built with --enable-arrow-keys, which is the configure default.

ok

When I run my example, then and when I press cursor keys, then I see ^[[D for left, and ^[[C for right key. So it looks like when I use callback functions, then cursor keys are not recognized.

This behaviour is consistent if I use or don't use wide chars.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/troglobit/editline/issues/55#issuecomment-893592991, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAEFO4YIDVY5BKTM7FEHFK3T3K3MJANCNFSM5BUEHMWA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&utm_campaign=notification-email .

troglobit commented 3 years ago

OK, maybe someone else is interested in helping out to fix this issue. Pull requests and patches are welcome! :)

9999years commented 1 week ago

I'm not sure about rl_point or rl_end, but I've added support for those arrow keys in #70.