unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Stefan Monnier <monnier@iro.umontreal.ca>
Cc: emacs-devel@gnu.org
Subject: Re: python-mode: make sure output is not eaten
Date: Wed, 23 Aug 2006 00:04:40 -0400	[thread overview]
Message-ID: <87sljo40ra.fsf-monnier+emacs@gnu.org> (raw)
In-Reply-To: <20060822201045.4975.SLAWOMIR.NOWACZYK.847@student.lu.se> (Slawomir Nowaczyk's message of "Tue, 22 Aug 2006 20:26:33 +0200")

> #>    (cond ((and (string-match (rx string-start (repeat 3 (any ".>"))
> #>  				" " string-end)
> #> -                            s)
> #> +                              s start)
> as you setq `s' to the appropriate substring one line earlier, in 
>   (unless (zerop start) (setq s (substring s start)))

Oh, right.  I missed this one spot, sorry.

> Also, "\n\n" in python-send-string still needs to be changed into a
> single "\n" in order to avoid spurious prompts.

Yes, of course.  BTW do you have any idea why the current code uses "\n\n"?

> Finally, when you test this patch, make sure you also try enabling
> eldoc-mode (it doesn't work too well, a patch to improve it a bit is
> forthcoming, but even now it works for built-in functions like "apply"
> or "map"). It is important to make sure no extra ">>>"s get added to
> the inferior buffer when eldoc is talking to Python process.

Would it be because eldoc ends up sending commands to the underlying process
while some other command is still being processed?  Maybe we'd need
a "python-process-busy" variable to prevent eldoc from interfering.

> This is -- partially -- the reason why it is important to save
> whatever text exists in front of "_emacs_out"... For example, when I
> python-send-buffer I can get output like "\nTest!\n>>> _emacs_out
> ()\n>>> "... and the ">>>" after "Test!" must show in the buffer. On
> the other hand, after eldoc asks Python about argument list, the
> output may look like this: "_emacs_out apply(object[, args[,
> kwargs]])\n>>> " and it is important that *nothing* is shown in the
> inferior buffer.

The handling of the prompt looks pretty messy, indeed.  I think we should
never send a command followed by "\n" followed by "print _emacs_out ()", but
instead we should send the command augmented with "; print _emacs_out ()\n".
This should avoid those nasty intermediate prompts.

How 'bout the patch below which also removes the _emacs_ok and preoutput
continuation stuff which doesn't seem to be used any more.


        Stefan


--- python.el	20 aoû 2006 14:13:46 -0400	1.41
+++ python.el	23 aoû 2006 00:00:28 -0400	
@@ -1250,47 +1250,45 @@
 (defvar python-preoutput-result nil
   "Data from last `_emacs_out' line seen by the preoutput filter.")
 
-(defvar python-preoutput-continuation nil
-  "If non-nil, funcall this when `python-preoutput-filter' sees `_emacs_ok'.")
-
 (defvar python-preoutput-leftover nil)
 
 ;; Using this stops us getting lines in the buffer like
 ;; >>> ... ... >>>
-;; Also look for (and delete) an `_emacs_ok' string and call
-;; `python-preoutput-continuation' if we get it.
 (defun python-preoutput-filter (s)
   "`comint-preoutput-filter-functions' function: ignore prompts not at bol."
   (when python-preoutput-leftover
     (setq s (concat python-preoutput-leftover s))
     (setq python-preoutput-leftover nil))
+  (let ((start 0)
+        (res ""))
+    ;; First process whole lines.
+    (while (string-match "\n" s start)
+      (let ((line (substring s start (setq start (match-end 0)))))
+        (if (string-match "\\`_emacs_out \\(.*\\)\n\\'" line)
+            (setq python-preoutput-result (match-string 1 line))
+          (setq res (concat res line)))))
+    ;; Then process the remaining partial line.
+    (unless (zerop start) (setq s (substring s start)))
   (cond ((and (string-match (rx string-start (repeat 3 (any ".>"))
 				" " string-end)
                             s)
-              (/= (let ((inhibit-field-text-motion t))
-                    (line-beginning-position))
-                  (point)))
+                ;; Drop this prompt only if it's not gonna be inserted at BOL.
+                (if (zerop (length res))
+                    (not (bolp))
+                  (string-match res ".\\'")))
 	 ;; The need for this seems to be system-dependent:
          ;; What is this all about, exactly?  --Stef
 	 ;; (if (and (eq ?. (aref s 0)))
 	 ;;     (accept-process-output (get-buffer-process (current-buffer)) 1))
-         "")
-        ((string= s "_emacs_ok\n")
-         (when python-preoutput-continuation
-           (funcall python-preoutput-continuation)
-           (setq python-preoutput-continuation nil))
-         "")
-        ((string-match "_emacs_out \\(.*\\)\n" s)
-         (setq python-preoutput-result (match-string 1 s))
-         "")
-	((string-match ".*\n" s)
-	 s)
-	((or (eq t (compare-strings s nil nil "_emacs_ok\n" nil (length s)))
-	     (let ((end (min (length "_emacs_out ") (length s))))
-	       (eq t (compare-strings s nil end "_emacs_out " nil end))))
+           res)
+          ((let ((end (min (length "_emacs_out ") (length s))))
+             (eq t (compare-strings s nil end "_emacs_out " nil end)))
+           ;; The leftover string is a prefix of _emacs_out so we don't know
+           ;; yet whether it's an _emacs_out or something else: wait until we
+           ;; get more output so we can resolve this ambiguity.
 	 (setq python-preoutput-leftover s)
-	 "")
-        (t s)))
+           res)
+          (t (concat res s)))))
 
 (autoload 'comint-check-proc "comint")
 
@@ -1342,9 +1340,8 @@
   ;; file.  The code might be inline here, but there's enough that it
   ;; seems worth putting in a separate file, and it's probably cleaner
   ;; to put it in a module.
-  (python-send-string "import emacs")
   ;; Ensure we're at a prompt before doing anything else.
-  (python-send-receive "print '_emacs_out ()'")
+  (python-send-receive "import emacs; print '_emacs_out ()'")
   ;; Without this, help output goes into the inferior python buffer if
   ;; the process isn't already running.
   (sit-for 1 t)        ;Should we use accept-process-output instead?  --Stef
@@ -1362,9 +1359,8 @@
   (let ((end (marker-position (process-mark (python-proc)))))
     (with-current-buffer python-buffer (goto-char (point-max)))
     (compilation-forget-errors)
-    (python-send-string command)
     ;; Must wait until this has completed before re-setting variables below.
-    (python-send-receive "print '_emacs_out ()'")
+    (python-send-receive (concat comand "; print '_emacs_out ()'"))
     (with-current-buffer python-buffer
       (set-marker compilation-parsing-end end)
       (setq compilation-last-buffer (current-buffer)))))
