On Mar 17, 9:39 pm, Ken Wesson <[email protected]> wrote: > On Thu, Mar 17, 2011 at 7:32 PM, Martin Blais <[email protected]> wrote: > > Emacs-using Clojurians may enjoy the following tidbit of > > Slime I just dreamed of: > > > (defun slime-eval-at-register (reg) > > "Take the cursor to a register's location and eval > > the expression there. Useful for testing stuff without > > having to 'go there' first." > > (interactive "cEval at register: ") > > (save-excursion > > (jump-to-register reg) > > (slime-eval-last-expression))) > > > ;; Note: slime-interactive-eval is also available on C-c :, > > ;; so we override it for something that looks like C-x C-e. > > (define-key slime-mode-map "\C-c\C-e" 'slime-eval-at-register) > > I'm curious. How does this work? I'll take a stab at it: > > 1. (interactive ...) is a macro that expands to nothing. > 2. (define-key ...) parses the source of the named function, and if it > sees (interactive ...), binds the key to a closure that presents the > prompt string after interactive, gets a response from the user, and > then calls that function with that response as the parameter. > 3. (save-excursion ...) is a macro that wraps its body in code to push > and pop the cursor location, so the insertion point returns to where > it was immediately. > > Am I close?
(interactive) makes the function into a "command". I don't know how it works under the covers. I imagine the emacs-lisp evaluator has a special case for it (maybe it attaches meta-data to the function object). Emacs knows to pass context to a command based on a format string provided to interactive, e.g. (interactive "r") will pass the current region to the function when it gets invoked "interactively," i.e. triggered from a key sequence via a keymap. In other words, commands are just functions which can be invoked from key events and optionally get extra context given to them. (define-key) creates a binding in Slime mode that invokes the command. (save-excursion) you got it. This is just a new Emacs command that expands the functionality of registers beyond storing text, positions and window configuration. You can set a position register as usual "C-x r SPC <reg>". If you invoke the command with "C-c C-e <reg>", it will move the cursor at the saved register position, slime-eval at that point, and return the cursor where it was. When I'm mucking around with Clojure from Emacs, I always have a few test expressions that I evaluate repeatedly. With this trick I can eval them quickly from anywhere without having to move my cursor. I prefer working like this over using deftest and running a full suite of tests every time (I'm sure you can customize that though); I just invoke a single function, change some code, invoke again, etc. until it works as I expect it to. I'm probably weird, I don't know. Does anyone else find this useful? (I had this idea yesterday and I thought it was useful so I shared it. Probably OT, should have sent to Emacs list. Sorry.) -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to [email protected] Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/clojure?hl=en
