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