Use a Macro!
You already have three excellent answers explaining how to achieve this using regular expressions. However, I thought I'd offer a solution that uses a completely different Vim feature. viz. a recording, or macro.
In many circumstances, a macro is a terrific alternative to a complex regular expression, and, to my mind, if you don't already have a good grasp of intermediate/advanced regular expression constructs, then macros are easier to pick up, because they just use all the editing commands you already know.
Getting your head around how to ensure that the macro you record will work in all the places you intend to play it back does take a little bit of practice, but, personally, I found this easier than learning how all Vim's various regexp atoms work, and remembering the arcane syntax required to invoke them.
The Solution
Here's how to uppercase all your headings with a recursive macro.
First, place your cursor on the beginning of the word New
, and then type the following:
qqqqqgUlhellbw@qq
This will record a recursive macro that updates all the words in the current section header to begin with an uppercase character. To play this back, just run the command:
:g/section/norm!f{l@q
Amazing! So how does this work?
Explanation
Let's break down the macro into its constituent parts:
qqqqq {some stuff} @qq
The beginning and end of our recording is just boilerplate for recording a recursive macro. You don't need to know how it works to use it, but how it does work is straightforward:
qqq
The first three q
characters starts recording a macro into register q
and then immediately ends the recording, so the macro ends up empty. This will become important when we get to the end of our recording
qq
Now we start recording our real macro into register q
{some stuff}
Then we type our macro steps. We'll come back to this.
@qq
Finally, we type @q
to make our macro recursive, and then type q
to end the recording.
When running the final macro, the @q
will cause our macro to run again and again until it hits an "error", but when recording the macro, the q
register is empty (because we specifically emptied it as the first thing we did), so typing it does nothing.
Now lets take a look at the commands in the middle that actually do the work. We need to write a series of commands that will a). perform one change, and b). move the cursor to the next location where we want the change to be made, throwing some kind of error if we've reached the last location. So:
gUhellbw
First we need to uppercase the first character:
gU
Done!
Next, we need to check if we're finished and jump to the next location. The easiest way to check if we're finished is to jump to the end of the current word and then attempt to move the cursor right twice. If we're on the final word, we'll hit the end of the line and the macro will stop.
he
This is an example of the sort of thing you need to watch out for when recording a macro. We want to jump to the end of the word. Normally, e
will do this. But if we're on a single letter word like A
, it will instead jump to the end of the next word. So first we move left once with h
and then we jump to the end of the word with e
.
llb
If we at the end of the final word on the line, attempting to move right twice will first move onto the }
character and then hit the end of the line, causing an "error" which means the macro will stop*. If there was no error, we are good to continue so we jump back to the start of the word with b
.
w
Now we just need to move to the next word that needs to be uppercased.
So our macro is complete!
Now we just need to play it back once per section heading:
:g/section/norm!f{l@q
We use the same :global
search that you already supplied: :g/section/
. Then, for our command, we just use some more normal mode commands, run via the :normal!
command:
f{l
This jumps to the first {
on the line and then moves right onto the first character of the section heading.
@q
This plays back the macro.
* N.B. I'm presuming you're using the default setting for 'whichwrap'
. If you have edited this setting to include l
, then replace the l
commands in the macro with either Right Arrow, or Space, depending on which of these is not present in your 'whichwrap'
setting. (There's not really any good reason to have all three in the setting, so if they are all present, consider removing one!)
:g/{pattern}/{cmd}
? Just use:h :s
. You just wantblabla section{This is a section}
to becomeblabla section{ This Is A Section}
, right? Look at:h /\zs
and:h /\ze
. If I'm wrong, add a 3-4 lines of test code, it would help.\zs
or\ze
to do what I want (see my comment in response to Ben Noble's answer.\zs
was helpful.