views:

80

answers:

3

What is a good way to evaluate the (+ 100 (+ 100 100)) part in

(+ (+ 1 2) (+ 100 (+ 100 100)))

?

For now, I do it by C-x C-e, which means I need to locate the ending parenthesis, which is difficult in most cases. Options > Paren Matching Highlighting helps, but still I need to move the cursor toward the ending parenthesis until the highlighted match is the starting parenthesis.

One way would be to have the reverse version of C-x C-e, so that I can place the cursor at the starting parenthesis like this:

(+ (+ 1 2) |(+ 100 (+ 100 100)))

and then press the appropriate keybinding.

Or I could place the cursor inside the expression, but not inside smaller expressions,:

(+ (+ 1 2) (+ | 100 (+ 100 100)))

and press a keybinding. Because aiming at a target is easier if the target is big.

How can I make such a command? Or is there one already provided?

Sidenote: bar cursor and box cursor

Emacsers who use box cursor (default) might wonder where I'm putting the cursor with the bar notation above. In emacs, you can choose box cursor or bar cursor, (bar-cursor-mode t). When the bar cursor is between the letters A and B, the box cursor is on B. So the bar is the left wall of the box.

BTW, the concept of bar cursor is useful in some unusual way: The practice of iterating from index1 to index2-1 in programming surprises beginners. It helps to imagine index1 and index2 as indicating bars (left walls) rather than boxes.

+2  A: 

You could write such a command like so:

(require 'thingatpt)
(defun eval-sexp-at-or-surrounding-pt ()
  "evaluate the sexp following the point, or surrounding the point"
  (interactive)
  (save-excursion
    (forward-char 1)
    (if (search-backward "(" nil t)
        (message "%s" (eval (read-from-whole-string (thing-at-point 'sexp)))))))
Trey Jackson
A: 

There is an inbuilt eval-defun. It's bound by default to C-M-x. It's similar to what you want but evals the top-level defun. Perhaps you can adapt that.

Noufal Ibrahim
`eval-defun` will grab too much (the whole top-level form that contains or comes after point). The OP clearly wants to evaluate only an internal sub-expression.
Chris Johnsen
Yup. I was suggesting adapting that. Particularly the way in which it finds the top level sexp.
Noufal Ibrahim
+2  A: 

Bind a key to one or both of these:

(defun eval-next-sexp ()
  (interactive)
  (save-excursion
    (forward-sexp)
    (eval-last-sexp nil)))

(defun eval-surrounding-sexp (levels)
  (interactive "p")
  (save-excursion
    (up-list (abs levels))
    (eval-last-sexp nil)))

Tangentially related, I highly recommend paredit for working with s-expressions. The structure editing commands and bindings make editing s-expressions a breeze. It binds C-down to up-list, so that eval-surrounding-sexp above is almost exactly the same as C-down C-x C-e (the only difference is that the function uses save-excursion to prevent movement).

Chris Johnsen