Skip to content

readline.set_completer_delims has no effect with libedit #112105

Closed
@gaogaotiantian

Description

@gaogaotiantian

Bug report

Bug description:

readline.set_completer_delims works fine with GNU readline, but not with libedit.

A quick example:

import readline

readline.set_completer_delims("\n")
if "libedit" in getattr(readline, "__doc__", ""):
    readline.parse_and_bind("bind ^I rl_complete")
else:
    readline.parse_and_bind("tab: complete")

def completer(text, state):
    if text == "$" and state == 0:
        return "$complete"
    return None

readline.set_completer(completer)

input()
# Type $ then <tab>

With GNU readline, it completes correctly, but with libedit, it can't - libedit still considers $ as a delimiter. You can confirm that by printing the text in completer function.

The issue is in readline.c:

cpython/Modules/readline.c

Lines 576 to 581 in d4f83e1

if (break_chars) {
free(completer_word_break_characters);
completer_word_break_characters = break_chars;
rl_completer_word_break_characters = break_chars;
Py_RETURN_NONE;
}

readline.c writes to rl_completer_word_break_characters, which works fine source.

However, libedit does not do the same thing, it uses rl_basic_word_break_characters instead:

if (rl_completion_word_break_hook != NULL)
	breakchars = (*rl_completion_word_break_hook)();
else
	breakchars = rl_basic_word_break_characters;

Thus, writing to rl_completer_word_break_characters will not have any effect on libedit. The simplest way I can think of, is to write to both rl_completer_word_break_characters and rl_basic_word_break_characters. They both exist in GNU readline and libedit, for slightly different purposes.

  • GNU readline:
    • rl_completer_word_break_characters is the one that takes effect
    • rl_basic_word_break_characters just keeps a string as default value for rl_completer_word_break_characters
  • libedit
    • rl_completer_word_break_characters is not used at all
    • rl_basic_word_break_characters is used for break words

From what I can observe, writing to both variables has no unexpected side effect, because rl_basic_word_break_characters is not used on CPython with GNU readline.

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux, macOS

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions