I'd like to replicate something in emacs that I do in AutoHotkey all the time:

  1. type td
  2. have that string be replaced with the current date

I'm trying to do this with Emacs abbrevs but I'm running into an Invalid function: error.

I've also tried using a builtin function, but I get the same Invalid function error. I've done a bunch of research but no avail.

Here's the code I have currently in my .emacs:

(defun insert-current-iso-date ()
    (format-time-string "%Y-%m-%d"))

(define-abbrev-table 'global-abbrev-table
  '(("td" "" (insert-current-iso-date))))
  • One can use C-u M-! date -I to insert a date, assuming GNU date, the prefix arg means insert the output of the shell command. I don't have experience with abbrev (it seems too heavy to me), so I'm not sure that's possible with Emacs' built-in abbrev, and I hear YASnippet is popular and powerful.
    – xuchunyang
    May 22, 2020 at 4:13
  • Related Emacs Wiki - insert current date.
    – Drew
    May 22, 2020 at 4:14

1 Answer 1


You need to remove the parenthesis from your custom function. It's calling for hook function name there, not its evaluation.

(define-abbrev-table 'global-abbrev-table
  '(("td" "" insert-current-iso-date)))

Anyway, to my understanding, you should define your abbrevs the way it's intended which is using define-abbrev, whose syntax is easier to follow, and not overriding the whole table definition unless you have a good reason to do so.

(define-abbrev global-abbrev-table "td" "" 'insert-current-iso-date)

And, as @NickD pointed:

you have to change the insert-current-iso-date to insert the string: it is not enough to return it as it does currently:

(defun insert-current-iso-date ()
  (insert (format-time-string "%Y-%m-%d"))

And of course you have to turn on abbrev-mode.

  • I think you also need to change the insert-current-iso-date to insert the formatted string: atm it just returns it.
    – NickD
    May 22, 2020 at 15:04
  • @NickD Hook name calls to confusion, but it's all it needs as the symbol is defined. The hook is the function [insert-current-iso-date] for performing the expansion, so its return is what is inserted. Probably it should be named current-iso-date for clarity.
    – Muihlinn
    May 22, 2020 at 16:26
  • 1
    In my experiment, that did not work: td was replaced by an empty string; I had to explicitly insert - I didn't spend much time on it however, so I may very well be wrong.
    – NickD
    May 22, 2020 at 17:51
  • 1
    Thank you all so much for this. I appreciate the rapid, accurate response, the back and forth about using insert, and the advice to use (define-abbrev). I was just trying to get it working, I'll now make it proper (eg. define-abbrev). I appreciate this, since 'td' is hard-coded into my muscle memory at this point and KNEW there would be a way to do it in Emacs! Thanks!!
    – may
    May 23, 2020 at 14:13
  • 1
    Without good understanding of lisp, I just added this code (to replace what I had connected to ^Cd before). It works, except calling unexpand-abbrev (just in case I actually need the string 'td'!) leaves td2020-05-24 instead of just td. Any ideas why? May 24, 2020 at 16:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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