The problem with your first binding is not that comment-dwim
interprets "TODO: "
as an argument, it's that global-set-key
tries to do so. You're giving "TODO: "
as a third argument to global-set-key
, but it only accepts two (the keys and the command).
To be clear, let me make another example using the command insert-char
, which uses its argument in a more straightforward way than comment-dwim
. (insert-char ?c)
inserts a c
in the current buffer. Now can you bind that call like this: (global-set-key (kbd "C-c T") (insert-char ?c))
? No you can't. Key bindings only accept commands, not command calls (insert-char
is a command, (insert-char ?c)
is a call to that command). Note, command means interactive function, i.e. a function with an interactive
form in its definition (see the manual). That's one of the problems with your second binding, the function is not interactive.
The other problem with your insert-todo
is that the way it's defined, it returns "TODO: "
, you didn't tell Emacs to insert it. Did you try to run insert-todo
? Type M-:
, enter (defun insert-todo () "TODO: ")
, hit RET
, then type M-:
again, (insert-todo)
, RET
. You'll see "TODO: "
in the echo area, as its return value. You need to give "TODO: "
as argument to the function insert
in order to insert it in the buffer when you call the function.
So I'd say you don't want to string together a function and an "action", you want to string together two function calls: (comment-dwim nil)
(comment-dwim
requires an argument and nil
will do) and (insert "TODO: ")
. Now if you need to call one or more functions with their arguments using a key combination, you can define a new interactive function that includes the calls to the functions and bind this new function, or you can put the same definition as an unnamed interactive function directly in the key binding:
(defun insert-todo-comment ()
(interactive "*")
(comment-dwim nil)
(insert "TODO: "))
(global-set-key (kbd "C-c T") #'insert-todo-comment)
(global-set-key (kbd "C-c T") (lambda ()
(interactive "*")
(comment-dwim nil)
(insert "TODO: ")))
(lambda () (interactive) (comment-dwim) (insert-todo))
. – NickD Feb 09 '21 at 02:27