Git Product home page Git Product logo

editline's People

Contributors

abitmore avatar al20878 avatar c0deh4cker avatar cfischer1967 avatar cogutvalera avatar dtzwill avatar dvolynets avatar jakubpawlo avatar jmjatlanta avatar lnl7 avatar mattiaswal avatar mlundh avatar nobody5050 avatar oxalica avatar rcombs avatar rofl0r avatar tejing1 avatar the-king-of-toasters avatar tobygoodwin avatar trofi avatar troglobit avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

editline's Issues

Usage with an external event loop

I am looking for a line editing library that I can use together with an event loop. That means no blocking readline function and no direct access to stdin.
Instead, I would call readline() with one or more the user pressed, readline should process these keys and return.
Is this possible with editline, or if not, could you give an estimate on how much work it would be to implement something like this?

Prompt not redisplayed after displaying completion possibilities

I have a simple application that uses editline v1.17.1, and returns 4 possible completions on the empty string.

The 4 completions are displayed correctly, however the prompt is not re-displayed, ending up with this:

Run cli:

(device) [email protected] /> 

Press tab once, you get 4 completions as expected, but no redisplay of the prompt:

(device) [email protected] /> 
services  system    exit      quit

Type 's' followed by tab, and you get 2 completions as expected, but no redisplay of prompt, and the 's' character appears twice:

(device) [email protected] /> 
services  system    exit      quit
s
services  system
ss

Type 'e' followed by tab, giving you the unique option 'services'. This is displayed, but the prompt is still missing, and we still have a stray s:

(device) [email protected] /> 
services  system    exit      quit
s
services  system
sservices 

Press 'enter' despite the corrupt prompt, and the line is returned correctly and the prompt redisplayed:

(device) [email protected] /> 
services  system    exit      quit
s
services  system
sservices 
(device) [email protected] /services> 

The prompt is "(device) %s@%s /%s> " and contains no special characters.

Is this a known issue?

Apple Terminal on Big Sur, cli running on CentOS8.

Run with mpi

I use editline with mpi and have the loop in rank 0. Everything seems OK except the prompt message.

Feature request: able to gracefully end readline() from another thread

When readline() is running in a thread waiting for input from tty, terminal is prepped, the function blocks until got an "end" (e.g. EOL, EOF, SIGINT or etc) from tty. In case when another thread decided to no longer accept input from tty (e.g. timeout or got a signal from outside), we need a way to gracefully end readline() and restore terminal, rather than waiting for an end. We can't forcefully end the thread because terminal won't be restored.

Request for \1 and \2 (RL_PROMPT_START_IGNORE, RL_PROMPT_END_IGNORE) support

Editline currently uses a "one byte per column" heuristic, and one way that breaks down is when it encounters colored prompts. The way readline (and libedit) handles this issue is by having the program tell it what parts of the prompt don't count into the width calculation: \1 (RL_PROMPT_START_IGNORE) starts the width-ignore area and \2 (RL_PROMPT_END_IGNORE) ends it.

See https://github.com/cdesjardins/libedit/search?q=RL_PROMPT_START_IGNORE for how it works in NetBSD libedit.

How to call function 'el_bind_key'

Using the readline library, one can have this rl_bind_key('\t', rl_insert); which disables readline from displaying files that exist on the current working directory when the user presses TAB.

