reddit / emacs

How to combine evil operator keys + isearch?

franticnerd · 2022-09-09 06:55
I love both evil and isearch. However, I have a hard time combining evil operator keys (e.g., d c y) with isearch. ​ When I call isearch in the evil operator state, the operator states quits before isearch activates -- the cursor point is indeed jumped, but the operation is NOT completed. For example, when I pressed "d c-s abc", the operator state quits first, and then the cursor moves to "abc". The content between my old point (before the search) and "abc" is not deleted. (I don't encounter this issue when I combine the v key for visual selection with isearch) ​ Does any one have any idea how to fix this issue? ​ P.s., if it matters, I am on emacs 28 + doom.
tonicinhibition · 2022-09-09 08:45
I installed a package called [avy](https://github.com/abo-abo/avy) which [can do anything](https://karthinks.com/software/avy-can-do-anything/) I have no issues whatsoever. If you're interested here is my very simple config. There are several options, I like the one with the timer. (use-package avy :after evil :bind ("C-s" . 'avy-goto-char-timer)) Additionally, I'm wondering if your situation is complicated by a similar customization or replacement of isearch. I say this because I really don't think the evil operator state quits. If I type `d`, I should be able to go make my coffee before I hit the next key in the sequence. If there's a timer being invoked during your search query, you may need to complete the search by selecting with `ENTER` or a hotkey. This is the case with avy. If your needs are simple, you might just get away with using slash (`/`) as your search forward. This is what I use in nearly all circumstances. Example: `d` `/` `any-text` `ENTER` Do you have a more nuanced use-case?
franticnerd · 2022-09-09 09:22
Thanks for your comment! I'm a heavy avy user too. While I love avy, avy and isearch serve for different purposes in my use cases: avy is good at longer range jump, but isearch excels at short range jump. For evil search /, it indeed works with operator keys. However, isearch just feels snappier and faster in my experience and is thus more preferable to me. If I cannot find a way to make isearch work with evil operator keys, I guess I will just settle with using evil search in such use cases.
organic-bookworm · 2022-09-09 09:53
You should use `'isearch` [`evil-search-module`](https://evil.readthedocs.io/en/latest/settings.html?highlight=isearch#elispobj-evil-search-module). This will remap search commands to Evil's isearch wrappers. If you wanna use `C-s` specifically, you'll have to bind it to `evil-search-forward` (see `evil-select-search-module` function). I remember there were some issues, like match (`g n`/`g N`) text objects not working with this module.
franticnerd · 2022-09-09 10:44
Sound good, will try it out! Thanks very much! ​ Update: I confirm that evil-search-forward works seamlessly with operator keys, thanks again!
redguardtoo · 2022-09-09 11:00
evil operator works on text object, so you need define your own object. Say the text object's shortcut is `s`, then you can `dis` or `vis` or `das`, `vas` to opertate on the text object. Text object is basically a function to return a range, it can use `isearch-forward` or `swiper` to calculate the range. Here is complete code, (defvar my-evil-search-forward-function #'isearch-forward "Search forward function.") (defun my-evil-search-range (count beg end type inclusive) "Get minimum range of search text object. COUNT, BEG, END, TYPE is used. If INCLUSIVE is t, the text object is inclusive." (let ((start (point)) (end (funcall my-evil-search-forward-function))) (evil-range start (- end (if inclusive 0 (length isearch-string))) type :expanded t))) (evil-define-text-object my-evil-a-search (count &optional beg end type) "Select a paren." :extend-selection t (my-evil-search-range count beg end type t)) (evil-define-text-object my-evil-inner-search (count &optional beg end type) "Select 'inner' paren." :extend-selection nil (my-evil-search-range count beg end type nil)) (define-key evil-inner-text-objects-map "s" #'my-evil-inner-search) (define-key evil-outer-text-objects-map "s" #'my-evil-a-search) You can replace `isearch-forward` with `swiper` ([https://github.com/abo-abo/swiper](https://github.com/abo-abo/swiper)). I'm not sure if any 3rd party packages could do the same thing out of box. Even such packages do exist, my code is still a good example to study evil api.