--- a/acknowledgements.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/acknowledgements.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -8,10 +8,36 @@
[Zed Shaw]: http://zedshaw.com/
[Learn Python the Hard Way]: http://learnpythonthehardway.org/
-I'd also like to thank the following GitHub users who sent pull requests,
-pointed out typos, raised issues, and otherwise contributed:
+I'd also like to thank the following GitHub and Bitbucket users who sent pull
+requests, pointed out typos, raised issues, and otherwise contributed:
-* [Psycojoker](https://github.com/Psycojoker)
-* [manojkumarm](https://github.com/manojkumarm)
+* [aperiodic](https://github.com/aperiodic)
+* [chiphogg](https://github.com/chiphogg)
+* [ciwchris](https://github.com/ciwchris)
* [dmedvinsky](https://github.com/dmedvinsky)
* [flatcap](https://github.com/flatcap)
+* [manojkumarm](https://github.com/manojkumarm)
+* [markscholtz](https://github.com/markscholtz)
+* [marlun](https://github.com/marlun)
+* [NagatoPain](https://github.com/NagatoPain)
+* [Psycojoker](https://github.com/Psycojoker)
+* [tapichu](https://github.com/tapichu)
+* [ZyX-I](https://github.com/ZyX-I)
+* [nvie](https://github.com/nvie)
+* [riceissa](https://github.com/riceissa)
+* [mrgrubb](https://github.com/mrgrubb)
+* [Mr-Happy](https://github.com/Mr-Happy)
+* [jrib](https://github.com/jrib)
+* [sedm0784](https://github.com/sedm0784)
+* [lheiskan](https://github.com/lheiskan)
+* [nathanaelkane](https://github.com/nathanaelkane)
+* [lightningdb](https://github.com/lightningdb)
+* [sherrillmix](https://github.com/sherrillmix)
+* [cwarden](https://github.com/cwarden)
+* [manojkumarm](https://github.com/manojkumarm)
+* [nielsbom](https://github.com/nielsbom)
+* [billturner](https://github.com/billturner)
+* [mattsacks](https://github.com/mattsacks)
+* [helixbass](https://bitbucket.org/helixbass)
+
+I apologize to anyone I've forgotten.
--- a/chapters/01.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/01.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -12,7 +12,7 @@
:::vim
:echo "Hello, world!"
-You should see "Hello, world!" appear at the bottom of the window.
+You should see `Hello, world!` appear at the bottom of the window.
Persistent Echoing
------------------
@@ -22,15 +22,15 @@
:::vim
:echom "Hello again, world!"
-You should see "Hello again, world!" appear at the bottom of the window.
+You should see `Hello again, world!` appear at the bottom of the window.
To see the difference between these two commands, run the following:
:::vim
:messages
-You should see a list of messages. "Hello, world!" will *not* be in this list,
-but "Hello again, world!" *will* be in it.
+You should see a list of messages. `Hello, world!` will *not* be in this list,
+but `Hello again, world!` *will* be in it.
When you're writing more complicated Vimscript later in this book you may find
yourself wanting to "print some output" to help you debug problems. Plain old
@@ -41,9 +41,9 @@
Comments
--------
-Before moving, let's look at how to add comments. When you write Vimscript code
-(in your `~/.vimrc` file or any other one) you can add comments with the `"`
-character, like this:
+Before moving on, let's look at how to add comments. When you write Vimscript
+code (in your `~/.vimrc` file or any other one) you can add comments with the
+`"` character, like this:
:::vim
" Make space more useful
--- a/chapters/02.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/02.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -56,8 +56,8 @@
:set nonumber
:set number?
-Notice how the first `:set number?` command displayed "number" while the second
-displayed "nonumber".
+Notice how the first `:set number?` command displayed `number` while the second
+displayed `nonumber`.
Options with Values
-------------------
--- a/chapters/03.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/03.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -55,8 +55,8 @@
:::vim
:map <space> viw " Select word
-If you try pressing `<space>` now, something horrible will almost certainly
-happen. Why?
+If you try pressing space now, something horrible will almost certainly happen.
+Why?
When you press the space bar now, Vim thinks you want it to do what
`viw<space>"<space>Select<space>word` would do. Obviously this isn't what we
--- a/chapters/04.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/04.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -77,7 +77,7 @@
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
+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:
@@ -93,14 +93,15 @@
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.
+out the name of a long constant like `MAX_CONNECTIONS_ALLOWED`. I type out the
+constant in lower case and then uppercase it with the mapping instead of holding
+shift the entire time.
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.
+because you don't need to enter normal mode. You should end up back in normal
+mode at the end instead of in insert mode as well.
-Add that mapping to your `~/.vimrc` file as well.
+Add that mapping to your `~/.vimrc` file.
--- a/chapters/05.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/05.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -72,9 +72,9 @@
their behavior can change if you install a plugin that maps keys they depend on.
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 a key
-that the plugin has mapped.
+memorize every mapping it creates. 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
+a key that the plugin has mapped.
This would make installing plugins tedious and error-prone. There must be
a better way.
--- a/chapters/06.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/06.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -40,8 +40,8 @@
Leader
------
-Vim calls this "prefix" key "leader". You can set your leader key to whatever
-you like. Run this command:
+Vim calls this "prefix" key the "leader". You can set your leader key to
+whatever you like. Run this command:
:::vim
:let mapleader = "-"
@@ -65,17 +65,17 @@
on down the road. Defining it in one place makes it easy to change later.
Second, when someone else is looking at your `~/.vimrc` file they'll immediately
-know what you mean when you say `<leader>`, and they can simply copy your
-mapping into their own `~/.vimrc` if they like it even if they use a different
-leader.
+know what you mean when you say `<leader>`. They can simply copy your mapping
+into their own `~/.vimrc` if they like it even if they use a different leader.
Finally, many Vim plugins create mappings that start with `<leader>`. If you've
-already got it set up they'll work properly and will feel familiar.
+already got it set up they'll work properly and will feel familiar right out of
+the box.
Local Leader
------------
-Vim has a second "leader" key called "localleader". This is meant to be
+Vim has a second "leader" key called "local leader". This is meant to be
a prefix for mappings that only take effect for certain types of files, like
Python files or HTML files.
@@ -86,10 +86,10 @@
:let maplocalleader = "\\"
Notice that we have to use `\\` and not just `\` because `\` is the escape
-character in strings. You'll learn more about this later.
+character in Vimscript strings. You'll learn more about this later.
Now you can use `<localleader>` in mappings and it will work just like
-`<leader>` does, except for resolving to a different key.
+`<leader>` does (except for resolving to a different key, of course).
Feel free to change this key to something else if you don't like backslash.
--- a/chapters/07.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/07.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -4,17 +4,18 @@
Before we move on to learning more Vimscript, let's find a way to make it easier
to add new mappings to our `~/.vimrc` file.
-When you're coding away furiously at a problem and realize a new mapping would
-make your life easier, you should add it to your `~/.vimrc` file right then and
-there to make sure you don't forget, but you *don't* want to lose your
+Sometimes you're coding away furiously at a problem and realize a new mapping
+would make your editing easier. You should add it to your `~/.vimrc` file right
+then and there to make sure you don't forget, but you *don't* want to lose your
concentration.
-The idea is that you want to make it easier to make it easier to edit text.
+The idea of this chapter is that you want to make it easier to make it easier to
+edit text.
That's not a typo. Read it again.
-The idea is that you want to (make it easier to (make it easier to (edit
-text))).
+The idea of this chapter is that you want to (make it easier to (make it easier
+to (edit text))).
Editing Mapping
---------------
@@ -28,7 +29,7 @@
I like to think of this command as "**e**dit my **v**imrc file".
`$MYVIMRC` is a special Vim variable that points to your `~/.vimrc` file. Don't
-worry about that for right now, just trust me that that variable works.
+worry about that for right now, just trust me that it works.
`:vsplit` opens a new vertical split. If you'd prefer a horizontal split you
can replace it with `:split`.
@@ -44,45 +45,6 @@
When you're in the middle of coding and come up with a new mapping that would
save you time it's now trivial to add it to your `~/.vimrc` file.
-Meta Efficiency
----------------
-
-This is important because part of becoming more efficient is making it *easier*
-for yourself to become more efficient!
-
-Think of it this way: suppose you're trying to become a better digital
-photographer. When you're practicing taking photos and want to see how they
-came out, you:
-
-* Take a photo.
-* Upload it to your computer.
-* Open it and see how it looks.
-
-That process probably takes a minute. What if you could improve that?
-
-Let's say you invest $50 and buy an [Eye-Fi](http://www.eye.fi/). The Eye-Fi is
-a memory card for your camera that has a built-in wifi card, so as soon as you
-snap a photo it gets transferred to your computer.
-
-I know, we're definitely living in the future. Isn't it awesome?
-
-Now you spend an hour and write a little script to automatically open the photos
-that get transferred to your computer by the Eye-Fi.
-
-You've spent $50 and one hour, but now instead of taking a full minute to check
-your work, it takes ten seconds.
-
-Assuming you charge $100 per hour for freelance work, you've got to make up one
-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.
-
-109 photos is *nothing*. You'd blow past that number in a day's practice
-without even noticing!
-
-The same goes for our new mapping. It saves us only a few seconds each time we
-use it, but it pays for itself if we use it often enough.
-
Sourcing Mapping
----------------
@@ -105,12 +67,12 @@
* Use `<leader>ev` to open the file.
* Add the mapping.
-* Use `ZZ` to write the file and close the split, bringing us back to where we
- were.
+* Use `:wq<cr>` (or `ZZ`) to write the file and close the split, bringing you
+ back to where you were.
* Use `<leader>sv` to source the file and make our changes take effect.
That's eight keystrokes plus whatever it takes to define the mapping. It's very
-little overhead, which reduces the chance that we break our concentration.
+little overhead, which reduces the chance of breaking focus.
Exercises
---------
@@ -121,3 +83,4 @@
Try them out a few times, adding dummy mappings each time.
Read `:help myvimrc`.
+
--- a/chapters/08.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/08.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -16,7 +16,7 @@
:::text
One adn two.
-As soon as you hit space after typing the "adn" Vim will replace it with "and".
+As soon as you hit space after typing the `adn` Vim will replace it with `and`.
Correcting typos like this is a great use for abbreviations. Run these
commands:
@@ -57,7 +57,7 @@
If you want to read the *full* description of this option's format you can check
out `:help isfname`, but I'll warn you that you'd better have a beer at the
-ready if you don't want to start crying while reading.
+ready for this one.
For our purposes you can simply remember that abbreviations will be expanded
when you type anything that's not a letter, number, or underscore.
@@ -70,7 +70,7 @@
:::vim
:iabbrev @@ steve@stevelosh.com
- :iabbrev ccopy Copyright 2011 Steve Losh, all rights reserved.
+ :iabbrev ccopy Copyright 2013 Steve Losh, all rights reserved.
Feel free to replace my name and email address with your own, then enter insert
mode and try them out.
--- a/chapters/09.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/09.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -3,7 +3,7 @@
I know we've talked a lot about mappings so far, but we're going to practice
them again now. Mappings are one of the easiest and fastest ways to make your
-Vim editing more productive, so it's good to focus on them quite a bit.
+Vim editing more productive so it's good to focus on them quite a bit.
One concept that has showed up in several examples but that we haven't
explicitly talked about is mapping a sequence of multiple keys.
@@ -90,3 +90,4 @@
Add all of these mappings to your `~/.vimrc` file, making sure to use your "edit
my `~/.vimrc`" and "source my `~/.vimrc`" mappings to do so.
+
--- a/chapters/10.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/10.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -49,14 +49,14 @@
:inoremap <esc> <nop>
This effectively disables the escape key in insert mode by telling Vim to
-perform `<nop>` (no operation) instead.
+perform `<nop>` (no operation) instead. Now you *have* to use your `jk` mapping
+to exit insert mode.
-Now you *have* to use your `jk` mapping to exit insert mode. At first you'll
-forget, type escape and start trying to do something in normal mode and you'll
-wind up with stray characters in your text. It will be frustrating, but if you
-stick with it you'll be surprised at how fast your mind and fingers absorb the
-new mapping. Within an hour or two you won't be accidentally hitting escape any
-more.
+At first you'll forget, type escape and start trying to do something in normal
+mode and you'll wind up with stray characters in your text. It will be
+frustrating, but if you stick with it you'll be surprised at how fast your mind
+and fingers absorb the new mapping. Within an hour or two you won't be
+accidentally hitting escape any more.
This idea applies to any new mapping you create to replace an old one, and even
to life in general. When you want to change a habit, make it harder or
@@ -80,3 +80,4 @@
If you still use the arrow keys in insert mode, map them to `<nop>` there too.
The right way to use Vim is to get out of insert mode as soon as you can and use
normal mode to move around.
+
--- a/chapters/11.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/11.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -2,7 +2,7 @@
=================================
Now we're going to take a few minutes to revisit three things we've already
-talked about: mappings, abbreviations, and options, but with a twist: we're
+talked about: mappings, abbreviations, and options, but with a twist. We're
going to set each of them in a single buffer at a time.
The true power of this idea will become apparent in the next chapter, but we
@@ -22,7 +22,7 @@
:nnoremap <buffer> <leader>x dd
Now stay in file `foo`, make sure you're in normal mode, and type `<leader>d`.
-Vim will delete a line. This is nothing new to us.
+Vim will delete a line. This is nothing new.
Still in file `foo`, type `<leader>x`. Vim will delete a line again. This
makes sense because we mapped `<leader>x` to `dd` as well.
@@ -30,7 +30,7 @@
Now move over to file `bar`. While in normal mode, type `<leader>d`. Again,
Vim deletes the current line. Nothing surprising here either.
-Now for the twist: while still in file `bar` type `<leader>x`.
+Now for the twist: while still in file `bar`, type `<leader>x`.
Instead of deleting the entire line, Vim just deleted a single character!
What happened?
--- a/chapters/12.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/12.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -121,7 +121,7 @@
This is almost like our last command, except it will also reindent the code
whenever we *read* an HTML file as well as when we write it. This could be
-useful if you have coworkers that don't indent their HTML well.
+useful if you have coworkers that don't indent their HTML nicely.
A common idiom in Vim scripting is to pair the `BufRead` and `BufNewFile` events
together to run a command whenever you open a certain kind of file, regardless
@@ -142,8 +142,8 @@
following commands:
:::vim
- :autocmd FileType javascript nnoremap <buffer> <localleader>c I//
- :autocmd FileType python nnoremap <buffer> <localleader>c I#
+ :autocmd FileType javascript nnoremap <buffer> <localleader>c I//<esc>
+ :autocmd FileType python nnoremap <buffer> <localleader>c I#<esc>
Open a Javascript file (a file that ends in `.js`), pick a line and type
`<localleader>c`. This will comment out the line.
@@ -160,15 +160,12 @@
think about moving to the beginning of the line and adding a comment character
we can simply think "comment this line".
-You may have noticed that this mapping leaves us in insert mode. Unfortunately
-we can't fix that just yet, but we'll get to it later in the book!
-
Exercises
---------
Skim `:help autocmd-events` to see a list of all the events you can bind
-autocommands to. You don't need to memorize each one right now; just try to get
-a feel for the kinds of things you can do.
+autocommands to. You don't need to memorize each one right now. Just try to
+get a feel for the kinds of things you can do.
Create a few `FileType` autocommands that use `setlocal` to set options for your
favorite filetypes just the way you like them. Some options you might like to
--- a/chapters/14.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/14.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -7,10 +7,10 @@
:autocmd BufWrite * :echom "Writing buffer!"
Now write the current buffer with `:write` and run `:messages` to view the
-message log. You should see the "Writing buffer!" message in the list.
+message log. You should see the `Writing buffer!` message in the list.
Now write the current buffer again and run `:messages` to view the message log.
-You should see the "Writing buffer!" message in the list twice.
+You should see the `Writing buffer!` message in the list twice.
Now run the exact same autocommand again:
@@ -18,7 +18,7 @@
:autocmd BufWrite * :echom "Writing buffer!"
Write the current buffer one more time and run `:messages`. You will see the
-"Writing buffer!" message in the list *four* times. What happened?
+`Writing buffer!` message in the list *four* times. What happened?
When you create an autocommand like this Vim has no way of knowing if you want
it to replace an existing one. In our case, Vim created two *separate*
@@ -73,7 +73,7 @@
The indentation in the middle two lines is insignificant. You don't have to
type it if you don't want to.
-Write a buffer and check `:messages`. You should see both "Foo" and "Bar". Now
+Write a buffer and check `:messages`. You should see both `Foo` and `Bar`. Now
run the following commands:
:::vim
@@ -90,7 +90,7 @@
What happened when you wrote the file? Was it what you expected?
-If you thought Vim would "replace" the group, you can see that you guessed
+If you thought Vim would replace the group, you can see that you guessed
wrong. Don't worry, most people think the same thing at first (I know I did).
When you use `augroup` multiple times Vim will *combine* the groups each time.
@@ -105,7 +105,7 @@
:augroup END
Now try writing your file and checking `:messages`. This time Vim only echoed
-"Cats" when you wrote the file.
+`Cats` when you wrote the file.
Using Autocommands in Your Vimrc
--------------------------------
@@ -136,3 +136,4 @@
Try to figure out what the mapping in the last example does.
Read `:help autocmd-groups`.
+
--- a/chapters/15.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/15.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -65,8 +65,8 @@
return foo
-Put you cursor on the `i` in the second line and press `db`. What happened?
-Vim deleted the entire body of the function, all the way up until the "return",
+Put your cursor on the `i` in the second line and press `db`. What happened?
+Vim deleted the entire body of the function, all the way up until the `return`,
which our mapping used Vim's normal search to find.
When you're trying to think about how to define a new operator-pending movement,
@@ -98,7 +98,7 @@
:::python
print foo(bar)
-Put your cursor somewhere in the word "print" and type `cin(`. Vim will delete
+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 parentheses", and it will
@@ -114,16 +114,16 @@
Try it out on some text of your own to make sure it works.
So how do these mappings work? First, the `<c-u>` is something special that you
-can ignore for now -- just know that it needs to be there to make the mappings
-work in all cases. If we remove that we're left with:
+can ignore for now -- just trust me that it needs to be there to make the
+mappings work in all cases. If we remove that we're left with:
:::vim
:normal! F)vi(<cr>
`:normal!` is something we'll talk about in a later chapter, but for now it's
-enough to know that it's a command that can be used to simulate pressing keys in
-normal mode. For example, running `:normal! dddd` will delete two lines, just
-like pressing `dddd`. The `<cr>` at the end of the mapping is what executes the
+enough to know that it is a command used to simulate pressing keys in normal
+mode. For example, running `:normal! dddd` will delete two lines, just like
+pressing `dddd`. The `<cr>` at the end of the mapping is what executes the
`:normal!` command.
So now we know that the mapping is essentially just running the last block of
--- a/chapters/16.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/16.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -32,7 +32,7 @@
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.
+section you're in and put you in insert mode ("change inside heading").
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
@@ -68,13 +68,13 @@
Execute
-------
-The `execute` takes a Vimscript string (which we'll cover in more detail later)
-and performs it as a command. Run this:
+The `execute` command takes a Vimscript string (which we'll cover in more detail
+later) and performs it as a command. Run this:
:::vim
:execute "write"
-Vim will write your file, just as if you had typed `:write`. Now run this
+Vim will write your file, just as if you had typed `:write<cr>`. Now run this
command:
:::vim
@@ -165,7 +165,7 @@
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
+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:
@@ -213,3 +213,4 @@
Create a "inside next email address" operator-pending mapping so you can say
"change inside next email address". `in@` is a good candidate for the keys to
map. You'll probably want to use `/...some regex...<cr>` for this.
+
--- a/chapters/17.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/17.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -14,7 +14,7 @@
:::vim
:set statusline=%f\ -\ FileType:\ %y
-Now you'll see something like "foo.markdown - FileType: [markdown]" in the
+Now you'll see something like `foo.markdown - FileType: [markdown]` in the
status line.
If you're familiar with C's `printf` or Python's string interpolation the format
@@ -49,7 +49,7 @@
:set statusline+=%L " Total lines
Now the status line contains only the current line number and number of lines in
-the file, and looks something like "12/223".
+the file, and looks something like `12/223`.
Width and Padding
-----------------
@@ -94,7 +94,7 @@
:::vim
:set statusline=%04l
-Now your status line will read "0012" when on line twelve.
+Now your status line will read `0012` when on line twelve.
Finally, you can also set the maximum width of a code's output. Run this
command:
--- a/chapters/18.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/18.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -13,7 +13,7 @@
----------
Vimscript is extremely powerful, but has grown organically over the years into
-a twisty maze ready to ensnare the unwary programmers who enter it.
+a twisty maze ready to ensnare unwary programmers who enter it.
Options and commands are often terse and hard to read, and working around
compatibility issues can increase the complexity of your code. Writing a plugin
@@ -21,7 +21,7 @@
Be defensive when writing anything that takes more than a few lines of
Vimscript. Add a comment explaining what it does, and if there is a relevant
-help topic mention it in that comment!
+help topic, mention it in the comment!
This not only benefits you when you try to maintain it months or years later,
but also helps other people understand it if you share your `~/.vimrc` file on
@@ -52,11 +52,12 @@
files.
Go ahead and run `:setlocal foldmethod=marker` in the window with your
-`~/.vimrc` now. Sourcing the file won't work, because Vim has already set the
-FileType for this file and the autocommand only fires when that happens. In the
-future you won't need to do it manually.
+`~/.vimrc` file now. Sourcing the file won't work, because Vim has already set
+the FileType for this file and the autocommand only fires when that happens. In
+the future you won't need to do it manually.
-Now add lines before and after that autocommand group so that it looks like this:
+Now add lines before and after that autocommand group so that it looks like
+this:
:::vim
" Vimscript file settings ---------------------- {{{
--- a/chapters/19.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/19.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -14,14 +14,14 @@
:let foo = "bar"
:echo foo
-Vim will display "bar". `foo` is now a variable, and we've assigned it
-a string: "bar". Now run these commands:
+Vim will display `bar`. `foo` is now a variable, and we've assigned it
+a string: `"bar"`. Now run these commands:
:::vim
:let foo = 42
:echo foo
-Vim will display "42", because we've reassigned `foo` to the integer "42".
+Vim will display `42`, because we've reassigned `foo` to the integer `42`.
From these short examples it may seem like Vimscript is dynamically typed.
That's not the case, but we'll talk more about that later.
@@ -36,7 +36,7 @@
:set textwidth=80
:echo &textwidth
-Vim will display "80". Using an ampersand in front of a name tells Vim that
+Vim will display `80`. Using an ampersand in front of a name tells Vim that
you're referring to the option, not a variable that happens to have the same
name.
@@ -46,13 +46,13 @@
:set nowrap
:echo &wrap
-Vim displays "0". Now try these commands:
+Vim displays `0`. Now try these commands:
:::vim
:set wrap
:echo &wrap
-This time Vim displays "1". This is a very strong hint that Vim treats the
+This time Vim displays `1`. This is a very strong hint that Vim treats the
integer `0` as "false" and the integer `1` as "true". It would be reasonable to
assume that Vim treats *any* non-zero integer as "truthy", and this is indeed
the case.
@@ -64,7 +64,7 @@
:let &textwidth = 100
:set textwidth?
-Vim will display "textwidth=100".
+Vim will display `textwidth=100`.
Why would we want to do this when we could just use `set`? Run the following
commands:
@@ -73,7 +73,7 @@
:let &textwidth = &textwidth + 10
:set textwidth?
-This time Vim displays "textwidth=110". When you set an option using `set` you
+This time Vim displays `textwidth=110`. When you set an option using `set` you
can only set it to a single literal value. When you use `let` and set it as
a variable you can use the full power of Vimscript to determine the value.
@@ -105,14 +105,14 @@
Now put your cursor somewhere in your text and type `"ap`. This command tells
Vim to "paste the contents of register `a` here". We just set the contents of
-that register, so Vim pastes "hello!" into your text.
+that register, so Vim pastes `hello!` into your text.
Registers can also be read. Run the following command:
:::vim
:echo @a
-Vim will echo "hello!".
+Vim will echo `hello!`.
Select a word in your file and yank it with `y`, then run this command:
--- a/chapters/20.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/20.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -12,7 +12,7 @@
:let b:hello = "world"
:echo b:hello
-As expected, Vim displays "world". Now switch to the other buffer and run the
+As expected, Vim displays `world`. Now switch to the other buffer and run the
`echo` command again:
:::vim
--- a/chapters/21.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/21.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -45,7 +45,7 @@
: echom "ONE"
:endif
-Vim will display "ONE", because the integer `1` is "truthy". Now try these
+Vim will display `ONE`, because the integer `1` is "truthy". Now try these
commands:
:::vim
@@ -53,7 +53,7 @@
: echom "ZERO"
:endif
-Vim will *not* display "ZERO" because the integer `0` is "falsy". Let's see how
+Vim will *not* display `ZERO` because the integer `0` is "falsy". Let's see how
strings behave. Run these commands:
:::vim
@@ -80,8 +80,8 @@
:echom "10hello" + 10
:echom "hello10" + 10
-The first command causes Vim to echo "10", the second command echoes "20", and
-the third echoes "10" again!
+The first command causes Vim to echo `10`, the second command echoes `20`, and
+the third echoes `10` again!
After observing all of these commands we can draw a few informed conclusions
about Vimscript:
@@ -109,7 +109,7 @@
: echom "finally!"
:endif
-Vim echoes "finally!" because both of the previous conditions evaluate to zero,
+Vim echoes `finally!` because both of the previous conditions evaluate to zero,
which is falsy.
Exercises
--- a/chapters/22.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/22.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -12,7 +12,7 @@
: echom "foo"
:endif
-Vim will, of course, display "foo". Now run these commands:
+Vim will, of course, display `foo`. Now run these commands:
:::vim
:if 10 > 2001
@@ -29,7 +29,7 @@
: echom "second"
:endif
-Vim displays "second". Nothing surprising here. Let's try comparing strings.
+Vim displays `second`. Nothing surprising here. Let's try comparing strings.
Run these commands:
:::vim
@@ -39,7 +39,7 @@
: echom "two"
:endif
-Vim echoes "two". There's still nothing surprising, so what was I going on
+Vim echoes `two`. There's still nothing surprising, so what was I going on
about at the beginning of the chapter?
Case Sensitivity
@@ -97,7 +97,7 @@
: echom "second"
:endif
-Vim displays "first" because `==?` is the "case-insensitive no matter what the
+Vim displays `first` because `==?` is the "case-insensitive no matter what the
user has set" comparison operator. Now run the following commands:
:::vim
@@ -108,7 +108,7 @@
: echom "two"
:endif
-Vim displays "two" because `==#` is the "case-sensitive no matter what the user
+Vim displays `two` because `==#` is the "case-sensitive no matter what the user
has set" comparison operator.
The moral of this story is that you should *always* use explicit case sensitive
--- a/chapters/23.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/23.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -31,7 +31,7 @@
:::vim
:call Meow()
-Vim will display "Meow!" as expected.
+Vim will display `Meow!` as expected.
Let's try returning a value. Run the following commands:
@@ -46,7 +46,7 @@
:echom GetMeow()
Vim will call the function and give the result to `echom`, which will display
-"Meow String!".
+`Meow String!`.
Calling Functions
-----------------
@@ -61,7 +61,7 @@
:call Meow()
:call GetMeow()
-The first will display "Meow!" but the second doesn't display anything. The
+The first will display `Meow!` but the second doesn't display anything. The
return value is thrown away when you use `call`, so this is only useful when the
function has side effects.
@@ -81,7 +81,7 @@
:::vim
:echom Meow()
-This will display two lines: "Meow!" and "0". The first obviously comes from
+This will display two lines: `Meow!` and `0`. The first obviously comes from
the `echom` inside of `Meow`. The second shows us that if a Vimscript function
doesn't return a value, it implicitly returns `0`. Let's use this to our
advantage. Run the following commands:
--- a/chapters/24.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/24.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -14,7 +14,7 @@
:::vim
:call DisplayName("Your Name")
-Vim will display two lines: "Hello! My name is:" and "Your Name".
+Vim will display two lines: `Hello! My name is:` and `Your Name`.
Notice the `a:` in the name of the variable that we passed to the `echom`
command. This represents a variable scope, which we talked about in an earlier
@@ -56,12 +56,12 @@
The `...` in the function definition tells Vim that this function can take any
number of arguments. This is like a `*args` argument in a Python function.
-The first line of the function echoes the message `a:0` and displays "2". When
+The first line of the function echoes the message `a:0` and displays `2`. When
you define a function that takes a variable number of arguments in Vim, `a:0`
will be set to the number of extra arguments you were given. In this case we
-passed two arguments to `Varg` so Vim displayed "2".
+passed two arguments to `Varg` so Vim displayed `2`.
-The second line echoes `a:1` which displays "a". You can use `a:1`, `a:2`, etc
+The second line echoes `a:1` which displays `a`. You can use `a:1`, `a:2`, etc
to refer to each extra argument your function receives. If we had used `a:2`
Vim would have displayed "b".
@@ -83,7 +83,7 @@
:call Varg2("a", "b", "c")
-We can see that Vim puts "a" into the named argument `a:foo`, and the rest are
+We can see that Vim puts `"a"` into the named argument `a:foo`, and the rest are
put into the list of varargs.
Assignment
@@ -111,7 +111,7 @@
:call AssignGood("test")
-This time the function works, and Vim displays "Yep".
+This time the function works, and Vim displays `Yep`.
Exercises
---------
--- a/chapters/25.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/25.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -15,12 +15,12 @@
:::vim
:echom 100
-No surprises here -- Vim displays "100". Now run this command:
+No surprises here -- Vim displays `100`. Now run this command:
:::vim
:echom 0xff
-This time Vim displays "255". You can specify numbers in hex notation by
+This time Vim displays `255`. You can specify numbers in hex notation by
prefixing them with `0x` or `0X`. Now run this command:
:::vim
@@ -33,8 +33,8 @@
:echom 017
:echom 019
-Vim will print "15" for the first command, because "17" in octal is equal to
-"15" in decimal. For the second command Vim treats it as a decimal number, even
+Vim will print `15` for the first command, because `17` in octal is equal to
+`15` in decimal. For the second command Vim treats it as a decimal number, even
though it starts with a `0`, because it's not a valid octal number.
Because Vim silently does the wrong thing in this case, I'd recommend avoiding
@@ -51,24 +51,24 @@
Notice that we're using `echo` here and not `echom` like we usually to. We'll
talk about why in a moment.
-Vim displays "100.1" as expected. You can also use exponential notation. Run
+Vim displays `100.1` as expected. You can also use exponential notation. Run
this command:
:::vim
:echo 5.45e+3
-Vim displays "5450.0". A negative exponent can also be used. Run this command:
+Vim displays `5450.0`. A negative exponent can also be used. Run this command:
:::vim
:echo 15.45e-2
-Vim displays "0.1545". The `+` or `-` before the power of ten is optional. If
+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
-Vim will display "1.53e10", which is equivalent. The decimal point and number
+Vim will display `1.53e10`, which is equivalent. The decimal point and number
after it are *not* optional. Run the following command and see that it crashes:
:::vim
@@ -84,7 +84,7 @@
:::vim
:echo 2 * 2.0
-Vim displays "4.0".
+Vim displays `4.0`.
Division
--------
@@ -94,14 +94,14 @@
:::vim
:echo 3 / 2
-Vim displays "1". If you want Vim to perform floating 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:
:::vim
:echo 3 / 2.0
-Vim displays "1.5". The "3" is coerced to a Float, and then normal floating
+Vim displays `1.5`. The `3` is coerced to a Float, and then normal floating
point division is performed.
Exercises
--- a/chapters/26.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/26.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -9,7 +9,7 @@
:::vim
:echom "Hello"
-Vim will echo "Hello". So far, so good.
+Vim will echo `Hello`. So far, so good.
Concatenation
-------------
@@ -20,7 +20,7 @@
:::vim
:echom "Hello, " + "world"
-What happened? Vim displayed "0" for some reason!
+What happened? Vim displayed `0` for some reason!
Here's the issue: Vim's `+` operator is *only* for Numbers. When you pass
a string to `+` Vim will try to coerce it to a Number before performing the
@@ -29,8 +29,8 @@
:::vim
:echom "3 mice" + "2 cats"
-This time Vim displays "5", because the strings are coerced to the numbers "3"
-and "2" respectively.
+This time Vim displays `5`, because the strings are coerced to the numbers `3`
+and `2` respectively.
When I said "Number" I really *meant* Number. Vim will *not* coerce strings to
Floats! Try this command to see prove this:
@@ -38,8 +38,8 @@
:::vim
:echom 10 + "10.10"
-Vim displays "20" because it dropped everything after the decimal point when
-coercing "10.10" to a Number.
+Vim displays `20` because it dropped everything after the decimal point when
+coercing `10.10` to a Number.
To combine strings you need to use the concatenation operator. Run the
following command:
@@ -47,7 +47,7 @@
:::vim
:echom "Hello, " . "world"
-This time Vim displays "Hello, world". `.` is the "concatenate strings"
+This time Vim displays `Hello, world`. `.` is the "concatenate strings"
operator in Vim, which lets you combine strings. It doesn't add whitespace or
anything else in between.
@@ -56,7 +56,7 @@
:::vim
:echom 10 . "foo"
-Vim will display "10foo". First it coerces `10` to a String, then it
+Vim will display `10foo`. First it coerces `10` to a String, then it
concatenates it with the string on the right hand side. Things get a bit
stickier when we're working with Floats, though. Run this command:
@@ -99,13 +99,13 @@
:::vim
:echo "foo\nbar"
-This time Vim will display two lines, "foo" and "bar", because the `\n` is
+This time Vim will display two lines, `foo` and `bar`, because the `\n` is
replaced with a newline. Now try running this command:
:::vim
:echom "foo\nbar"
-Vim will display something like "foo^@bar". When you use `echom` instead of
+Vim will display something like `foo^@bar`. When you use `echom` instead of
`echo` with a String Vim will echo the *exact* characters of the string, which
sometimes means that it will show a different representation than plain old
`echo`. `^@` is Vim's way of saying "newline character".
@@ -145,7 +145,7 @@
: echo "no"
:endif
-Vim will display "no". If you're wondering why this happens you should reread
+Vim will display `no`. If you're wondering why this happens you should reread
the chapter on conditionals, because we talked about it there.
Exercises
--- a/chapters/27.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/27.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -12,13 +12,13 @@
:::vim
:echom strlen("foo")
-Vim displays "3", which is the length of the string "foo". Now try the
+Vim displays `3`, which is the length of the string `"foo"`. Now try the
following command:
:::vim
:echom len("foo")
-Vim once again displays "3". When used with Strings `len` and `strlen` have
+Vim once again displays `3`. When used with Strings `len` and `strlen` have
identical effects. We'll come back to `len` later in the book.
Splitting
@@ -52,14 +52,14 @@
:::vim
:echo join(["foo", "bar"], "...")
-Vim will display "foo...bar". Don't worry about the list syntax for now.
+Vim will display `foo...bar`. Don't worry about the list syntax for now.
`split` and `join` can be paired to great effect. Run the following command:
:::vim
:echo join(split("foo bar"), ";")
-Vim displays "foo;bar". First we split the string "foo bar" into a list, then
+Vim displays `foo;bar`. First we split the string `"foo bar"` into a list, then
we joined that list together using a semicolon as the separator.
Lower and Upper Case
@@ -72,7 +72,7 @@
:echom tolower("Foo")
:echom toupper("Foo")
-Vim displays "foo" and "FOO". This should be pretty easy to understand.
+Vim displays `foo` and `FOO`. This should be pretty easy to understand.
In many languages (like Python) a common idiom is to force strings to lowercase
before comparing them to perform a case-insensitive comparison. In Vimscript
--- a/chapters/29.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/29.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -62,7 +62,7 @@
:::vim
:normal! /foo<cr>
-At first glance it may seem like this should perform a search for "foo", but
+At first glance it may seem like this should perform a search for `foo`, but
you'll see that it doesn't work. The problem is that `normal!` doesn't parse
special character sequences like `<cr>`.
--- a/chapters/30.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/30.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -7,7 +7,7 @@
:::vim
:execute "normal! gg/foo\<cr>dd"
-This will move to the top of the file, search for the first occurrence of "foo",
+This will move to the top of the file, search for the first occurrence of `foo`,
and delete the line that contains it.
Previously we tried to use `normal!` with a search command but couldn't enter
--- a/chapters/31.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/31.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -49,7 +49,7 @@
/print
As you type in each letter, Vim will start highlighting them in the first line.
-When you press return to execute the search *all* the instances of "print" will
+When you press return to execute the search *all* the instances of `print` will
be highlighted and your cursor will be moved to the next match.
Now try running the following command:
@@ -57,7 +57,7 @@
:::vim
:execute "normal! gg/print\<cr>"
-This will go to the top of the file and perform a search for "print", putting us
+This will go to the top of the file and perform a search for `print`, putting us
at the first match. It does this using `:execute "normal! ..."` which we saw in
the previous chapter.
@@ -67,7 +67,7 @@
:::vim
:execute "normal! gg/print\<cr>n"
-Vim will put the cursor on the second "print" in the buffer (and all the matches
+Vim will put the cursor on the second `print` in the buffer (and all the matches
will be highlighted).
Let's try going in the opposite direction. Run this command:
--- a/chapters/32.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/32.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -7,7 +7,7 @@
together in practice.
As you work through this case study make sure to look up anything unfamiliar
-with `:help`. If you coast through without fully understanding everything you
+with `:help`. If you coast through without fully understanding everything, you
won't learn much.
Grep
@@ -18,24 +18,24 @@
quickfix window before.
In a nutshell: `:grep ...` will run an external grep program with any arguments
-you give, parse the result, and fill the quickfix list for easy use inside of
-Vim.
+you give, parse the result, and fill the quickfix list so you can jump to
+results inside Vim.
-Our example is going to make it easier to invoke by adding a "grep operator"
-that you can use with any of Vim's built-in (or custom!) motions to select the
-text you want to search for.
+Our example is going to make `:grep` easier to invoke by adding a "grep
+operator" you can use with any of Vim's built-in (or custom!) motions to select
+the text you want to search for.
Usage
-----
The first thing you should think about when creating any non-trivial piece of
Vimscript is: "how will this functionality be used?". Try to come up with
-a smooth, easy, intuitive way for you and your code's users to invoke it.
+a smooth, easy, intuitive way to invoke it.
In this case I'll do that step for you:
* We're going to create a "grep operator" and bind it to `<leader>g`.
-* It will act like any other Vim operator and take a motion, like `w` or `i{`.
+* It will act like any other Vim operator and take a motion (like `w` or `i{`).
* It will perform the search immediately and open the quickfix window to show
the results.
* It will *not* jump to the first result, because that can be jarring if the
@@ -51,14 +51,14 @@
the word after it, then grep for the selected text.
There are many, *many* other ways to use this. It may seem like it will take
-a lot of coding, but actually all we need to do is implement the operator
-functionality -- Vim will handle the rest.
+a lot of coding, but actually all we need to do is implement the "operator"
+functionality and Vim will handle the rest.
A Preliminary Sketch
--------------------
One thing that's sometimes helpful when writing tricky bits of Vimscript is to
-simplify your goal and implement that to get an idea of the "shape" your final
+simplify your goal and implement *that* to get an idea of the "shape" your final
solution will take.
Let's simplify our goal to: "create a mapping to search for the word under the
@@ -81,7 +81,7 @@
---------------
First we need to search for the word under the cursor, not the string
-"something". Run the following command:
+`something`. Run the following command:
:::vim
:nnoremap <leader>g :grep -R <cword> .<cr>
@@ -95,12 +95,12 @@
:::vim
:nnoremap <leader>g :grep -R <cWORD> .<cr>
-Now try the mapping when your cursor is over something like "foo-bar". Vim will
-grep for "foo-bar" instead of just part of the word.
+Now try the mapping when your cursor is over something like `foo-bar`. Vim will
+grep for `foo-bar` instead of just part of the word.
There's still a problem with our search term: if there are any special shell
characters in it Vim will happily pass them along to the external grep command,
-which will explode (or, worse, do something terrible).
+which will explode (or worse: do something terrible).
Go ahead and try this to make sure it breaks. Type `foo;ls` into a file and run
the mapping while your cursor is over it. The grep command will fail, and Vim
@@ -118,8 +118,8 @@
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
+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
@@ -138,9 +138,9 @@
:::vim
:nnoremap <leader>g :execute "grep -R " . shellescape("<cWORD>") . " ."<cr>
-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?
+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 still doesn't
+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
@@ -153,13 +153,13 @@
: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.
+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:
+a word with a quote, like `that's`, and run the following command:
:::vim
:echom expand("<cWORD>")
@@ -170,10 +170,10 @@
:::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.
+This time Vim outputs `'that'\''s'`. If this looks a little funny, you probably
+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
@@ -182,7 +182,7 @@
:::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
+Try it out. This 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
@@ -228,6 +228,8 @@
Read `:help :grep` if you didn't read it before.
+Read `:help cword`.
+
Read `:help cnext` and `:help cprevious`. Try them out after using your new
grep mapping.
@@ -242,3 +244,4 @@
quickfix window is opened to whatever height you prefer.
Read `:help silent`.
+
--- a/chapters/33.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/33.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -48,7 +48,7 @@
endfunction
Write the file and source it with `:source %`. Try it out by pressing
-`<leader>giw` to say "grep inside word". Vim will echo "Test" *after* accepting
+`<leader>giw` to say "grep inside word". Vim will echo `Test` *after* accepting
the `iw` motion, which means we've laid out the skeleton.
The function is simple and nothing we haven't seen before, but that mapping is
@@ -69,7 +69,7 @@
vnoremap <leader>g :<c-u>call GrepOperator(visualmode())<cr>
Write and source the file. Now visually select something and press `<leader>g`.
-Nothing happens, but Vim does echo "Test", so our function is getting called.
+Nothing happens, but Vim does echo `Test`, so our function is getting called.
We've seen the `<c-u>` in this mapping before but never explained what it did.
Try visually selecting some text and pressing `:`. Vim will open a command line
@@ -86,7 +86,7 @@
the `visualmode()` we're passing as an argument is new. This function is
a built-in Vim function that returns a one-character string representing the
last type of visual mode used: `"v"` for characterwise, `"V"` for
-linewise, and a `ctrl-v` character for blockwise.
+linewise, and a `Ctrl-v` character for blockwise.
Motion Types
------------
--- a/chapters/34.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/34.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -5,7 +5,6 @@
being considerate and making your users' lives easier. We can do two more
things to make our operator play nicely in the Vim ecosystem.
-
Saving Registers
----------------
@@ -51,7 +50,7 @@
Namespacing
-----------
-Our script created a function named "GrepOperator" in the global namespace.
+Our script created a function named `GrepOperator` in the global namespace.
This probably isn't a big deal, but when you're writing Vimscript it's far
better to be safe than sorry.
--- a/chapters/35.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/35.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -28,7 +28,7 @@
:::vim
:echo [0, [1, 2]][1]
-Vim displays "[1, 2]". You can also index from the end of the list, much like
+Vim displays `[1, 2]`. You can also index from the end of the list, much like
Python. Try this command:
:::vim
@@ -46,7 +46,7 @@
:::vim
:echo ['a', 'b', 'c', 'd', 'e'][0:2]
-Vim displays "['a', 'b', 'c']" (elements 0, 1 and 2). You can safely exceed the
+Vim displays `['a', 'b', 'c']` (elements 0, 1 and 2). You can safely exceed the
upper bound as well. Try this command:
:::vim
@@ -59,7 +59,7 @@
:::vim
:echo ['a', 'b', 'c', 'd', 'e'][-2:-1]
-Vim displays "['d', 'e']" (elements -2 and -1).
+Vim displays `['d', 'e']` (elements -2 and -1).
When slicing lists you can leave off the first index to mean "the beginning"
and/or the last index to mean "the end". Run the following commands:
@@ -68,7 +68,7 @@
:echo ['a', 'b', 'c', 'd', 'e'][:1]
:echo ['a', 'b', 'c', 'd', 'e'][3:]
-Vim displays "['a', 'b']" and "['d', 'e']".
+Vim displays `['a', 'b']` and `['d', 'e']`.
Like Python, Vimscript allows you to index and slice strings too. Run the
following command:
@@ -76,14 +76,14 @@
:::vim
:echo "abcd"[0:2]
-Vim displays "abc". However, you can't use negative bare indices with strings.
+Vim displays `abc`. However, you can't use negative bare indices with strings.
You *can* use negative indices when slicing strings though! Run the following
command:
:::vim
:echo "abcd"[-1] . "abcd"[-2:]
-Vim displays "cd" (using a negative index silently resulted in an empty string).
+Vim displays `cd` (using a negative index silently resulted in an empty string).
Concatenation
-------------
@@ -93,7 +93,7 @@
:::vim
:echo ['a', 'b'] + ['c']
-Vim, unsurprisingly, displays "['a', 'b', 'c']". There's not much else to say
+Vim, unsurprisingly, displays `['a', 'b', 'c']`. There's not much else to say
here -- Vimscript lists are surprisingly sane compared to the rest of the
language.
@@ -108,19 +108,19 @@
:call add(foo, 'b')
:echo foo
-Vim mutates the list `foo` in-place to append `'b'` and displays "['a', 'b']".
+Vim mutates the list `foo` in-place to append `'b'` and displays `['a', 'b']`.
Now run this command:
:::vim
:echo len(foo)
-Vim displays "2", the length of the list. Try these commands:
+Vim displays `2`, the length of the list. Try these commands:
:::vim
:echo get(foo, 0, 'default')
:echo get(foo, 100, 'default')
-Vim displays "a" and "default". The `get` function will get the item at the
+Vim displays `a` and `default`. The `get` function will get the item at the
given index from the given list, or return the given default value if the index
is out of range in the list.
@@ -130,7 +130,7 @@
:echo index(foo, 'b')
:echo index(foo, 'nope')
-Vim displays "1" and "-1". The `index` function returns the first index of the
+Vim displays `1` and `-1`. The `index` function returns the first index of the
given item in the given list, or `-1` if the item is not in the list.
Now run this command:
@@ -140,7 +140,7 @@
:echo join(foo, '---')
:echo join([1, 2, 3], '')
-Vim displays "a b", "a---b", and "123". `join` will join the items in the given
+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.
@@ -152,13 +152,13 @@
:call reverse(foo)
:echo foo
-Vim displays "['b', 'a']" and then "['a', 'b']". `reverse` reverses the given
+Vim displays `['b', 'a']` and then `['a', 'b']`. `reverse` reverses the given
list *in place*.
Exercises
---------
-Read `:help List`. All of it. Notice the capital "L".
+Read `:help List`. All of it. Notice the capital `L`.
Read `:help add()`.
@@ -174,4 +174,4 @@
Skim `:help functions` to find some other list-related functions I haven't
mentioned yet. Run `:match Keyword /\clist/` to case-insensitively highlight
-the word "list" to make it easier to find what you're looking for.
+the word `list` to make it easier to find what you're looking for.
--- a/chapters/36.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/36.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -25,7 +25,7 @@
:echom c
-Vim displays "10", which is the result of adding together each element in the
+Vim displays `10`, which is the result of adding together each element in the
list. Vimscript `for` loops iterate over lists (or dictionaries, which we'll
cover later).
@@ -48,7 +48,7 @@
:echom total
-Once again Vim displays "10". This loop should be familiar to just about anyone
+Once again Vim displays `10`. This loop should be familiar to just about anyone
who's programmed before, so we won't spend any time on it. You won't use it
very often. Keep it in the back of your mind for the rare occasions that you
want it.
--- a/chapters/37.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/37.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -138,7 +138,7 @@
Exercises
---------
-Read `:help Dictionary`. All of it. Notice the capital "D".
+Read `:help Dictionary`. All of it. Notice the capital `D`.
Read `:help get()`.
--- a/chapters/39.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/39.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -117,7 +117,7 @@
not familiar with that term, higher-order functions are functions that take
*other* functions and do something with them.
-We'll begin with the trusty "map" function. Add this to your file:
+We'll begin with the trusty `map` function. Add this to your file:
:::vim
function! Mapped(fn, l)
@@ -132,8 +132,8 @@
:let mylist = [[1, 2], [3, 4]]
:echo Mapped(function("Reversed"), mylist)
-Vim displays `[[2, 1], [4, 3]]`, which is the results of applying `Reversed()`
-to every element in the list.
+Vim displays `[[2, 1], [4, 3]]`, which is the result of applying `Reversed()` to
+every element in the list.
How does `Mapped()` work? Once again we create a fresh list with `deepcopy()`,
do something to it, and return the modified copy -- nothing new there. The
@@ -143,8 +143,8 @@
a function") and a list. We use the built-in `map()` function to perform the
actual work. Read `:help map()` now to see how it works.
-Now we'll create a few other common higher-order functions. Add the following to
-your file:
+Now we'll create a few other common higher-order functions. Add the following
+to your file:
:::vim
function! Filtered(fn, l)
@@ -210,10 +210,7 @@
*gigabytes* of RAM.
You'll need to use your own judgement about when this style of programming
-creates unacceptably bad performance. I'd *strongly* encourage you to at least
-give it a fair try though. Using immutable data structures and higher order
-functions can greatly simplify your code and eliminate lots of state-related
-bugs.
+creates unacceptably bad performance.
Exercises
---------
--- a/chapters/41.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/41.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -3,7 +3,7 @@
We've covered a lot of ground in the last forty or so chapters. In the final
part of the book we're going to walk through creating a Vim plugin for
-a language from scratch.
+a programming language from scratch.
This is not for the faint of heart. It's going to take a lot of effort.
@@ -11,7 +11,7 @@
to make serious enhancements to your own `~/.vimrc` file and to fix bugs you
find in other people's plugins.
-There's no shame in saying "that's enough for me -- I don't want to spend hours
+There's no shame in saying "that's enough for me, I don't want to spend hours
of my life creating plugins I won't use very often". Be practical. If you
can't think of a full plugin you want to make, stop now and come back when you
do.
@@ -30,19 +30,19 @@
disappearance. It's an extremely small language which makes it ideal for our
purposes.
-Potion feels a lot like [Io][], with some ideas from Ruby, Lua and other
+Potion feels a lot like [Io][], with some ideas from Ruby, Lua, and other
languages mixed in. If you've never tried Io it may seem weird. I strongly
recommend playing with Potion for at least an hour or two. You won't use it in
real life, but it might change the way you think and expose you to new ideas.
The current implementation of Potion has a lot of rough edges. For example: if
-you mess up the syntax it usually segfaults. Try not to get too hung up on this
--- I'll provide you with lots of sample code that works so you can focus mostly
-on the Vimscript and not Potion.
+you mess up the syntax it usually segfaults. Try not to get too hung up on
+this. I'll provide you with lots of sample code that works so you can focus
+mostly on the Vimscript and not Potion.
-The goal is not to learn Potion (though I think doing so *will* make you
-a better programmer). The goal is to use Potion as a small example so we can
-touch on a lot of different aspects of writing Vim plugins.
+The goal is not to learn Potion (though that can be fun too). The goal is to
+use Potion as a small example so we can touch on a lot of different aspects of
+writing full Vim plugins.
Exercises
---------
--- a/chapters/42.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/42.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -23,8 +23,8 @@
a bunch of related stuff". Vim has a more specific meaning of "plugin", which
is "a file in `~/.vim/plugins/`".
-Most of the time I'll be using the first definition, but if something is unclear
-please [let me know](http://twitter.com/stevelosh/) and I'll try to reword it.
+Most of the time I'll be using the first definition. I'll try to be clear when
+I mean the second.
~/.vim/colors/
--------------
@@ -50,7 +50,7 @@
Any files in `~/.vim/ftdetect/` will *also* be run every time you start Vim.
-"ftdetect" stands for "filetype detection". The files in this directory should
+`ftdetect` stands for "filetype detection". The files in this directory should
set up autocommands that detect and set the `filetype` of files, and *nothing
else*. This means they should never be more than one or two lines long.
@@ -59,7 +59,7 @@
Files in `~/.vim/ftplugin/` are different.
-The naming of these files matters. When Vim sets a buffer's `filetype` to
+The naming of these files matters! When Vim sets a buffer's `filetype` to
a value it then looks for a file in `~/.vim/ftplugin/` that matches. For
example: if you run `set filetype=derp` Vim will look for
`~/.vim/ftplugin/derp.vim`. If that file exists, it will run it.
@@ -76,7 +76,7 @@
~/.vim/indent/
--------------
-Files in `~/.vim/indent/` are a lot like `ftplugin` files -- they get loaded
+Files in `~/.vim/indent/` are a lot like `ftplugin` files. They get loaded
based on their names.
`indent` files should set options related to indentation for their filetypes,
@@ -102,8 +102,8 @@
be loaded every time Vim starts, but *after* the files in `~/.vim/plugin/`.
This allows you to override Vim's internal files. In practice you'll rarely
-need this, so don't worry about it until you find yourself thinking "Vim sets
-option X and I want something different".
+need this, so don't worry about it until you find yourself thinking "Vim itself
+sets option `x`, but I want something different".
~/.vim/autoload/
----------------
@@ -127,3 +127,6 @@
Reread this chapter. I'm not kidding. Make sure you understand (in a very
rough way) what each directory we've talked about does.
+
+For extra credit, find some Vim plugins you use and look at how they structure
+their files.
--- a/chapters/43.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/43.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -7,7 +7,7 @@
In the past, when you wanted to use a plugin someone else wrote you would
download the files and place them, one-by-one, into the appropriate directories.
-You could also use zip or tar to do the placing for you.
+You could also use `zip` or `tar` to do the placing for you.
There are a few significant problems with this approach:
@@ -92,7 +92,7 @@
potion/
README
LICENSE
- docs/
+ doc/
potion.txt
ftdetect/
potion.vim
--- a/chapters/46.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/46.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -44,7 +44,7 @@
*regexes* instead of literal keywords.
Notice that the regular expression we're using starts with `\v` which tells Vim
-to use "very magic" mode. Reread the chapter on Basic Regular Expressions if
+to use "very magic" mode. Reread the chapter on basic regular expressions if
you're not sure what that means.
In this particular case the "very magic" mode isn't necessary. But in the
--- a/chapters/48.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/48.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -145,3 +145,4 @@
Read `:help foldminlines`.
Read `:help foldignore`.
+
--- a/chapters/51.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/51.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -6,7 +6,7 @@
First we need to decide what "section" should mean for a Potion file. There are
two pairs of section movement commands, so we can come up with two "schemes" and
-our users can choose the one they prefer.
+our users can use the one they prefer.
Let's use the following two schemes to define where Potion sections start:
@@ -194,7 +194,7 @@
The answer is that we searched using `/` (or `?`) and by default Vim places your
cursor at the beginning of matches. For example, when you run `/foo` your
-cursor will be placed on the "f" in "foo".
+cursor will be placed on the `f` in `foo`.
To tell Vim to put the cursor at the end of the match instead of the beginning,
we can use a search flag. Try searching in your Potion file like so:
@@ -202,7 +202,7 @@
:::vim
/factorial/e
-Vim will find the word "factorial" and move you to it. Press `n` a few times to
+Vim will find the word `factorial` and move you to it. Press `n` a few times to
move through the matches. The `e` flag tells Vim to put the cursor at the end
of matches instead of the beginning. Try it in the other direction too:
@@ -308,7 +308,7 @@
:::vim
:echom "hello"
-Vim will display "hello" but the visual selection will also be cleared!
+Vim will display `hello` but the visual selection will also be cleared!
When running an ex mode command with `:` the visual selection is always cleared.
The `gv` command reselects the previous visual selection, so this will "undo"
--- a/chapters/52.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/52.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -51,11 +51,11 @@
Let's take a look at how `PotionCompileAndRunFile()` function works.
-!
---------
+Bang!
+-----
-The `:!` command in Vim runs external commands and displays their output on the
-screen. Try it out by running the following command:
+The `:!` command (pronounced "bang") in Vim runs external commands and displays
+their output on the screen. Try it out by running the following command:
:::vim
:!ls
@@ -72,14 +72,14 @@
Type a few lines and you'll see that the `cat` command spits them back out, just
as it normally would if you ran `cat` outside of Vim. Use Ctrl-D to finish.
-To run an external command without the "Press ENTER or type command to continue"
+To run an external command without the `Press ENTER or type command to continue`
prompt, use `:silent !`. Run the following command:
:::vim
:silent !echo Hello, world.
-If you run this in a GUI Vim like MacVim or gVim, you won't see the "Hello,
-world." output of the command.
+If you run this in a GUI Vim like MacVim or gVim, you won't see the `Hello,
+world.` output of the command.
If you run it in a terminal Vim, your results may vary depending on your
configuration. You may need to run `:redraw!` to fix your screen after running
@@ -98,7 +98,7 @@
endfunction
First we run a `silent !clear` command, which should clear the screen without
-a "Press ENTER..." prompt. This will make sure we only see the output of this
+a `Press ENTER...` prompt. This will make sure we only see the output of this
run, which is helpful when you're running the same commands over and over.
The next line uses our old friend `execute` to build a command dynamically. The
@@ -187,7 +187,7 @@
:::vim
:echom system("wc -c", "abcdefg")
-Vim will display "7" (with some padding). If you pass a second argument like
+Vim will display `7` (with some padding). If you pass a second argument like
this, Vim will write it to a temporary file and pipe it into the command on
standard input. For our purposes we won't need this, but it's good to know.
@@ -241,7 +241,8 @@
`vsplit` creates a new vertical split for a buffer named `__Potion_Bytecode__`.
We surround the name with underscores to make it clearer to the user that this
-isn't a normal file -- it's a buffer just to hold the output.
+isn't a normal file (it's a buffer just to hold the output). The underscores
+aren't special, they're just a convention.
Next we delete everything in this buffer with `normal! ggdG`. The first time
the mapping is run this won't do anything, but subsequent times we'll be reusing
--- a/chapters/53.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/53.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -233,7 +233,7 @@
Save the files, close Vim, and open up your `factorial.pn` file. Try using the
mappings to make sure they still work properly.
-Make sure that you see the diagnostic "Autoloading..." message only the first
+Make sure that you see the diagnostic `Autoloading...` message only the first
time you run one of the mappings (you may need to use `:messages` to see it).
Once you confirm that autoloading is working properly you can remove that
message.
--- a/chapters/54.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/54.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -51,7 +51,7 @@
Next you should put the title of your plugin along with a longer description.
Some authors (including me) like to have a bit of fun with this and use some
-ASCII-art to spice things up. Add a nice title section to the `potion.txt`
+ASCII art to spice things up. Add a nice title section to the `potion.txt`
file:
:::text
@@ -67,7 +67,7 @@
Includes syntax highlighting, code folding, and more!
I got those fun letters by running the `figlet -f ogre "Potion"` command.
-[Figlet][] is a great little program for generating ASCII-art text. The `~`
+[Figlet][] is a great little program for generating ASCII art text. The `~`
characters at the end of the lines ensure that Vim doesn't try to highlight or
hide individual characters inside the art.
@@ -260,13 +260,13 @@
:::vim
" "Uppercase word" mapping.
"
- " This mapping allows you to press <c-u> in insert mode to convert the current
- " word to uppercase. It's handy when you're writing names of constants and
- " don't want to use Capslock.
+ " This mapping allows you to press <c-u> in insert mode to convert the
+ " current word to uppercase. It's handy when you're writing names of
+ " constants and don't want to use Capslock.
"
- " To use it you type the name of the constant in lowercase. While your
- " cursor is at the end of the word, press <c-u> to uppercase it, and then
- " continue happily on your way:
+ " To use it you type the name of the constant in lowercase. While
+ " your cursor is at the end of the word, press <c-u> to uppercase it,
+ " and then continue happily on your way:
"
" cursor
" v
@@ -276,12 +276,12 @@
" ^
" cursor
"
- " It works by exiting out of insert mode, recording the current cursor location
- " in the z mark, using gUiw to uppercase inside the current word, moving back to
- " the z mark, and entering insert mode again.
+ " It works by exiting out of insert mode, recording the current cursor
+ " location in the z mark, using gUiw to uppercase inside the current
+ " word, moving back to the z mark, and entering insert mode again.
"
- " Note that this will overwrite the contents of the z mark. I never use it, but
- " if you do you'll probably want to use another mark.
+ " Note that this will overwrite the contents of the z mark. I never
+ " use it, but if you do you'll probably want to use another mark.
inoremap <C-u> <esc>mzgUiw`za
It's much shorter than the documentation for a full plugin, but it's a good
@@ -296,4 +296,5 @@
Read `:help help-writing` for help about writing help.
Read `:help :left`, `:help :right`, and `:help :center` to learn about three
-useful commands for getting your ASCII-art perfect.
+useful commands for getting your ASCII art perfect.
+
--- a/chapters/56.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/chapters/56.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -71,7 +71,7 @@
If you're interested in this you can dive in by reading through `:help
quickfix.txt` in its entirety. However, I will warn you now that `errorformat`
-is *not* for the faint of heart.
+is *not* for the faint of heart!
Other Languages
---------------
--- a/introduction.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/introduction.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -14,12 +14,7 @@
* The third walks through the creation of a sample plugin intended for
distribution to other Vim users.
-Currently Learn Vimscript the Hard Way is a work in progress. Once it's
-finished you'll be able to buy ebook and possibly hard copy versions. If you
-want to get on the mailing list to know when it's officially completed you can
-sign up at [Learn Vimscript the Hard Way on Leanpub][leanpub].
-
-The book is [copyright][license] 2012 by Steve Losh, all rights reserved. You
+The book is [copyright][license] 2013 by Steve Losh, all rights reserved. You
can redistribute it as long as you don't make any changes and don't charge for
it.
--- a/license.markdown Wed Jan 23 23:09:51 2013 +0100
+++ b/license.markdown Wed Apr 03 23:04:29 2013 -0400
@@ -1,7 +1,7 @@
License
=======
-This book is copyright (C) 2012 by Steve Losh, all rights reserved.
+This book is copyright (C) 2013 by Steve Losh, all rights reserved.
You are free to distribute this book to anyone you want, so long as you do not
charge anything for it, and it is not altered. You must give away the book in
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/style.txt Wed Apr 03 23:04:29 2013 -0400
@@ -0,0 +1,13 @@
+Output should be enclosed in backticks. So:
+
+ If you type `:echom "Hello!"` Vim will output `Hello`.
+
+Filenames should also be in backticks.
+
+Key mappings should be lowercase.
+
+ nnoremap <esc> ...
+
+Keep code within 70 or so cols.
+
+Prefix code blocks with :::vim or :::text.