From: Johannes Weiner <hannes@saeurebad.de>
To: emacs-devel@gnu.org
Subject: Re: [PATCH] Interactive macro expansion added
Date: Mon, 20 Aug 2007 03:31:26 +0200 [thread overview]
Message-ID: <20070820013126.GA24021@saeurebad.de> (raw)
In-Reply-To: <20070819220806.GA14139@saeurebad.de>
[-- Attachment #1: Type: text/plain, Size: 706 bytes --]
Hi,
On Mon, Aug 20, 2007 at 12:08:06AM +0200, Johannes Weiner wrote:
> Hi Emacs-hackers,
>
> here is a patch that extracts last-sexp from already existing code so that one
> can use last-sexp for other purposes too.
My real goals where of course, interactive macro expansion while editing lisp
code. So I implemented that also. The result is now a more generalized
operation functionality on the sexp before point.
I promise to write documentation for the rest of the new functions if the
actual code is agreed upon.
> Note: I ripped out the let-binding of `stap' in the original code because it
> looked stale. Please correct me if I am wrong.
The old patch is superseeded by the new one.
Hannes
[-- Attachment #2: emacs-lisp-mode-interactive-macroexpand.patch --]
[-- Type: text/x-diff, Size: 7829 bytes --]
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.
[-- Attachment #3: Type: text/plain, Size: 142 bytes --]
_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-devel
next prev parent reply other threads:[~2007-08-20 1:31 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-08-19 22:08 [PATCH] Extract last-sexp from eval-last-sexp-1 Johannes Weiner
2007-08-20 1:31 ` Johannes Weiner [this message]
2007-08-20 15:25 ` [PATCH] pp-macroexpansion Johannes Weiner
2007-08-20 18:30 ` [PATCH] Interactive macro expansion added Richard Stallman
2007-09-09 0:50 ` Johannes Weiner
2007-09-09 20:06 ` Richard Stallman
2007-09-10 0:46 ` Johannes Weiner
2007-09-10 16:53 ` Richard Stallman
2007-09-10 18:55 ` David Hansen
2007-09-11 10:15 ` Johannes Weiner
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=20070820013126.GA24021@saeurebad.de \
--to=hannes@saeurebad.de \
--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).