emacs-evil / evil

The extensible vi layer for Emacs.
GNU General Public License v3.0
3.29k stars 276 forks source link

`evil-define-key' can no longer bind key in `gtags-mode-map' #130

Open TheBB opened 12 years ago

TheBB commented 12 years ago

Originally reported by: York Zhao (Bitbucket: york, GitHub: york)


Here is all in .eamcs

(require 'evil)
(evil-mode 1)

(require 'gtags)

(eval-after-load 'gtags
  '(progn
     ;; gtags-mode
     (evil-define-key 'motion gtags-mode-map
       "\C-]" 'gtags-find-tag-from-here)
     (evil-define-key 'normal gtags-mode-map
       "\C-t" 'gtags-pop-stack)))

Open a C++ file (or any file), type "M-x gtags-mode". Type "C-h k C-]" and I suppose to see the key being binded to gtags-find-tag-from-here' but it's not, what it shows is still the old bindingevil-jump-to-tag'. Same thing happens if you type "C-h k C-t". This used to be working for me, I have no idea why it just stops working anymore. Even last night it worked for awhile, nothing has changed but it just never works.


TheBB commented 8 years ago

Original comment by Nick DeCoursin (Bitbucket: CapinCape, GitHub: Unknown):


Here's a couple more issues that reference the same bug: [issue 497](https://bitbucket.org/lyro/evil/issues/497/regarding-initial-states* 1. ) and issue 391

TheBB commented 12 years ago

Original comment by Vegard Øye (Bitbucket: epsil, GitHub: epsil):


True. evil-normalize-keymaps is presently very economical: it only concerns itself with auxiliary keymaps that are currently active. However, the //entry// for an auxiliary keymap, once it is created, is actually very toggleable, because it depends on the same mode variable as the main keymap. A heavier, but more general approach would therefore be to find all auxiliary keymaps up-front.

The big question is whether it will be efficient enough (keymap normalization is currently unnoticeable, and I very much intend to keep it so). I'll run some tests with make profiler and see what can be done.

TheBB commented 12 years ago

Original comment by Frank Fischer (Bitbucket: lyro, GitHub: lyro):


But would this be sufficient? I may be wrong, but AFAIK evil-define-key is usually called before the buffer is created (not necessarily in a corresponding mode-hook). When the buffer is created and gtags-mode is enabled after evil (or enabled exlicitely using M-x gtags-mode) then this call to evil-define-key and hence evil-normalize-keymaps would not be executed.

TheBB commented 12 years ago

Original comment by Vegard Øye (Bitbucket: epsil, GitHub: epsil):


What Frank says is correct - and fixable. I can make evil-define-key call evil-normalize-keymaps if the keymap being updated is currently active (i.e., is listed in (current-active-maps)).

TheBB commented 12 years ago

Original comment by York Zhao (Bitbucket: york, GitHub: york):


The problem is that the list of active auxiliary keymaps needs to be updated
(i.e., exactly those auxiliary keymaps are activated whose corresponding
"activator" keymap (in this case gtags-mode-map) is active). This update usually
happens after each state switch.

This makes sense.

This means if you, after starting gtags-mode, switch to insert state and back
then the auxiliary keymap with your bindings should be active.

This finally explained why it was working for me every day at my office (this is something I can't live without), but "suddenly" stopped working yesterday while at home, because at office I was editing the C++ source code all the time while yesterday I didn't have a need to edit anything.

Unfortunately this does not happen after enabling or disabling some minor mode
currently (I have no idea if there is something like
after-change-major-mode-hook for minor modes).

Too bad if there is no `after-change-major-mode-hook' for minor-mode.

In the meantime a workaround would be to call evil-normalize-keymaps
immediately after loading gtags-mode.

Added "(evil-normalize-keymaps)" to `gtags-mode-hook' and worked. Apparently this is just a workaround as this requires adding "(evil-normalize-keymaps)" to every minor mode hook in similar situation. If there is no way to solve this I guess you might want to write this in the manual and/or add comment in the source code.

Thank you very much for the explaination Frank.

TheBB commented 12 years ago

Original comment by Frank Fischer (Bitbucket: lyro, GitHub: lyro):


Nasty bug. The problem is that the list of active auxiliary keymaps needs to be updated (i.e., exactly those auxiliary keymaps are activated whose corresponding "activator" keymap (in this case gtags-mode-map) is active). This update usually happens after each state switch. This means if you, after starting gtags-mode, switch to insert state and back then the auxiliary keymap with your bindings should be active. Unfortunately this does not happen after enabling or disabling some minor mode currently (I have no idea if there is something like after-change-major-mode-hook for minor modes). In the meantime a workaround would be to call evil-normalize-keymaps immediately after loading gtags-mode.