--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/chapters/16.markdown Sun Oct 09 15:01:27 2011 -0400
@@ -0,0 +1,196 @@
+More Operator-Pending Mappings
+==============================
+
+The idea of operators and movements is one of the most important concepts in Vim,
+and it's one of the biggest reasons Vim is so efficient. We're going to
+practice defining new motions a bit more, because extending this powerful idea
+makes Vim even *more* powerful.
+
+Let's say you're writing some text in Markdown. If you haven't used Markdown
+before, don't worry, for our purposes here it's very simple. Type the following
+into a file:
+
+ Topic One
+ =========
+
+ This is some text about topic one.
+
+ It has multiple paragraphs.
+
+ Topic Two
+ =========
+
+ This is some text about topic two. It has only one paragraph.
+
+The lines "underlined" with `=` characters are treated as heading by Markdown.
+Lets create some mappings that let us target headings with movements. Run the
+following command:
+
+ :onoremap ih :<c-u>execute "normal! ?^==\\+$\r:nohlsearch\rkvg_"<cr>
+
+This mapping is pretty complicated, so put your cursor in one of the paragraphs
+(not the headings) and type `cih`. Vim will delete the heading of whatever
+section you're in and put you in insert mode.
+
+It uses some things we've never seen before, so let's look at each piece
+individually. The first part of the mapping, `:onoremap ih` is just the mapping
+command that we've seen before, so we'll skip over that. We'll keep ignoring
+the `<c-u>` for the moment as well.
+
+Now we're looking at the remainder of the line:
+
+ :execute "normal! ?^==\\+$\r:nohlsearch\rkvg_"<cr>
+
+Normal
+------
+
+The `:normal` command takes a set of characters and performs whatever action
+they would do if they were typed in normal mode. Run this command:
+
+ :normal gg
+
+Vim will move you to the top of the file. Now run this command:
+
+ :normal >>
+
+Vim will indent the current line.
+
+In our mapping we're using a version of `:normal` with a `!` at the end. This
+version will *not* take any existing mappings into account, whereas plain
+`:normal` will use them.
+
+In effect, `:normal!` is to `:normal` as `nnoremap` is to `nmap`. You should
+*always* prefer `:normal!` for the same reasons you should always use
+`nnoremap`, which we discussed in an earlier chapter.
+
+Execute
+-------
+
+The `execute` takes a string and performs it as a command. Run this:
+
+ :execute "write"
+
+Vim will write your file, just as if you had typed `:write`. Now run this
+command:
+
+ :execute "normal! gg"
+
+Vim will run `:normal! gg`, which as we just saw will move you to the top of the
+file. But why bother with this when we could just run the `normal!` command
+itself?
+
+Look at the following command and try to guess what it will do:
+
+ :normal! gg/a<cr>
+
+It seems like it should:
+
+* Move to the top of the file.
+* Start a search.
+* Fill in "a" as the target to search for.
+* Press return to perform the search.
+
+Run it. Vim will move to the top of the file and nothing else!
+
+The problem is that `normal!` doesn't recognize "special characters" like
+`<cr>`. There are a number of ways around this, but the easiest to use and read
+is `execute`.
+
+When `execute` looks at the string you tell it to run, it will substitute any
+special characters it finds *before* running it. In this case, `\r` is an
+escape sequence that means "carriage return". The double backslash is also an
+escape sequence that puts a literal backslash in the string.
+
+If we perform this replacement in our mapping and look at the result we can see
+that the mapping is going to perform:
+
+ :normal! ?^==\+$<cr>:nohlsearch<cr>kvg_
+ ^^^^ ^^^^
+ || ||
+ These are ACTUAL carriage returns, NOT the four characters
+ "left angle bracket", "c", "r", and "right angle bracket".
+
+So now `normal!` will execute these characters as if we had typed them in normal
+mode. Let's split them apart at the returns to find out what they're doing:
+
+ ?^==\+$
+ :nohlsearch
+ kvg_
+
+The first piece, `?^==\+$` performs a search backwards for any line that
+consists of two or more equal signs and nothing else. This will leave our cursor
+on the first character of the line of equal signs.
+
+We're searching backwards because when you say "change inside heading" while
+your cursor is in a section of text, you probably want to change the heading for
+*that* section, not the next one.
+
+The second piece is the `:nohlsearch` command. This simply clears the search
+highlighting from the search we just performed so it's not distracting.
+
+The final piece is a sequence of three normal mode commands:
+
+* `k`: move up a line. Since we were on the first character of the line of
+ equal signs, we're now on the first character of the heading text.
+* `v`: enter (characterwise) visual mode.
+* `g_`: move to the last non-blank character of the current line. We use this
+ instead of `$` because `$` would highlight the newline character as well, and
+ this isn't what we want.
+
+Results
+-------
+
+That was a lot of work, but now we've looked at each part of the mapping. To
+recap it in a nutshell:
+
+* We created a operator-pending mapping for "inside this section's heading".
+* We used `execute` and `normal!` to run the normal commands we needed to select
+ the heading, and allowing us to use special characters in those.
+* Our mapping searches for the line of equal signs which denotes a heading and
+ visually selects the heading text above that.
+* Vim handles the rest.
+
+Let's look at one more mapping before we move on. Run the following command:
+
+ :onoremap ah :<c-u>execute "normal! ?^==\\+\r:nohlsearch\rg_vk0"<cr>
+
+Try it by putting your cursor in a section's text and typing `cah`. This time
+Vim will delete not only the heading's text but also the line of equal signs
+that denotes a heading. You can think of this movement as "around this
+section's heading".
+
+What's different about this mapping? Let's look at them side by side:
+
+ :onoremap ih :<c-u>execute "normal! ?^==\\+$\r:nohlsearch\rkvg_"<cr>
+ :onoremap ah :<c-u>execute "normal! ?^==\\+\r:nohlsearch\rg_vk0"<cr>
+
+The only difference from the previous mapping is the very end, where we select
+the text to operate on:
+
+ kvg_
+ g_vk0
+
+The rest of the mapping is the same, so we still start on the first character of
+the line of equal signs. From there:
+
+* `g_`: move to the last non-blank character in the line.
+* `v`: enter (characterwise) visual mode.
+* `k`: move up a line. This puts us on the line containing the heading's text.
+* `0`: move to the first character of the line.
+
+The result is that both the text and the equal signs end up visually selected,
+and Vim performs the operation on both.
+
+Exercises
+---------
+
+Markdown can also have headings delimited with lines of `-` characters. Adjust
+the regex in these mappings to work for either type of heading. You may want to
+check out `:help pattern-overview`. Remember that the regex is inside of
+a string, so backslashes will need to be escaped.
+
+Read `:help normal`.
+
+Read `:help execute`.
+
+Read `:help expr-quote` to see the escape sequences you can use in strings.