5

I am thinking of binding C-x C-e to a single command, which does eval-last-sexp if there is no selection or eval-region if there is a selection. This is what I have tried:

(defun my/eval()
(interactive)
(if (region-active-p) (eval-region region-beginning region-end)
(eval-last-sexp EVAL-LAST-SEXP-ARG-INTERNAL)))
(global-set-key (kbd "C-x C-e") 'my/eval)
  • Changing EVAL-LAST-SEXP-ARG-INTERNAL to nil seems to do the job. – Name Sep 5 '15 at 16:42
  • Also changing region-beginning to (region-beginning) and region-end to (region-end). – Name Sep 5 '15 at 16:53
  • Also, (use-region-p) might be a better choice than (region-active-p). – mbork Oct 16 '15 at 12:42
9

First of all, a few stylistic recommendations. (Style is important in programming :-D) In Lisps, we use dashes as separators, so your function is better called my-eval, not my/eval:

(defun my-eval()
(interactive)
(if (region-active-p) (eval-region region-beginning region-end)
(eval-last-sexp EVAL-LAST-SEXP-ARG-INTERNAL)))
(global-set-key (kbd "C-x C-e") 'my-eval)

Now, Lisp code is bare syntax trees, so they have levels of nesting and proper indentation is very important, it helps to see how expressions are composed. Also, it's a good idea to have one empty line between top level forms:

(defun my-eval()
  (interactive)
  (if (region-active-p)
      (eval-region region-beginning region-end)
    (eval-last-sexp EVAL-LAST-SEXP-ARG-INTERNAL)))

(global-set-key (kbd "C-x C-e") 'my-eval)

Isn't it beautiful?

You can find out more about region-beginning and region-end with help of built-in help system: type C-h f region-beginning RET. Here we see that this is a function, actually. You call this function and it returns position of beginning of region. To call functions you place their names on the first position in a form:

(function-name arg1 arg2 ...)

Since region-beginning and region-end don't take arguments we write:

(defun my-eval()
  (interactive)
  (if (region-active-p)
      (eval-region (region-beginning) (region-end))
    (eval-last-sexp EVAL-LAST-SEXP-ARG-INTERNAL)))

Great. Now we only need to fix EVAL-LAST-SEXP-ARG-INTERNAL. As written you're trying to use value that symbol EVAL-LAST-SEXP-ARG-INTERNAL is bound to, but chances are it's not bound to any value, so you will get an error. You can read about first argument of eval-last-sexp using the same trick: C-h f eval-last-sexp RET. Documentation tells us how the argument is used, it's mainly used to handle various interactive details. We can preserve these behavioral details in my-eval this way:

(defun my-eval()
  (interactive)
  (if (region-active-p)
      (eval-region (region-beginning) (region-end))
    (call-interactively #'eval-last-sexp)))

This should do the trick. Note that when there is a region, eval-region won't print anything in the mini-buffer. If this is not the desired behavior, supply the print-flag argument:

(defun my-eval()
  (interactive)
  (if (region-active-p)
      (eval-region (region-beginning) (region-end) t)
    (call-interactively #'eval-last-sexp)))

(global-set-key (kbd "C-x C-e") #'my-eval)
  • 1
    my/eval is ok too. This originates in Clojure as far as I can tell, but in Emacs Lisp people often use it to mean that the definition is in a file my.el. I do this sometimes to mean that this is my addition to a library written by someone else, eg. my/org-do-something etc. – wvxvw Sep 5 '15 at 18:18
  • @wvxvw, Emacs Lisp is not Clojure. Emacs Lisp conventions should be used, they are written and easy to follow. Some people have written packages where / separator is used, and I consider it harmful because others think it's OK now. You can do whatever you want in your own config, but let's tell people what is generally accepted. For example, if you submit something for MELPA these days, Steve Purcell will politely note that / separator is not acceptable. – Mark Karpov Sep 5 '15 at 18:43
  • 1
    Try find ~/.emacs.d/elpa -type f -exec grep --color -nPH -e 'defun [^\/]+\/[^\/]+' {} + and see how many matches you get. I get around 300 hits. It's like with natural language: you cannot prevent it on such grounds (the rule was arbitrary in the first place). – wvxvw Sep 5 '15 at 18:46
  • @wvxvw, this is irrelevant. - is the recommended way, so this should be advised. You can try your search for hyphens too and see how many matches you get then compare the two numbers. – Mark Karpov Sep 5 '15 at 18:51
  • But I didn't say that hyphens are bad... – wvxvw Sep 5 '15 at 18:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.