I am now trying to get ride of readline and use the editline library instead. I found out function el_bind_key (which looks like it's the replacement for function rl_bind_key) but not sure how the second parameter of this function should look like.

Basically, I want to disable editline displaying files that exist on the current working directory when the user presses TAB.

How to bind Ctrl + W to delete word backwards?

I am using the mysql client from which comes with editLine in my distribution:

$ mysql --version
mysql  Ver 14.14 Distrib 5.7.17, for Linux (x86_64) using  EditLine wrapper

I would not mind if it was a in-place replacment behaving similar to readline. Yet certain emac-like keybindings from readline, I am very much used to, don't work anymore, breaking my habitual workflow.

I am very much used to delete the last word by Ctrl + W. Yet via editline, it deletes to the beginning of the line instead just one word back.

I tried adding .editrc with the content:

bind ^W backward-delete-word

Yet it doesn't work.

How can I bind keys to my liking, and how can I get Ctrl + W to delete one word backwards?

Can you state in the source it's licensed under Apache-2.0?

It seems LICENSE is completely custom and similar to Zlib License.
README says:

  • This line editing library was created by Rich Salz and Simmule Turner and in 1992. It is distributed with a “C News-like” license, similar to the BSD license. Rich's current version is however under the Apache license. For details on the licensing terms of this version of the software, see License.
 Copyright 1992,1993 Simmule Turner and Rich Salz
 All rights reserved.

 This software is not subject to any license of the American Telephone
 and Telegraph Company or of the Regents of the University of California.

 Permission is granted to anyone to use this software for any purpose on
 any computer system, and to alter it and redistribute it freely, subject
 to the following restrictions:
 1. The authors are not responsible for the consequences of use of this
    software, no matter how awful, even if they arise from flaws in it.
 2. The origin of this software must not be misrepresented, either by
    explicit claim or by omission.  Since few users ever read sources,
    credits must appear in the documentation.
 3. Altered versions must be plainly marked as such, and must not be
    misrepresented as being the original software.  Since few users
    ever read sources, credits must appear in the documentation.
 4. This notice may not be removed or altered.

But the text does not resemble Apache-1.0, Apache-1.1, Apache-2.0.

Please, can you state clearly it's licensed under Apache-2.0? Maybe update LICENSE file?

Inclusion in a debian repository

Currently Debian distributes what it seems to be a very old version in comparison (1.12), based solely in the version numbering and release date, I believe is one of the original sources that was merged, based in the readme description. Is there any particular reason why is that? Given that the required build files for such package are already part of this repo (and they do work, recently tested in debian bullseye), is it just a matter of coordination with a debian maintainer? Or is there something else?.

Personally I have a particular interest in this package because is a dependency of Nix and the packaging effort of nix in debian would benefit itself by having a recent editline in the official repos, currently they have opted for trying to implement readline support in nix PR1/merged PR2/pending instead of packaging this library. At this time, Nix doesn't have the autocomplete functionality for the readline build option and it seems that the the Nix maintainers are even reconsidering the idea of allowing the extra option to support readline and stick only to editline.

Not sure if this is the best place to get more context. But I suppose it would be better to have this discussion in some place that can be publicly found for any future reference.

Thanks.

Completion functions returning strings containing tabs or spaces display incorrectly

In a project of mine, I wrote a completer function that does only return strdup("\t"); (to disable completion of filenames, which are meaningless for my project). However, this prints ^I instead of a tab as it should. When I try to return something like strdup("hello world"), it prints hello\ world instead. I assume that the issue is due to the very questionable implementation of CTL() and META(). It seems to me that the proper way of doing this is to use a type larger than a char, where the modifers are stored in higher bits. Of course this will require changing the public interface to libeditline, so maybe the current functions should be deprecated (but still remain), and new, proper functions should be added.

I just did some digging and found out that the string returned from my completer function is passed to insert_string(), which passes it to tty_string(), and then each character goes to tty_show(), which does use the ISCTL() and ISMETA() macros to incorrectly convert a tab into ^I. Also, it is line 1385 of editline.c which adds a newline before spaces. No idea why it does that though.

README: slightly incorrect statement about netbsd libedit dependencies

( refering to the sentence "The libraries have much in common, but the latter is heavily refactored and also relies on ncurses, whereas this library only uses termios from the standard C library." in README)

at least the libedit version used in sabotage linux, worked fine when linked against stallmann's original termcap library (before i changed the package to use netbsd's curses[0] instead): sabotage-linux/sabotage@9b3107c

[0] https://github.com/sabotage-linux/netbsd-curses

Example Step 2 needs header file <stdio.h>

#include <stdlib.h>
#include <stdio.h> // This line should put before #include <editline.h>, or it will be failed to compile.
#include <editline.h>

int main(void)
{
    char *p;
    while ((p = readline("CLI> ")) != NULL) {
        puts(p);
        free(p);
    }

    return 0;
}

without #include <stdio.h>, the error message

$ g++ test.cc -I$HOME/mylib/include -L$HOME/mylib/lib -leditline

/mylib/include/editline.h:87:8: error: ‘FILE’ does not name a type
extern FILE       *rl_instream;  /* The stdio stream from which input is read. Defaults to stdin if NULL - Not supported yet! */
        ^~~~
In file included from test.cc:3:0:
mylib/include/editline.h:88:8: error: ‘FILE’ does not name a type
extern FILE       *rl_outstream; /* The stdio stream to which output is flushed. Defaults to stdout if NULL - Not supported yet! */

test.cc: In function ‘int main()’:
test.cc:10:9: error: ‘puts’ was not declared in this scope
         puts(p);
         ^~~~

