-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Highlight all search matches in document #5702
base: master
Are you sure you want to change the base?
Conversation
9be5377
to
e8cd334
Compare
ec8de2a
to
c4e8146
Compare
I haven't looked at this yet but also see #4635 which I think will have some overlap implementation-wise |
Thanks. I'll definitely look into that work. |
34dc5d2
to
0cb2cf9
Compare
i think the only optimization left is to search only the visible text for matches versus the entire document EDIT: the above is fixed, but a bug is introduced: |
Just a couple comments:
|
5acdb12
to
91d2a61
Compare
91d2a61
to
9361993
Compare
i have this PR in the following state:
|
c46d038
to
5eb6e2f
Compare
helix-view/src/view.rs
Outdated
impl fmt::Debug for SearchMatches { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
f.debug_struct("SearchMatches") | ||
.field("matches", &self.matches) | ||
.field("new", &self.new) | ||
.field("old", &self.old) | ||
.finish() | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
probably not needed - can remove
pub fn has_changed(&self, regex: &Regex) -> bool { | ||
regex.as_str() != self.old.as_str() | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could not figure out a clean way to compare Regex
, so this is what i came up with
new: Regex::new("").unwrap(), | ||
old: Regex::new("").unwrap(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i assume unwrap
is safe to use in a case like this? but it is a big assumption...
// but set search_matches.old to "" so that if 'n' is pressed | ||
// to continue to traverse matches, highlights resume | ||
view.search_matches.clear(); | ||
view.search_matches.old = Regex::new("").unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
again... is unwrap
safe to use here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As it is initialize code with empty string. I don't think unwrap will panic here in runtime. It's ok imo.
Is the color here the same as selections? Might need to difference between those. A feature I would like is to highlight words that match the current primary selection, and that seems to overlap with this (since when you search the search term gets selected) |
the
an easy update or change to have a different highlight for |
5eb6e2f
to
4cac675
Compare
pub fn update_search_matches(&mut self, contents: &str, regex: &Regex) { | ||
// this is expensive. only update search matches if search criteria has changed | ||
if self.search_matches.has_changed(regex) { | ||
self.search_matches.update(regex); | ||
self.search_matches.clear(); | ||
for one_match in self.search_matches.new.find_iter(contents) { | ||
self.search_matches | ||
.matches | ||
.push((one_match.start(), one_match.end())); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the first if
checks if the Regex
search criteria has changed. this prevents this block from executing if the user is traversing match results using n
or similar. if the Regex
search criteria has indeed changed, old
is set equal to new
, and existing matches are cleared. new matches are calculated via expensive Regex
operation based on new
search criteria
606e0c1
to
629acc9
Compare
this one is ready for a closer look guys i think the behavior is close to what @pascalkuthe outlined in the comment above |
629acc9
to
99e46d5
Compare
99e46d5
to
a3a435d
Compare
376efed
to
a3a435d
Compare
a3a435d
to
b4e8ddd
Compare
would either of you please take a look? |
What's status of this PR? this is really helpful to have all matched words highlighted. |
I've been looking into adding a search index/total matches statusline as I was used to back in nvim (e.g., indicating you're on match 2 out of 5 with something like [2/5] on the bottom) and it does look like I should wait until this gets merged in the interest of not duplicating the work made here so that the context holds search match information and whatnot, so I'll be keeping an eye on this. |
@the-mikedavis @archseer @pascalkuthe @sudormrfbin |
my concern from #5702 (comment) still apply/are unadressed. Running a regex over document contents synchronously on every keypress is unacceotable. Particularly of the rope -> string conversion is very non-ideal and should be done rarely (or rather not at all, the current implementation is a workaround). I am working on a streaming regex engine but that still takes some time and even with that solved (which would improve pref a lot) running a regex on every keypress is stijj not something I am ok with. Using the transactional word mapping in #6447 could allow you to update the ranges without actually running a regex and then you could run the actual regex with a 5s debounce or similar (with #8021). I don't think regularly covering to string would be ok tough so that has to wait until we have a streaming regex engine... Which will be a while. You could keep all of this simpler by dismissing changes when transactions are applied just as I said in my first comment. |
Altering document clears
search_matches
highlights(PS: the extra whitespace being highlighted in the demo gif is a glitch in asciicinema capture)
Updated display of matching text to use

ui.cursor.match
. this is the result:References:
#4798