pyreadline/pyreadline — pull request #15 by stephengithub (2013-08-04 19:24:07+00:00)
Title: Modified rlmain.py to make saving the prompt position an option that is

In the product my company is developing, we have a python-based command input line and we use a custom command completer with pyreadline to satisfy customer requirements for command completion and persistent history. We also have asynchronous messages (generated from background threads) printed to the python command line, typically as a result of some user-entered command. These asynchronous messages are important and need to be preserved. Other than creating a custom GUI where such asynchronous messages are captured in a separate window or sending the asynchronous text to a log file (where they are hidden until viewed), printing the messages to the python command window was deemed the most useful approach. However, pyreadline's functionality of erasing everything from the prompt onward (because of the saved prompt position), caused the asynchronous messages to be lost.

I modified rlmain.py to make saving the prompt position an option that is enabled by default (so the current behavior remains the same). When this option is disabled, pressing Enter or right arrow will move the prompt to after any text that might have been displayed asynchronously while waiting for input from the command line. The default behavior is to erase such asynchronous text and restore the prompt to its original starting position before the asynchronous text was printed.

Here is a test python module that shows the problem being solved (save the following as pyreadlinetest.py):

````
# 8/4/2013 (stephengithub):
# Demonstrates clearing asynchronous messages with pyreadline 2.0.
# To run:
# 1. From a Windows Command Prompt, enter the following line:
# python
# 2. On the python command line, enter the following line:
# import pyreadlinetest
# 3. Press Enter or right-arrow to recover the input prompt.
#
# In the unpatched version of pyreadline 2.0 (or earlier), the asynchronous
# text is erased and the prompt is restored to where it was before the
# text was printed.
#
# With the patched version of pyreadline 2.0 installed, do the following:
# 1. From a Windows Command Prompt, enter the following line:
# python
# 2. On the python command line, enter the following lines:
# import readline
# readline.parse_and_bind("set enable-save-prompt-position off")
# 3. Enter the following line:
# import pyreadlinetest
# 4. Press Enter or right-arrow to recover the input prompt.
#
# In the patched version with the enable-save-prompt-position turned off, the
# prompt appears after the asynchronous text, leaving the asynchronous text
# alone.

import time
import threading

def callback():
for i in range(5):
print("Important text %d"%i)
time.sleep(0.1)

def runtest():
t = threading.Thread(target=callback)
t.start()

runtest()
````

Here is the results of the first run when the enable-save-prompt-position option is turned on (the default setting and the current behavior of pyreadline):
````
>>> import pyreadlinetest
>>> Important text 0
Important text 1
Important text 2
Important text 3
Important text 4
````
Pressing Enter to recover the prompt results in this display:
````
>>> import pyreadlinetest
>>>
>>>
````

Now, with the enable-save-prompt-position turned off, pressing Enter after the text is displayed results in this display:
````
>>> import pyreadlinetest
>>> Important text 0
Important text 1
Important text 2
Important text 3
Important text 4
>>>
>>>
````