hlissner / evil-snipe

2-char searching ala vim-sneak & vim-seek, for evil-mode
MIT License
340 stars 25 forks source link

Configure a quicker repeating like in Clever-F? #21

Closed ReneFroger closed 9 years ago

ReneFroger commented 9 years ago

Thanks for sharing this awesome plugin!

Although your plugin works for me, I would like to have same thing as Clever-F. I wonder if it's possible to emulate same behaviour as in Clever-F?

hlissner commented 9 years ago

You're very welcome!

Also, this exists in evil-snipe already with s and S. Do (evil-snipe-override-mode 1) and you'll be able to repeat with f/F/t/T too (; and , will work as well).

ReneFroger commented 9 years ago

Thanks for your fast response! I couldn't get it working, while evil-snipe-override-mode was enabled. Maybe because it conflicts with my existing keybindings for s in normal mode. I will test it again.

And if I'm understand it right, for example, you have the sentence [cursor here] foo bar example foo bar. Then you press fr, then you will go to the first bar, then press f again, then you get to the second bar?

hlissner commented 9 years ago

By default, evil-snipe disables evil's s/S bindings, so I doubt that's the case.

What version of emacs are you running?

ReneFroger commented 9 years ago

I use Emacs GUI version 24.4.51.1 (x86_64-w64-mingw32), compiled from Harroogan Emacs.

I understand I can repeat it with s and S, but I have the keys s/S reserved for window switching. And the default repeat-key ; is bounded to Helm M-x. So I'm wondering if I could get repeat the latest character with f, after initiating it?

hlissner commented 9 years ago

So I'm wondering if I could get repeat the latest character with f, after initiating it?

With (evil-snipe-override-mode 1), yes.

As for s/S repeating. If you want an alternative to repeating with s/S, look into linktohack/evil-space.

With it you can repeat any search with SPC and S-SPC.

This is how you'd get it to work with evil-snipe (and evil-snipe-override-mode)

