Commits

Steve Losh committed a4dc774

Moar.

Comments (0)

Files changed (6)

sample/chapters/01.markdown

 
 You should see `Hello, world!` appear at the bottom of the window.
 
+Persistent Echoing
+------------------
+
 Now run the following command:
 
     :echom "Hello again, world!"
 done.  Using `:echom` will save the output and let you run `:messages` to view
 it later.
 
+Comments
+--------
+
 Before we move on we should mention comments.  When you write Vimscript code (in
 your `~/.vimrc` file or another one) you can add comments with the `"`
 character, like this:

sample/chapters/02.markdown

 off or on.  You turn it "on" by running `:set number` and "off" with `:set
 nonumber`.
 
+Toggling Options
+----------------
+
 You can also "toggle" boolean options to set them to the *opposite* of whatever
 they are now.  Run this:
 
 They should disappear once more.  Adding a `!` (exclamation point or "bang") to
 a boolean option toggles it.
 
+Checking Options
+----------------
+
 You can ask Vim what an option is currently set to by using a `?`.  Run these
 commands and watch what happens after each:
 
 Notice how the first `:set number?` command displayed `number` while the second
 displayed `nonumber`.
 
+Options with Values
+-------------------
+
 Some options take a value instead of just being off or on.  Run the following
 commands and watch what happens after each:
 
     :set wrap?
     :set numberwidth?
 
+Setting Multiple Options at Once
+--------------------------------
+
 Finally, you can specify more than one option in the same `:set` command.  Try
 running this:
 

sample/chapters/04.markdown

 Modal Mapping
 =============
