How do I bind a key for general use, but differently for a specific mode, such as dired?

eg how would I resolve this?

(define-key dired-mode-map (kbd F12) #'dired-up-directory)
(global-set-key (kbd F12) 'shell)

  • please consult the manual. this topic is easy to find
    – shynur
    Commented Sep 28, 2023 at 9:35
  • A link would be useful...
    – balanga
    Commented Sep 28, 2023 at 10:27
  • Have you tried the code you've posted? I think it may work after you fix the kbd.
    – Pkkm
    Commented Sep 28, 2023 at 13:36

2 Answers 2


To globally bind a key, keymap-global-set function can be used:

(keymap-global-set "C-z" 'shell)

To bind a key for a specific mode, you should use a hook:

(add-hook 'texinfo-mode-hook
          (lambda ()
            (keymap-set texinfo-mode-map "C-c p"
            (keymap-set texinfo-mode-map "C-c n"
            (keymap-set texinfo-mode-map "C-c C-x x" nil)

You can find more information in here.


In addition to hooks as in the other answer, you can achieve a different behavior of a function for specific modes by defining a single function which checks major-mode with cond and executes custom function for that mode.

For example, if you wanted to have a single binding for documentation at point but customize this for emacs-lisp-mode and python-mode you could use:

(defun help-for-major-mode ()
  (cond ((equal major-mode 'emacs-lisp-mode) (call-interactively 'helpful-at-point))
        ((equal major-mode 'python-mode) (call-interactively 'python-eldoc-at-point))
        (t (call-interactively 'counsel-dash-at-point)))

The t part at the end is the default function. Note that you may not need the call-interactively for some functions - depends on the function.

More general way of conditional execution of a function (not necessarily based on major-mode - any condition) can be easily done with the cmds! macro from Doom Emacs (you can copy the defmacro definition, you don't have to run Doom). For example, if you wanted to have one function which works just like other-window but in the special case, if there's only one window, creates a new window by splitting and switches to it, you could use:

 (singlep (window-list))


This can be then bound to any key the same way you bind defuns.

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.