GNU bug report logs - #61523
python.el first prompt missing field=output

Previous Next

Package: emacs;

Reported by: JD Smith <jdtsmith <at> gmail.com>

Date: Wed, 15 Feb 2023 02:36:02 UTC

Severity: normal

To reply to this bug, email your comments to 61523 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#61523; Package emacs. (Wed, 15 Feb 2023 02:36:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to JD Smith <jdtsmith <at> gmail.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Wed, 15 Feb 2023 02:36:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: JD Smith <jdtsmith <at> gmail.com>
To: bug-gnu-emacs <at> gnu.org
Subject: python.el first prompt missing field=output
Date: Tue, 14 Feb 2023 21:34:52 -0500
[Message part 1 (text/plain, inline)]
The first >>> python prompt in an inferior-python-mode comint buffer is incorrectly missing its field=output text property.  This causes a few problems:
C-c C-a at the first prompt moves back to before the prompt.
Mouse-2 clicking on the first input brings the first prompt along with it forward to the current prompt.
If you recall history at the first prompt, then change your mind and “restore”(missing)  input, comint’s history mechanism mistakenly identifies the prompt text (and sometimes text before the first prompt like python version information) as input, copying it to the prompt line.  
If the prompt is read-only, that will now be stuck on the input line.  Only Return and adding it to history is possible from here, which is not ideal.
The reason for the missing field property is subtle:

python.el sets up `python-shell-comint-watch-for-first-prompt-output-filter' among the `comint-output-filter-functions’.  These filter functions are run just after the prompt string is inserted by `comint-output-filter'.
That function arranges to send setup code to define __PYTHON_EL_eval and perform other setup, with no output.  This process interaction recursively calls `comint-output-filter’ several times.
The setup code places a function on `comint-preoutput-filter-functions’ to accumulate the hidden output, and search for the next prompt.  It finally returns the empty string to avoid placing any output in the comint buffer.
Even though no output is placed in the buffer in these recursive calls, `comint-last-output-start’ gets moved forward to the end of the first prompt (which again, is already in the buffer):  
(set-marker comint-last-output-start (point)).
When the recursive process filter calls finally finish and control returns to the “outer” filter function invocation — the one which has originally inserted the prompt text — the application of the field=output property to the original prompt is now erroneously made over a zero character range at the very end of the buffer:

		(add-text-properties comint-last-output-start (point)
                                     `(rear-nonsticky
				       ,comint--prompt-rear-nonsticky
				       front-sticky
				       (field inhibit-line-move-field-capture)
				       field output
				       inhibit-line-move-field-capture t))

A simple fix (in python.el) would be to run the python setup from the main event loop instead of in place, i.e. to avoid recursively calling the process filter.  A more defensive fix (in comint) would be to store the value of `comint-last-output-start' (or use some other “starting marker”) to guard against filter-function disturbance.  This is already done for the process mark.

[Message part 2 (text/html, inline)]

This bug report was last modified 1 year and 42 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.