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

consult-line should jump to the position of the match on the line #26

Closed
minad opened this issue Dec 2, 2020 · 33 comments
Closed

consult-line should jump to the position of the match on the line #26

minad opened this issue Dec 2, 2020 · 33 comments
Labels
feature New feature or request

Comments

@minad
Copy link
Owner

minad commented Dec 2, 2020

related #7

@minad minad added feature New feature or request consult-line labels Dec 2, 2020
@oantolin
Copy link
Contributor

oantolin commented Dec 8, 2020

I don't know a good generic way to figure out where a completion style found a match. Since completion-styles can basically do whatever they want, and are, for example, under no obligation to actually match anything, this is probably impossible to do in general.

@minad
Copy link
Owner Author

minad commented Dec 8, 2020

I had hoped for you chiming in. I have no idea how these matching styles work, so if you could describe it a bit or point me to some resources it would be good. But for now this is very low priority, maybe let's have this discussion at some other point.

There is also the idea of having something like consult-match which should behave like counsel-isearch and starts generating the candidates base on the matches etc. But this depends on me figuring out how all the dynamic candidates work and it probably also depends on the matching style as in this issue.

@irigone
Copy link

irigone commented Dec 13, 2020

More than that, it also has to move to the end of the position on the line. It's the default behavior for isearch (which I use currenly for moving in my file. Nothing but isearch does that) and swiper (which I didn't use, but I watched the 10 minute example video and it goes to the end of the candidate indeed), and I believe that it's the behavior that most people would expect. I really wish I could use avy or ctrlf or consult-line, but to me they're unusable when they work like that.
Isearch also goes to the beginning of the candidate if you press C-r (I find it very useful for keyboard macros), but that's probably not possible with swiper and consult-line.
For more argumentation, see abo-abo/avy#316

@minad
Copy link
Owner Author

minad commented Dec 13, 2020

@veronikazaglotova Right now consult-line jumps to the beginning of the line. You want to have it jump to the end of the line or the end of the match? But as of now it looks unlikely we can implement the feature in a generic way, since it depends on the completion style being used and these completion-styles can do whatever they want as @oantolin said. Therefore we will probably keep the behavior of jumping to the beginning of the line.

EDIT: What we could do - offer an option which allows to configure if we either want to jump to the beginning or the end of the line. But that's all we can do as of now.

@irigone
Copy link

irigone commented Dec 13, 2020

@minad I want neither. I want it to go after the match. If I have the following:

(use-pakcage something

and want to fix the typo, I want to search for "use-pak", then RET. After that cursor moves to letter "c". I type C-t, and it fixes the typo.

Here's how it looks like when using isearch: https://streamable.com/rsjldc

@minad
Copy link
Owner Author

minad commented Dec 13, 2020

@veronikazaglotova As I said, it is technically not possible as of now. But for such local jumps I rather recommend avy. I use consult-line differently, e.g., if I want to edit something in the context of multiple occurrences of some string, not for local jumps.

@irigone
Copy link

irigone commented Dec 13, 2020

it is technically not possible as of now.

I don't know ELisp and didn't really understand what you were talking about in this thread, if that's a dumb question just ignore it
Can you get the text written in the minibuffer (e.g. text that the user typed) in some way? I think it's what M-x isearch-occur does. There's no completion for it and it does that right after you run the command, so that might not be the case for consult.

I rather recommend avy

Avy has the same issue. It's just incredibly confusing to use.

@minad
Copy link
Owner Author

minad commented Dec 13, 2020

Can you get the text written in the minibuffer (e.g. text that the user typed) in some way? I think it's what M-x isearch-occur does. There's no completion for it and it does that right after you run the command, so that might not be the case for consult.

Yes, that is possible. But the problem is that it is not clear what the text in the minibuffer means. It could be a regular expression, plain text, flex matching string, depending on the completion-style. Therefore it is hard to implement a general solution here.

@oantolin
Copy link
Contributor

oantolin commented Dec 13, 2020

Let me give a concrete example, @veronikazaglotova, illustrating that this is not just a programming problem, you also have to decide where you want the cursor and it is a complicated question!

I use a completion style called orderless that lets you match several patterns in any order. If I type bar baz at the consult-line prompt, it will match any lines that contain the substring bar and also contain the substring baz, in either order. Where should the cursor be placed? After baz? After whichever of baz and bar comes last in the line? It gets trickier to decide when each each substring occurs more than once in the line: do I consider the first occurrence?, the last?, of the first occurences of both words, whichever comes second?

To further complicate matters I use orderless with a very non-standard configuration. In my setup, if I use consult-line and type the input string {baz}, it will match lines that contain the three letters a, b and z in any order, anywhere in the line. So same tricky question of where I want the cursor.

As another example, again in my personal setup, if I type !baz at the consult-line prompt, it matches lines that do not contain the substring baz. Where should the cursor be left in this case?

And, of course, there is also the programming problem: even if I manage to figure out where I want the cursor, how would consult know? The consult package doesn't have an easy way of knowing what {baz} or !baz mean in my personal configuration, and thus it was no easy way to figure out where to leave the cursor.

@minad
Copy link
Owner Author

minad commented Dec 13, 2020

@oantolin The question is if we could somehow hook a function into consult which tells it how the match looks. Orderless could provide such a function and we could write similar functions for the default matching styles?

@oantolin
Copy link
Contributor

oantolin commented Dec 13, 2020

Well, as usual selectrum throws its non-standard wrench into the mix, but ignoring selectrum, here's an idea that might work for all completion-styles:

  • consult-line stashes the actual minibuffer input somewhere (we need to save it, since by the time `consut--goto runs the minibuffer input is gone).

  • to figure out "where the match ends", given the full line and the minibuffer input you do this: starting with the full line, chop off one character at a time and ask completion-all-completions if the minibuffer input still matches in the singleton collection consisting of just the truncated line. The first time the answer is no, you chopped off one character too many, and that last character chopped off is "where the match ends".

@oantolin
Copy link
Contributor

Oh, that same method works for selectrum too, right? It has a function to filter the candidates, which we can use to test which truncations of the line match.

@irigone
Copy link

irigone commented Dec 13, 2020

What I understand now is that my use case is pretty basic. I'll just make my wrapper function for consult-line for now.
@ me when you figure it out please
Sorry if this sounded rude, English isn't my first language

minad added a commit that referenced this issue Dec 20, 2020
@minad
Copy link
Owner Author

minad commented Dec 20, 2020

I implemented @oantolin's algorithm. consult-line jumps to the beginning of the match during preview and for the final jump. Please test!

@minad minad closed this as completed Dec 20, 2020
@irigone
Copy link

irigone commented Dec 21, 2020

Consult-line jumps to the end of the line currently. Is this right? I did it and then ran M-x straight-pull-all.

(use-package consult-selectrum
  :straight (consult-selectrum :type git :host github :repo "minad/consult" :branch "main")
  :bind
  ("C-x b" . consult-buffer)
  ("M-y" . consult-yank-pop)
  ("C-," . consult-line))

@irigone
Copy link

irigone commented Dec 21, 2020

I mean, I use consult-line as a simple fuzzy search, no regex or anything. Is this how it should work?
https://user-images.githubusercontent.com/52463107/102770642-acf46380-43ae-11eb-8be0-01a36a98c4b8.mp4

@minad
Copy link
Owner Author

minad commented Dec 21, 2020

I cannot reproduce this. In my case it jumps to the beginning of the match. If I type git, the cursor is at the beginning of the word git.

@oantolin
Copy link
Contributor

Doesn't Selectrum out of the box not use completion styles? Maybe that's what @veronikazaglotova is using. In that case, completion-styles is probably at its default value, which is something like basic and partial-completion. I think, in that case, the whole line should not match and point should wind up at the beginning, so I'm confused by the video where it winds up at the end.

At any rate, I'm guessing this doesn't work for Selectrum users that sidestep completion-styles by sticking with the default or by using prescient. (and my information about Selectrum might be outdated again, is it still true that using Selectrum either out of the box or with prescient, keeps your completion-styles at the default value?).

@oantolin
Copy link
Contributor

Also, doesn't isearch leave you at the end of the match? I thought that's the behavior you wanted to imitate.

@irigone
Copy link

irigone commented Dec 21, 2020

At any rate, I'm guessing this doesn't work for Selectrum users that sidestep completion-styles by sticking with the default or by using prescient. (and my information about Selectrum might be outdated again, is it still true that using Selectrum either out of the box or with prescient, keeps your completion-styles at the default value?).

Yes I use selectrum. That's sad. I still didn't write my own wrapper for consult-line, only avy.

doesn't isearch leave you at the end of the match

Yes. isearch also goes to the beginning of the match if you type C-r (or M-x isearch-backward) which I find useful for scripting, next C-r searches backwards. I wish I could have that with ctrlf. I love macros! Imma write my own macro package for Emacs.

I thought that's the behavior you wanted to imitate

AFAIK consult tries to imitate swiper.
But yeah, swiper ends at the end of the match too.

@minad
Copy link
Owner Author

minad commented Dec 27, 2020

AFAIK consult tries to imitate swiper.
But yeah, swiper ends at the end of the match too.

No, it jumps to the beginning of the match.

@irigone
Copy link

irigone commented Dec 27, 2020

@minad I didn't use swiper, but I saw the demo for it which is linked in the project's readme: https://www.youtube.com/watch?v=VvnJQpTFVDc
At 5:05, he presses RET and it goes to the end of the match. I don't know if it's the default, but I wouldn't be surpised if it were.

@irigone
Copy link

irigone commented Dec 27, 2020

By default, swiper goes to the end of the match, but you can customize it
https://github.com/abo-abo/swiper/blob/d2891aab7b816aebf21ebd01ce33933a6ac6244f/swiper.el#L130

@oantolin
Copy link
Contributor

That makes sense, the default is to match the default for isearch.

@minad
Copy link
Owner Author

minad commented Dec 27, 2020

@veronikazaglotova @oantolin We could make it also customizable in consult, it is no problem. Please create a PR if you are interested in having this configurable.

@oantolin
Copy link
Contributor

oantolin commented Dec 27, 2020

Wait, what I said is slightly wrong isn't it? The default for isearch is not to always leave the cursor at the end of the match. Isn't the default to leave the cursor at the end if you are searching forward and to leave it at the beginning if you are searching backwards? [I just checked my init.el and apparently I customize isearch to always exit at the beginning (and bind S-RET to exit at the end). I did this so long ago I forgot exactly what the tricky direction-switching default behavior is.]

@oantolin
Copy link
Contributor

Since consult-line is sort of "global", and isn't really about moving forwards or backwards through the matches, I don't think isearch actual default behavior which depends on the direction would be appropriate for consult-line. Probably something like swiper were you can configure for the start of the match or for the end, would be more appropriate.

@irigone
Copy link

irigone commented Dec 27, 2020

The default for isearch is not to always leave the cursor at the end of the match. Isn't the default to leave the cursor at the end if you are searching forward and to leave it at the beginning if you are searching backwards

C-s goes to the end of the match. C-r goes to the beginning of the match.

When you are searching forward, first C-r goes to the beginning of the match, second starts isearch-backwards. And vice versa
isearch actual default behavior which depends on the direction would be appropriate for consult-line

I agree, it would be pretty dumb.

@minad
Copy link
Owner Author

minad commented Dec 27, 2020

Wait, what I said is slightly wrong isn't it? The default for isearch is not to always leave the cursor at the end of the match. Isn't the default to leave the cursor at the end if you are searching forward and to leave it at the beginning if you are searching backwards?

Yes, this is the natural thing which comes out if you implement this.

Since consult-line is sort of "global", and isn't really about moving forwards or backwards through the matches, I don't think isearch actual default behavior which depends on the direction would be appropriate for consult-line. Probably something like swiper were you can configure for the start of the match or for the end, would be more appropriate.

For consult-line it would make sense to have two things configurable - do you want to jump to the first/last match and do you want to jump to the beginning/end of the match. One could also fix the combinations last/end, beginning/first, which are the natural combinations due to the algorithm, depending on where you start the search, beginning or end.

@oantolin
Copy link
Contributor

Since the match is chosen via completion, "first match" sounds much more natural than "last match" to me: the first match is the one the completion system normally picks. I think having beginning/end of match configurable is probably enough.

@oantolin
Copy link
Contributor

I hadn't noticed the searching in steps of 16, 8, 4, 2, 1. Very nice, @minad!

@minad
Copy link
Owner Author

minad commented Dec 27, 2020

@oantolin It was slow without this speedup. Another alternative I tried was to pass a list of substrings of various length to completing-read and then advance depending on the length of the resulting filtered list. But it seemed more complex without benefits.

@oantolin
Copy link
Contributor

Just so it gets mentioned here in the relevant issue: there is now a customizable variable consult-line-point-placement with possible values line-beginning, match-beginning and match-end. The default value is match-beginning.

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

No branches or pull requests

3 participants