diff -Naur emacs.orig/lisp/emacs-lisp/lisp-mode.el emacs/lisp/emacs-lisp/lisp-mode.el --- emacs.orig/lisp/emacs-lisp/lisp-mode.el 2007-08-20 00:00:43.000000000 +0200 +++ emacs/lisp/emacs-lisp/lisp-mode.el 2007-08-20 03:18:27.000000000 +0200 @@ -444,6 +444,23 @@ Entry to this mode calls the value of `lisp-interaction-mode-hook' if that value is non-nil.") +(defun eval-last-sexp-and-print-1 (&optional expand-only) + "Evaluates or expands sexp before point, depending on `expand-only'. +The value is printed into the current buffer. + +If `eval-expression-debug-on-error' is non-nil, which is the +default, this command arranges for all errors to enter the +debugger. + +Note that printing the result is controlled by the variables +`eval-expression-print-length' and `eval-expression-print-level'." + (let ((standard-output (current-buffer))) + (terpri) + (if expand-only + (macroexpand-last-sexp t) + (eval-last-sexp t)) + (terpri))) + (defun eval-print-last-sexp () "Evaluate sexp before point; print value into current buffer. @@ -454,11 +471,19 @@ `eval-expression-print-length' and `eval-expression-print-level', which see." (interactive) - (let ((standard-output (current-buffer))) - (terpri) - (eval-last-sexp t) - (terpri))) + (eval-last-sexp-and-print-1)) +(defun macroexpand-print-last-sexp () + "Macroexpand sexp before point; print value into current buffer. + +If `eval-expression-debug-on-error' is non-nil, which is the +default, this command arranges for all errors to enter the +debugger. + +Note that printing the result is controlled by the variables +`eval-expression-print-length' and `eval-expression-print-level'." + (interactive) + (eval-last-sexp-and-print-1 t)) (defun last-sexp-setup-props (beg end value alt1 alt2) "Set up text properties for the output of `eval-last-sexp-1'. @@ -538,65 +563,59 @@ (= (car (read-from-string string)) char) string)))) +(defun last-sexp () + "Return sexp before the point." + (let ((opoint (point)) + ignore-quotes + expr) + (save-excursion + (with-syntax-table emacs-lisp-mode-syntax-table + ;; If this sexp appears to be enclosed in `...' + ;; then ignore the surrounding quotes. + (setq ignore-quotes + (or (eq (following-char) ?\') + (eq (preceding-char) ?\'))) + (forward-sexp -1) + ;; If we were after `?\e' (or similar case), + ;; use the whole thing, not just the `e'. + (when (eq (preceding-char) ?\\) + (forward-char -1) + (when (eq (preceding-char) ??) + (forward-char -1))) + + ;; Skip over `#N='s. + (when (eq (preceding-char) ?=) + (let (labeled-p) + (save-excursion + (skip-chars-backward "0-9#=") + (setq labeled-p (looking-at "\\(#[0-9]+=\\)+"))) + (when labeled-p + (forward-sexp -1)))) + + (save-restriction + ;; vladimir@cs.ualberta.ca 30-Jul-1997: skip ` in + ;; `variable' so that the value is returned, not the + ;; name + (if (and ignore-quotes + (eq (following-char) ?`)) + (forward-char)) + (narrow-to-region (point-min) opoint) + (setq expr (read (current-buffer))) + ;; If it's an (interactive ...) form, it's more + ;; useful to show how an interactive call would + ;; use it. + (and (consp expr) + (eq (car expr) 'interactive) + (setq expr + (list 'call-interactively + (list 'quote + (list 'lambda + '(&rest args) + expr + 'args))))) + expr))))) -(defun eval-last-sexp-1 (eval-last-sexp-arg-internal) - "Evaluate sexp before point; print value in minibuffer. -With argument, print output into current buffer." - (let ((standard-output (if eval-last-sexp-arg-internal (current-buffer) t))) - (let ((value - (eval (let ((stab (syntax-table)) - (opoint (point)) - ignore-quotes - expr) - (save-excursion - (with-syntax-table emacs-lisp-mode-syntax-table - ;; If this sexp appears to be enclosed in `...' - ;; then ignore the surrounding quotes. - (setq ignore-quotes - (or (eq (following-char) ?\') - (eq (preceding-char) ?\'))) - (forward-sexp -1) - ;; If we were after `?\e' (or similar case), - ;; use the whole thing, not just the `e'. - (when (eq (preceding-char) ?\\) - (forward-char -1) - (when (eq (preceding-char) ??) - (forward-char -1))) - - ;; Skip over `#N='s. - (when (eq (preceding-char) ?=) - (let (labeled-p) - (save-excursion - (skip-chars-backward "0-9#=") - (setq labeled-p (looking-at "\\(#[0-9]+=\\)+"))) - (when labeled-p - (forward-sexp -1)))) - - (save-restriction - ;; vladimir@cs.ualberta.ca 30-Jul-1997: skip ` in - ;; `variable' so that the value is returned, not the - ;; name - (if (and ignore-quotes - (eq (following-char) ?`)) - (forward-char)) - (narrow-to-region (point-min) opoint) - (setq expr (read (current-buffer))) - ;; If it's an (interactive ...) form, it's more - ;; useful to show how an interactive call would - ;; use it. - (and (consp expr) - (eq (car expr) 'interactive) - (setq expr - (list 'call-interactively - (list 'quote - (list 'lambda - '(&rest args) - expr - 'args))))) - expr))))))) - (eval-last-sexp-print-value value)))) - -(defun eval-last-sexp-print-value (value) +(defun operate-on-last-sexp-print-value (value) (let ((unabbreviated (let ((print-length nil) (print-level nil)) (prin1-to-string value))) (print-length eval-expression-print-length) @@ -618,8 +637,25 @@ (buffer-substring-no-properties beg end)) )))) +(defun operate-on-last-sexp-1 (operation operate-on-last-sexp-arg-internal) + (let ((standard-output (if operate-on-last-sexp-arg-internal + (current-buffer) + t))) + (operate-on-last-sexp-print-value (funcall operation (last-sexp))))) -(defvar eval-last-sexp-fake-value (make-symbol "t")) +(defvar operate-on-last-sexp-fake-value (make-symbol "t")) + +(defun operate-on-last-sexp (operation operate-on-last-sexp-arg-internal) + (if (null eval-expression-debug-on-error) + (operate-on-last-sexp-1 operation operate-on-last-sexp-arg-internal) + (let ((value + (let ((debug-on-error operate-on-last-sexp-fake-value)) + (cons (operate-on-last-sexp-1 operation + operate-on-last-sexp-arg-internal) + debug-on-error)))) + (unless (eq (cdr value) operate-on-last-sexp-fake-value) + (setq debug-on-error (cdr value))) + (car value)))) (defun eval-last-sexp (eval-last-sexp-arg-internal) "Evaluate sexp before point; print value in minibuffer. @@ -628,15 +664,16 @@ If `eval-expression-debug-on-error' is non-nil, which is the default, this command arranges for all errors to enter the debugger." (interactive "P") - (if (null eval-expression-debug-on-error) - (eval-last-sexp-1 eval-last-sexp-arg-internal) - (let ((value - (let ((debug-on-error eval-last-sexp-fake-value)) - (cons (eval-last-sexp-1 eval-last-sexp-arg-internal) - debug-on-error)))) - (unless (eq (cdr value) eval-last-sexp-fake-value) - (setq debug-on-error (cdr value))) - (car value)))) + (operate-on-last-sexp 'eval eval-last-sexp-arg-internal)) + +(defun macroexpand-last-sexp (macroexpand-last-sexp-arg-internal) + "Macroexpand sexp before point; print expansion in minibuffer. +Interactively, with prefix argument, print expansion into current buffer. + +If `eval-expression-debug-on-error' is non-nil, which is the default, +this command arranges for all errors to enter the debugger." + (interactive "P") + (operate-on-last-sexp 'macroexpand macroexpand-last-sexp-arg-internal)) (defun eval-defun-1 (form) "Treat some expressions specially.