Being a long-time "vi" user I find that I am constantly surprised by the little (and not-so-little) enhancements vim has added. One of them is the "inner" concept.
Any vi user knows that "c" starts a c change and the next keystroke determines what will be changed. "cw" changes from where the cursor is until the end of the word. For example, "c$" chances from where the cursor is to the end of the line. Think of a cursor movement command, type it after "c" and you are pretty sure that you will change from where the cursor is to.... wherever you've directed.
"d" works the same way. "dw" deletes word. "d$" deletes to the end of the line. "d^" deletes to the beginning of the line ("^"? "$"? gosh, whoever invented this stuff must have known a lot about regular expressions).
VIM adds the concept of "inner text". Text is structured. We put things in quotes, in parenthesis, between mustaches (that's "{" and "}") and so on. The text between those two things are the "inner text".
So suppose we have:
<span style="clean">Interesting quote here.</span>
but we want to change the style from "clean" to "unruly". Move the cursor anywhere between the quotes and type ci then a quote (read that as "change inner quote"). VIM will seek out the opening and closing quotes that surround the cursor and the next stuff you type will replace it.
It works for all three kinds of quotes (single, double, and backtick), it works for all the various braces: ( { and <. You can type the opening or the closing brace, they both do the same thing.
Therefore you can move the cursor to the word "style" in the above example and type "ci<" to change everything within that tag.
I find this particularly useful when editing python code. I'm often using ci' to change a single quoted string.
If there is an "inner", you'd expect there is an "outer" too, right? (How many of you tried typing co" to see if it worked?) Well, there is an there isn't.
In VIM the opposite of "inner" is "block". A block is kind of special. It don't just include the opening and closing elements plus sometimes a the space or two that follow. Given this text:
- The quick <span class="foo">>brown</span> fox.
If the cursor is in the <span> element, "cb<" will replace the entire element from the < all the way to the >. The whitespace after the element is also replaced for text-related things like change word (caw) and change sentence (cas).
Not having to move the cursor to the beginning of an element to change the entire thing is a great time saver. It is these little enhancements that makes using VIM so much more pleasant that using VI.
Give it a try!
More information about this is in the "Text Objects" section of Michael Jakl's excellent VIM tutorial.
--Tom
P.S. My second favorite thing about VIM? gVIM (The graphical version of VIM) preserves TABs when you use the windowing system to cut and paste.
Great post and in my case serendipitous! I was just wondering the other day if there is a better way to do this:
I do: s/"xyz abc"/"123 456"/ in [g]vim by positioning cursor on the 'x' and then typing 'cf"'. That would need me to retype/readd the closing quote. Not a big deal of course, but nice to know there's a proper way to do this.
And if I understand this right, it will even work multi-line? If so, this is quite useful.