doomemacs / doomemacs

An Emacs framework for the stubborn martian hacker
MIT License
19.27k stars 3.04k forks source link

[BUG] "SPC + SPC" binding for +evil/easymotion gives prefix error #1672

Closed ashiklom closed 4 years ago

ashiklom commented 5 years ago

Describe the issue Trying to map SPC SPC to +evil/easymotion fails with "non-prefix key SPC" error. Other functions map just fine.

The failing code looks like this:

(map! (:map doom-leader-map
        "SPC" #'+evil/easymotion))

However, both of these work just fine:

  (map! (:map doom-leader-map
          "SPC" evilem-map))

  (map! (:map doom-leader-map
          "SPC" #'find-file))

This suggests that there's something about the internals of +evil/easymotion that doesn't like being mapped to a prefix key...which is weird because the default g s mapping uses g as a prefix, which has other keys as well.

Debugger entered--Lisp error: (error "Key sequence SPC SPC starts with non-prefix key SPC")
  define-key((keymap (remap keymap (avy-goto-word-or-subword-1 . evil-avy-goto-word-or-subword-1) (avy-goto-word-1-below . evil-avy-goto-word-1-below) (avy-goto-word-1-above . evil-avy-goto-word-1-above) (avy-goto-word-1 . evil-avy-goto-word-1) (avy-goto-word-0 . evil-avy-goto-word-0) (avy-goto-symbol-1-below . evil-avy-goto-symbol-1-below) (avy-goto-symbol-1-above . evil-avy-goto-symbol-1-above) (avy-goto-symbol-1 . evil-avy-goto-symbol-1) (avy-goto-subword-1 . evil-avy-goto-subword-1) (avy-goto-subword-0 . evil-avy-goto-subword-0) (avy-goto-line-below . evil-avy-goto-line-below) (avy-goto-line-above . evil-avy-goto-line-above) (avy-goto-line . evil-avy-goto-line) (avy-goto-char-timer . evil-avy-goto-char-timer) (avy-goto-char-in-line . evil-avy-goto-char-in-line) (avy-goto-char-2-below . evil-avy-goto-char-2-below) (avy-goto-char-2-above . evil-avy-goto-char-2-above) (avy-goto-char-2 . evil-avy-goto-char-2) (avy-goto-char . evil-avy-goto-char) (ace-jump-word-mode . evil-ace-jump-word-mode) (ace-jump-line-mode . evil-ace-jump-line-mode) (ace-jump-char-mode . evil-ace-jump-char-mode)) (33 . evil-shell-command) (58 . evil-ex) (down-mouse-1 . evil-mouse-drag-region) (4 . evil-scroll-down) (21 . evil-scroll-up) (9 . evil-jump-forward) (26 . evil-emacs-state) (down . evil-next-line) (up . evil-previous-line) (right . evil-forward-char) (left . evil-backward-char) (30 . evil-buffer) (22 . evil-visual-block) (86 . evil-visual-line) (118 . evil-visual-char) (122 keymap (69 . vimish-fold-delete-all) (100 . vimish-fold-delete) (70 . evil-vimish-fold/create-line) (102 . evil-vimish-fold/create) (107 . +fold/previous) (106 . +fold/next) (72 . evil-scroll-left) (76 . evil-scroll-right) (left . "zh") (104 . evil-scroll-column-left) (right . "zl") (108 . evil-scroll-column-right) (45 . "zb^") (98 . evil-scroll-line-to-bottom) (46 . "zz^") (122 . evil-scroll-line-to-center) (13 . [122 return]) (return . "zt^") (116 . evil-scroll-line-to-top) (43 . evil-scroll-bottom-line-to-top) (94 . evil-scroll-top-line-to-bottom)) (92 . evil-execute-in-emacs-state) (13 . evil-ret) (25 . evil-scroll-line-up) (15 . evil-jump-backward) (6 . evil-scroll-page-down) (5 . evil-scroll-line-down) (2 . evil-scroll-page-up) (29 . evil-jump-to-tag) (67108918 . evil-switch-to-windows-last-buffer) (23 . evil-window-map) (45 . evil-previous-line-first-non-blank) (95 . evil-next-line-1-first-non-blank) (43 . evil-next-line-first-non-blank) (94 . evil-first-non-blank) (124 . evil-goto-column) (63 . evil-ex-search-backward) (59 . evil-repeat-find-char) (47 . evil-ex-search-forward) (44 . evil-repeat-find-char-reverse) (42 . evil-ex-search-word-forward) (91 keymap (100 . git-gutter:previous-hunk) (116 . hl-todo-previous) (104 . outline-previous-visible-heading) (101 . previous-error) (97 . evil-backward-arg) (121 . +evil:c-string-decode) (117 . +evil:url-decode) (92 . +evil/previous-comment) (42 . +evil/previous-comment) (35 . +evil/previous-preproc-directive) (77 . +evil/previous-end-of-method) (109 . +evil/previous-beginning-of-method) (115 . evil-prev-flyspell-error) (123 . evil-previous-open-brace) (40 . evil-previous-open-paren) (93 . evil-backward-section-end) (91 . evil-backward-section-begin)) (93 keymap (100 . git-gutter:next-hunk) (116 . hl-todo-next) (104 . outline-next-visible-heading) (101 . next-error) (97 . evil-forward-arg) (121 . +evil:c-string-encode) (117 . +evil:url-encode) (92 . +evil/next-comment) (42 . +evil/next-comment) (35 . +evil/next-preproc-directive) (77 . +evil/next-end-of-method) (109 . +evil/next-beginning-of-method) (115 . evil-next-flyspell-error) (125 . evil-next-close-brace) (41 . evil-next-close-paren) (91 . evil-forward-section-end) (93 . evil-forward-section-begin)) (41 . evil-forward-sentence-begin) (40 . evil-backward-sentence-begin) (39 . evil-goto-mark-line) (96 . evil-goto-mark) (37 . evil-jump-item) (36 . evil-end-of-line) (35 . evil-ex-search-word-backward) (125 . evil-forward-paragraph) (123 . evil-backward-paragraph) (103 keymap (115 keymap (47 . avy-goto-char-timer) (32 closure (t) nil (interactive) (let ((current-prefix-arg t)) (call-interactively (function avy-goto-char-timer)))) (83 . evil-easymotion-snipe-backward) (115 . evil-easymotion-snipe-forward) (65 . evilem--motion-function-evil-backward-arg) (97 . evilem--motion-function-evil-forward-arg) (43 . evilem-motion-next-line-first-non-blank) (45 . evilem-motion-previous-line-first-non-blank) (35 . evilem-motion-search-word-backward) (42 . evilem-motion-search-word-forward) (78 . evilem-motion-search-previous) (110 . evilem-motion-search-next) (41 . evilem-motion-forward-sentence-begin) (40 . evilem-motion-backward-sentence-begin) (93 keymap (91 . evilem-motion-forward-section-end) (93 . evilem-motion-forward-section-begin)) (91 keymap (93 . evilem-motion-backward-section-end) (91 . evilem-motion-backward-section-begin)) (70 . evilem-motion-find-char-backward) (102 . evilem-motion-find-char) (84 . evilem-motion-find-char-to-backward) (116 . evilem-motion-find-char-to) (107 . evilem-motion-previous-line) (106 . evilem-motion-next-line) (103 keymap (107 . evilem-motion-previous-visual-line) (106 . evilem-motion-next-visual-line) (69 . evilem-motion-backward-WORD-end) (101 . evilem-motion-backward-word-end)) (66 . evilem-motion-backward-WORD-begin) (98 . evilem-motion-backward-word-begin) (69 . evilem-motion-forward-WORD-end) (101 . evilem-motion-forward-word-end) (87 . evilem-motion-forward-WORD-begin) (119 . evilem-motion-forward-word-begin)) (78 . evil-previous-match) (110 . evil-next-match) (118 . evil-visual-restore) (42 . evil-ex-search-unbounded-word-forward) (35 . evil-ex-search-unbounded-word-backward) (29 . evil-jump-to-tag) (36 . evil-end-of-visual-line) (109 . evil-middle-of-visual-line) (94 . evil-first-non-blank-of-visual-line) (95 . evil-last-non-blank) (48 . evil-beginning-of-visual-line) (107 . evil-previous-visual-line) (106 . evil-next-visual-line) (103 . evil-goto-first-line) (69 . evil-backward-WORD-end) (101 . evil-backward-word-end) (100 . evil-goto-definition)) ...) "  " nil)
  evil-define-key*(motion global "  " nil)
  (let ((prefix (this-command-keys))) (evil-define-key* (quote motion) (quote global) prefix nil) (evilem-default-keybindings (key-description prefix)) (setq prefix-arg current-prefix-arg unread-command-events (mapcar (function (lambda (e) (cons t e))) (vconcat (if evil-this-operator (progn (where-is-internal evil-this-operator evil-normal-state-map t))) prefix))))
  +evil/easymotion()
  funcall-interactively(+evil/easymotion)
  call-interactively(+evil/easymotion nil nil)
  command-execute(+evil/easymotion)

System information

- OS: darwin (x86_64-apple-darwin14.5.0)
- Shell: /bin/zsh
- Emacs: 26.2 (Apr 12, 2019)
- Doom: 2.0.9 (HEAD -> develop, _upgrade/develop f754d4ff 2019-07-23 18:23:17 +0200)
- Graphic display: t (daemon: nil)
- System features: NOTIFY ACL GNUTLS LIBXML2 ZLIB TOOLKIT_SCROLL_BARS NS MODULES THREADS
- Details:
  ```elisp
  env bootstrapper: envvar-file
  elc count: 0
  uname -a:  Darwin 17.7.0 Darwin Kernel Version 17.7.0: Sun Jun  2 20:31:42 PDT 2019; root:xnu-4570.71.46~1/RELEASE_X86_64 x86_64
  modules:   (:completion company ivy :ui doom doom-dashboard doom-quit hl-todo modeline nav-flash ophints (popup +all +defaults) treemacs vc-gutter vi-tilde-fringe window-select workspaces :editor evil file-templates fold lispy multiple-cursors rotate-text snippets :emacs dired electric vc :term eshell :tools bibtex editorconfig eval flycheck flyspell (lookup +docsets) macos magit :lang data emacs-lisp my-ess markdown (org +ipython +pandoc) polymode python sh :config default)
  packages:  (dtrt-indent (fill-function-arguments :recipe (fill-function-arguments :fetcher github :repo davidshepherd7/fill-function-arguments)) deadgrep pandoc-mode)
  exec-path: (~/.gem/bin ~/.zplug/repos/zplug/zplug/bin ~/.zplug/bin ~/.cargo/bin ~/.nix-profile/bin ~/.gem/bin /usr/local/bin /usr/bin /bin /usr/sbin /sbin /Library/TeX/texbin /opt/X11/bin ~/.config/nvim/bundle/fzf/bin ~/.local/bin /Applications/Emacs.app/Contents/MacOS/bin-x86_64-10_10 /Applications/Emacs.app/Contents/MacOS/libexec-x86_64-10_10 ~/.local/bin /Applications/Emacs.app/Contents/MacOS/libexec/)
  ```
hlissner commented 5 years ago

You cannot bind +evil/easymotion anywhere else but on evil-motion-state-map, as it is by default:

(map! :leader :m "gs" #'evil/easymotion)  ; note the :m 

It was not designed to be bound anywhere else (and cannot be -- not reliably). It's a trick to lazy load evil-easymotion and then bind evilem-map to the key sequence that triggered it, without compromising which-key integration and without having to duplicate the built-in keybinds on evilem-map. There is no reliable mechanism for determining through what keymap a command was invoked, so there is no simple solution to this problem. Since these are meant to be "augmented" motion keys to begin with, this seemed like an acceptable compromise.

On an unrelated note, you should use :leader instead of :map doom-leader-map. They are equivalent.

hlissner commented 4 years ago

I'll assume the issue was sufficiently resolved, but mark it as wontfix since the underlying issue cannot be addressed. Thanks for bringing it to my attention!

hlissner commented 4 years ago

As of 27cabea, you can bind +evil/easymotion anywhere you like. I've found a way to work around the previously mentioned technical limitations.