all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Carlos Pita <carlosjosepita@gmail.com>
To: Noam Postavsky <npostavs@gmail.com>
Cc: 32390@debbugs.gnu.org
Subject: bug#32390: 26.1; python.el: cleanup font lock buffer after input is sent
Date: Tue, 4 Dec 2018 19:35:09 -0300	[thread overview]
Message-ID: <CAELgYhfnPv+fT4-T6yzkgknoZD_99Fc=GL1ni6oNdUQ4upqbzg@mail.gmail.com> (raw)
In-Reply-To: <CAELgYheGf76OT+uSNDjW-_0SvV5sLhxtUsF3Kvujd00mCMpRWA@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 3812 bytes --]

Hi Noam,

I've been carefully studying this issue and below I explain in detail
what is really happening and what different cases are being (sometimes
wrongly) covered. There is a patch attached, I hope you consider it
worth of being applied.

The condition for cleaning up of the font lock buffer is:

-------------
  (if (and (not (string= "" output))                             (1)
           ;; Is end of output and is not just a prompt.
           (not (member
                 (python-shell-comint-end-of-output-p
                  (ansi-color-filter-apply output))
                 '(nil
         (2)
                   0))))
        (3)
-------------

First nota that (1) is really irrelevant since
(python-shell-comint-end-of-output-p "") returns nil anyway.

Now, the problem originating this report was:

-------------
In [15]: "
  File "<ipython-input-15-3b7a06bb1102>", line 1
    "
     ^
SyntaxError: EOL while scanning string literal


In [16]:   string face still here"
-------------

This happens because
python-shell-font-lock-comint-output-filter-function is called twice,
first for the error output and then for the "In [16]: " part (I assume
this is because one part is coming from stderr and the other from
stdout, but that's just a guess). The first time (2) applies since
we're *not* at the end of an input prompt. The second time (3) applies
since we're at the end of *just* and input prompt. So in any case the
buffer is cleaned up.

Now, my first reaction was to ignore the *just* part: what damage
could it do to just check if we're at the end of an input prompt
disregarding the fact that it could be the only thing there? Well, the
problem is with multiline input, of course. Nevertheless the current
code is relying in a very weak rule: it considers "just an input
prompt" to be a continuation prompt. Another unreliable aspect of the
current rule is that sometimes (python-shell-comint-end-of-output-p
(ansi-color-filter-apply output)) returns 1 and not 0 for continuation
prompts. In short, the rule does a very poor job identifying
continuations.

So, all in all I had rewritten (in a previous post) the condition above as:

-------------
  (if (and (python-shell-comint-end-of-output-p
            (ansi-color-filter-apply output))
           (not (string-match "\\.\\.\\.: $" output)))        (4)
-------------

Where:
- Clause (1) is disregarded because it's redundant.
- Clause (2) is taken into account.
- Clause (3) is disregarded because it's unreliable.
- Clause (4) was added to address the multiline input case
(continuation prompt).

Now, it's a sad fact that python-shell-prompt-input-regexps doesn't
distinguish between initial and continuation input prompts, so I
explicitly had to put that particular regexp there. I assume this is
the main reason while my fix was not yet accepted, isn't it?

At this point we have at least two alternatives:

a) Consider that an input prompt that includes the pattern "\\.\\.\\."
is a continuation prompt. This is a heuristic but I think it's robust
enough. I favor this solution and the attached patch implements it.

b) Add a new customization option with a list of continuation prompts.
I believe this would be too much.

So the attached patch implements this new rule:

-------------
    (if (let ((output (ansi-color-filter-apply output)))
        (and (python-shell-comint-end-of-output-p output)
             (not (string-match "\\.\\.\\." output))))       (5)
-----------

The difference between (4) and (5) is that (5) relaxes the match to
just include three sequential dots (because we already know we have an
input prompt at the end of the output!). I've been more careful by
matching on the filtered string instead of the raw one also.

Please let me know if you prefer option (b) instead.

Best regards
--
Carlos

[-- Attachment #2: font-lock-cleanup-filter.diff --]
[-- Type: text/x-patch, Size: 1181 bytes --]

diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index c7bb2d9..218c6e4 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -2556,14 +2556,11 @@ python-shell-font-lock-cleanup-buffer
 
 (defun python-shell-font-lock-comint-output-filter-function (output)
   "Clean up the font-lock buffer after any OUTPUT."
-  (if (and (not (string= "" output))
-           ;; Is end of output and is not just a prompt.
-           (not (member
-                 (python-shell-comint-end-of-output-p
-                  (ansi-color-filter-apply output))
-                 '(nil 0))))
-      ;; If output is other than an input prompt then "real" output has
-      ;; been received and the font-lock buffer must be cleaned up.
+  (if (let ((output (ansi-color-filter-apply output)))
+        (and (python-shell-comint-end-of-output-p output)
+             (not (string-match "\\.\\.\\." output))))
+      ;; If output ends with an initial (not continuation) input prompt
+      ;; then the font-lock buffer must be cleaned up.
       (python-shell-font-lock-cleanup-buffer)
     ;; Otherwise just add a newline.
     (python-shell-font-lock-with-font-lock-buffer

  reply	other threads:[~2018-12-04 22:35 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-08-07 18:49 bug#32390: 26.1; python.el: cleanup font lock buffer after input is sent Carlos Pita
2018-08-07 19:10 ` bug#32390: Carlos Pita
2018-08-07 19:34   ` bug#32390: Carlos Pita
2018-08-07 19:52     ` bug#32390: Carlos Pita
2018-08-07 20:28       ` bug#32390: Carlos Pita
2018-09-06  2:32       ` bug#32390: [ipython 6.x] unmatched quotes break fontification in run-python Noam Postavsky
2018-08-23  3:24 ` bug#32390: 26.1; python.el: cleanup font lock buffer after input is sent Noam Postavsky
2018-08-31 11:56   ` Carlos Pita
2018-09-01  3:01     ` Noam Postavsky
2018-09-05 15:38       ` Carlos Pita
2018-09-06  2:27         ` Noam Postavsky
2018-09-12 16:56           ` Carlos Pita
2018-12-04 22:35             ` Carlos Pita [this message]
2018-12-05 16:00               ` Carlos Pita
2019-01-03  5:43                 ` Carlos Pita
2019-10-15  0:21                   ` Noam Postavsky
2019-10-15  0:27                     ` Carlos Pita
2019-10-15  0:30                       ` Carlos Pita
2019-10-15  0:36                         ` Lars Ingebrigtsen
2019-10-15  0:40                         ` Noam Postavsky
2019-02-14 11:50 ` bug#32390: (no subject) Carlos Pita

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAELgYhfnPv+fT4-T6yzkgknoZD_99Fc=GL1ni6oNdUQ4upqbzg@mail.gmail.com' \
    --to=carlosjosepita@gmail.com \
    --cc=32390@debbugs.gnu.org \
    --cc=npostavs@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.