"Wrong type argument: commandp" error when binding a lambda to a key - emacs

I am getting a "Wrong type argument: commandp, (lambda nil (forward-line 5))" here.
(global-set-key [?\M-n] (lambda () (forward-line 5)))
What is the error? I'm fairly sure it's simple & I'm missing something obvious.

global-set-key expects an interactive command. (lambda () (interactive) (forward-line 5)) ought to work.
By the way, C-h f commandp is a pretty good starting point for errors like that.

The correct form should be this -
(global-set-key (kbd "M-n") (lambda () (interactive) (forward-line 5)))
The problem was that you forgot to put (interactive) (as brendan mentioned).
By the way, you will notice that I used the (kbd) function for specifying the key-binding. That function is immensely useful since you can put the key-bindings almost literally.

I've also seen this error on a new machine where I am using my usual .emacs file but haven't installed my packages, and the command to be executed is in one of those packages. (Because a command that can't be executed definitely isn't interactive!)

Related

how to use occur in global-set-key

I'd like to list subroutine and function in fortran.
I think occur-mode looks promising but have to give regexp as a argument whenever I want to get list.
So, I want to make a key binding for automating listing as follows
(global-set-key (kbd "<f6>") (lambda () (occur '^[ ]*\(subroutine\|function\)')))
but I got error as
Wrong type argument: commandp, (lambda nil (occur (quote subroutine)))
I am not familiar Emacs Lisp. Also, it would helpful if I could get this function with neotree.

Elisp: simple function to split window and move cursor to new window

I feel dumb posting this but I really have no idea why this function doesn't compile:
(defun dc/split-window-below-and-move-cursor ()
(interactive)
(split-window-below)
(other-window 1))
Am I overlooking something super obvious?
Here's the error message:
Symbol's function definition is void: split-window-below
Update: So I tried it in another file (on a fresh Emacs session) and it worked fine. (Taking out progn and putting in (interactive) didn't resolve it either - I've updated the code above to reflect this change.)
Update 2: Okay, this is just silly. The following code works fine but I still can't get the defun code above to work. Would still be very curious to understand what's causing this behavior, if anyone has ideas.
(global-set-key (kbd "s--") (lambda() (interactive) (split-window-below) (other-window 1)))
No need for progn, but you need interactive:
(defun dc/split-window-below-and-move-cursor ()
(interactive)
(split-window-below)
(other-window 1))

Programatically insert text into command that normally blocks event loop

I'd like to implement a command that types the first few characters into an existing command and lets me type the rest.
For example, a variant of icicle-execute-extended-command that starts with "icicle-" already entered.
I have tried:
keyboard macros
fail (even on simple things like M-x i c i c l e s) for no apparent reason.
functions
calling icicle-execute-extended-command block the command sequence
How would I go about doing this in a generalized manner?
Nice question.
Here's something generic you can try:
(defun no-mondays ()
(interactive)
(minibuffer-with-setup-hook
(lambda()
(insert "monday"))
(call-interactively 'query-replace)))
And here's a refactoring:
(defun with-initial-minibuffer (str fun)
`(lambda ()
(interactive)
(minibuffer-with-setup-hook
(lambda ()
(insert ,str))
(call-interactively ',fun))))
(defalias 'no-weekends
(with-initial-minibuffer
"\\(?:satur\\|sun\\)day"
'query-replace-regexp))
If you are calling completing-read yourself in your command definition, then just pass the text to insert as the INITIAL-INPUT argument. That's what it's for.
If you use icicle-define-command or icicle-define-file-command (so that your command will be a multi-command), then same thing: pass the INITIAL-INPUT arg.
If you use such a macro, be sure to put something like this in the file that defines the command, so the macro definition is available a byte-compilation time:
(eval-when-compile
(or (condition-case nil
(load-library "icicles-mac") ; Use load-library to ensure latest .elc.
(error nil))
(require 'icicles-mac)))

Using flyspell in the current org-mode tree

I'm trying to write a small lisp function to run flyspell in a single org-mode branch. I have added this to my .emacs file:
(defun flyspell-current-tree()
(interactive)
(org-mark-subtree)
(flyspell-region))
(global-set-key (kbd "S-<f8>") 'flyspell-current-tree)
But when running it I get the following error:
flyspell-current-tree: Wrong number of arguments
Any ideas?
You need to provide beg and end to flyspell-region for it to work properly. The error is coming from that and not actually from your function.
If you include (point) and (mark) as arguments to flyspell-region it will work properly.
(defun flyspell-current-tree()
(interactive)
(org-mark-subtree)
(flyspell-region (point) (mark)))

In Emacs, can we make one keystroke to do different command?

I want to make one keystroke, say C-F12, to do delete-other-windows or winner-undo. I think it's easy if I already learning Emacs Lisp programming, and set a boolean flag. That is, if previously it run delete-other-window, now it'll run winner-undo.
How do you do that in Emacs Lisp?
Thanks
Try something like this
(setq c-f12-winner-undo t)
(define-key (current-global-map) [C-f12]
(lambda()
(interactive)
(if c-f12-winner-undo
(winner-undo)
(delete-other-windows))
(setq c-f12-winner-undo (not c-f12-winner-undo))))
(defun swdev-toggle-sole-window ()
(interactive)
(if (cdr (window-list))
(delete-other-windows)
(winner-undo)))
(global-set-key (kbd "<C-f12>") 'swdev-toggle-sole-window)
The first line starts the declaration of a function called swdev-toggle-sole-window, taking no argument.
This function is declared as interactive, i.e. it can be called with M-x or through a key binding.
If the window list contains more than one element, i.e. if there is more than one window, …
… then delete other windows …
… else undo the window deletion.
Bind the function to the key C-f12.
Here's a solution using the approach taken by Emacs' recenter-top-bottom function:
(defun delete-other-window-or-winner-undo ()
"call delete-other-window on first invocation and winner-undo on subsequent invocations"
(interactive)
(if (eq this-command last-command)
(winner-undo)
(delete-other-windows)))
(global-set-key (kbd "<C-f12>") 'delete-other-window-or-winner-undo)