2

I'm really struggling to remap some keys in pdf-view-mode. This is what I have so far:

;; Unbind keys; see https://github.com/hlissner/doom-emacs/blob/develop/docs/faq.org#my-new-keybinds-dont-work
(map! :after evil
      :map pdf-view-mode-map
         "C-i" nil
         "C-n" nil
         "C-e" nil
         "n"   nil
         "e"  nil)
(map! :map pdf-view-mode-map "C-i" 'org-noter-insert-precise-note
                          "C-n" 'pdf-view-next-page
                          "C-e" 'pdf-view-previous-page
                          "n"   'pdf-view-scroll-up-or-next-page
                          "e"   'pdf-view-scroll-down-or-previous-page)

But it seems to have no effect at all. What am I doing wrong?

Edit: Here's what I have now:

;; Unbind stuff
(map! :after evil-mc-mode :map :n "C-n" nil)
(map! :after better-jumper-mode :map :n "C-i" nil)
(map! :after evil-commands-mode :map :n "C-e" nil)
(map! :after isearch-mode :map :n "n" nil)
(map! :after evil-collection-pdf-mode :map :n "e" nil)

;; Bind stuff
(map! :map pdf-view-mode-map :n "C-i" 'org-noter-insert-precise-note
                             :n "C-n" 'pdf-view-next-page
                             :n "C-e" 'pdf-view-previous-page
                             :n "n"   'pdf-view-scroll-up-or-next-page
                             :n "e"   'pdf-view-scroll-down-or-previous-page)

It still isn't working.

Edit 2:

Here's an illustration of what I'm up against.

  • I run M-x describe-key n to figure out what's currently bound to n. It says n runs the command isearch-repeat-forward, which is an interactive compiled Lisp function in ‘isearch.el’..
  • I read isearch.el, and it says it provides a mode called isearch.
  • Yet isearch-mode doesn't appear to be something I can enable or disable with M-x. And it doesn't seem to be listed in the minor modes given with describe-mode. So this probably has something to do with why :after isearch-mode isn't taking.
  • Bizarrely, describe-mode reports that n is bound to pdf-view-scroll-up-or-next-page, as one would expect. Yet that is not the case, since pressing n still triggers isearch-next-search or something.

4 Answers 4

1

I am afraid I have no idea about doom emacs, but I can tell you how I do it in regular emacs. Maybe you then know what to do in doom emacs. For example, I have set the highlight function to be called when pressing "h" like this:

(with-eval-after-load 'pdf-view 
        (define-key pdf-view-mode-map (kbd "h") 'pdf-annot-add-highlight-markup-annotation) 

Maybe you just have to add ":after pdf-view" and it works, don't know.

1
  • The reason I have to specify that this is Doom-specific is that Doom has its own way of binding and rebinding keys which is rather complex. Defining keys in the usual emacs way doesn't work as expected. (Otherwise, why would Doom even need its own map! function?) Yet for some reason whenever I post a question about Doom specifically, most of the responses I get are "well I don't know about Doom, but in regular emacs..." Which doesn't help at all, in most cases, since the issue I'm having is with Doom, not with regular emacs.
    – Jonathan
    Commented Jan 24, 2022 at 2:49
0

I don't use Doom Emacs but, since it's just an extension of Emacs, working from "first principles" should help.

First, there's the binary of whether map! works or not. It could be broken. It's unlikely, but possible. If you try everything and it still doesn't produce the expected result, I'd check the Doom bug tracker. It's reasonable to assume that map! is behaving correctly, however, since it's pretty core to Doom. You might consider using the native keybind function just for debugging purposes, since that definitely works:

(define-key pdf-view-mode-map (kbd "<f5>") 'pdf-view-next-page)

Perhaps some syntax is incorrect. Check that you're calling map! as Doom intends. Once that's confirmed, there are some other possibilities.

It could be that map! correctly binds to the pdf-view-mode-map and another map takes precedence. Or, maybe the pdf-view-mode-map is simply the wrong map to use. Figure out what mode map the key binding needs to be on. There are several ways this could be done. One is to call C-h m in the buffer a pdf is displayed in. It will show something like:

(Information about these minor modes follows the major mode info.)

<current-mode> defined in ‘current-mode.el’:

If that shows pdf-view-mode-map, then you could see what is bound to the key that should have mapped by using C-h b. This shows all the current key bindings. You can use C-s to search through the result buffer. It will show you what mode the binding comes from. Click on that mode in the Help buffer and it will take you to the documentation for that mode. You can then jump to the source code for the mode. Again, search for something like "mode-map" in the source and you'll see what mode maps the mode uses. Another approach, you could call C-h k while in the pdf buffer to see what is bound to the given key. For example, after calling map!, you would expect C-h k C-n to show pdf-view-next-page.

If that's not showing anything other than pdf-view-mode-map, then I'd do something like this, taken from here:

(defun my-describe-all-keymaps ()
  "Describe all keymaps in currently-defined variables.

See URL `https://emacs.stackexchange.com/a/59507'."
  (interactive)
  (with-output-to-temp-buffer "*keymaps*"
    (let (symbs seen)
      (mapatoms (lambda (s)
                  (when (and (boundp s) (keymapp (symbol-value s)))
                    (push (indirect-variable s) symbs))))
      (dolist (keymap symbs)
        (unless (memq keymap seen)
          (princ (format "* %s\n\n" keymap))
          (princ (substitute-command-keys (format "\\{%s}" keymap)))
          (princ (format "\f\n%s\n\n" (make-string (min 80 (window-width)) ?-)))
          (push keymap seen))))
    (with-current-buffer standard-output ;; temp buffer
      (setq help-xref-stack-item (list #'my-describe-all-keymaps)))))

This is a function someone wrote that lists all variables currently bound to keymaps. Look through there and see if there's something else you could use or that may be conflicting.

If push comes to shove, you could always bind to the global map. That would make the binding work from any buffer. But, if you bound it to something that you don't use anywhere else, then it has the effect you want. At worst it would throw an error saying it doesn't work.

There are other paths the troubleshooting could go but without more information, I can't give you a path forward. I don't use Doom and I don't have pdf rendering enabled in my Emacs build.

Hope that gives you some insight into figuring things out!

2
  • I appreciate the thoughtful reply, but define-key doesn't seem to work as expected, when all of Doom's (and evil's, and friends) keybindings and keybinding mechanisms are at play. This is why I need a specifically Doom-related solution, and have written that in my question title. Similarly, non-Doom keybindings like C-h k C-n don't help me at all, since they don't work like that in Doom.
    – Jonathan
    Commented Jan 24, 2022 at 2:41
  • Well, that's no good. :/ At risk of being pedantic, you can run C-h k C-n from lisp with (describe-key (kbd "C-n")). In vanilla Emacs, you can run eval-expression with M-: which prompts for an elisp expression. Of course, you could run it in a buffer. Not sure how that would work for a pdf buffer, though. Commented Jan 25, 2022 at 21:13
0

Your code:

(map! :after evil
      :map pdf-view-mode-map
         "C-i" nil
         "C-n" nil
         "C-e" nil
         "n"   nil
         "e"  nil)

Unbinds the keys you want from pdf-view-mode-map. But if I understand your situation, you want to set the bindings in pdf-view-mode-map, but remove them from the some other keymap that is taking precedence.

Steps to fix:

  1. Find out what keymap the keys are bound in now. In pdf-view-mode, what command does C-i call? In plain emacs you can find out with C-h k C-i.
  2. The description of the key should include something like: (found in some-mode-map)
  3. Remove the bindings from this mode:
(map! :after some-mode
      :map some-mode-map
         "C-i" nil
         "C-n" nil
         "C-e" nil
         "n"   nil
         "e"  nil)

After you do this, the rest of your code should work:

(map! :map pdf-view-mode-map "C-i" 'org-noter-insert-precise-note
                          "C-n" 'pdf-view-next-page
                          "C-e" 'pdf-view-previous-page
                          "n"   'pdf-view-scroll-up-or-next-page
                          "e"   'pdf-view-scroll-down-or-previous-page)
2
  • When I run describe-key in pdf-mode, I get, e.g., "C-n runs the command evil-mc-make-and-goto-last-cursor, which is an interactive compiled Lisp function in ‘evil-mc-cursor-make.el’." Running (map! :after evil-mc-cursor-make ... doesn't seem to take. Probably because it isn't a mode.
    – Jonathan
    Commented Jan 24, 2022 at 1:55
  • When I turn on evil-mode, I see: C-n runs the command evil-paste-pop-next (found in evil-normal-state-map), which is an interactive compiled Lisp function in ‘evil-common.el’. This suggests (map! :after evil :map evil-normal-state-map ...)
    – Tyler
    Commented Jan 24, 2022 at 14:13
0

I think I've solved this issue for myself. I have no idea how this works; if anyone can tell, I'd love to know.

Try adapting this to your needs:

(add-hook 'pdf-view-mode-hook
          (lambda ()
            (map! :map pdf-view-mode-map
                  :n "C-u" #'pdf-view-scroll-down-or-previous-page
                  :n "C-d" #'pdf-view-scroll-up-or-next-page
                  :n "C-f" #'pdf-view-next-page-command
                  :n "C-b" #'pdf-view-previous-page-command
            )))

The enclosing add-hook seems to be essential for this to work - no idea why though.

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.