By default C-c C-t has sh-tmp-file binding in sh-mode, which I want to change.:

C-c C-t runs the command sh-tmp-file (found in sh-mode-map), which is an
interactive compiled Lisp function in ‘sh-script.el’.

It is bound to C-c C-t.

I have tried to bind the key binding as follows:

(defun insert-todo ()
  (interactive "*")
  (insert comment-start "TODO: "))

(define-key shell-mode-map (kbd "C-c C-t") 'insert-todo)
(define-key sh-mode-map (kbd "C-c C-t") 'insert-todo)

I am having following error message:

Debugger entered--Lisp error: (void-variable sh-mode-map)
  (define-key sh-mode-map (kbd "C-c C-t") 'insert-todo)
  eval-buffer(#<buffer  *load*> nil "/home/alper/.emacs" nil t)  ; Reading at
buffer position 100039
  load-with-code-conversion("/home/alper/.emacs" "/home/alper/.emacs" t t)
  load("~/.emacs" noerror nomessage)
  startup--load-user-init-file(#f(compiled-function () #<bytecode
0x15948fd477f1>) #f(compiled-function () #<bytecode
0x15948fd46d41>) t)

How could I resolve this error?

  • 1
    sh-mode-map is defined out of the box in Emacs 26 and Emacs 27. Absent additional facts regarding which version of Emacs you are using and your operating system, I don't see why the variable would be void. If for, example, you are using Emacs 25 or something like that where sh-mode-map has not yet been defined, you could try using: (defvar sh-mode-map) (with-eval-after-load 'sh-script (define-key sh-mode-map (kbd "C-c C-t") 'insert-todo))
    – lawlist
    Aug 8, 2021 at 15:54

1 Answer 1


Mode keymaps aren't defined until the defining library has been loaded, so you just need to defer binding the key until that happens.

(with-eval-after-load "sh-script"
  (define-key sh-mode-map (kbd "C-c C-t") 'insert-todo))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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