unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* ielm changes: display standard-output in buffer
@ 2013-09-26 18:13 Daniel Colascione
  2013-09-26 20:49 ` Stefan Monnier
  2013-09-28  0:46 ` Stefan Monnier
  0 siblings, 2 replies; 8+ messages in thread
From: Daniel Colascione @ 2013-09-26 18:13 UTC (permalink / raw)
  To: Emacs development discussions

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

How does this change look?

=== modified file 'lisp/ielm.el'
--- lisp/ielm.el	2013-05-30 03:30:34 +0000
+++ lisp/ielm.el	2013-09-25 23:56:17 +0000
@@ -1,3 +1,4 @@
+;;; -*- lexical-binding: t -*-
 ;;; ielm.el --- interaction mode for Emacs Lisp

 ;; Copyright (C) 1994, 2001-2013 Free Software Foundation, Inc.
@@ -311,14 +312,20 @@

 ;;; Evaluation

-(defvar ielm-string)
-(defvar ielm-form)
-(defvar ielm-pos)
-(defvar ielm-result)
-(defvar ielm-error-type)
-(defvar ielm-output)
-(defvar ielm-wbuf)
-(defvar ielm-pmark)
+(defvar ielm-output-buffer nil
+  "List of characters to eventually output")
+
+(defvar ielm-active-process nil
+  "When ielm is evaluating a form, the comint process.")
+
+(defun ielm-standard-output-impl (char)
+  "`standard-output' while evaluating in ielm."
+  (push char ielm-output-buffer)
+  (when (eq char ?\n)
+    (comint-output-filter
+     ielm-active-process
+     (apply #'string (nreverse ielm-output-buffer)))
+    (setf ielm-output-buffer nil)))

 (defun ielm-eval-input (input-string)
   "Evaluate the Lisp expression INPUT-STRING, and pretty-print the result."
@@ -331,41 +338,41 @@
   ;; this as in output filter that converted sexps in the output
   ;; stream to their evaluated value.  But that would have involved
   ;; more process coordination than I was happy to deal with.
-  ;;
-  ;; NOTE: all temporary variables in this function will be in scope
-  ;; during the eval, and so need to have non-clashing names.
-  (let ((ielm-string input-string)      ; input expression, as a string
-        ielm-form			; form to evaluate
-	ielm-pos			; End posn of parse in string
-	ielm-result			; Result, or error message
-	ielm-error-type			; string, nil if no error
-	(ielm-output "")		; result to display
-	(ielm-wbuf ielm-working-buffer)	; current buffer after evaluation
-	(ielm-pmark (ielm-pm)))
-    (unless (ielm-is-whitespace-or-comment ielm-string)
+  (let ((string input-string)        ; input expression, as a string
+        form                         ; form to evaluate
+        pos                          ; End posn of parse in string
+        result                       ; Result, or error message
+        error-type                   ; string, nil if no error
+        (output "")                  ; result to display
+        (wbuf ielm-working-buffer)   ; current buffer after evaluation
+        (pmark (ielm-pm)))
+    (unless (ielm-is-whitespace-or-comment string)
       (condition-case err
-	  (let ((rout (read-from-string ielm-string)))
-	    (setq ielm-form (car rout)
-		  ielm-pos (cdr rout)))
-	(error (setq ielm-result (error-message-string err))
-	       (setq ielm-error-type "Read error")))
-      (unless ielm-error-type
+          (let ((rout (read-from-string string)))
+            (setq form (car rout)
+                  pos (cdr rout)))
+        (error (setq result (error-message-string err))
+               (setq error-type "Read error")))
+      (unless error-type
 	;; Make sure working buffer has not been killed
 	(if (not (buffer-name ielm-working-buffer))
-	    (setq ielm-result "Working buffer has been killed"
-		  ielm-error-type "IELM Error"
-		  ielm-wbuf (current-buffer))
-	  (if (ielm-is-whitespace-or-comment (substring ielm-string ielm-pos))
+            (setq result "Working buffer has been killed"
+                  error-type "IELM Error"
+                  wbuf (current-buffer))
+          (if (ielm-is-whitespace-or-comment (substring string pos))
 	      ;; To correctly handle the ielm-local variables *,
 	      ;; ** and ***, we need a temporary buffer to be
 	      ;; current at entry to the inner of the next two let
 	      ;; forms.  We need another temporary buffer to exit
 	      ;; that same let.  To avoid problems, neither of
 	      ;; these buffers should be alive during the
-	      ;; evaluation of ielm-form.
+              ;; evaluation of form.
 	      (let ((*1 *)
 		    (*2 **)
 		    (*3 ***)
+                    (ielm-active-process (ielm-process))
+                    (ielm-output-buffer nil)
+                    (standard-output #'ielm-standard-output-impl)
 		    ielm-temp-buffer)
 		(set-match-data ielm-match-data)
 		(save-excursion
@@ -377,7 +384,7 @@
 			     ;; these default bindings are
 			     ;; identical to the ielm-local
 			     ;; bindings.  Hence, during the
-			     ;; evaluation of ielm-form, the
+                            ;; evaluation of form, the
 			     ;; ielm-local values are going to be
 			     ;; used in all buffers except for
 			     ;; other ielm buffers, which override
@@ -388,51 +395,53 @@
 				   (** *2)
 				   (*** *3))
 			       (kill-buffer (current-buffer))
-			       (set-buffer ielm-wbuf)
-			       (setq ielm-result
-                                     (eval ielm-form lexical-binding))
-			       (setq ielm-wbuf (current-buffer))
+                              (set-buffer wbuf)
+                              (setq result
+                                    (eval form lexical-binding))
+                              (setq wbuf (current-buffer))
 			       (setq
 				ielm-temp-buffer
 				(generate-new-buffer " *ielm-temp*"))
 			       (set-buffer ielm-temp-buffer))
 			  (when ielm-temp-buffer
 			    (kill-buffer ielm-temp-buffer)))
-		      (error (setq ielm-result (error-message-string err))
-			     (setq ielm-error-type "Eval error"))
-		      (quit (setq ielm-result "Quit during evaluation")
-			    (setq ielm-error-type "Eval error")))))
+                      (error (setq result (error-message-string err))
+                             (setq error-type "Eval error"))
+                      (quit (setq result "Quit during evaluation")
+                            (setq error-type "Eval error")))))
+                (when ielm-output-buffer
+                  (ielm-standard-output-impl ?\n))
 		(setq ielm-match-data (match-data)))
-	    (setq ielm-error-type "IELM error")
-	    (setq ielm-result "More than one sexp in input"))))
+            (setq error-type "IELM error")
+            (setq result "More than one sexp in input"))))

       ;; If the eval changed the current buffer, mention it here
