2

I am always editing my .emacs file, and I was just wondering if I could reload it without restarting Emacs?

Note: I have tried M-x load-file and choosing the .emacs file, but I get this error message:

error message

Could faulty code be causing this? Here is my code:

(set-background-color "#1E1E20")
(set-foreground-color "#D9CB9E")

(add-to-list 'load-path "~/.emacs.d/")
(require 'auto-complete-config)
(add-to-list 'ac-dictionary-directories "~/.emacs.d//ac-dict")
(ac-config-default)

(defun defun ()
  "Insert defun function."
  (interactive)
  (insert "(defun name () 
  \"Insert description here.\"
)")
  (backward-char 35)
)

(defun hello () 
  "Just a gretting."
  (interactive)
  (message "Hello World!")
)
  • 2
    Yes, it's faulty code in your .emacs =) – Malabarba Sep 27 '14 at 17:26
  • @Malabarba Thank you! I will post my code. – Luke Sep 27 '14 at 17:29
3

The first thing to know is that Elisp has almost no special syntax--defun is just an Elisp macro for defining functions. Its expansion is rather simple, as you can see from running a quick macroexpansion:

(defalias 'defun
  (function
   (lambda nil "Insert defun function."
     (interactive)
     (insert "(defun name () 
  \"Insert description here.\"
)")
     (backward-char 35))))

An important thing to note: the name of the function being defined in defun is just an argument to a macro. Since defun is a macro, it does not evaluate its arguments immediately. defalias, on the other hand, is a built-in function, so it takes a quoted version of the function name--otherwise it would try to evaluate the function name as a variable.

Elisp is incredibly flexible, so it is more than happy to re-define defun to be a function rather than a macro, which is what you did in your code, and for functions (unlike macros) all arguments are immediately evaluated. The error I got was slightly different than yours--I got hello being undefined as a variable (I'm guessing your error was caused by some sort of byte-compilation or double-evaluation). Once you understand how function evaluation works in Elisp, this makes perfect sense--the interpreter first evaluates hello as a variable in order to pass that value to the new function defun. If hello were defined, you would probably get a "wrong number of arguments" error instead (since your new version of defun takes no arguments).

The moral of the story: Elisp lets you do pretty much anything, but that doesn't mean you should. Never re-define built-in functions or macros unless you want debugging hell.

4

The problem

defun is already an elisp macro, which is similar to a function. So doing something like (defun defun () ..) is redefining the function called defun to do something else.
Since defun is used throughout Emacs (including in your .emacs), redefining it is a recipe for disaster.

The problem should be fixed if you change that to anything that doesn't override a fundamental elisp function (defun write-defun () ..).

What you actually wanted

What you are trying to do is auto-insert a template for defining a new defun. To achieve that you can use the yasnippet package.

Here is an inbuilt yasnippet template for inserting defun's [Source]:

# -*- mode: snippet -*-
# name: defun
# key: def
# --
(defun ${1:fun} (${2:args})
  ${3:(interactive${4: "P"})}
  $0)

How to use this template?

  • Install yasnippet from Melpa
  • Add (require 'yasnippet) and (yas-global-mode 1) to your init.el.
  • Restart emacs or load-file your init.el
  • Now in a buffer with emacs-lisp-mode major mode, type def and hit TAB.
    • Magic! You will see the defun template inserted for you. This is because of the # key: def line in the template for defun.
    • Now by hitting TAB consecutively, you cursor will jump through the positions labeled $1, $2, $3, $4, and finally end up at the $0 position.

If you'd like to understand that template in more detail, I would suggest having a read of this tutorial by Matthew Keeler. It was very useful for me to help get started with yasnippet.

  • 1
    defun is an elisp keyword. So (defun defun () .. will be illegal. Nonsense. This works fine: (defun defun (x) "..." (interactive "sXxx: ") (message "X: %S" x)) Then M-x defun RET abcd RET. defun itself is just a symbol. – Drew Sep 27 '14 at 19:44
  • 2
    Defun is just a macro, it can be redefined. But (defun defun ...) is indeed a recipe for disaster. – Malabarba Sep 27 '14 at 19:52
  • @Malabarba: Yes, a recipe for trouble. But not "illegal". – Drew Sep 28 '14 at 3:17
  • @Drew yes, I was correcting kaushal, not you. =) I was trying to reinforce what you said. – Malabarba Sep 28 '14 at 8:25
  • @Drew It was good to learn that. I had incorrectly assumed the elisp defun to be like a function in C. Artur, thanks for fixing the solution. – Kaushal Modi Sep 28 '14 at 13:52

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.