Vimium: In find mode, highlight all matches on the page, not just the current

Created on 18 Jul 2012  路  47Comments  路  Source: philc/vimium

In chrome find mode,it can highlight all match word in the page
Can vimium also do this?

suggestions

Most helpful comment

6 years later, I still hope to have this feature

All 47 comments

Not at the moment. I think we'd accept a patch if it didn't cause noticeable lag.

This would be a fairly large undertaking -- assuming we still use window.find() to perform the search, we'd need to call it repeatedly to surface all matches and then show our own highlight UI.

If we end up going through that trouble, we should rip off Safari's matches aesthetic, IMO.

+1 for this feature.

+1

Vimium is awesome! This is the only missing piece as far as I'm concerned.

+1 for this feature. I actually wanted to suggest this myself, but I had that "I can't be the only one" feeling.

Yeyahh!

+1

+1

If/when this gets implemented it would also be nice to see all the matches visually marked in the scrollbar like Chromium does.

+1

Recently found out about vimium, can't believe I haven't installed this sooner.

+1

+1

+1

+1

+1
and I think this would be another killer feature

+1

please STOP replying with useless +1 comments. it does not add anything to the discussion, and will waste a lot of people's time since they will get notifications of your useless "contribution". use the "watch" function to subscribe to a ticket.

+1

+1, the default chrome behaves highlighting all matched hit. If implementing it again would be a performance issue, is it possible to directly call chrome's search?

is it possible to directly call chrome's search?

No.

To implement something like this would want something like (an updated) #1081 so the browser doesn't hang on every search, which increases the development/maintainance burden substantially.

Closing.
Popular as it is, we don't really have a way to implement this.

