So this might not be perfect but I found it already does a lot of what you want.
You can use the \%$
pattern to match the end of the file. (Also, \%^
to match the start of the file.) Which should help you match either two lines above the start of the next section, or the end of the file.
For example, this search should match what you're looking for:
/\n--*\nsection \|\%$
Breaking it down:
\n
matches the end of a line, followed by
--*
a line with one or more dashes (nothing else), then
\n
another end of line, right after the dashes and finally
section
the next line starting with the word "section" and a space.
All this, OR (\|
):
\%$
matches the end of the file.
If you use this pattern, you'll see it cycle through the end of sections or the end of the file.
If you want a mapping to select a whole section, something like this might work:
:noremap \s :<c-u>execute "normal! ?\\v^section \|%^\rv/\\v\\n--*\\nsection \|%$\r"<cr>
This works in normal, visual and operator-pending mode. The mapping uses the \s
key sequence (s
for "section").
The searches are using the \v
option for 'verymagic'
mode in patterns to ensure consistency. The <c-u>
at the start is to erase the implicit range :'<,'>
when executing this macro in visual mode. It's using execute "normal! ..."
so the whole expression is executed as a single command, which is important in operator-pending mode.
This macro works as:
- Typing
\s
in normal mode, will switch to visual mode and highlight the section around where the cursor currently is.
- Typing
\s
in visual mode, will highlight the section around where the current visual highlighting starts (visual mapping.)
- Typing
>\s
will indent the current section, or d\s
will delete the current section (operator-pending mapping.)
This is not perfect, as the ------
preceding a section ...
does not belong to either the current or the next section, which can be easily seen when using d\s
, which will leave two lines with dashes in a row. It should be possible to adjust the regular expressions to account for that, by either including it in the start of the section or in the end of the section (I think start of the section makes more sense, since the beginning or end of the file don't have any lines with dahses in them.)
Perhaps a slightly more complete macro is:
:noremap \s :<c-u>execute "normal! g_?\\v^--*\\nsection \|%^\rv/\\v\\n--*\\nsection \|%$\r"<cr>
The additional g_
makes the selection work when you're in the first line of the section (either the line with dashes, or the first line of the file, with the introduction.)
I hope you'll find this useful!
See also:
/^section /^Mv/^section /^M
then the up key twice in a macro. For the last section, it's/^section /^MvG
.