+
+In the last chapter we talked about how to map keys in Vim.  We used the `map`
+command which made our keys work in normal mode.  If you played around a bit
+before moving on to this chapter, you may have noticed that our mappings also
+took effect in visual mode.
+
+We can be more specific about when we want our mappings to work by using `nmap`,
+`vmap`, and `imap`.  These tell Vim to only use the mapping in normal, visual,
+or insert mode respectively.
+
+Run this command:
+
+    nmap \ dd
+
+Now put your cursor in your text file, make sure you're in normal mode, and
+press `\`.  Vim will delete the current line.
+
+Now enter visual mode and try pressing `\`.  Nothing will happen, because we
+told Vim to only use that mapping in normal mode (and `\` doesn't do anything by
+default).
+
+Run this command:
+
+    vmap \ U
+
+Enter visual mode and select some text, then press `\`.  Vim will convert the
+text to uppercase!
+
+Try the `\` key a few times in normal and visual modes and notice that it now
+does something completely different depending on which mode you're in.
+
+Muscle Memory
+-------------
+
+At first the idea of mapping the same key to do different things depending on
+which mode you're in may sound like a terrible idea.  Why would you want to
+have to stop and think which mode you're in before pressing the key?  Wouldn't
+that negate any time you saved from the mapping itself?
+
+In practice it turns out that this isn't really a problem.  Once you start using
+Vim a lot you won't be thinking about the individual keys you're typing any
+more.  You'll think: "delete a line" and not "press `dd`".  Your fingers and
+brain will learn your mappings and the keys themselves will become subconscious.
+
+Insert Mode
+-----------
+
+Now that we've covered how to map keys in normal and visual mode, let's move on
+to insert mode.  Run this command:
+
+    imap <c-d> dd
+
+You might think that this would let you press `Ctrl+d` whenever you're in insert
+mode to delete the current line.  This would be nice, because now you don't need
+to go back into normal mode to cut out lines!
+
+Go ahead and try it.  It won't work -- instead it will just put two `d`s in your
+file!  That's pretty useless.
+
+The problem is that Vim is doing exactly what we told it to.  We said: "when
+I press `<c-d>` I want you to do what pressing `d` and `d` would normally do".
+
+Well, normally when you're in insert mode and press the `d` key twice, you get
+two `d`s in a row!
+
+To make this mapping do what we intended we need to be very explicit.  Run this
+command to change the mapping:
+
+    imap <c-d> <esc>dd
+
+The `<esc>` is our way of telling Vim to press the Escape key, which will take
+us out of insert mode.
+
+Now try the mapping.  It works!  But notice how you're now back in normal mode.
+This makes sense, because we told Vim that `<c-d>` should exit insert mode and
+delete a line, but we never told it to go back into insert mode.
+
+Run one more command to fix the mapping once and for all:
+
+    imap <c-d> <esc>ddi
+
+The `i` at the end reenters insert mode for us, and our mapping is finally
+complete.
+
+Exercises
+---------
+
+Set up a mapping so that you can press `<c-u>` to convert the current word to
+uppercase when you're in insert mode.  Remember that `U` in visual mode will
+uppercase the selection.  I find this mapping extremely useful when I'm writing
+out the name of a long constant -- I type out the constant in lower case and
+then uppercase it.
+
+Add that mapping to your `~/.vimrc` file.
+
+Set up a mapping so that you can uppercase the current word with `<c-u>` when in
+*normal* mode.  This will be slightly different than the previous mapping
+because you don't need to enter normal mode and you should end up back in normal
+mode instead of in insert mode.
+
+Add that mapping to your `~/.vimrc` file as well.

sample/chapters/05.markdown

 Strict Mapping
 ==============
+
+Hold on, things are about to get a little wild.
+
+So far we've used `map`, `nmap`, `vmap`, and `imap` to create key mappings that
+will save time.  These work, but they have a downside.
+
+Run the following commands:
+
+    :nmap - dd
+    :nmap \ -
+
+Now try pressing `\` (in normal mode).  What happens?
+
+When you press `\` Vim sees the mapping and says "I should run `-` instead".
+But we've already mapped `-` to do something else!  Vim sees that and says "oh,
+now I need to run `dd`", and so it deletes the current line.
+
+When you map keys with these commands Vim will take *other* mappings into
+account.  This may sound like a good thing at first but in reality it's pure,
+unadulterated evil.  Let's talk about why.
+
+Recursion
+---------
+
+Run this command:
+
+    :nmap dd O<esc>jddk
+
+You might think that this would change `dd` to:
+
+* Open a new line above this one.
+* Exit insert mode.
+* Move back down.
+* Delete the current line.
+* Move up to the blank line just created.
+
+In effect, this should "clear the current line".  Try it.
+
+Vim will seem to freeze when you press `dd`.  If you press `<c-c>` you'll get
+Vim back, but there will be a ton of empty lines in your file!  What happened?
+
+This mapping is actually *recursive*!  When you press `dd`, Vim says:
+
+* `dd` is mapped, so perform the mapping.
+    * Open a line.
+    * Exit insert mode.
+    * Move down a line.
+    * `dd` is mapped, so perform the mapping.
+        * Open a line.
+        * Exit insert mode.
+        * Move down a line.
+        * `dd` is mapped, so perform the mapping.
+            * ...
+
+This mapping can never finish running!
+
+Side Effects
+------------
+
+Not only do the `*map` commands we've learned so far run the danger of
+recursing, but because they take other mappings into account they can change
+when we install various plugins.
+
+When you install a new Vim plugin there's a good chance that you won't use and
+memorize every mapping it uses.  Even if you *do*, you'd have to go back and
+look through your `~/.vimrc` file to make sure none of your custom mappings use
+something that the plugin has mapped, and vice versa.
+
+This would make installing plugins tedious and error-prone.  There must be
+a better way.
+
+Nonrecursive Mapping
+--------------------
+
+Vim offers another set of mapping commands that will *not* take mappings into
+account when they perform their actions.  Run these commands:
+
+    :nmap x dd
+    :nnoremap \ x
+
+Now press `\` and see what happens.
+
+When you press `\` Vim ignores the `x` mapping and does whatever it would do for
+`x` by default.  Instead of deleting the current line, it deletes the current
+character.
+
+Each of the `*map` commands has a `*noremap` counterpart that ignores other
+mappings: `nnoremap`, `vnoremap`, and `inoremap`.
+
+When to Use
+-----------
+
+When should you use these nonrecursive variants instead of their normal
+counterparts?  The answer is: always.
+
+**Always.**
+
+**No, seriously, ALWAYS.**
+
+Using a bare `nmap` is just *asking* for pain down the road when you install
+a plugin or add a new custom mapping.  Save yourself the trouble and type the
+extra characters to make sure it never happens.
+
+Exercises
+---------
+
+Convert all the mappings you added to your `~/.vimrc` file in the previous
+chapters to their nonrecursive counterparts.

sample/chapters/06.markdown

+Leaders
+=======
+
+We've learned how to map keys in a way that won't make us want to tear our hair
+out later, but you might have noticed one more problem.
+
+Every time we do something like `:nnoremap <space> dd` we've overwritten what
+`<space>` normally does.  What if we need that key later?
+
+There are a bunch of keys that you don't normally need in your day-to-day Vim
+usage.  `\` doesn't do anything.  `-`, `H`, `L`, and `<space>` do things that
+you almost never need.  Depending on how you work you may find others that you
+never use.
+
+Those are safe to map, but that only gives us five keys to work with.  What
+happened to Vim's legendary customizability?
+
+Mapping Key Sequences
+---------------------
+
+Unlike Emacs, Vim makes it easy to map more than just single keys.  Run these
+commands:
+
+    :nnoremap -d dd
+    :nnoremap -c ddO
+
+Try them out by typing the keys in sequence (quickly) in normal mode.  The first
+creates a custom mapping to delete a line, while the second "clears" a line and
+puts you into insert mode.
+
+

sample/publish.sh

+#!/usr/bin/env bash
+
+set -e
+../bookmarkdown/bookmarkdown build
+rsync --delete -az build/html/ sl:/var/www/vimscript/