@@ -1409,7 +1405,7 @@
   "Evaluate STRING in inferior Python process."
   (interactive "sPython command: ")
   (comint-send-string (python-proc) string)
-  (comint-send-string (python-proc) "\n\n"))
+  (comint-send-string (python-proc) "\n"))
 
 (defun python-send-buffer ()
   "Send the current buffer to the inferior Python process."

  reply	other threads:[~2006-08-23  4:04 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-08-21 20:16 python-mode: make sure output is not eaten Slawomir Nowaczyk
2006-08-22  6:10 ` Stefan Monnier
2006-08-22 18:26   ` Slawomir Nowaczyk
2006-08-23  4:04     ` Stefan Monnier [this message]
2006-08-25  0:18       ` Steven Huwig
2006-08-25  0:34         ` Steven Huwig
2006-08-25  1:29         ` Steven Huwig
2006-08-25  9:03         ` Slawomir Nowaczyk
2006-08-25 19:53         ` Ken Manheimer
2006-08-25 20:10           ` Stefan Monnier
2006-08-25  9:03       ` Slawomir Nowaczyk
2006-08-25 22:53         ` Stefan Monnier
2006-08-26 12:41           ` Slawomir Nowaczyk
2006-08-26 14:48             ` Stefan Monnier
2006-08-26 22:22               ` Slawomir Nowaczyk
2006-08-28 21:43                 ` Stefan Monnier
2006-08-30 21:08                   ` Slawomir Nowaczyk
2006-08-30 22:10                     ` Stefan Monnier
2006-08-31 11:19                       ` Slawomir Nowaczyk

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

  List information: https://www.gnu.org/software/emacs/

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

  git send-email \
    --in-reply-to=87sljo40ra.fsf-monnier+emacs@gnu.org \
    --to=monnier@iro.umontreal.ca \
    --cc=emacs-devel@gnu.org \
    /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 public inbox

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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).