1995eaton / chromium-vim

Vim bindings for Google Chrome.
https://chrome.google.com/webstore/detail/cvim/ihlenndgcmojhcghmfjfneahoeklbjjh
MIT License
2.25k stars 325 forks source link

Implement searching beginning/ending of a word? #687

Open crabdancing opened 5 years ago

crabdancing commented 5 years ago

In VIM, if for instance I want to search for app without also turning up results for apple, I can just search \<app\>. Can this be implemented in cVim?

skaniol commented 5 years ago

The JavaScript regex uses the Perl syntax. The equivalent to the word boundaries \< and \> is \b. \B is the negative. A search like \bapp\b should work for your example.

It's not incredibly reliable, though. I found that it doesn't always work. Like with some of the examples in the previous link. Try for example \bis\b in order to match the lone "is" inside "This island is beautiful". I get the "is" mismatched in "This" instead, which doesn't make sense. It doesn't seem to be related to #581, because even if you write that sentence in a simple txt file and then open the file in the browser, the same search produces the same bug.

Interestingly, If I append an " is " (surrounded by spaces and thus should-be-matched), then the second "is" is also mismatched (the one in "island"). if I append another " is ", then the next "is" is matched, etc... Somehow the new should-be-match turns a previous "is" non-match on, even if that's a mismatch. Whenever an "is" is mismatched, the number of trailing should-have-been-matches increases.
thisislandismatched

The problem doesn't appear to be in the JS Regex Engine, 'cause if I open the console and enter:

var myRe = /\bis\b/g; //NB: do not omit the /g or an infinite loop will happen below
var str = 'This island is beautiful is is is is isis is is is is';
var myArray;
while ((myArray = myRe.exec(str)) !== null) {
  var msg = 'Found "' + myArray[0] + '" at index: ' + myArray["index"] + '. ';
  msg += 'Next match starts at ' + myRe.lastIndex;
  console.log(msg);
}

I get this:

Found "is" at index: 12. Next match starts at 14
Found "is" at index: 25. Next match starts at 27
Found "is" at index: 28. Next match starts at 30
Found "is" at index: 31. Next match starts at 33
Found "is" at index: 34. Next match starts at 36
Found "is" at index: 42. Next match starts at 44
Found "is" at index: 45. Next match starts at 47
Found "is" at index: 48. Next match starts at 50
Found "is" at index: 51. Next match starts at 53

This island is beautiful is is is is isis is is is is
01234567890123456789012345678901234567890123456789012
          1         2         3         4         5

That's what cVim should have matched too.

BTW, the regex engine also supports

named capture groups by
(?<name>...), which is later referenced by \k<name>

lookaraound by
(?=...) for positive lookahead
(?!...) for negative lookahead
(?<=...) for positive lookbehind
(?<!...) for negative lookbehind

Unfortunately, these suffer from the same issue.