How to redefine a key inside a "minibuffer" mode-map?

2.9k Views Asked by At

I'm trying to redefine the keys used to navigate the history when inside several commands accepting regexps and offering C-p / C-n history navigation. I'd like to use other keys, in addition to C-p / C-n. For example when using occur or replace-regexp, C-p and C-n can be used to go to previous and next elements.

I've tried several things but can't make it work. I think I'm missing the "big picture" here.

Which mode-map do I need to modify, when and how? Everything I tried failed.

P.S: Note that I've got my own minor mode with all my keymaps as adviced here.

2

There are 2 best solutions below

7
On

I'm assuming you just needed minibuffer-local-map. Subsequent definitions using keys previously assigned to that key map will trump the prior definitions. To disable a prior key assignment, then just create a new definition and set the last portion to nil instead of 'function-name.

(define-key minibuffer-local-map (kbd "<f6>") 'help-for-help)

Here is an excerpt from Emacs Trunk .../lisp/bindings.el:

(let ((map minibuffer-local-map))
  (define-key map "\en"   'next-history-element)
  (define-key map [next]  'next-history-element)
  (define-key map [down]  'next-history-element)
  (define-key map [XF86Forward] 'next-history-element)
  (define-key map "\ep"   'previous-history-element)
  (define-key map [prior] 'previous-history-element)
  (define-key map [up]    'previous-history-element)
  (define-key map [XF86Back] 'previous-history-element)
  (define-key map "\es"   'next-matching-history-element)
  (define-key map "\er"   'previous-matching-history-element)
  ;; Override the global binding (which calls indent-relative via
  ;; indent-for-tab-command).  The alignment that indent-relative tries to
  ;; do doesn't make much sense here since the prompt messes it up.
  (define-key map "\t"    'self-insert-command)
  (define-key map [C-tab] 'file-cache-minibuffer-complete))
2
On

To add to what @lawlist said (which was to bind the key in minibuffer-local-map):

There are multiple minibuffer keymaps, depending on what is being read in the minibuffer, and how. And which of those keymaps you might want to use can depend on which Emacs version you are using.

In addition, there is also the keymap for interaction with buffer *Completions*: completion-list-mode-map.

For completion in the minibuffer, the main keymap is minibuffer-local-completion-map.

Here is a list of the minibuffer keymaps. Some of these might not be available (used) in your Emacs version.

  • minibuffer-local-map
  • minibuffer-local-ns-map
  • minibuffer-local-isearch-map
  • minibuffer-local-completion-map
  • minibuffer-local-must-match-map
  • minibuffer-local-filename-completion-map
  • minibuffer-local-filename-must-match-map
  • minibuffer-local-must-match-filename-map

In addition, you can use minibuffer-with-setup-hook (or minibuffer-setup-hook directly) to add key bindings on the fly, for the duration of a single minibuffer reading.

I will add this info, since it can be really helpful when you are manipulating minibuffer keymaps: You can use C-h M-k (command describe-keymap), from library help-fns+.el, to see all of the bindings of a given minibuffer keymap in human-readable form.