(let ((map (evil-get-auxiliary-keymap evil-snipe-override-mode-map 'motion)))
  (evil-space-setup "t" ";" "," map)
  (evil-space-setup "f" ";" "," map)
  (evil-space-setup "T" "," ";" map)
  (evil-space-setup "F" "," ";" map))
(let ((map (evil-get-auxiliary-keymap evil-snipe-mode-map 'motion)))
  (evil-space-setup "s" ";" "," map)
  (evil-space-setup "S" ";" "," map))
ReneFroger commented 9 years ago

Thanks for your reply, but I got an error on your code (evil-snipe-mode enabled). The debugger says the function of evil-space-setup is empty. And you seems to have unbalanced parentheses in your code?

I consider this issue not solved yet, by the way.

hlissner commented 9 years ago

The debugger says the function of evil-space-setup is empty.

This function is from this plugin: linktohack/evil-space -- did you install it?

And you seems to have unbalanced parentheses in your code?

Oh yes, you are correct, there's an extra ) in there, I have now corrected the code in the post above.

ReneFroger commented 9 years ago

Thanks for helping me. I have no idea what your code is exactly doing, but I'm trying to figure it out. I installed evil-snipe and evil-space, and enabled the minor modes with evil-snipe-mode and evil-space-mode. But I ran into another error, the function map is void (thus not be defined). What is your intention with the unknown map?

hlissner commented 9 years ago

Actually, let's put evil-space aside for a moment: I understand you remapped ; and s, but evil-snipe creates a "transient map" after you do a search. What that means is this map temporarily overrides all other keymaps. This transient map contains the s and S repeat bindings, as well as evil-snipe repeat functions on ; and ,.

Right after sniping you should be able to repeat with those keys regardless of any remapping you've done. Does that work?

ReneFroger commented 9 years ago

Thanks for your explaination, it's appreciated.

My question is more about repeating the f, because I have already mapped the sh, sj, sk and sl for window navigation. When I press f, press the character to find, and then trying to repeat with s, as well with ; and ,, but I notice they are not overridden with the snipe keymaps. Instead, I get the default behaviour of my custom keybindings. Any suggestion, in order to debug this behaviour?

hlissner commented 9 years ago

Sorry, I might not have explained properly before. The repeats are triggered by pressing the same key you initiated the search with. e.g. repeat an fsearch with the f and F keys. Or repeat an s search with s and S.

So, to confirm, this doesn't work for you?

; and , should work regardless of which search you used, unless you have evil-snipe-override-evil-repeat-keys set to nil (it is on by default). So the fact that it doesn't is odd. I haven't been able to reproduce this.

You are certain you've done a (evil-snipe-override-mode 1) somewhere?

ReneFroger commented 9 years ago

Sorry for the delay.

Yes. I have (evil-snipe-override-mode 1) enabled.

[]= the cursor.

The sentence: foo bar foo bar foo bar foo bar.

When I press fb in normal mode, then I see the characters b highlighted.

When I press ;, I see the function (evil-snipe-repeat) is being called. So that works fine. But I would like to assign the function (evil-snipe-repeat) to the key f in this case. And return the key f back to normal, if I break my search, like the Vim plugin Clever-F does.

So is there any hook of Snipe, or something, that I could temporilaly assign the key f. And have you tried the Vim plugin Clever-F inside Vim, by the way? Maybe it helps you to understand the behaviour of Clever-F to emulate it in Evil-Snipe.

ReneFroger commented 9 years ago

Any suggestions on this?

hlissner commented 9 years ago

@ReneFroger sorry for the radio silence; I just stepped off an 8 hour flight and am a bit jetlagged.

I would like to assign the function (evil-snipe-repeat) to the key f in this case. And return the key f back to normal, if I break my search, like the Vim plugin Clever-F does.

This is odd. Clever-F functionality is in evil-snipe already. I'm familiar with Clever-F because it's where I got the idea.

But I am starting to suspect the set-transient-map function on emacs 24.4 -- which is what evil-snipe uses to implement Clever-F functionality. It works fine in 24.5 (which is what I use).

Give me a day, then I'll build 24.4 and do some tests.

hlissner commented 9 years ago

So after building 24.4 and testing it, nothing seems amiss. set-transient-map works fine, so I'm not any closer to understanding why it doesn't work for you. Perhaps you have something bound to f? Check the evil-snipe-mode-f-mapvariable to make sure it contains:

(keymap
 (44 . evil-snipe-repeat-reverse)
 (59 . evil-snipe-repeat))

Do (set-transient-map evil-snipe-mode-f-map) to artificially invoke this transient map and then press f. If it invokes evil-snipe-repeat, then something else is interfering with the map (which is odd, because transient maps take precedence over other keymaps). Otherwise, it is definitely an issue with evil snipe.

ReneFroger commented 9 years ago

Sorry for bothering you. After reading your comment, I started Emacs without any configuration, only with Evil and Evil-snipe. And it worked fine, so it's related to my configuration. After dissecting my configuration, and cleaned up, the evil-snipe is working fine now with the f key.

The values of evil-snipe-mode-f-map are now:

(70 . evil-snipe-repeat-reverse)
(102 . evil-snipe-repeat)
(44 . evil-snipe-repeat-reverse)
(59 . evil-snipe-repeat))

The mistake is entirely from my side. Sorry for any inconvience.

You can consider this issue to be closed. If I might ask another question, for example, same sentence: foo bar foo bar foo bar foo bar. When I press fb in normal mode, then I see the characters b highlighted. After breaking my f-operation (like move to another line e.g.), I noticed the b-characters are still highlighted. Is there any way to disable the highlighting when the evil-snipe operation is stopped? Pressing ESC to disable the highlighting didn't help.

hlissner commented 9 years ago

It's no bother, I'm glad we could figure it out!

As for the highlighting issue, that's also odd. It's working for me; evil-snipe already does this, and does it in two ways: a) when you press ESC in Normal mode and b) when you do anything other than press a repeat key after a search. If these two don't work for you, could you do describe-function (C-h f) and search for these things for me:

  1. advice-add — I want to know if this exists or not on emacs 24.4. It should, but I want to be sure.
  2. evil-force-normal-state — tell me what advice has been applied to this function. For example, this is mine:
:around advice: `ad-Advice-evil-force-normal-state'
:before advice: `evil-snipe--pre-command'
:after advice: `evil-search-highlight-persist-remove-all'
ReneFroger commented 9 years ago
  1. Advice-add exists, it's a compiled Lisp function in nadvice.el.
  2. Evil-force-normal-state also exists. An interactive compiled Lisp function in ‘evil-commands.el’

For this case, I upgraded my Emacs from 24.4 to Emacs 25.0.5 snapshot, you can download it from here for Windows 64 bit. Unfortunately, the problem still occur.

I made a clip to illustrate my problem more clear:

evil snipe

After pressing ff, I only press f to go to next f, and I terminate the operation to open a new line with new foo bar. And repeat the process again, the highlighting still stands. I use Emacs 25.0.5 on Windows 7 x64 by the way.

hlissner commented 9 years ago

Odd. I just installed the 25.0.5 snapshot you linked on a windows VM, loaded it up with the only evil and evil-snipe, and highlighting works fine.

You're certain there are no other plugins installed that cause this? Perhaps one that has highlights of its own, like flycheck or flyspell? I see an underline under the first foo and bar, what is causing that?

ReneFroger commented 9 years ago

That's flycheck indeed. In order to be sure that's not related with any package, I tested it with empty Emacs with only Evil and Evil-snipe, and I get the same issue:

evilsnipe

I press here fb then repeat it with f.

On the new line, I press ff then repeat it with f. Then go to back to first character and press fb. Then I terminate my operation, to begin a new line above. In order to reproduce the issue, it's exactly my setup:

Setup:

GUI version GNU Emacs 25.0.50.1 (x86_64-w64-mingw32) of 2015-07-25 on KAEL Evil-snipe, using the latest version of Evil-snipe from MELPA Windows 7 x64 bit.

You can get Emacs 25.0.5 64-bit for Windows from here

Configuration:

Here is the same configruation as I have in the screencast above:

(require 'package)
(package-initialize)

(add-to-list 'package-archives
            '("melpa" . "http://melpa.org/packages/") t)

(setq user-emacs-directory "C:/Dropbox/Emacs/")
(setq default-directory "C:\\Dropbox\\Emacs\\")
(setq custom-file (concat user-emacs-directory "custom-settings.el"))
(add-to-list 'load-path "C:/Dropbox/Emacs/.emacs.d/")

;; Basic requires
(eval-when-compile (require 'cl))
(eval-when-compile (require 'cl-lib))
(require 'use-package)

(use-package evil
:config
(evil-mode 1))

(use-package evil-snipe
    :config
    (evil-snipe-override-mode 1))
hlissner commented 9 years ago

Ah ha! I've found the culprit. It's because you are enabling evil-snipe-override-mode without enabling evil-snipe-mode — they are meant to both be enabled together. Try prepending (evil-snipe-mode 1) to evil-snipe's :config and see if it fixes the problem.

I'll update the README to be more specific about this soon.

ReneFroger commented 9 years ago

Oh, that was quite dumb from me. Maybe to prevent such dumb actions in future, it might be an idea to define inside (evil-snipe-override-mode) to eval if evil-snipe-mode is being active. If not, then enable.

And thanks for the support, after adding (evil-snipe-mode 1), it works like a charm and my issue is solved now. Your help in this case is really appreciated.