Kungsgeten / ryo-modal

Roll your own modal mode
MIT License
222 stars 14 forks source link

major-mode-keys not always working #22

Open thorstengrothe opened 6 years ago

thorstengrothe commented 6 years ago

I'm using ryo with auctex and have a small issue with my major mode key setting, see here:

(ryo-modal-major-mode-keys
   'latex-mode
   ("q" LaTeX-fill-environment)
   ("E" LaTeX-close-environment)
   )

LaTeX-fill-environment is working fine but LaTeX-close-environment not. I got an error message

Error (use-package): ryo-modal/:config: ‘LaTeX-close-environment’ isn’t a function

Auctex is loaded by use-package like so:

(use-package tex
  :ensure auctex
  :mode ("\\.tex\\'" . latex-mode)

BTW it's the same with LaTeX-fill-region, only LaTeX-fill-environment is working... What can I do to fix this?

Regards Thorsten

Kungsgeten commented 6 years ago

I think the problem is that tex is lazy loaded, so that the functions you describe isn't available until you use tex. This is because of the mode: clause in your use-package declaration. You could add :demand t to fix this.

Another alternative is to not add the keys until latex is loaded:

(with-eval-after-load 'latex
  (ryo-modal-major-mode-keys
   'latex-mode
   ("q" LaTeX-fill-environment)
   ("E" LaTeX-close-environment)))

I think that should work.

Kungsgeten commented 6 years ago

Another way could be (I haven't tried it) to use the ryo: keyword in use-package:

(use-package tex
  :ensure auctex
  :mode ("\\.tex\\'" . latex-mode)
  :ryo
  (:mode 'latex-mode)
  ("q" LaTeX-fill-environment)
  ("E" LaTeX-close-environment))
thorstengrothe commented 6 years ago

The first suggestion works fine, the second with use-package fails with an error:

Failed to parse package tex: use-package: Unrecognized keyword: :ryo

I can live with the first solution but I'm wondering why the :ryo keyword with use-package is not working..

Thanks for the fast help!

Thorsten

Kungsgeten commented 6 years ago

I'm not quite sure, since I haven't written the use-package integration feature myself. My guess is that you're using use-package with the ryo: keyword before you've loaded ryo. This could be because you are lazy loading ryo, or because ryo comes later in your init-file.

Perhaps @hgersen have suggestions on what to do?

thorstengrothe commented 6 years ago

Yes indeed, in my config ryo is loaded very late and all other packages are lazy loaded before with use-package. I did that because ryo complains about undefined functions if the packages, take avy here, are not loaded before ryo. That's a small dilemma here. If I load ryo early the :ryo keyword is working but I got a lot of not defined funcs, if I load it at the end of my config the funcs are defined but the ryo keyword is not working. I don't really know a way out of this.

Kungsgeten commented 6 years ago

I've experienced these problems to. I'm not sure what's the best approach.

Perhaps you could load ryo early, and put the bindings dependant on other packages in a with-eval-after-load (if you don't want to use the ryo: keyword in use-package for all those commands)? Another way, which might save you some trouble, could be to load ryo early, then use the ryo: keyword throughout the config (where you see fit), and at the end then load all your default ryo bindings. Something like this (example):

;; Demands ryo-modal early, so the ryo: use-package keyword works
(use-package ryo-modal :ensure t :demand t)

;; Example of keywords in use-package
(use-package avy
  :ryo
  ("f" avy-goto-word-1))

;; Example of instead doing it without the ryo keyword (probably makes more
;; sense for major-mode specific packages, like tex below).
(use-package tex
  :ensure auctex
  :mode ("\\.tex\\'" . latex-mode)
  :config
  (ryo-modal-major-mode-keys
   'latex-mode
   ("q" LaTeX-fill-environment)
   ("E" LaTeX-close-environment)))

;; End of config, add the rest of your ryo stuff
(bind-key "C-c SPC" 'ryo-modal-mode)

(ryo-modal-keys
 (:norepeat t)
 ("0" "M-0")
 ("1" "M-1")
 ("2" "M-2")
 ("3" "M-3")
 ("4" "M-4")
 ("5" "M-5")
 ("6" "M-6")
 ("7" "M-7")
 ("8" "M-8")
 ("9" "M-9")
 ("p" counsel-projectile)               ; Example if you do not defer this
                                        ; package, and therefore can use it
                                        ; right away at the end of the config
 )

;; etc...
hgersen commented 6 years ago

Sorry for the slow response as I was very busy with work.

When I was using :ryo to bind keys I indeed used the demand t option for ryo-modal to be able to use the :ryo keyword and it needs to come before the :ryo keyword would be used. I don't see a way around that as otherwise use-package doesn't know that the :ryo keyword exists!

Note that even when using :ryo it is important to keep the notes on lazy loading in the use-package readme in mind as it is not a case of just adding defer t. Use-package will still need to have enough info to know what commands/functions need to be auto-loaded, through things like :command, :mode, :hook.

Unfortunately I have personally stopped using the :ryo keyword as I went back to using :bind, :hook, etc from use-package directly. Although it worked when I used it, the key reason to do this was to have one less layer of confusion/error to deal with. My personal config has bits where :bind should work, but it doesn't for example.

btw) from the description of the problem I find it very hard to see what is going wrong. It might be worth posting a very minimal example to illustrate the problem better?

btw2) If your problem is to get latex working. I think you should be using

use-package latex
:ensure auctex
...etc

so not tex!

edit) Now I look in a bit more detail at the examples....maybe you should be using :hook instead of :mode? My current config is still work in progress, but the example for flyspell below is what I do.

(use-package flyspell
  :straight t
  :bind
  (:map flyspell-mode-map
        ("C-;" . flyspell-correct-previous-word-generic))
  :hook ((text-mode . flyspell-mode)
         (org-mode . flyspell-mode))
  :config
  (setq ispell-program-name "hunspell"
        ispell-really-hunspell t
        ispell-dictionary "en_GB"))
thorstengrothe commented 6 years ago

Thanks both of you for your detailed answers. I fiddled a bit in my config and decided keep it like it is. ryo-modal with it's keybinds is loaded at the end. I find it very convenient to have keybinds at one place. So I do not use :ryo keyword at all. I can live with that as I said.

@hgersen yes I changed from tex to latex and most of it works now but not everything, see here:

(with-eval-after-load 'latex
    (ryo-modal-major-mode-keys
     'latex-mode
     ("q q" LaTeX-fill-environment) --> works
     ("h e" TeX-fold-env) --> fails
     ))

I guess that has something to do with a special auctex minor mode, but I don't know. I solved it with a custom hydra for folding, that worked!

In general I think, ryo-modal is a bit sensitive in relation to the load order of packages. I don't know if evil or boon-mode do not have this problem...

Kungsgeten commented 6 years ago

Perhaps you could try with-eval-after-load 'auctex instead? At least if you always run auctex when eding LaTeX files.

hgersen commented 6 years ago

Seeing this example I would personally check the one that fails with a different keybinding as I have been bitten by that one before. Things tend to fail in obscure ways if you reuse a binding by accident....and h e or h on its own might already exist in latex-mode.

btw) My understanding is that using :hook would have the same effect as doing eval-after-load, but cleaner.

thorstengrothe commented 6 years ago

Ok, after some fiddeling with use-package I got the following configured

(use-package ryo-modal
  ...
  :hook
  (LaTeX-mode . my/ryo-modal-latex-keybinds)
  :config
  ;; keybinds for major modes
  (defun my/ryo-modal-latex-keybinds ()
    "Ryo modal keybinds for latex mode"
    (ryo-modal-major-mode-keys
     'latex-mode
     ("m e" LaTeX-mark-environment :name "latex mark env")
     ("q q" LaTeX-fill-environment)
     ("q p" LaTeX-fill-paragraph)
    ...
    ))

This works fine without eval-after-load but not for TeX-fold-env I have no clue why. It has nothing to do with reused keybinds, I checked that...

But not problem, I works with a personal hydra, so for me the problem is solved.

Thanks for the detailed explanations...

Thorsten

ksafford commented 2 years ago

This is quite late, but seeing that this issue is still 'open' I thought I'd add my experience.

Facing a similar issue with a different package, adding that package to the :after keyword as such:

(use-package ryo-modal
  :defer t
  :after frog-jump-buffer
  :config
  (all my configs here))

resolved the errors.