Reputation: 55
I have a lot of files which starts with some tags I defined.
Example:
=Title
@context
!todo
#topic
#subject
#etc
And some text (notice the blank line just before this text).
Foo
Bar
I'd like to write a Vim search command (with vimgrep) to match something before an empty line.
How do I grep only in the lines before the first blank line? Will it make quicker grep action? Please, no need to mention :grep
and binary like Ag - silver search
.
I know \_.*
to match everything including EOL. I know the negation [^foo]
. I succeed to match everything but empty lines with /[^^$]
. But I didn't manage to compose my :vimgrep command. Thank you for your help!
Upvotes: 2
Views: 627
Reputation: 196476
AFAIK the most you can do with :vimgrep
is use the \%<XXl
atom to search below a specific line number:
:vim /\%<20lfunction/ *.vim
That command will find all instances of function
above line 20 in the given files.
See :help \%l
.
Upvotes: 0
Reputation: 6421
If you want a general solution which works for any content of file let me tell you that AFAK, you can't with that form of text. You may ask why ?
vimgrep
requires a pattern argument to do the search line by line which behaves exactly as the :global
cmd.
For your case we need to get the first part preceding the first blank line. (It can be extended to: Get the first non blank text)
Let's call:
A :Every block of text not containing any single blank line inside
x :Blank lines
With these only 5 forms of content file you can get the first A block with vimgrep
(case 2,4,5 are obvious):
1 |
2
| 3 |4
| 5
x |
x
| A |x
| AA |
A
| x |A
| xx |
x
| AA |
Looking to your file, it is having this form:
A
x
A
x
A
the middle block causes a problem that's why you cannot split the first A
unless you delimit it by some known UNIQUE text.
So the only solution that I can come up for the only 5 cases is:
:vimgrep /\_.\{-}\(\(\n\s*\n\)\+\)\@=/ %
Upvotes: 0
Reputation: 85757
[...]
always matches a single character. [^^$]
matches a character that is not ^
or $
. This is not what you want.
One of the things you can do is:
/\%^\%(.\+\n\)\{-}.\{-}\zsfoo/
This matches
\%^
- the beginning of the file\%(
\)
- a non-capturing group\{-}
- ... repeated 0 or more times (as few as possible).\+
- 1 or more non-newline characters\n
- a newline.\{-}
- 0 or more non-newline characters (as few as possible)\zs
- the official start of the matchThis will find the first occurrence of foo
, starting from the beginning of the file, searching only non-empty lines. But that's all it does: You can't use it to find multiple matches.
Alternatively:
/\%(^\n\_.*\)\@<!foo/
\%(
\)
- a non-capturing group\@<!
- not-preceded-by modifier^
- beginning of line\n
- newline\_.*
- 0 or more of any characterThis matches every occurrence of foo
that is not preceded anywhere by an empty line (i.e. a beginning-of-line / newline combo).
Upvotes: -1