bug-readline
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug-readline] Aborting reverse-i-search with the callback interface


From: Martin Panter
Subject: [Bug-readline] Aborting reverse-i-search with the callback interface
Date: Mon, 25 May 2015 01:13:31 +0000

This is regarding a bug reported for Python:
<https://bugs.python.org/issue24266>, but I am wondering if it should
actually be fixed inside Readline. When you press Ctrl+R, it switches
to an incremental history search mode. In Bash, pressing Ctrl+C will
cancel the entry completely, letting you start a new entry from
scratch. However in Python, Ctrl+C clears the display, but does not
actually cancel the search, and the entry is still there if you press
enter. I noticed similar behaviour in GDB.

Here is an example of cancelling from search mode in Python.
Everything looks fine on the surface. KeyboardInterrupt is Python’s
way of saying Ctrl+C was hit:

    >>> print("Hello")
    Hello
    (reverse-i-search)`p': print("Hello")
    KeyboardInterrupt
    >>>

But if I then press “r”, it is still in the original search mode:

    >>> print("Hello")
    Hello
    (reverse-i-search)`p': print("Hello")
    KeyboardInterrupt
    (reverse-i-search)`pr': print("Hello")

Alternatively, if I press Enter after Ctrl+C, the original searched
line is magically displayed and executed:

    >>> print("Hello")
    Hello
    (reverse-i-search)`p': print("Hello")
    KeyboardInterrupt
    >>> print("Hello")
    Hello

Python uses the rl_callback_read_char() function to invoke Readline.
It has a signal handler for SIGINT (Ctrl-C), which sets an exception
flag, and then returns. If an exception is set, Python should abort
the entry in Readline, and the next time we start calling Readline it
should start a new entry. The code which handles this is at
<https://hg.python.org/cpython/file/0d0989359bbb/Modules/readline.c#l1153>
and looks a bit like this:

s = PyErr_CheckSignals();
if (s < 0) {
    rl_free_line_state();
    rl_cleanup_after_signal();
    rl_callback_handler_remove();
    *signal = 1;
    completed_input_string = NULL;
}

The documentation of rl_free_line_state() at
<https://cnswww.cns.cwru.edu/php/chet/readline/readline.html#IDX341>
says it “will free any partial state”. I am far from an expert on
Readline, but this sounds like it should clear the search mode and
forget the searched entry. A workaround has been proposed for Python
to unset the RL_STATE_ISEARCH flag and set RL_STATE_DONE flag, but I
wonder if you think this sort of thing should be done inside the
rl_free_line_state() function instead?



reply via email to

[Prev in Thread] Current Thread [Next in Thread]