Issue #26870: Add readline.set_auto_history(), originally by Tyler Crompton
This commit is contained in:
parent
4dd27f0adc
commit
f0dbf7a6ab
|
@ -156,6 +156,20 @@ The following functions operate on a global history list:
|
||||||
This calls :c:func:`add_history` in the underlying library.
|
This calls :c:func:`add_history` in the underlying library.
|
||||||
|
|
||||||
|
|
||||||
|
.. function:: set_auto_history(enabled)
|
||||||
|
|
||||||
|
Enable or disable automatic calls to :c:func:`add_history` when reading
|
||||||
|
input via readline. The *enabled* argument should be a Boolean value
|
||||||
|
that when true, enables auto history, and that when False, disables
|
||||||
|
auto history.
|
||||||
|
|
||||||
|
.. versionadded:: 3.6
|
||||||
|
|
||||||
|
.. impl-detail::
|
||||||
|
Auto history is enabled by default, and changes to this do not persist
|
||||||
|
across multiple sessions.
|
||||||
|
|
||||||
|
|
||||||
Startup hooks
|
Startup hooks
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
|
|
@ -239,6 +239,14 @@ Protocol version 4 already supports this case. (Contributed by Serhiy
|
||||||
Storchaka in :issue:`24164`.)
|
Storchaka in :issue:`24164`.)
|
||||||
|
|
||||||
|
|
||||||
|
readline
|
||||||
|
--------
|
||||||
|
|
||||||
|
Added :func:`~readline.set_auto_history` to enable or disable
|
||||||
|
automatic addition of input to the history list. (Contributed by
|
||||||
|
Tyler Crompton in :issue:`26870`.)
|
||||||
|
|
||||||
|
|
||||||
rlcompleter
|
rlcompleter
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
"""
|
"""
|
||||||
Very minimal unittests for parts of the readline module.
|
Very minimal unittests for parts of the readline module.
|
||||||
"""
|
"""
|
||||||
|
from errno import EIO
|
||||||
import os
|
import os
|
||||||
|
import selectors
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import unittest
|
import unittest
|
||||||
from test.support import import_module, unlink
|
from test.support import import_module, unlink
|
||||||
|
@ -96,6 +100,51 @@ class TestReadline(unittest.TestCase):
|
||||||
TERM='xterm-256color')
|
TERM='xterm-256color')
|
||||||
self.assertEqual(stdout, b'')
|
self.assertEqual(stdout, b'')
|
||||||
|
|
||||||
|
auto_history_script = """\
|
||||||
|
import readline
|
||||||
|
readline.set_auto_history({})
|
||||||
|
input()
|
||||||
|
print("History length:", readline.get_current_history_length())
|
||||||
|
"""
|
||||||
|
|
||||||
|
def test_auto_history_enabled(self):
|
||||||
|
output = run_pty(self.auto_history_script.format(True))
|
||||||
|
self.assertIn(b"History length: 1\r\n", output)
|
||||||
|
|
||||||
|
def test_auto_history_disabled(self):
|
||||||
|
output = run_pty(self.auto_history_script.format(False))
|
||||||
|
self.assertIn(b"History length: 0\r\n", output)
|
||||||
|
|
||||||
|
|
||||||
|
def run_pty(script, input=b"dummy input\r"):
|
||||||
|
pty = import_module('pty')
|
||||||
|
output = bytearray()
|
||||||
|
[master, slave] = pty.openpty()
|
||||||
|
args = (sys.executable, '-c', script)
|
||||||
|
proc = subprocess.Popen(args, stdin=slave, stdout=slave, stderr=slave)
|
||||||
|
os.close(slave)
|
||||||
|
with proc, selectors.DefaultSelector() as sel:
|
||||||
|
sel.register(master, selectors.EVENT_READ | selectors.EVENT_WRITE)
|
||||||
|
os.set_blocking(master, False)
|
||||||
|
while True:
|
||||||
|
for [_, events] in sel.select():
|
||||||
|
if events & selectors.EVENT_READ:
|
||||||
|
try:
|
||||||
|
chunk = os.read(master, 0x10000)
|
||||||
|
except OSError as err:
|
||||||
|
# Linux raises EIO when the slave is closed
|
||||||
|
if err.errno != EIO:
|
||||||
|
raise
|
||||||
|
chunk = b""
|
||||||
|
if not chunk:
|
||||||
|
os.close(master)
|
||||||
|
return output
|
||||||
|
output.extend(chunk)
|
||||||
|
if events & selectors.EVENT_WRITE:
|
||||||
|
input = input[os.write(master, input):]
|
||||||
|
if not input:
|
||||||
|
sel.modify(master, selectors.EVENT_READ)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -307,6 +307,7 @@ Ryan Coyner
|
||||||
Christopher A. Craig
|
Christopher A. Craig
|
||||||
Jeremy Craven
|
Jeremy Craven
|
||||||
Laura Creighton
|
Laura Creighton
|
||||||
|
Tyler Crompton
|
||||||
Simon Cross
|
Simon Cross
|
||||||
Felipe Cruz
|
Felipe Cruz
|
||||||
Drew Csillag
|
Drew Csillag
|
||||||
|
|
|
@ -277,6 +277,10 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #26870: Added readline.set_auto_history(), which can stop entries
|
||||||
|
being automatically added to the history list. Based on patch by Tyler
|
||||||
|
Crompton.
|
||||||
|
|
||||||
- Issue #26039: zipfile.ZipFile.open() can now be used to write data into a ZIP
|
- Issue #26039: zipfile.ZipFile.open() can now be used to write data into a ZIP
|
||||||
file, as well as for extracting data. Patch by Thomas Kluyver.
|
file, as well as for extracting data. Patch by Thomas Kluyver.
|
||||||
|
|
||||||
|
|
|
@ -575,6 +575,24 @@ PyDoc_STRVAR(doc_add_history,
|
||||||
"add_history(string) -> None\n\
|
"add_history(string) -> None\n\
|
||||||
add an item to the history buffer");
|
add an item to the history buffer");
|
||||||
|
|
||||||
|
static int should_auto_add_history = 1;
|
||||||
|
|
||||||
|
/* Enable or disable automatic history */
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
py_set_auto_history(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
if (!PyArg_ParseTuple(args, "p:set_auto_history",
|
||||||
|
&should_auto_add_history)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyDoc_STRVAR(doc_set_auto_history,
|
||||||
|
"set_auto_history(enabled) -> None\n\
|
||||||
|
Enables or disables automatic history.");
|
||||||
|
|
||||||
|
|
||||||
/* Get the tab-completion word-delimiters that readline uses */
|
/* Get the tab-completion word-delimiters that readline uses */
|
||||||
|
|
||||||
|
@ -791,6 +809,7 @@ static struct PyMethodDef readline_methods[] =
|
||||||
|
|
||||||
{"set_completer_delims", set_completer_delims,
|
{"set_completer_delims", set_completer_delims,
|
||||||
METH_VARARGS, doc_set_completer_delims},
|
METH_VARARGS, doc_set_completer_delims},
|
||||||
|
{"set_auto_history", py_set_auto_history, METH_VARARGS, doc_set_auto_history},
|
||||||
{"add_history", py_add_history, METH_VARARGS, doc_add_history},
|
{"add_history", py_add_history, METH_VARARGS, doc_add_history},
|
||||||
{"remove_history_item", py_remove_history, METH_VARARGS, doc_remove_history},
|
{"remove_history_item", py_remove_history, METH_VARARGS, doc_remove_history},
|
||||||
{"replace_history_item", py_replace_history, METH_VARARGS, doc_replace_history},
|
{"replace_history_item", py_replace_history, METH_VARARGS, doc_replace_history},
|
||||||
|
@ -1266,7 +1285,7 @@ call_readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt)
|
||||||
|
|
||||||
/* we have a valid line */
|
/* we have a valid line */
|
||||||
n = strlen(p);
|
n = strlen(p);
|
||||||
if (n > 0) {
|
if (should_auto_add_history && n > 0) {
|
||||||
const char *line;
|
const char *line;
|
||||||
int length = _py_get_history_length();
|
int length = _py_get_history_length();
|
||||||
if (length > 0)
|
if (length > 0)
|
||||||
|
|
Loading…
Reference in New Issue