-      (unless (eq ielm-wbuf ielm-working-buffer)
-	(message "current buffer is now: %s" ielm-wbuf)
-	(setq ielm-working-buffer ielm-wbuf))
+      (unless (eq wbuf ielm-working-buffer)
+        (message "current buffer is now: %s" wbuf)
+        (setq ielm-working-buffer wbuf))

-      (goto-char ielm-pmark)
-      (unless ielm-error-type
+      (goto-char pmark)
+      (unless error-type
 	(condition-case nil
 	    ;; Self-referential objects cause loops in the printer, so
 	    ;; trap quits here. May as well do errors, too
-	    (setq ielm-output (concat ielm-output (pp-to-string ielm-result)))
-	  (error (setq ielm-error-type "IELM Error")
-		 (setq ielm-result "Error during pretty-printing (bug in pp)"))
-	  (quit  (setq ielm-error-type "IELM Error")
-		 (setq ielm-result "Quit during pretty-printing"))))
-      (if ielm-error-type
+            (setq output (concat output (pp-to-string result)))
+          (error (setq error-type "IELM Error")
+                 (setq result "Error during pretty-printing (bug in pp)"))
+          (quit  (setq error-type "IELM Error")
+                 (setq result "Quit during pretty-printing"))))
+      (if error-type
 	  (progn
 	    (when ielm-noisy (ding))
-	    (setq ielm-output (concat ielm-output "*** " ielm-error-type " ***
 "))
-	    (setq ielm-output (concat ielm-output ielm-result)))
+            (setq output (concat output "*** " error-type " ***  "))
+            (setq output (concat output result)))
 	;; There was no error, so shift the *** values
 	(setq *** **)
 	(setq ** *)
-	(setq * ielm-result))
-      (setq ielm-output (concat ielm-output "\n")))
-    (setq ielm-output (concat ielm-output ielm-prompt-internal))
-    (comint-output-filter (ielm-process) ielm-output)))
+        (setq * result))
+      (setq output (concat output "\n")))
+    (setq output (concat output ielm-prompt-internal))
+    (comint-output-filter (ielm-process) output)))

 ;;; Process and marker utilities