Prompt not displayed on non-interactive sessions, inconsistent with GNU readline

On editline-1.17.1:

co/nix » echo '1+1' | LD_PRELOAD=result/lib/libreadline.so nix repl --quiet | cat
nix-repl> 1+1
2


co/nix » echo '1+1' | nix repl --quiet | cat
Failed tcsetattr(TCSADRAIN): Inappropriate ioctl for device
Failed tcsetattr(TCSADRAIN): Inappropriate ioctl for device
2

Confirmed by inspection of the code: when !isatty(), prompts aren't printed.

missing functions to use editline as drop-in replacement for readline with gdb 7.6

gdb 7.6 seems to be the most elaborate readline user in sabotage linux, but it can be tricked, to link against libedit instead of readline, and i hoped as well against editline...

Here's a list of missing functions:

  • undefined reference to `history_base'
  • undefined reference to `history_expand'
  • undefined reference to `history_get'
  • undefined reference to `history_is_stifled'
  • undefined reference to `history_length'
  • undefined reference to `max_input_history'
  • undefined reference to `rl_add_defun'
  • undefined reference to `rl_already_prompted'
  • undefined reference to `rl_callback_handler_install'
  • undefined reference to `rl_callback_handler_remove'
  • undefined reference to `rl_callback_read_char'
  • undefined reference to `rl_completer_quote_characters'
  • undefined reference to `rl_completer_word_break_characters'
  • undefined reference to `rl_completion_entry_function'
  • undefined reference to `rl_completion_word_break_hook'
  • undefined reference to `rl_filename_completion_function'
  • undefined reference to `rl_get_previous_history'
  • undefined reference to `rl_get_screen_size'
  • undefined reference to `rl_newline'
  • undefined reference to `rl_pre_input_hook'
  • undefined reference to `rl_redisplay'
  • undefined reference to `rl_set_screen_size'
  • undefined reference to `rl_terminal_name'
  • undefined reference to `stifle_history'
  • undefined reference to `tilde_expand'
  • undefined reference to `unstifle_history'
  • undefined reference to `where_history'

undocumented dependency on libtermcap

checking termcap.h usability... no                                              
checking termcap.h presence... no                                               
checking for termcap.h... no                                                    
checking for termio.h... no                                            
checking for termios.h... yes                                          
...
make[2]: Entering directory `/src/build/editline/editline-1.15.1/examples'
libtool: link: gcc -I../src -I../include -fdata-sections -ffunction-sections -Os ...
/bin/ld: cannot find -ltermcap                                                  

and with --disable-termcap:

 libtool: link: gcc -I../src -I../include -fdata-sections -ffunction-sections -Os
