--- a/.hgignore Tue Apr 17 16:37:41 2012 +0100
+++ b/.hgignore Sat Jun 16 16:10:29 2012 -0400
@@ -8,3 +8,4 @@
.ropeproject
tags
build
+venv
--- a/acknowledgements.markdown Tue Apr 17 16:37:41 2012 +0100
+++ b/acknowledgements.markdown Sat Jun 16 16:10:29 2012 -0400
@@ -7,3 +7,4 @@
* [Psycojoker](https://github.com/Psycojoker)
* [manojkumarm](https://github.com/manojkumarm)
* [dmedvinsky](https://github.com/dmedvinsky)
+* [flatcap](https://github.com/flatcap)
--- a/chapters/07.markdown Tue Apr 17 16:37:41 2012 +0100
+++ b/chapters/07.markdown Sat Jun 16 16:10:29 2012 -0400
@@ -19,7 +19,7 @@
Editing Mapping
---------------
-Lets add a mapping that will open our `~/.vimrc` file in a split so we can edit
+Let's add a mapping that will open our `~/.vimrc` file in a split so we can edit
it and get back to coding. Run this command:
:::vim
@@ -74,7 +74,7 @@
your work, it takes ten seconds.
Assuming you charge $100 per hour for freelance work, you've got to make up one
-an a half hours of time for this investment to be worthwhile. If you're saving
+and a half hours of time for this investment to be worthwhile. If you're saving
50 seconds per photo, you need to take about 109 photos for project to pay for
itself.
--- a/chapters/09.markdown Tue Apr 17 16:37:41 2012 +0100
+++ b/chapters/09.markdown Sat Jun 16 16:10:29 2012 -0400
@@ -20,7 +20,7 @@
after the `j`, Vim decides that you don't want to activate the mapping and
instead runs the normal `j` functionality (moving down a line).
-This mapping will make it painful to move around our file, so lets remove it.
+This mapping will make it painful to move around our file, so let's remove it.
Run the following command:
:::vim
--- a/chapters/13.markdown Tue Apr 17 16:37:41 2012 +0100
+++ b/chapters/13.markdown Sat Jun 16 16:10:29 2012 -0400
@@ -41,7 +41,7 @@
Create a few more "snippet" abbreviations for some of the things you type often
in specific kinds of files. Some good candidates are `return` for most
-languages, `function` for javascript, and thinks like `“` and `”`
+languages, `function` for javascript, and things like `“` and `”`
for HTML files.
Add these snippets to your `~/.vimrc` file.
--- a/chapters/14.markdown Tue Apr 17 16:37:41 2012 +0100
+++ b/chapters/14.markdown Sat Jun 16 16:10:29 2012 -0400
@@ -51,7 +51,7 @@
Write the file again. This time the slowness will be more apparent.
Obviously you won't have any autocommands that do nothing but sleep, but the
-`~/.vimrc` of a seasoned Vim user can easy reach 1,000 lines, many of which will
+`~/.vimrc` of a seasoned Vim user can easily reach 1,000 lines, many of which will
be autocommands. Combine that with autocommands defined in any installed
plugins and it can definitely affect performance.
@@ -107,14 +107,14 @@
Now try writing your file and checking `:messages`. This time Vim only echoed
"Cats" when you wrote the file.
-Using in Your Vimrc
--------------------
+Using Autocommands in Your Vimrc
+--------------------------------
Now that we know how to group autocommands and clear those groups, we can use
this to add autocommands to `~/.vimrc` that don't add a duplicate every time we
source it.
-Add the follow to your `~/.vimrc` file:
+Add the following to your `~/.vimrc` file:
:::vim
augroup filetype_html
--- a/chapters/15.markdown Tue Apr 17 16:37:41 2012 +0100
+++ b/chapters/15.markdown Sat Jun 16 16:10:29 2012 -0400
@@ -26,7 +26,7 @@
:::vim
:onoremap p i(
-Now type the follow text into a buffer:
+Now type the following text into a buffer:
:::python
return person.get_pets(type="cat", fluffy_only=True)
@@ -100,11 +100,11 @@
Put your cursor somewhere in the word "print" and type `cin(`. Vim will delete
the contents of the parentheses and place you in insert mode between them.
-You can think of this mapping as meaning "inside next parenthesis", and it will
-perform the operator on the text inside the next set of parenthesis on the
+You can think of this mapping as meaning "inside next parentheses", and it will
+perform the operator on the text inside the next set of parentheses on the
current line.
-Let's make a companion "inside last parenthesis" ("previous" woud be a better
+Let's make a companion "inside last parentheses" ("previous" would be a better
word, but it would shadow the "paragraph" movement). Run the following command:
:::vim
@@ -153,8 +153,8 @@
Exercises
---------
-Create operator-pending mappings for "around next parenthesis" and "around last
-parenthesis".
+Create operator-pending mappings for "around next parentheses" and "around last
+parentheses".
Create similar mappings for in/around next/last for curly brackets.
--- a/chapters/16.markdown Tue Apr 17 16:37:41 2012 +0100
+++ b/chapters/16.markdown Sat Jun 16 16:10:29 2012 -0400
@@ -24,7 +24,7 @@
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
+Let's create some mappings that let us target headings with movements. Run the
following command:
:::vim
--- a/chapters/17.markdown Tue Apr 17 16:37:41 2012 +0100
+++ b/chapters/17.markdown Sat Jun 16 16:10:29 2012 -0400
@@ -41,7 +41,7 @@
comments explaining each piece for other people reading the code (or ourselves
several months later).
-Run the following command:
+Run the following commands:
:::vim
:set statusline=%l " Current line
--- a/chapters/19.markdown Tue Apr 17 16:37:41 2012 +0100
+++ b/chapters/19.markdown Sat Jun 16 16:10:29 2012 -0400
@@ -22,7 +22,7 @@
:let foo = 42
:echo foo
-Vim will display "42", because we've reassigned `bar` to the integer "42". From
+Vim will display "42", because we've reassigned `foo` to the integer "42". From
this it may seem that Vimscript is dynamically typed. That's not the case, but
we'll talk more about that later.
--- a/chapters/21.markdown Tue Apr 17 16:37:41 2012 +0100
+++ b/chapters/21.markdown Sat Jun 16 16:10:29 2012 -0400
@@ -92,7 +92,7 @@
* Strings that start with a number are coerced to that number, otherwise they're
coerced to `0`.
* Vim will execute the body of an `if` statement when its condition evaluates to
- a non-zero integer, *after* all coersion takes place.
+ a non-zero integer, *after* all coercion takes place.
Else and Elseif
---------------
@@ -115,4 +115,4 @@
Exercises
---------
-Drink a beer to console yourself about Vim's coersion of strings to integers.
+Drink a beer to console yourself about Vim's coercion of strings to integers.
--- a/chapters/22.markdown Tue Apr 17 16:37:41 2012 +0100
+++ b/chapters/22.markdown Sat Jun 16 16:10:29 2012 -0400
@@ -66,7 +66,7 @@
: echom "this must be the one"
:endif
-**Woah**. Stop right there. Yes, you saw that right.
+**Whoa**. Stop right there. Yes, you saw that right.
**The behavior of `==` depends on a user's settings.**
@@ -90,7 +90,7 @@
Run the following commands:
:::vim
- :set ignorecase
+ :set noignorecase
:if "foo" ==? "FOO"
: echom "first"
:elseif "foo" ==? "foo"
--- a/chapters/25.markdown Tue Apr 17 16:37:41 2012 +0100
+++ b/chapters/25.markdown Sat Jun 16 16:10:29 2012 -0400
@@ -62,8 +62,8 @@
:::vim
:echo 15.45e-2
-Vim displays "0.1545". The `+` or `-` before the power of ten is optional, if
-it's omitted the it's assumed to be positive. Run the following command:
+Vim displays "0.1545". The `+` or `-` before the power of ten is optional. If
+it's omitted then it's assumed to be positive. Run the following command:
:::vim
:echo 15.3e9
@@ -94,7 +94,7 @@
:::vim
:echo 3 / 2
-Vim displays "1". If you want Vim to perform float point division one of the
+Vim displays "1". If you want Vim to perform floating point division one of the
numbers needs to be a Float, which will cause the other one to be coerced to
a Float as well. Run this command:
--- a/chapters/26.markdown Tue Apr 17 16:37:41 2012 +0100
+++ b/chapters/26.markdown Sat Jun 16 16:10:29 2012 -0400
@@ -120,7 +120,7 @@
:echom '\n\\'
Vim displays `\n\\`. Using single quotes tells Vim that you want the string
-*exactly* as-in, with no escape sequences. The one exception is that two single
+*exactly* as-is, with no escape sequences. The one exception is that two single
quotes in a row will produce a single single quote. Try this command:
:::vim
--- a/chapters/28.markdown Tue Apr 17 16:37:41 2012 +0100
+++ b/chapters/28.markdown Sat Jun 16 16:10:29 2012 -0400
@@ -21,7 +21,7 @@
Vim will open the first file in a vertical split to the right of the second
file. What happened here?
-First, Vim sees builds the command string by concatenating "rightbelow vsplit
+First, Vim builds the command string by concatenating "rightbelow vsplit
" with the result of the `bufname("#")` call.
We'll look at the function more later, but for now just trust that it returns
@@ -45,7 +45,7 @@
Contrast this with other languages, where programs constantly take input from
untrusted users. Vim is a unique environment where the normal security concerns
-simple aren't common.
+simply aren't common.
The second reason is that because Vimscript has sometimes arcane and tricky
syntax, `execute` is often the easiest, most straightforward way to get
--- a/chapters/30.markdown Tue Apr 17 16:37:41 2012 +0100
+++ b/chapters/30.markdown Sat Jun 16 16:10:29 2012 -0400
@@ -14,7 +14,7 @@
the return needed to actually perform the search. Combining `normal!` with
`execute` fixes that problem.
-`execute` lets you build commands programatically, so you can use Vim's normal
+`execute` lets you build commands programmatically, so you can use Vim's normal
string escape sequences to generate the non-printing characters you need. Try
the following command:
--- a/chapters/32.markdown Tue Apr 17 16:37:41 2012 +0100
+++ b/chapters/32.markdown Sat Jun 16 16:10:29 2012 -0400
@@ -2,7 +2,7 @@
===================================
In this chapter and the next we're going to walk through creating
-a fairly-complicated piece of Vimscript. We'll talk about several things we
+a fairly complicated piece of Vimscript. We'll talk about several things we
haven't seen before, as well as how some of the things we've studied fit
together in practice.
@@ -74,7 +74,7 @@
If you've read `:help grep` this should be pretty easy to understand. We've
looked at lots of mappings before, and there's nothing new here.
-Obviously we're not done yet, so lets refine this mapping until it meets our
+Obviously we're not done yet, so let's refine this mapping until it meets our
simplified goal.
The Search Term
@@ -113,9 +113,14 @@
:nnoremap <leader>g :grep -R '<cWORD>' .<cr>
Most shells treat single-quoted text as (almost) literal, so our mapping is much
-more robust now. However there's still one more problem with the search term!
-Try the mapping on the word "that's". It won't work, because the single quote
-inside the word interferes with the quotes in the grep command!
+more robust now.
+
+Escaping Shell Command Arguments
+--------------------------------
+
+However there's still one more problem with the search term. Try the mapping on
+the word "that's". It won't work, because the single quote inside the word
+interferes with the quotes in the grep command!
To get around this we can use Vim's `shellescape` function. Read `:help
escape()` and `:help shellescape()` to see how it works (it's pretty simple).
@@ -133,7 +138,51 @@
:::vim
:nnoremap <leader>g :execute "grep -R " . shellescape("<cWORD>") . " ."<cr>
-And now our mapping won't break if the word we're searching for happens to
+Try it out by running it on a normal word like "foo". It will work properly.
+Now try it out on a word with a quote in it, like "that's". It will not work!
+What happened?
+
+The problem is that Vim performed the `shellescape()` call *before* it expanded
+out special strings like `<cWORD>` in the command line. So Vim shell-escaped
+the literal string `"<cWORD>"` (which did nothing but add single quotes to it)
+and then concatenated it with the strings of our `grep` command.
+
+You can see this by running the following command:
+
+ :::vim
+ :echom shellescape("<cWORD>")
+
+Vim will output `'<cWORD>'`. Note that those quotes are actually part of the
+string -- Vim has prepared it for use as a shell command argument.
+
+To fix this we'll use the `expand()` function to force the expansion of
+`<cWORD>` into the actual string *before* it gets passed to `shellescape`.
+
+Let's break this apart and see how it works, in steps. Put your cursor over
+a word with q quote, like "that's", and run the following command:
+
+ :::vim
+ :echom expand("<cWORD>")
+
+Vim outputs `that's` because `expand("<cWORD>")` will return the current word
+under the cursor as a Vim string. Now let's add `shellescape` back in:
+
+ :::vim
+ :echom shellescape(expand("<cWORD>"))
+
+This time Vim outputs `'that'\''s'`. If this looks a little funny, you haven't
+had the pleasure of wrapping your brain around shell-quoting in all its insane
+glory. For now, don't worry about it. Just trust the Vim has taken the string
+from `expand` and escaped it properly.
+
+Now that we know how to get a fully-escaped version of the word under the
+cursor, it's time to concatenate it into our mapping! Run the following
+command:
+
+ :::vim
+ :nnoremap <leader>g :execute "grep -R " . shellescape(expand("<cWORD>")) . " ."<cr>
+
+Try it out. Our mapping won't break if the word we're searching for happens to
contain strange characters.
The process of starting with a trivial bit of Vimscript and transforming it
@@ -149,14 +198,14 @@
this command:
:::vim
- :nnoremap <leader>g :execute "grep! -R " . shellescape("<cWORD>") . " ."<cr>
+ :nnoremap <leader>g :execute "grep! -R " . shellescape(expand("<cWORD>")) . " ."<cr>
Try it out again and nothing will seem to happen. Vim has filled the quickfix
window with the results, but we haven't opened it yet. Run the following
command:
:::vim
- :nnoremap <leader>g :execute "grep! -R " . shellescape("<cWORD>") . " ."<cr>:copen<cr>
+ :nnoremap <leader>g :execute "grep! -R " . shellescape(expand("<cWORD>")) . " ."<cr>:copen<cr>
Now try the mapping and you'll see that Vim automatically opens the quickfix
window with the search results. All we did was tack `:copen<cr>` onto the end
@@ -166,7 +215,7 @@
searching. Run the following command:
:::vim
- :nnoremap <leader>g :silent execute "grep! -R " . shellescape("<cWORD>") . " ."<cr>:copen<cr>
+ :nnoremap <leader>g :silent execute "grep! -R " . shellescape(expand("<cWORD>")) . " ."<cr>:copen<cr>
We're done, so try it out and admire your hard work! The `silent` command just
runs the command that follows it while hiding any messages it would normally
@@ -185,6 +234,8 @@
Set up mappings for `:cnext` and `:cprevious` to make it easier to quickly run
through matches.
+Read `:help expand`.
+
Read `:help copen`.
Add a height to the `:copen` command in the mapping we created to make sure the
--- a/chapters/35.markdown Tue Apr 17 16:37:41 2012 +0100
+++ b/chapters/35.markdown Sat Jun 16 16:10:29 2012 -0400
@@ -133,9 +133,9 @@
:echo join(foo, '---')
:echo join([1, 2, 3], '')
-Vim displays "a b" and "a---b". `join` will join the items in the given list
-together into a string, separated by the given separator string (or a space if
-none is given), coercing each item to a string if necessary/possible.
+Vim displays "a b", "a---b" and "123". `join` will join the items in the given
+list together into a string, separated by the given separator string (or a space
+if none is given), coercing each item to a string if necessary/possible.
Run the following commands:
--- a/chapters/38.markdown Tue Apr 17 16:37:41 2012 +0100
+++ b/chapters/38.markdown Sat Jun 16 16:10:29 2012 -0400
@@ -3,7 +3,7 @@
In one of the first chapters we talked about how to set options in Vim. For
boolean options we can use `set someoption!` to "toggle" the option. This is
-expecially nice when we create a mapping for that command.
+especially nice when we create a mapping for that command.
Run the following command:
--- a/chapters/43.markdown Tue Apr 17 16:37:41 2012 +0100
+++ b/chapters/43.markdown Sat Jun 16 16:10:29 2012 -0400
@@ -108,7 +108,7 @@
Exercises
---------
-Install Pathogen if you haven't already done so.
+Install [Pathogen][] if you haven't already done so.
Create a Mercurial or Git repository for your plugin, called `potion`. You can
put it anywhere you like and symlink it into `~/.vim/bundle/potion/` or just put
--- a/chapters/45.markdown Tue Apr 17 16:37:41 2012 +0100
+++ b/chapters/45.markdown Sat Jun 16 16:10:29 2012 -0400
@@ -59,7 +59,7 @@
don't need to know about individual languages.
Potion has a bunch of other keywords that we haven't used in our toy program, so
-lets edit our syntax file to highlight those too:
+let's edit our syntax file to highlight those too:
:::vim
syntax keyword potionKeyword loop times to while
--- a/chapters/49.markdown Tue Apr 17 16:37:41 2012 +0100
+++ b/chapters/49.markdown Sat Jun 16 16:10:29 2012 -0400
@@ -78,17 +78,17 @@
Now run the following command to view the foldlevel of line 1:
:::vim
- :echom foldmethod(1)
+ :echom foldlevel(1)
Vim will display `0`. Now let's find the foldlevel of line 2:
:::vim
- :echom foldmethod(2)
+ :echom foldlevel(2)
Vim will display `1`. Let's try line 3:
:::vim
- :echom foldmethod(3)
+ :echom foldlevel(3)
Once again Vim displays `1`. This means that lines 2 and 3 are part of a level
1 fold.
@@ -330,7 +330,7 @@
a given line. Add the following function above `IndentLevel`:
:::vim
- function! s:NextNonBlankLine(lnum)
+ function! NextNonBlankLine(lnum)
let numlines = line('$')
let current = a:lnum + 1
--- a/chapters/51.markdown Tue Apr 17 16:37:41 2012 +0100
+++ b/chapters/51.markdown Sat Jun 16 16:10:29 2012 -0400
@@ -87,7 +87,7 @@
mappings will call.
You'll see this strategy in a lot of Vim plugins that create a number of similar
-mappings. It's easier to read and maintain then stuffing all the functionality
+mappings. It's easier to read and maintain than stuffing all the functionality
in to a bunch of mapping lines.
Change the `sections.vim` file to contain this:
@@ -298,7 +298,7 @@
execute 'silent normal! ' . dir . pattern . dir . flags . "\r"
endfunction
-Two things have changed. First, the function takes an extra argument so it know
+Two things have changed. First, the function takes an extra argument so it knows
whether it's being called from visual mode or not. Second, if it's called from
visual mode we run `gv` to restore the visual selection.
@@ -353,7 +353,7 @@
* Using a single function with several arguments to simplify creating related
mappings.
* Building up functionality in a Vimscript function incrementally.
-* Building up an `execute 'normal! ...'` string programatically.
+* Building up an `execute 'normal! ...'` string programmatically.
* Using simple searches to move around with regexes.
* Using special regex atoms like `%^` (beginning of file).
* Using search flags to modify how searches work.
--- a/publish.sh Tue Apr 17 16:37:41 2012 +0100
+++ b/publish.sh Sat Jun 16 16:10:29 2012 -0400
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
set -e
-../../bookmarkdown/bookmarkdown/bookmarkdown build
+./venv/bin/python ../bookmarkdown/bookmarkdown/bookmarkdown build
rsync --delete -az build/html/ sl:/var/www/vimscript/