[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: ielm changes: display standard-output in buffer
  2013-09-26 18:13 ielm changes: display standard-output in buffer Daniel Colascione
@ 2013-09-26 20:49 ` Stefan Monnier
  2013-09-27  3:37   ` Daniel Colascione
  2013-09-28  0:46 ` Stefan Monnier
  1 sibling, 1 reply; 8+ messages in thread
From: Stefan Monnier @ 2013-09-26 20:49 UTC (permalink / raw)
  To: Daniel Colascione; +Cc: Emacs development discussions

> How does this change look?

Looks OK, but see comments/questions.

> +;;; -*- lexical-binding: t -*-
>  ;;; ielm.el --- interaction mode for Emacs Lisp

Please just put -*- lexical-binding: t -*- at the end of the first line,
rather than pushing the first line to the second line.  I know it makes
the first line too long, but for now, this is the convention we use.

> +(defun ielm-standard-output-impl (char)

I don't really understand the standard-output part of your patch.
Could you provide a simple example where it makes a difference (and put
it in some comment somewhere in the code)?


        Stefan



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: ielm changes: display standard-output in buffer
  2013-09-26 20:49 ` Stefan Monnier
@ 2013-09-27  3:37   ` Daniel Colascione
  0 siblings, 0 replies; 8+ messages in thread
From: Daniel Colascione @ 2013-09-27  3:37 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Emacs development discussions

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

On 9/26/13 1:49 PM, Stefan Monnier wrote:
>> How does this change look?
> 
> Looks OK, but see comments/questions.

Thanks for taking a look.

> 
>> +;;; -*- lexical-binding: t -*-
>>  ;;; ielm.el --- interaction mode for Emacs Lisp
> 
> Please just put -*- lexical-binding: t -*- at the end of the first line

Sure.

>> +(defun ielm-standard-output-impl (char)
> 
> I don't really understand the standard-output part of your patch.
> Could you provide a simple example where it makes a difference (and put
> it in some comment somewhere in the code)?

Sure: it's a new feature: the basic idea is that if a form being
evaluated through ielm writes to standard-output (say, using princ),
that output appears in the ielm buffer, making it work more like a
normal command line. I looked into doing the same thing for message
output, but I couldn't get after-change-functions in *Messages* to run
reliably.



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: ielm changes: display standard-output in buffer
  2013-09-26 18:13 ielm changes: display standard-output in buffer Daniel Colascione
  2013-09-26 20:49 ` Stefan Monnier
@ 2013-09-28  0:46 ` Stefan Monnier
  2013-10-03  6:23   ` Daniel Colascione
  1 sibling, 1 reply; 8+ messages in thread
From: Stefan Monnier @ 2013-09-28  0:46 UTC (permalink / raw)
  To: Daniel Colascione; +Cc: Emacs development discussions

> +(defun ielm-standard-output-impl (char)
> +  "`standard-output' while evaluating in ielm."
> +  (push char ielm-output-buffer)
> +  (when (eq char ?\n)
> +    (comint-output-filter
> +     ielm-active-process
> +     (apply #'string (nreverse ielm-output-buffer)))
> +    (setf ielm-output-buffer nil)))

You could avoid the two global vars with:

   (defun ielm-standard-output-impl (proc)
     "`standard-output' while evaluating in ielm."
     (let ((buffer nil))
       (lambda (char)
         (push char buffer)
         (when (eq char ?\n)
           (comint-output-filter proc (apply #'string (nreverse buffer)))
           (setf buffer nil)))))

> +                    (ielm-active-process (ielm-process))
> +                    (ielm-output-buffer nil)
> +                    (standard-output #'ielm-standard-output-impl)

And here do (standard-output (ielm-standard-output-impl (ielm-process)))

I do have one objection to the patch, tho: it resets standard-output
after each IELM command, so you can't use (setq standard-output <foo>) RET
and then (princ <bar>) RET and expect <bar> to be sent to <foo> any more.

Maybe a buffer-local setting (instead of a let-binding) of
standard-output would solve this problem?


        Stefan



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: ielm changes: display standard-output in buffer
  2013-09-28  0:46 ` Stefan Monnier
@ 2013-10-03  6:23   ` Daniel Colascione
  2013-10-03 13:50     ` Stefan Monnier
  0 siblings, 1 reply; 8+ messages in thread
From: Daniel Colascione @ 2013-10-03  6:23 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Emacs development discussions

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

On 9/27/13 5:46 PM, Stefan Monnier wrote:>> +(defun ielm-standard-output-impl (char)
>> +  "`standard-output' while evaluating in ielm."
>> +  (push char ielm-output-buffer)
>> +  (when (eq char ?\n)
>> +    (comint-output-filter
>> +     ielm-active-process
>> +     (apply #'string (nreverse ielm-output-buffer)))
>> +    (setf ielm-output-buffer nil)))
>
> You could avoid the two global vars with:
>
>    (defun ielm-standard-output-impl (proc)
>      "`standard-output' while evaluating in ielm."
>      (let ((buffer nil))
>        (lambda (char)
>          (push char buffer)
>          (when (eq char ?\n)
>            (comint-output-filter proc (apply #'string (nreverse buffer)))
>            (setf buffer nil)))))

Good idea.

>
>> +                    (ielm-active-process (ielm-process))
>> +                    (ielm-output-buffer nil)
>> +                    (standard-output #'ielm-standard-output-impl)
>
> And here do (standard-output (ielm-standard-output-impl (ielm-process)))
>
> I do have one objection to the patch, tho: it resets standard-output
> after each IELM command, so you can't use (setq standard-output <foo>) RET
> and then (princ <bar>) RET and expect <bar> to be sent to <foo> any more.
>
> Maybe a buffer-local setting (instead of a let-binding) of
> standard-output would solve this problem?

I've changed the code so that we don't bind standard-output anymore,
but instead explicitly set and reset it, skipping the reset if the
value changed while we evaluated the form. I've also added a flush
timer so that we don't need to wait for a while line of output to
accumulate before displaying output.  (Imagine a loop that calls
(princ ".") occasionally to indicate progress.)

I've also added an ielm-return-for-effect mode and bound C-M-RET to
it.  This function works like ielm-return, except that it doesn't
print the result of evaluating the input expression.  This
functionality is useful when the expression evaluates to something
voluminous and useless.

=== modified file 'lisp/ielm.el'
--- lisp/ielm.el	2013-05-30 03:30:34 +0000
+++ lisp/ielm.el	2013-10-03 06:14:15 +0000
@@ -1,3 +1,4 @@
+;;; -*- lexical-binding: t -*-
 ;;; ielm.el --- interaction mode for Emacs Lisp

 ;; Copyright (C) 1994, 2001-2013 Free Software Foundation, Inc.
@@ -169,6 +170,7 @@
   (let ((map (make-sparse-keymap)))
     (define-key map "\t" 'completion-at-point)
     (define-key map "\C-m" 'ielm-return)
+    (define-key map "\e\C-m" 'ielm-return-for-effect)
     (define-key map "\C-j" 'ielm-send-input)
     (define-key map "\e\C-x" 'eval-defun)         ; for consistency with
     (define-key map "\e\t" 'completion-at-point)  ; lisp-interaction-mode
@@ -264,7 +266,7 @@

 ;;; Other bindings

-(defun ielm-return nil
+(defun ielm-return (&optional for-effect)
   "Newline and indent, or evaluate the sexp before the prompt.
 Complete sexps are evaluated; for incomplete sexps inserts a newline
 and indents.  If however `ielm-dynamic-return' is nil, this always
@@ -277,7 +279,7 @@
 	       (parse-partial-sexp (ielm-pm)
 				   (point)))))
 	(if (and (< (car state) 1) (not (nth 3 state)))
-	    (ielm-send-input)
+            (ielm-send-input for-effect)
 	  (when (and ielm-dynamic-multiline-inputs
 		     (save-excursion
 		       (beginning-of-line)
@@ -288,6 +290,11 @@
 	  (newline-and-indent)))
     (newline)))

+(defun ielm-return-for-effect ()
+  "Like `ielm-return', but do not print the result."
+  (interactive)
+  (ielm-return t))
+
 (defvar ielm-input)

 (defun ielm-input-sender (_proc input)
@@ -295,12 +302,12 @@
   ;; `ielm-send-input's call.
   (setq ielm-input input))

-(defun ielm-send-input nil
+(defun ielm-send-input (&optional for-effect)
   "Evaluate the Emacs Lisp expression after the prompt."
   (interactive)
   (let (ielm-input)			; set by ielm-input-sender
     (comint-send-input)			; update history, markers etc.
-    (ielm-eval-input ielm-input)))
+    (ielm-eval-input ielm-input for-effect)))

 ;;; Utility functions

@@ -311,16 +318,42 @@

 ;;; Evaluation

-(defvar ielm-string)
-(defvar ielm-form)
-(defvar ielm-pos)
-(defvar ielm-result)
-(defvar ielm-error-type)
-(defvar ielm-output)
-(defvar ielm-wbuf)
-(defvar ielm-pmark)
+(defun ielm-standard-output-impl (process)
+  "Return a function to use for `standard-output' while in ielm eval.
+The returned function takes one character as input.  Passing nil
+to this function instead of a character flushes the output
+buffer.  Passing t appends a terminating newline if the buffer is
+nonempty, then flushes the buffer."
+  ;; Use an intermediate output buffer because doing redisplay for
+  ;; each character we output is too expensive.  Set up a flush timer
+  ;; so that users don't have to wait for whole lines to appear before
+  ;; seeing output.
+  (let* ((output-buffer nil)
+         (flush-timer nil)
+         (flush-buffer
+          (lambda ()
+            (comint-output-filter
+             process
+             (apply #'string (nreverse output-buffer)))
+            (redisplay)
+            (setf output-buffer nil)
+            (when flush-timer
+              (cancel-timer flush-timer)
+              (setf flush-timer nil)))))
+    (lambda (char)
+      (let (flush-now)
+        (cond ((and (eq char t) output-buffer)
+               (push ?\n output-buffer)
+               (setf flush-now t))
+              ((characterp char)
+               (push char output-buffer)
+               (setf flush-now (eq char ?\n))))
+        (if flush-now
+            (funcall flush-buffer)
+          (unless flush-timer
+            (setf flush-timer (run-with-timer 0.1 nil flush-buffer)))))))))

-(defun ielm-eval-input (input-string)
+(defun ielm-eval-input (input-string &optional for-effect)
   "Evaluate the Lisp expression INPUT-STRING, and pretty-print the result."
   ;; This is the function that actually `sends' the input to the
   ;; `inferior Lisp process'. All comint-send-input does is works out
@@ -331,41 +364,41 @@
   ;; this as in output filter that converted sexps in the output
   ;; stream to their evaluated value.  But that would have involved
   ;; more process coordination than I was happy to deal with.
-  ;;
-  ;; NOTE: all temporary variables in this function will be in scope
-  ;; during the eval, and so need to have non-clashing names.
-  (let ((ielm-string input-string)      ; input expression, as a string
-        ielm-form			; form to evaluate
-	ielm-pos			; End posn of parse in string
-	ielm-result			; Result, or error message
-	ielm-error-type			; string, nil if no error
-	(ielm-output "")		; result to display
-	(ielm-wbuf ielm-working-buffer)	; current buffer after evaluation
-	(ielm-pmark (ielm-pm)))
-    (unless (ielm-is-whitespace-or-comment ielm-string)
+  (let ((string input-string)        ; input expression, as a string
+        form                         ; form to evaluate
+        pos                          ; End posn of parse in string
+        result                       ; Result, or error message
+        error-type                   ; string, nil if no error
+        (output "")                  ; result to display
+        (wbuf ielm-working-buffer)   ; current buffer after evaluation
+        (pmark (ielm-pm)))
+    (unless (ielm-is-whitespace-or-comment string)
       (condition-case err
-	  (let ((rout (read-from-string ielm-string)))
-	    (setq ielm-form (car rout)
-		  ielm-pos (cdr rout)))
-	(error (setq ielm-result (error-message-string err))
-	       (setq ielm-error-type "Read error")))
-      (unless ielm-error-type
+          (let ((rout (read-from-string string)))
+            (setq form (car rout)
+                  pos (cdr rout)))
+        (error (setq result (error-message-string err))
+               (setq error-type "Read error")))
+      (unless error-type
 	;; Make sure working buffer has not been killed
 	(if (not (buffer-name ielm-working-buffer))
-	    (setq ielm-result "Working buffer has been killed"
-		  ielm-error-type "IELM Error"
-		  ielm-wbuf (current-buffer))
-	  (if (ielm-is-whitespace-or-comment (substring ielm-string ielm-pos))
+            (setq result "Working buffer has been killed"
+                  error-type "IELM Error"
+                  wbuf (current-buffer))
+          (if (ielm-is-whitespace-or-comment (substring string pos))
 	      ;; To correctly handle the ielm-local variables *,
 	      ;; ** and ***, we need a temporary buffer to be
 	      ;; current at entry to the inner of the next two let
 	      ;; forms.  We need another temporary buffer to exit
 	      ;; that same let.  To avoid problems, neither of
 	      ;; these buffers should be alive during the
-	      ;; evaluation of ielm-form.
-	      (let ((*1 *)
+              ;; evaluation of form.
+              (let* ((*1 *)
 		    (*2 **)
 		    (*3 ***)
+                     (active-process (ielm-process))
+                     (old-standard-output standard-output)
+                     new-standard-output
 		    ielm-temp-buffer)
 		(set-match-data ielm-match-data)
 		(save-excursion
@@ -377,7 +410,7 @@
 			     ;; these default bindings are
 			     ;; identical to the ielm-local
 			     ;; bindings.  Hence, during the
-			     ;; evaluation of ielm-form, the
+                            ;; evaluation of form, the
 			     ;; ielm-local values are going to be
 			     ;; used in all buffers except for
 			     ;; other ielm buffers, which override
@@ -387,52 +420,63 @@
 			     (let ((* *1)
 				   (** *2)
 				   (*** *3))
+                              (when (eq standard-output t)
+                                (setf new-standard-output
+                                      (ielm-standard-output-impl
+                                       active-process))
+                                (setf standard-output new-standard-output))
 			       (kill-buffer (current-buffer))
-			       (set-buffer ielm-wbuf)
-			       (setq ielm-result
-                                     (eval ielm-form lexical-binding))
-			       (setq ielm-wbuf (current-buffer))
+                              (set-buffer wbuf)
+                              (setq result
+                                    (eval form lexical-binding))
+                              (setq wbuf (current-buffer))
 			       (setq
 				ielm-temp-buffer
 				(generate-new-buffer " *ielm-temp*"))
 			       (set-buffer ielm-temp-buffer))
 			  (when ielm-temp-buffer
-			    (kill-buffer ielm-temp-buffer)))
-		      (error (setq ielm-result (error-message-string err))
-			     (setq ielm-error-type "Eval error"))
-		      (quit (setq ielm-result "Quit during evaluation")
-			    (setq ielm-error-type "Eval error")))))
+                            (kill-buffer ielm-temp-buffer))
+                          (when (eq new-standard-output standard-output)
+                            (ignore-errors
+                              (funcall standard-output t))
+                            (setf standard-output old-standard-output)))
+                      (error (setq result (error-message-string err))
+                             (setq error-type "Eval error"))
+                      (quit (setq result "Quit during evaluation")
+                            (setq error-type "Eval error")))))
 		(setq ielm-match-data (match-data)))
-	    (setq ielm-error-type "IELM error")
-	    (setq ielm-result "More than one sexp in input"))))
+            (setq error-type "IELM error")
+            (setq result "More than one sexp in input"))))

       ;; If the eval changed the current buffer, mention it here
-      (unless (eq ielm-wbuf ielm-working-buffer)
-	(message "current buffer is now: %s" ielm-wbuf)
-	(setq ielm-working-buffer ielm-wbuf))
+      (unless (eq wbuf ielm-working-buffer)
+        (message "current buffer is now: %s" wbuf)
+        (setq ielm-working-buffer wbuf))

-      (goto-char ielm-pmark)
-      (unless ielm-error-type
+      (goto-char pmark)
+      (unless error-type
 	(condition-case nil
 	    ;; Self-referential objects cause loops in the printer, so
 	    ;; trap quits here. May as well do errors, too
-	    (setq ielm-output (concat ielm-output (pp-to-string ielm-result)))
-	  (error (setq ielm-error-type "IELM Error")
-		 (setq ielm-result "Error during pretty-printing (bug in pp)"))
-	  (quit  (setq ielm-error-type "IELM Error")
-		 (setq ielm-result "Quit during pretty-printing"))))
-      (if ielm-error-type
+            (unless for-effect
+              (setq output (concat output (pp-to-string result))))
+          (error (setq error-type "IELM Error")
+                 (setq result "Error during pretty-printing (bug in pp)"))
+          (quit  (setq error-type "IELM Error")
+                 (setq result "Quit during pretty-printing"))))
+      (if error-type
 	  (progn
 	    (when ielm-noisy (ding))
-	    (setq ielm-output (concat ielm-output "*** " ielm-error-type " ***  "))
-	    (setq ielm-output (concat ielm-output ielm-result)))
+            (setq output (concat output "*** " error-type " ***  "))
+            (setq output (concat output result)))
 	;; There was no error, so shift the *** values
 	(setq *** **)
 	(setq ** *)
-	(setq * ielm-result))
-      (setq ielm-output (concat ielm-output "\n")))
-    (setq ielm-output (concat ielm-output ielm-prompt-internal))
-    (comint-output-filter (ielm-process) ielm-output)))
+        (setq * result))
+      (when (or (not for-effect) (not (equal output "")))
+        (setq output (concat output "\n"))))
+    (setq output (concat output ielm-prompt-internal))
+    (comint-output-filter (ielm-process) output)))

 ;;; Process and marker utilities

@@ -462,6 +506,11 @@
   Inputs longer than one line are moved to the line following the
   prompt (but see variable `ielm-dynamic-multiline-inputs').

+* \\[ielm-return-for-effect] works like `ielm-return', except
+  that it doesn't print the result of evaluating the input.  This
+  functionality is useful when forms would generate voluminous
+  output.
+
 * \\[completion-at-point] completes Lisp symbols (or filenames, within strings),
   or indents the line if there is nothing to complete.

@@ -478,6 +527,13 @@
 buffer, then the values in the working buffer are used.  The variables
 `*1', `*2' and `*3', yield the process buffer values.

+If, at the start of evaluation, `standard-output' is `t' (the
+default), `standard-output' is set to a special function that
+causes output to be directed to the ielm buffer.
+`standard-output' is restored after evaluation unless explicitly
+set to a different value during evaluation.  You can use (princ
+VALUE) or (pp VALUE) to write to the ielm buffer.
+
 Expressions evaluated by IELM are not subject to `debug-on-quit' or
 `debug-on-error'.





[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: ielm changes: display standard-output in buffer
  2013-10-03  6:23   ` Daniel Colascione
@ 2013-10-03 13:50     ` Stefan Monnier
  2013-10-05  1:42       ` Daniel Colascione
  0 siblings, 1 reply; 8+ messages in thread
From: Stefan Monnier @ 2013-10-03 13:50 UTC (permalink / raw)
  To: Daniel Colascione; +Cc: Emacs development discussions

> but instead explicitly set and reset it, skipping the reset if the
> value changed while we evaluated the form. I've also added a flush
> timer so that we don't need to wait for a while line of output to
> accumulate before displaying output.  (Imagine a loop that calls
> (princ ".") occasionally to indicate progress.)

I'm curious: why go through this trouble instead of just setting it
buffer-locally at the beginning and forgetting about it?


        Stefan



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: ielm changes: display standard-output in buffer
  2013-10-03 13:50     ` Stefan Monnier
@ 2013-10-05  1:42       ` Daniel Colascione
  2013-10-05 13:45         ` Stefan Monnier
  0 siblings, 1 reply; 8+ messages in thread
From: Daniel Colascione @ 2013-10-05  1:42 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Emacs development discussions

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

On 10/3/13 6:50 AM, Stefan Monnier wrote:
>> but instead explicitly set and reset it, skipping the reset if the
>> value changed while we evaluated the form. I've also added a flush
>> timer so that we don't need to wait for a while line of output to
>> accumulate before displaying output.  (Imagine a loop that calls
>> (princ ".") occasionally to indicate progress.)
> 
> I'm curious: why go through this trouble instead of just setting it
> buffer-locally at the beginning and forgetting about it?

Because then I can't work with code that operates in a different buffer
and outputs debug tracing to standard-output.



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: ielm changes: display standard-output in buffer
  2013-10-05  1:42       ` Daniel Colascione
@ 2013-10-05 13:45         ` Stefan Monnier
  0 siblings, 0 replies; 8+ messages in thread
From: Stefan Monnier @ 2013-10-05 13:45 UTC (permalink / raw)
  To: Daniel Colascione; +Cc: Emacs development discussions

> Because then I can't work with code that operates in a different buffer
> and outputs debug tracing to standard-output.

Ah, you want it to be global rather than buffer-local.  Makes sense.
Please add a comment about it.


        Stefan



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2013-10-05 13:45 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-09-26 18:13 ielm changes: display standard-output in buffer Daniel Colascione
2013-09-26 20:49 ` Stefan Monnier
2013-09-27  3:37   ` Daniel Colascione
2013-09-28  0:46 ` Stefan Monnier
2013-10-03  6:23   ` Daniel Colascione
2013-10-03 13:50     ` Stefan Monnier
2013-10-05  1:42       ` Daniel Colascione
2013-10-05 13:45         ` Stefan Monnier

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).