Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Examples with evil mode ? #2

Open
aadi58002 opened this issue Jun 26, 2023 · 7 comments
Open

Examples with evil mode ? #2

aadi58002 opened this issue Jun 26, 2023 · 7 comments

Comments

@aadi58002
Copy link

bind really help to organize and view the bindings in a logical way but i am not sure how to set evil mode specific bindings

Like how can i set

  (org-mode-map
            "<RET>" '+org/dwim-at-point
            "?\t" 'org-cycle
            (:prefix "z"
                "i" (cons "inline images" org-toggle-inline-images)))

For just the evil normal state

@repelliuss
Copy link
Owner

Is there a function or a map you would normally bind into for evil mode?

@aadi58002
Copy link
Author

aadi58002 commented Aug 5, 2023

I am not sure here what general does. I used general which handled that for me. I can't see how I can bind a function to two maps like in evil normal state map if the other open map is org mode map then have this key call x function.

@repelliuss
Copy link
Owner

It seems like we can make use of evil-define-key*. One would need to write something similar to bind-undo and bind-save. That function would put evil states to bind metadata, then write a wrapper function for evil-define-key* to transform it to what bind--definer expects and read states through metadata.

I am guessing that this would cover most of the cases but needs a bit of testing but I don't have time for it right now. Nonetheless, it would be good to have someone who is knowledgeable about evil-mode.

@Luis-Henriquez-Perez
Copy link

Hi @repelliuss I'm a big fan of this package. Perhaps you won't believe it but every time I went down your show-don't-tell section I was wowed--not just because of the impressiveness of the macro but also because it was as if you read my mind. Your macro is essentially the embodiment of almost all I wanted. Anyways I digress.

I use evil too and I tried to write the code you described. Lmk what you think.

;; 1. Write something similar to =bind-undo= and =bind-save=
;; This function would put evil states to bind metadata.
(defmacro evil-bind! (state &rest forms)
  "Undo (or unbind) `bind' FORM keys."
  `(let ((bind--definer #'+bind--evil-definer))
     (bind-with-metadata (:engine 'evil-bind :state ,state)
       (bind ,@forms))))

;; 2. write a wrapper function for evil-define-key* to
;; transform it to what bind--definer expects and read states through metadata.
(defun +bind--evil-definer (keymap key def)
  (-when-let (state (plist-get bind--metadata :state))
    ;; (message "%s->%s %s" state key def)
    (evil-define-key* state keymap key def)))

While writing this I realized it's probably even better to wrap the call to evil-define-key* around eval-after-load evil. @aadi58002 this would be a more accurate implementation of what general does.

(defun +bind--evil-definer (keymap key def)
  (-when-let (state (plist-get bind--metadata :state))
    ;; (message "%s->%s %s" state key def)
    (with-eval-after-load 'evil
      (evil-define-key* state keymap key def))))

@Luis-Henriquez-Perez
Copy link

Also I wonder whether it is possible to make a processing function for this. This may be even more desirable because it would allow you to be able to bind to different states in one binding form. But I'm not sure whether you can apply different values of bind metadata for different bindings.

;; Processing function that does not actually modify bindings. Instead it adds
;; the `state' to `bind--metadata' for those bindings.
(defun bind-state (states &rest bindings)...)

;; This would be nice.
(bind org-mode-map
      (:states '(normal insert) ;; bind--metadata would contain `:states '(normal insert) only for these bindings
       "i" #'foo
       "g" #'bar)
      (:states '(emacs)
       "t" #'lap
       "v" #'lop))

Then you could have a more generalized definer.

(defun +bind--definer (keymap key def)
  (cond ((plist-get bind--metadata :state)
	 (with-eval-after-load 'evil
	   (evil-define-key* state keymap key def)))
	(t
	 (define-key state keymap key def))))

@repelliuss
Copy link
Owner

Hi, @Luis-Henriquez-Perez . Thank you for your kind words, I really appreciate it.

The functionality you described with processing function would be a perfect match for bind. Though, only thing propagates upwards is bindings. bind--metadata are used to propagate data downwards. Fortunately this is not something impossible but needs a bit of change to base code. Basically we need to change the definiton of definer which should accept a contextual data. I will do so when I have free time.

Other than this, it is certainly one way to implement evil-bind! like that

@Luis-Henriquez-Perez
Copy link

Thank you for your kind words, I really appreciate it.

I spoke the truth.

Basically we need to change the definiton of definer which should accept a contextual data.

I'll also try to take a stab at it soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants