-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
feat: nextMatchFromCursor, PrevSearchMatchFromCursor #5151
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
Conversation
|
I'm not sure a separate keybinding is the best solution for this. I could imagine always searching from the cursor downwards, for those views that have a selection. If you only press I'm a little less sure what to do about views that don't have a selection (e.g. the focused main view), but I think the behavior would be desirable there, as well. If you press |
This sounds the same behavior as the new navigation in this pr, which is also Vim's default, also Emacs... don't seem allow cursor move without abort in once isearch.
Didn't consider it before, scroll only but not move selection? |
|
push a new change to use bisect to get the nearest prev/next. Test on linux repo, no noticable perfmance change. If you like I can replace next/prev with this. I add a new key bind cause I'm also not sure if someone would prefer to old way. |
|
Yes, I'm reasonably sure that the new behavior is better, and that we don't need to make it configurable. I'm wondering if it is better to update the "match x of y" status right away when changing the selection (including highlighting the new current match), I feel that this makes it more predictable. I made a draft PR trying this out: #5169. In general I like the behavior; there are just a few edge cases that are a bit weird, e.g. typing
No, that's not what I meant. If you only scroll with the mouse wheel but don't move the selection, nothing should change; this is consistent with e.g. scrolling the selection out of view and then pressing down, which moves to the next line from where it was, and makes it visible again. No, I was talking about views that don't have a selection at all, like the diff view of a commit (which you can search in by pressing |
right, this pr don't work in that case. Tested #5169, it's different because currently if you update immediately, you have to update to previous entry to ensure vim/nvim by default won't live update the match messsage on cursor move. With a plugin (https://github.com/kevinhwang91/nvim-hlslens) use another way to display: normally it show |
I added a commit that fixes these: 65c06fa. I think the jumping behavior is now the same as in your PR, but it still selects the nearest search result as you move the selection, which I guess is the best of both worlds.
I feel that's overkill. I also added two more commits that fixes existing bugs (bf2780b and fc19fb7), and then I added a commit (b7f0f85) that tries to select visible search results as you scroll a view that doesn't have a selection. As soon as the current search result leaves the visible area of the view, it tries to select the first one (or last one, if you scroll up) that is now visible. It might be a bit controversial whether this is the best behavior, but I kind of like it so far. Let me know how you feel about this. |
|
Many Thanks. Two more advice: We can highlight the nearest one (prefer func (v *View) nearestSearchPosition() int {
currentLineIndex := v.cy + v.oy
index := sort.Search(len(v.searcher.searchPositions), func(i int) bool {
return v.searcher.searchPositions[i].Y >= currentLineIndex
})
if index == 0 {
return 0
}
if index == len(v.searcher.searchPositions) {
return index - 1
}
deltaBefore := currentLineIndex - v.searcher.searchPositions[index-1].Y
deltaAfter := v.searcher.searchPositions[index].Y - currentLineIndex
if deltaBefore < deltaAfter {
return index - 1
}
return index
}bisect search, if it's ordered? @@ -323,12 +323,10 @@ func (v *View) UpdateSearchResults(str string, modelSearchResults []SearchPositi
// ...but only if we're showing the highlighted line
adjustedY := v.oy + v.cy
adjustedX := v.ox + v.cx
- for i, pos := range v.searcher.searchPositions {
- if pos.Y > adjustedY || (pos.Y == adjustedY && pos.XStart > adjustedX) {
- currentIndex = i
- break
- }
- }
+ currentIndex = sort.Search(len(v.searcher.searchPositions), func(i int) bool {
+ pos := v.searcher.searchPositions[i]
+ return pos.Y > adjustedY || (pos.Y == adjustedY && pos.XStart > adjustedX)
+ })
}
v.searcher.currentSearchIndex = currentIndex
} |
We could do that, and I can see how it can sometimes make sense. However, there are cases where it feels very weird that the highlighted result changes as you move the cursor between two items (especially if one of them isn't visible), and in general it feels more stable and predictable to me if we always highlight the last match before the cursor, so I'd like to keep it that way.
I would only do that if performance measurements suggest that it's a noticeable improvement. In many cases, linear search is actually faster than binary search (because of better cache locality), especially when the data set is small or you only need few iterations until you hit the target, as is typically the case here. |
|
Ok. I thought go library should handle small scale case but actually it doesn't. Also search seems not the bottlenecks here. I think this can be closed now. Thanks again. |
PR Description
When in log/file panel, often I want to goto prevmatch/nextmatch from the cursor.
gocui pr: jesseduffield/gocui#91
This feature is not enabled by default, to enable it use:
Please check if the PR fulfills these requirements
go generate ./...)