vanjoe
vanjoe

Reputation: 439

passing functions as arguments in emacs lisp

I am unsure how exactly emacs lisp treats function objects, is there a hidden argument that I am not seeing, when I have this then when I hit C-c p it gives the error Wrong type argument: commandp, load-cenet-files

I don't know lisp at all.

(defun load-cenet-files ()
  (load-file "~/.emacs.d/cedet/common/cedet.elc")
  (require 'semantic-gcc)
)

(global-set-key (kbd "C-c p") '(load-cenet-files)) 

Upvotes: 3

Views: 1222

Answers (2)

Thomas
Thomas

Reputation: 17422

Emacs distinguishes between functions and commands - the latter are a special type of functions, namely those that can be invoked interactively by the user. The error message Wrong type argument: commandp, load-cenet-files tells you that some point in the code is expecting a command, but got something else. commandp is a predicate function that checks if its argument is a command; here, it tested load-cenet-files and found that is is not a command, thus barfed.

You can turn a function into a command by declaring it interactive. You do this by adding the (interactive) declaration as the first line after the (defun function-name (args). Note that (interactive) is a special construction, it is not really a function call, but rather a declaration.

(defun load-cenet-files ()
  (interactive)
  (load-file "~/.emacs.d/cedet/common/cedet.elc")
  (require 'semantic-gcc)
)

Once you turned a function into a command, you can then call it via M-x function-name. Also, if you want to bind a function to a keyboard shortcut, it must be a command. The latter is exactly why you're seeing that error message: you've bound the load-cenet-files function to C-c p but it is a function, not a command. Once you insert (interactive) you should be fine.

Lastly, it seems somewhat unusual that you're trying to bind this functionality to a keyboard shortcut. Could you not just put the load-file and require into your ".emacs" file? Or, if you don't want the files to be loaded globally, attach it to a mode-specific hook?

Upvotes: 5

FatalError
FatalError

Reputation: 54551

It wants an interactive function http://www.gnu.org/software/emacs/emacs-lisp-intro/html_node/Interactive.html#Interactive which would potentially allow the user to enter parameters to your function. If you don't want any, something like this might work:

(defun load-cenet-files ()
  (interactive)
  (load-file "~/.emacs.d/cedet/common/cedet.elc")
  (require 'semantic-gcc)
)

(global-set-key (kbd "C-c p") 'load-cenet-files) 

Upvotes: 3

Related Questions