Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rl_point is always zero #55

Open
okbob opened this issue Aug 5, 2021 · 4 comments
Open

rl_point is always zero #55

okbob opened this issue Aug 5, 2021 · 4 comments

Comments

@okbob
Copy link

okbob commented Aug 5, 2021

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
Copy link
Owner

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
Copy link
Author

okbob commented Aug 5, 2021 via email

@troglobit
Copy link
Owner

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

@9999years
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants