Having written a function (say, my-func), I wanted to map it in ledger-mode-map to the keypress that I will call "Control dollar," that is, the dollar sign $, typed while the Ctrl key is held down.

The expression:

(define-key ledger-mode-map (kbd "C-$") 'my-func)

when executed does not indicate a failure, but a subsequent C-h my-func indicates no key binding.

Executing C-h k C-$ produces the output "C-$ is undefined".

I need a way to express "Control dollar" so that Emacs can recognize it as a keypress, if that is even possible. Here are a few of the alternatives I have tried to (kbd "C-$"):

Expression Result when evaluated
[?\C-4] 67108916
[?\C-\$] 67108900
(kbd "C-\$") 67108900
[C-S-4] [C-S-4]
(kbd "[67108900]") "[67108916]"
[$] [$]
[\$] [$]
(kbd "C-[$]") C- must prefix a single character, not [$]
(kbd "C-$") 67108900
[(control $)] [(control $)]
[(control \$)] [(control $)]

@amitp: It does work if I use global-map instead of ledger-mode-map. It does not work if I use, say, C-! instead of C-$ with ledger-mode-map.

  • Hm, interesting. To narrow it down, let's try to figure out if it's the C-$ part or the mode map part. Does it work if you use global-map instead of ledger-mode-map? Does it work if you use a different keybinding instead of C-$?
    – amitp
    Commented May 6, 2021 at 20:06
  • It does work if I use global-map instead of ledger-mode-map. It does not work if I use, say, C-! instead of C-$ with ledger-mode-map Commented May 6, 2021 at 20:10
  • Since the problem is with ledger-mode-map, which is not bundled with Emacs, can you please provide a way to reproduce the problem from emacs -q? E.g. how you installed ledger-mode, which version exactly. Do you have the same problem if you run emacs -q and do whatever minimum steps are needed to enable Ledger mode? Commented May 6, 2021 at 20:56
  • 1
    This is all you ever need as a key description: (kbd "C-$"). kbd accepts as input what Emacs shows you as help when you use C-h k.
    – Drew
    Commented May 6, 2021 at 22:31
  • @Gilles'SO-stopbeingevil': I set up a minimal ledger-mode environment, and in that the key assignment did work correctly. Commented May 6, 2021 at 23:58

1 Answer 1


Here's a MWE:

(require 'package)
(setq package-archives nil)
(add-to-list 'package-archives '("org"   . "https://orgmode.org/elpa/"    ) t)
(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/"   ) t)
(add-to-list 'package-archives '("gnu"   . "http://elpa.gnu.org/packages/") t)

(defun my-func ()
  "Say `HEY'."
  (message "HEY"))

(use-package ledger-mode
  :ensure         t
  :bind           (:map ledger-mode-map
                        ("<C-f13>"   . my-func)))

(define-key ledger-mode-map (kbd "C-$") 'my-func)

If we evaluate the above expression, then edit a buffer in ledger-mode, and then press either C-$or C-f13, "HEY" shows up in the minibuffer.

But if instead of using define-key to do the mapping for C-$, we add it to the :bind section of use-package thus:

(use-package ledger-mode
  :ensure         t
  :bind           (:map ledger-mode-map
                        ("<C-f13>"   . my-func)
                        ((kbd "C-$") . my-func)))

and then evaluate the expression, the *Warnings* buffer displays this:
Error (use-package): Failed to parse package ledger-mode: use-package: ledger-mode wants arguments acceptable to the 'bind-keys' macro, or a list of such values

The trick is to change that last line from

                        ((kbd "C-$") . my-func)))


                        ("C-$"       . my-func)))

Then once again either C-$ or C-f13 display "HEY" in the minibuffer.

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.