From 7acc621e373ba1371495e15e5e78aa6ce948a9a6 Mon Sep 17 00:00:00 2001 From: Carlos Pita Date: Tue, 4 Dec 2018 19:35:09 -0300 Subject: [PATCH] Fix python-shell font-lock cleanup for unclosed quotes (Bug#32390) The problem originating this report was: ------------- In [15]: " File "", 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. The first time python-shell-comint-end-of-output-p returns nil since we're *not* at the end of an input prompt. The second time it returns 0 since we're at the end of *just* an input prompt. So we don't call python-shell-font-lock-cleanup-buffer either time. 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. * lisp/progmodes/python.el (python-shell-font-lock-cleanup-buffer): Don't check for empty OUTPUT since python-shell-comint-end-of-output-p returns nil for that anyway. Don't check for python-shell-comint-end-of-output-p returning a specific number because it's unreliable, just check for any non-nil. Identify continuation prompts by looking for "...". --- lisp/progmodes/python.el | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index ae5aff351c0..b168b62c291 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -2600,14 +2600,12 @@ goes wrong and syntax highlighting in the shell gets messed up." (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) + ;; Assume "..." represents a continuation prompt. + (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 -- 2.39.5