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

Add Option to Use Jump Characters #25

Closed
noctuid opened this issue Aug 22, 2015 · 15 comments
Closed

Add Option to Use Jump Characters #25

noctuid opened this issue Aug 22, 2015 · 15 comments

Comments

@noctuid
Copy link
Contributor

noctuid commented Aug 22, 2015

I think it would be awesome if evil-snipe had jump characters like sneak's streak mode (or like avy, easymotion, etc.). This is the one thing I'm really missing from sneak. For example, if there are more than 2 matches, the start of each match is highlighted with a home row key (or from user defined keys), and pressing that key moves the point directly to the match. If there are more matches then defined keys, each match is highlighted with multiple letters/keys.

@hlissner
Copy link
Owner

Is there a reason you can't use avy together with snipe? This is exactly what avy offers (it even has a 2-char search). I use snipe for short range jumps and avy for long range ones.

@noctuid
Copy link
Contributor Author

noctuid commented Aug 23, 2015

I don't see any downside in combining the functionality of the two. With vim, I use sneak for all visible range jumps; there is no need to have two keys bound. Avy's 2-char search is lacking features of evil-snipe. For example, it is not interactive and isn't integrated with evil (motions and the ability to cycle with same key) .

@hlissner
Copy link
Owner

Fair point, I agree. I'll look into it.

@PythonNut
Copy link

@angelic-sedition you might want to look into evil-easymotion, specifically integrating with evil-snipe. :-)

@hlissner
Copy link
Owner

@PythonNut that looks interesting! I'll give it a try myself.

@noctuid
Copy link
Contributor Author

noctuid commented Aug 30, 2015

@PythonNut I wasn't familiar with your plugin; thank you for mentioning it. I was able to briefly test this, and I think it's pretty much what I want. I did notice that doing it this way, it won't automatically jump to the first match like sneak does (though I think I might prefer this behaviour if it isn't the case when there is only one match). Also, it's very slow when using after d or c (you can see the highlights appearing from bottom to top for maybe a second). Unlike avy, if multiple keypresses are needed, they don't show up all at the beginning; is it possible to change this behaviour?

Unfortunately, avy keeps giving me errors that it fails to autoload suddenly. Anyway, I think having evil-easymotion able to integrate with various motions is a great idea.

@noctuid noctuid closed this as completed Aug 30, 2015
@PythonNut
Copy link

@noctuid would you be so kind as to post each of your problems in a separate issue on my issue tracker? :)

I'll admit, I don't know why composing the motions with operators is slow.
I'm not entirely sure what you mean by the multiple keypresses.

@sooheon
Copy link
Contributor

sooheon commented Apr 10, 2016

Does @noctuid or the maintainer mind reopening this? I think there is still something to be explored here.

Take ivy-avy for example: You do a regular search with swiper and when you have n candidates, you can call ivy-avy to add avy targetable letter overlays to each candidate. To have functionality like this, I think we need a function snipe-avy which will take a list of all currently highlighted snipe targets in buffer, and add avy overlays to them. Then we can simply bind this to a key in snipe transient map (maybe C-; to build on ;). This is different from easymotion because you don't need to take on the overhead of typing the target letters every time--it's there if while sniping you decide you need them. There is also no upfront choice about "should I snipe or easymotion?" when you start your movement. It should always be snipe, and if after sniping you find there are too many candidates, avy can step in and take you to a specific one.

@hlissner
Copy link
Owner

Sure. Having integrated easymotion into my workflow, I've found myself thinking the same. When I fix #35, I'll make it easier for users to bind keys to the transient maps. Then, you'll be able to do something like this to integrate easymotion into evil-snipe:

(define-key evil-snipe-parent-transient-map "\C-;" 
  (evilem-define "gs" 'evil-snipe-repeat
      :pre-hook (save-excursion (call-interactively #'evil-snipe-s))
      :bind ((evil-snipe-scope 'buffer)
             (evil-snipe-enable-highlight)
             (evil-snipe-enable-incremental-highlight))))

A little messy, but it works.

Alternatively, directly integrating avy is an option, but I don't know anything about avy under the hood. I'll look into it.

@hlissner hlissner reopened this Apr 10, 2016
@PythonNut
Copy link

@sooheon although the transient map is out of my control, do note that the :pre-hook is optional.

You should be able to do something like this to repeat without first prompting for characters to search:

(evilem-define "gs" 'evil-snipe-repeat
               :bind ((evil-snipe-scope 'buffer)
                      (evil-snipe-enable-highlight)
                      (evil-snipe-enable-incremental-highlight)))

@hlissner also, if you want to bind an easymotion to a map without also binding it in normal/motion state, you can use evilem-create:

(define-key evil-snipe-parent-transient-map "\C-;" 
  (evilem-create 'evil-snipe-repeat
                 :pre-hook (save-excursion (call-interactively #'evil-snipe-s))
                 :bind ((evil-snipe-scope 'buffer)
                        (evil-snipe-enable-highlight)
                        (evil-snipe-enable-incremental-highlight))))

@hlissner
Copy link
Owner

@PythonNut perfect! Thanks! I removed the pre-hook so it doesn't prompt on repeats:

(define-key evil-snipe-parent-transient-map (kbd "C-;")
  (evilem-create 'evil-snipe-repeat
                 :bind ((evil-snipe-scope 'buffer)
                        (evil-snipe-enable-highlight)
                        (evil-snipe-enable-incremental-highlight))))

@sooheon evil-snipe-parent-transient-map was just pushed in ddba4fc — this should work now.

@sooheon
Copy link
Contributor

sooheon commented Apr 10, 2016

I've tried out your snippet, and it looks like it has 90% of the functionality. The only thing is that there's no reason for the avy targets to only be applied to the initial direction of the search. I think the limitation is that evilem takes a motion, and the evil motions just happen to be directional. Would there be value in having a special function defined just so that all candidates in a buffer could be targets?

@PythonNut
Copy link

@sooheon you can also pass multiple functions to evilem-create and co.:

(define-key evil-snipe-parent-transient-map (kbd "C-;")
  (evilem-create (list 'evil-snipe-repeat
                       'evil-snipe-repeat-reverse)
                 :bind ((evil-snipe-scope 'buffer)
                        (evil-snipe-enable-highlight)
                        (evil-snipe-enable-incremental-highlight))))

@sooheon
Copy link
Contributor

sooheon commented Apr 10, 2016

Ah I should have rtfm :) Thanks, this looks great. And if you let evil-snipe take over f/t bindings, this gives the easy motion functionality to those as well for free.

@hlissner
Copy link
Owner

Great! Thanks for the help @PythonNut

That wraps this up.

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

4 participants