../src/.libs/libeditline.a(editline.o): In function `rl_reset_terminal':        
editline.c:(.text.rl_reset_terminal+0x57): undefined reference to `tgetent'     
editline.c:(.text.rl_reset_terminal+0x68): undefined reference to `tgetstr'     
editline.c:(.text.rl_reset_terminal+0x8d): undefined reference to `tgetnum'     
editline.c:(.text.rl_reset_terminal+0x9d): undefined reference to `tgetnum'     
collect2: error: ld returned 1 exit status                                 

Address sanitizer reports error

Hi,
I am using editline in a project where I am also enabling address sanitizer. I get a buffer overrun error in completion.c:203. I am not quite sure what the correct way of fixing the issue is, but it seems as the memcpy is trying to read beyond the allocated memory in the av[0] array. Reducing the size of the copy (+1 instead of +2 on line 200) resolves that particular issue, but I can not guarantee that it will not break anything else.

Support for Latin-1?

Is it possible editline only supports UTF8?

As you may know, mysql now only supports editline and this causes problems with german umlaut characters on systems with LC_CTYPE=de_DE or de_DE.iso88591 instead of de_DE.utf8

Segmentation violation

This shows up on macOS 10.13 (and maybe others).

editline/src/editline.c

Lines 178 to 182 in 534b389

Screen[ScreenCount] = c;
if (++ScreenCount > ScreenSize) {
ScreenSize += SCREEN_INC;
Screen = realloc(Screen, sizeof(char) * ScreenSize);
}

I believe the realloc should happen before the character is added to the array. Once I made that change, the SIGSEV went away.

Note: The array of items to display had 122 entries, longest 46 (3 columns).

Update: After taking another look, changing the > to a >= will do the trick.

The process that uses editline does not respect CTRL+Z

When I press CTRL+Z to suspend the process that runs editline (I'm in Linux), it doesn't react. FYI, when using the readline library everything works as expected (i.e. the process would have been suspended and the prompt returns to the terminal). How can this be fixed? Thanks!

Cannot find sgstat.h or modes.h.

This is not an issue with the compilation of the library, more of an issue with that I cannot find where these headers reside, I cannot find much information about them, but it compiles perfectly fine.

#include <sgstat.h>
#include <modes.h>

Request for UTF-8 support

Any idea if UTF support can be added to this lib?
Preferably without depending on locale stuff from glibc

strdup implementation has off-by-one error

In src/sysunix.c there is this:

#ifndef HAVE_STRDUP
/* Return an allocated copy of a string. */
char *strdup(const char *p)
{
    char *new = malloc(sizeof(char) * strlen(p));

This forgets to malloc the terminating NUL for the string and causes undefined behavior for the subsequent strcpy.

This should be

malloc(strlen(p) + 1);

Note that multiplying by sizeof(char) is considered silly, since it is 1 by definition in the C Standard.

Does editline support context specific auto-complete?

Hi
I've just been looking at this library for use in a simple CLI application.
I see that there is some support for supplying custom auto-complete functions so that (for example) the application can auto-complete commands from a fixed set of command names.
When I try out the example cli application, I see that auto-complete searches the same list with each and every argument.
What I'd like to do is vary the auto-complete function depending on the arguments already entered by the user so that (for example) auto-completing the second argument in a command searches one list if the first argument is 'a', and a different list if the first argument is 'b'.
Is this possible out of the box with this library? Is there a way to obtain the arguments already entered so that auto-complete can be made more context specific?
Thanks

No file name configure.

I normally don't still things from github, and I'm sorry if the answer is too obvious. But after cloning, and cd-ing into the editline folder on Fedora I tried the first step. After doing a find for this file in other folders, still nothing.

rl_point is always zero

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).

Does not compile cleanly

I tried to build this library with GCC 11 on Cygwin just now, and it does not compile cleanly:

In file included from editline.c:23:
editline.c: In function 'do_case':
editline.c:497:29: warning: array subscript has type 'char' [-Wchar-subscripts]
  497 |                 if (islower(*p))
      |                             ^~
editline.c:499:32: warning: array subscript has type 'char' [-Wchar-subscripts]
  499 |             } else if (isupper(*p)) {
      |                                ^~
editline.c: In function 'argify':
editline.c:1878:28: warning: array subscript has type 'char' [-Wchar-subscripts]
 1878 |     for (c = line; isspace(*c); c++)
      |                            ^~
editline.c:1885:22: warning: array subscript has type 'char' [-Wchar-subscripts]
 1885 |         if (!isspace(*c)) {
      |                      ^~
  CC       libeditline_la-complete.lo
In file included from complete.c:23:
complete.c: In function 'rl_find_token':
complete.c:281:35: warning: array subscript has type 'char' [-Wchar-subscripts]
  281 |         if (isspace(rl_line_buffer[pos])) {
      |                     ~~~~~~~~~~~~~~^~~~~
complete.c:289:47: warning: array subscript has type 'char' [-Wchar-subscripts]
  289 |     while (pos >= 0 && !isspace(rl_line_buffer[pos])) {
      |                                 ~~~~~~~~~~~~~~^~~~~

A "char" subscript can actually be a big deal for characters with the 8th bit set (will get converted to a negative "int"), so the warnings do not look great.
Any chance you can fix these please (e.g. by adding explicit (unsigned char) casts where necessary)?
Thanks.

P.S. BTW the "Build & Install" instructions in README.md call for running configure but it is not provided in the source tree if cloned directly from github, and it looks like autogen.sh needs to be executed first in order to actually build configure -- but that step is missing entirely from the instructions.

fileman.c example. Error free(): double free detected in tcache 2

Error Description

So I'm using rl_attempted_completion_function to add my own keyword completion, but ever since that the filepath completion doesn't work as expected, it will crash with free(): double free detected in tcache 2. I thought it was my problem, so I tried the fileman.c given in the example, but it ended up the same.
Comment out the binding to rl_attempted_completion_function, then it will work normally. So I guess there's something wrong with executing that function.

How to trigger

If you input ./ <tab>, then it will crash, but if you quote the path it works, e.g "/usr <tab>, it will show /usr/lib.

Sysinfo

System: Lubuntu 20.04
GCC Version: 9.3.0

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.