I'm trying to find words before the cursor using searchpos
, then use matchlist
to get the captures. I can't find a reliable way to anchor the pattern for matchlist
. For example, if the cursor is positioned on [cursor]
" 3456789012345
" !!foobar !!foobaz [cursor] !!foobat
let pat = '\%(!!\)\@<=fooba\(.\)'
let [l, c] = searchpos(pat, 'bWn') " returns [2, 14]
echo 'pat1'
echo l c matchlist(getline(l), pat) | " bad
echo l c matchlist(getline(l), pat, c-3) | " ok
echo l c matchlist(getline(l), '\%'.c.'c\%('.pat.'\)') | " ok
searchpos
finds the column 14, since the look-behind is not included in the match. The first matchlist
finds the wrong fooba.
. Thus, I need to anchor the pattern using the column number. The second alternative is not an option because it would require me to know how many characters were zero-width'd. The third one works great, until...
let pat = '!!\zsfooba\(.\)'
let [l, c] = searchpos(pat, 'bWn') " also returns [2, 14]
echo 'pat2'
echo l c matchlist(getline(l), pat) | " bad
echo l c matchlist(getline(l), pat, c-3) | " ok
echo l c matchlist(getline(l), '\%'.c.'c\%('.pat.'\)') | " bad
Here, prepending the column number doesn't work because although \zs
is zero-width, the stuff before it is not.
Note:
- I need a general-purpose solution since this is for a plugin and
pat
is supplied by the user. - I can't simply replace
\zs
with\%14c\zs
, because there may be alternations\|
in the pattern. For examplefoo\%14c\zsbar\|foobaz
will allowfoobaz
in any position. - This is not actually peculiar to
searchpos
- the same would be seen with e.g., the character index frommatch
. - Negative look-behinds in
pat
are possible. - A perfect answer would include the possibility of
\ze
.
searchpos
. Could you add a new test case to demonstrate how it's failing withmatch
? (Or just describe it more?) Similarly, a test case for\ze
would be helpful. – Rich Nov 21 '17 at 22:44