(Vimium doesn't actually do the highlighting at all, currently. We just call window.find().)

4 years...

+1 This is really a great feature if it can be implemented.

I did some research. This seems to do it http://stackoverflow.com/a/5887719/96100 (the solution includes IE, so it can be further simplified by removing the IE part)

But I think there's a further question - when and how to remove the highlight. For when, I think when starting the next search or when executing something like :noh; for how, I assume execCommand('undo') would do it.

Really look forward to the feature.

This is needed and not sure if it's suppose to be a vimium-specific feature, but other vim-like extensions do this (like surfingkeys for example). It's already been nearly 5 years and this feature isn't here yet. What in the world is going on?

I did some research. This seems to do it http://stackoverflow.com/a/5887719/96100 (the solution includes IE, so it can be further simplified by removing the IE part)

This solution seems to involve inline modifications to pages' DOMs, which makes me very uncomfortable.

What in the world is going on?

This is hard to do properly (or, at least, to my satisfaction).

A complete implementation would have to

  • find across elements (which surfingkeys looks unable to do; see here and here for their code)

    • eg. find and highlight class SuppressPrintable (or, even harder, highlight lass Supp) on this page

    • note that the line we care about has HTML <span class="pl-k">class</span> <span class="pl-en" style="background-color: transparent;">SuppressPrintable</span> <span class="pl-k">extends</span> <span class="pl-e">Mode</span>

    • eg. find and hightlight testtest in test<img src="#">test, like native find does

    • either find and highlight testtest in test<input type="text">test (like Firefox) or don't (like Chrome).

  • find and highlight a string copied directly from a page. Two cases apply:

    • the parent has white-space: normal or nowrap. test string renders as test string, so we need to find that. (surfingkeys cannot do this, as it uses node.data)

    • the parent has white-space: pre, pre-line or pre-wrap. test string renders as test string, so we need to find that

  • find across elements that represent whitespace (eg. <br /> or <p></p>). (surfingkeys can't do this)

    • eg. Test<br />Test should be found and highlighted by searching Test\nTest (or perhaps Test\r\nTest?)

    • eg. <p>Test</p><p>Test</p> should be found and highlighted by searching Test\n\nTest (or Test\r\n\r\nTest)

  • (optionally) find and highlight matches in <input>s, <textarea>s, <button>s, etc. This is a major hassle to do correctly.

We can use the innerText property to get a text representation of the page, which tells us most of the matches (except -- notably -- those mentioned in the last bullet point), and which Vimium uses. However, to highlight (or even create a selection without using window.find), we have to map the results of the text search (on innerText) back into ranges in the DOM.

My suggested (lazy) approach for that would involve a kind of poor-man's binary search, creating Ranges, and using toString() to map into innerText. I'm not particularly interested in implementing this myself.

Seems like this is a highly desired feature, but perhaps all of the requirements taken together are too large to tackle. Perhaps a smaller set of sub-steps might make this more accessible.

+1

6 years later, I still hope to have this feature

  • btw, this plugin Chrome Regex Search implemented this function.
  • It would be great if vimium can also support this.

The extension Chrome Regex Search uses a very dangerous way to implement the highlighting feature, and may break some normal web pages because it might break down host JavaScript code and remove some clicking actions.

It seems not only me have this issue.

I did some research. This seems to do it http://stackoverflow.com/a/5887719/96100 (the solution includes IE, so it can be further simplified by removing the IE part)

This solution seems to involve inline modifications to pages' DOMs, which makes me very uncomfortable.

What in the world is going on?

This is hard to do properly (or, at least, to my satisfaction).

A complete implementation would have to

  • find across elements (which surfingkeys looks unable to do; see here and here for their code)

    • eg. find and highlight class SuppressPrintable (or, even harder, highlight lass Supp) on this page
    • note that the line we care about has HTML <span class="pl-k">class</span> <span class="pl-en" style="background-color: transparent;">SuppressPrintable</span> <span class="pl-k">extends</span> <span class="pl-e">Mode</span>
    • eg. find and hightlight testtest in test<img src="#">test, like native find does
    • either find and highlight testtest in test<input type="text">test (like Firefox) or don't (like Chrome).
  • find and highlight a string copied directly from a page. Two cases apply:

    • the parent has white-space: normal or nowrap. test string renders as test string, so we need to find that. (surfingkeys cannot do this, as it uses node.data)
    • the parent has white-space: pre, pre-line or pre-wrap. test string renders as test string, so we need to find that
  • find across elements that represent whitespace (eg. <br /> or <p></p>). (surfingkeys can't do this)

    • eg. Test<br />Test should be found and highlighted by searching Test\nTest (or perhaps Test\r\nTest?)
    • eg. <p>Test</p><p>Test</p> should be found and highlighted by searching Test\n\nTest (or Test\r\n\r\nTest)
  • (optionally) find and highlight matches in <input>s, <textarea>s, <button>s, etc. This is a major hassle to do correctly.

We can use the innerText property to get a text representation of the page, which tells us most of the matches (except -- notably -- those mentioned in the last bullet point), and which Vimium uses. However, to highlight (or even create a selection without using window.find), we have to map the results of the text search (on innerText) back into ranges in the DOM.

My suggested (lazy) approach for that would involve a kind of poor-man's binary search, creating Ranges, and using toString() to map into innerText. I'm not particularly interested in implementing this myself.

I also do some research on window.find(). It only highlights the current result on the web, not highlights all the result. Maybe call the method multi times? I think it's not a good idea for this issue.

how about this routine?

in find mode, before users hit the enter key, only call window.find() once for each updated input.

after use hit the enter key, call window.find() to show all occurrences.
[ possibly, to remember the find result position right before enter ]

window.find() always highlights "current" selected area, while no perfect method to simulate the background color block (for example, if a line has owned its background color/image, then simulated background color will be invisible).

window.find() always highlights "current" selected area, while no perfect method to simulate the background color block (for example, if a line has owned its background color/image, then simulated background color will be invisible).

Hi, Let me be more clear about my routine.

User type a, call window.find until it returns NULL. collect all matches
User type ab, call window.find until it returns NULL. collect all matches, drop previous
When use hit enter, actually utilize the the search result array.

@Piping window.find() always drops all old highlighting areas and then only highlights one new, so in fact there's no JavaScript APIs to highlight a list of areas.

Disclaimer: I no longer work on browser extensions in any form, so my knowledge is likely out of date.

User type a, call window.find until it returns NULL. collect all matches
User type ab, call window.find until it returns NULL. collect all matches, drop previous

window.find is horrible and should be avoided whenever possible

  • It runs on the main thread, so it blocks user input
  • It has UI effects, so it also forces rendering and further blocks user input
  • It is selection-based, so CSS that blocks text from being selected can have a variety of strange behaviours, depending on your browser of choice
  • It doesn't (or at least, didn't used to) wrap in FF
  • It's outside the spec and officially deprecated, with no intention to standardise behaviour between browsers
  • Retrieving the selection data this way is far is more expensive than querying the DOM directly.

    • As Dahan rightly mentions, the true highlighting is always discarded, so we would have to collect this to highlight more than 1 match

    • <input>/<textarea>s are hard to get this data out of well, even before we have to worry about the non-trivial problem of highlighting text in them.

When I was a contributor, we battled over counting the number of search results because of how slow it was on large pages. Using window.find was about an order of magnitude slower, and didn't work at all with regular expression searches. I strongly advise against using it for more than executing a single search, and even then it should be a last resort.

@gdh1995 I don't meant to use windows.find() that way like you said. It is just merely find the text.
@mrmr1993 I understand this feature requires more computing power or man effort. But at least user should have a choice [option in config] to do this using vimium even if it is slow for user perspective. Anyway, it is kind of annoying that sometimes Ctrl-F is used and sometimes / is used and / does not work as expected ( not even in vim ).

Is there anything other than a philosophical reason why the extension can't just allow this type of feature, and tuck it into an "experimental" section of the extension's settings, with proper warnings in place noting that it may break some pages? This seems like enough of a popular request that it'd make sense to add it there. I've been quite happy with the extension "Selection Highlighter" for example, despite the fact that it might break pages, simply because the utility outweighs the risk; I think the same applies here.

+1 around here. :)

I echo macintaco's sentiments.

I use vimium search as a replacement for the find tool so that I can keep keyboard shortcuts uniform across different installs (always use / to find stuff).

+1

Firefox has browser.find.find and browser.find.highlightResults. It doesn't appear to support regex, but otherwise looks like exactly what this issue would need.

I'd just like to note that SurfingKeys highlights matches on the page via its search functionality. I don't know how they do it (it seems to be some kind of overlay) but it's "good enough" to the point that I'm using that extension instead now. YMMV.

+1 - wish there was at least a workaround for this.

8 years... :)

Recently I got another idea: it's not necessary to draw the highlighting background color, and we may use masking rects instead. Therefore I've implemented a simple version in my customized Vimium, Vimium C, and it supports Ctrl+J/K to find next/prev and Ctrl+Shift+J/K to flash rects on all matches in the current visible area.

Was this page helpful?
0 / 5 - 0 ratings