Feineigle.com - Practical Vim 2E

Home · Book Reports · 2018 · Practical Vim 2E

Published: June 1, 2018
Tags:  Linux · Programming · Vim



The book in...
One sentence:
If you are new to vim or want to take your game to the next level, this is THE vim book to do it.

Five sentences:
This is meant to be picked at, not read cover to cover (I read it cover to cover... and I agree, not all at once). It is set up in a less typical cookbook style, where each tips is grouped with other tips that can be construed in the same vein, but the tips are meaty enough to go into some detail while still providing the curious reader a jumping off point for deeper understanding. The examples are nice, not too contrived, and apparently available on either the website of github. Overall I say this book is highly recommended, no matter what level your vim proficiency might be at. The only word of warning, avoid the vimcasts; the audio is horrible.

designates my notes. / designates important.


Thoughts

Right off the bat Drew tells you not to read the book linearly, to pick at it here and there. I read it linearly. It is set up like a cookbook, which I normally don’t like at all, but there was enough elaboration with each tip and the similar tips were grouped together. Not a particularly easy task since there are so many ways you might get to the same solution with vim, none being the ‘right’ way.

Though I didn’t take the advice and read it cover to cover, I did do it slowly, over about two weeks. I tried to pick a few things that I wanted to integrate and made a point of consciously using them for a few days; many of the habits stuck. This is the best way to learn vim, bit by bit. Learn one new thing a day, or a week, and, eventually, you’ll have attained mastery, or at least competence.

On top of this strategy, I also have a list of all the stuff I’d eventually like to integrate as second nature. This prevents me from ever getting to the point where I become comfortable without having to be constantly looking for new tips. This book would be great to poke around in, there will always be something new, or at least will lead you to a more advanced understanding of something old, but I rather prefer my making one pass and compiling a TODO list. I’ll probably go through the book again though, maybe even before my list is empty.

The other key thing to realize is, reading alone is not enough. You get good at vim the same way you get to Carnegie Hall; practice, practice, practice! You should always try out new and interesting ways of doing things. By having a scratch file to work with, which apparently are available online to follow the book exactly, though I simply made up my own examples, you can fiddle with new commands without wrecking a real project.

All in all, when you hear people online saying that this is THE vim book, I think they are right. This book is highly recommended; I was very pleased with it.

My list of random stuff I want to learn:

Keystrokes | Effect
-------------------
`<C-h>`    | Delete back one character (backspace)
`<C-w>`    | Delete back one word
`<C-u>`    | Delete back to start of line
Keystrokes | Effect
-----------+-------
`<C-o>`    | Switch to Insert Normal mode

:2,$!sort -t',' -k2

Keystrokes Current   | Keystrokes Current
---------------------+-------------------
`iw`       word      | `aw`       word plus space(s)           
`iW`       WORD      | `aW`       WORD plus space(s)           
`is`       sentence  | `as`       sentence plus space(s)       
`ip`       paragraph | `ap`       paragraph plus blank line(s) 
Keystrokes | Buffer Contents
---------- +-------------------------------------------
`“`        | Position before the last jump within current file
`‘.`       | Location of last change
`‘^`       | Location of last insertion
`‘[`       | Start of last change or yank
`‘]`       | End of last change or yank
`‘<`       | Start of last visual selection
`‘>`       | End of last visual selection
set nocompatible
filetype plugin on
runtime macros/matchit.vim
Keystrokes | Buffer Contents
-----------+----------------------------------------
`{start}`  | cities = ["London", "Berlin", New York]
`vee`      | cities = ["London", "Berlin", New York]
`S"`       | cities = ["London", "Berlin", "New York"]
Keystrokes              | Buffer Contents
------------------------+-----------------------------------------
`{start}`               | Match "quoted words"---not quote marks. 
`/\v"[^"]+" <CR>`       | Match "quoted words"---not quote marks. 
`/\v"\zs[^"]+\ze" <CR>` | Match "quoted words"---not quote marks. 
Command | Effect
--------+----------------------------------------------------
`n`     | Jump to next match, preserving direction and offset
`N`     | Jump to previous match, preserving direction and offset
`/<CR>` | Jump forward to next match of same pattern
`?<CR>` | Jump backward to previous match of same pattern
`gn`    | Enable character-wise Visual mode and select next search match
`gN`    | Enable character-wise Visual mode and select previous search match
:reg a
--- Registers ---
 "a
:g/TODO/yank A
:reg a
"a // TODO: Cache this regexp for certain depths.
// TODO: No matching end code found - warn!

Exceptional Excerpts

Table 2. Vim’s Operator Comm

Trigger | Effect
----------------
`c`     | Change
`d`     | Delete
`y`     | Yank into register
`g~`    | Swap case
`gu`    | Make lowercase
`gU`    | Make uppercase
`>`     | Shift right
`<`     | Shift left
`=`     | Autoindent
`!`     | Filter {motion} lines through an external program 

“If you’re curious about how to create your own custom operators, start by reading :help map-operator

“If you’re curious about how to create your own custom motions, start by reading :h omap-info

“From insert mode, command line, or b

Keystrokes | Effect
-----------+-------
`<C-h>`    | Delete back one character (backspace)
`<C-w>`    | Delete back one word
`<C-u>`    | Delete back to start of line

“The expression register is addressed by the = symbol. From Insert mode we can access it by typing <C-r>=. This opens a prompt at the bottom of the screen where we can type the expression that we want to evaluate. When done, we hit <CR>, and Vim inserts the result at our current position in the document.

“The effect of the :write !sh command is that each line of the current buffer is executed in the shell. Refer to :h rename-files

“The basic pattern uses a common regex idiom: ‘[^’]+’ . The pattern begins and ends with a quote mark and then matches one or more characters in between that are anything but a quote.


Table of Contents


· Introduction

· 01: The Vim Way

page 39:

page 44:

con+cat+these+with+spaces

,f+s + <Esc>   # I've remapped f to ,f
;.             # so I can use f for easymotion without leader
;.
;.

con + cat + these + with + spaces

page 46:

· 02: Normal Mode

page 60:

page 61:

page 64:

Trigger | Effect
----------------
`c`     | Change
`d`     | Delete
`y`     | Yank into register
`g~`    | Swap case
`gu`    | Make lowercase
`gU`    | Make uppercase
`>`     | Shift right
`<`     | Shift left
`=`     | Autoindent
`!`     | Filter {motion} lines through an external program 

page 65:

· 03: Insert Mode

page 68:

Keystrokes | Effect
-----------+-------
`<C-h>`    | Delete back one character (backspace)
`<C-w>`    | Delete back one word
`<C-u>`    | Delete back to start of line
Keystrokes | Effect
-----------+-------
`<Esc>`    | Switch to Normal mode
`<C-[>`    | Switch to Normal mode
`<C-o>`    | Switch to Insert Normal mode

page 71:

page 73:

page 74:

If you want to find out the numeric code for any character in your document, just place the cursor on it and trigger the ga command.

page 75:

Keystrokes            | Effect
----------------------+-------
`<C-v>{123}`          | Insert character by decimal code
`<C-v>u{1234}`        | Insert character by hexadecimal code
`<C-v>{nondigit}`     | Insert nondigit literally
`<C-k>{char1}{char2}` | Insert character represented by {char1}{char2} digraph

page 76:

· 04: Visual Mode

page 82:

Command | Effect
--------+-------
`v`     | Enable character-wise Visual mode
`V`     | Enable line-wise Visual mode
`<C-v>` | Enable block-wise Visual mode
`gv`    | Reselect the last visual selection

page 83:

Command | Effect
--------+-------
`o`     | Go to other end of highlighted text

page 88:

page 90:

page 93:

Keystrokes   | Buffer Contents
-------------+-----------------------
{start}      | var foo = 1
Normal mode  | var bar = 'a'
             | var foobar = foo + bar
-------------+-----------------------
<C-v>jj$     | var foo = 1
Visual-Block | var bar = a
             | var foobar = foo + bar
-------------+-----------------------
A;           | var foo = 1;
Insert mode  | var bar = 'a' 
             | var foobar = foo + bar
-------------+-----------------------
<Esc>        | var foo = 1;
Normal mode  | var bar = 'a';
             | var foobar = foo + bar;
-------------+-----------------------

· 05: Command-Line Mode

:[range]delete [x]
Delete specified lines [into register x]

:[range]yank [x]
Yank specified lines [into register x]

:[line]put [x]
Put the text from register x after the specified line

:[range]copy {address}
Copy the specified lines to below the line specified by {address}

:[range]move {address}
Move the specified lines to below the line specified by {address}

:[range]join
Join the specified lines

:[range]normal {commands}
Execute Normal mode {commands} on each specified line

:[range]substitute/{pattern}/{string}/[flags]
Replace occurrences of {pattern} with {string} on each specified line

:[range]global/{pattern}/[cmd]
Execute the Ex command [cmd] on all specified lines where the {pattern} matches

page 99:

page 100:

page 101:

= > :/<html>/,/<\/html>/p

< = 2 <html>
    3 <head><title>Practical Vim</title></head>
    4 <body><h1>Practical Vim</h1></body>
    5 </html>

page 105:

Command    | Effect
-----------+-------
`:6t.`     | Copy line 6 to just below the current line                    
`:t6`      | Copy the current line to just below line 6                    
`:t.`      | Duplicate the current line (similar to Normal mode yyp )      
`:t$`      | Copy the current line to the end of the file                  
`:<,>t0` | Copy the visually selected lines to the start of the file     

page 106:

page 108:

page 110:

page 117:

page 118:

Command  | Action
---------+-------
`q/`     | Open the command-line window with history of searches
`q:`     | Open the command-line window with history of Ex commands
`ctrl-f` | Switch from Command-Line mode to the command-line window

page 119:

page 120:

=> $ jobs
<= [1]+ Stopped     vim

page 121:

first name,last name,email
john,smith,john@example.com
drew,neil,drew@vimcasts.org
jane,doe,jane@example.com

:2,$!sort -t',' -k2

first name,last name,email
jane,doe,jane@example.com
drew,neil,drew@vimcasts.org
john,smith,john@example.com

page 122:

Command                | Effect
-----------------------+-------------------------------------------------------
`:shell`               | Start a shell (return to Vim by typing exit)
`:!{cmd}`              | Execute {cmd} with the shell
`:read !{cmd}`         | Execute {cmd} in the shell and insert its standard output below the cursor
`:[range]write !{cmd}` | Execute {cmd} in the shell with [range] lines as standard input
`:[range]!{filter}`    | Filter the specified [range] through external program {filter}

page 124:

global/href/join
vglobal/ href/delete
%normal A: http:/ /vimcasts.org
%normal yi"$p
%substitute/\v^[^\>]+\>\s//g

page 125: :argdo source batch.vim

· 06: Manage Multiple Files

page 140:

Ex Command | Normal Command Effect
-----------+----------------------
`:clo[se]` | `<C-w>c` Close the active window
`:on[ly]`  | `<C-w>o` Keep only the active window, closing all others

page 142:

Command                 | Effect
----------------------- +-----------------------------
`:tabe[dit] {filename}` | Open {filename} in a new tab                      
`<C-w>T`                | Move the current window into its own tab          
`:tabc[lose]`           | Close the current tab page and all of its windows 
`:tabo[nly]`            | Keep the active tab page, closing all others      

· 07: Open Files and Save Them to Disk

page 155:

= > : w !sudo tee % > /dev/null
< = Password:
    W12: Warning: File "hosts" has changed and the buffer was
    changed in Vim as well
    [O]k, (L)oad File, Load (A)ll, (I)gnore All:

· 08: Navigate Inside Files with Motions

page 158:

page 163:

Command | Move Cursor
--------+------------
`w`     | Forward to start of next word
`b`     | Backward to start of current/previous word
`e`     | Forward to end of current/next word
`ge`    | Backward to end of previous word

page 172:

Keystrokes   | Buffer Contents
-------------+-----------------
{start}      | This phrase [t]akes time but 
             | eventually gets to the point.
             |
`d /ge <CR>` | This phrase [g]ets to the point. 

page 177:

Keystrokes Current   | Keystrokes Current
---------------------+-------------------
`iw`       word      | `aw`       word plus space(s)           
`iW`       WORD      | `aW`       WORD plus space(s)           
`is`       sentence  | `as`       sentence plus space(s)       
`ip`       paragraph | `ap`       paragraph plus blank line(s) 

page 178:

page 179:

page 180:

Keystrokes | Buffer Contents
---------- +-------------------------------------------
`“`        | Position before the last jump within current file
`‘.`       | Location of last change
`‘^`       | Location of last insertion
`‘[`       | Start of last change or yank
`‘]`       | End of last change or yank
`‘<`       | Start of last visual selection
`‘>`       | End of last visual selection

page 181:

page 182:

Keystrokes | Buffer Contents
---------- +------------------------------------
`{start}`  | cities = %w{London Berlin New\ York}
`dt{`      | cities = {London Berlin New\ York}
`%`        | cities = {London Berlin New\ York}
`r]`       | cities = {London Berlin New\ York]
````       | cities = {London Berlin New\ York]
`r[`       | cities = [London Berlin New\ York]

page 183:

set nocompatible
filetype plugin on
runtime macros/matchit.vim
Keystrokes | Buffer Contents
-----------+----------------------------------------
`{start}`  | cities = ["London", "Berlin", @N@ew York]
`vee`      | cities = ["London", "Berlin", New Yor@k@]
`S"`       | cities = ["London", "Berlin", "New York"]

· 09: Navigate Between Files with Jumps

page 190:

= > :set path?
< = path=.,/usr/include,,

· 10: Copy and Paste

page 201:

page 202:

page 203:

page 204:

Keystrokes | Buffer Contents
-----------+----------------
`"+`       | The X11 clipboard, used with cut, copy, and paste
`"*`       | The X11 primary, used with middle mouse button

page 205:

Register | Contents
---------+---------
`"%`     | Name of the current file
`"#`     | Name of the alternate file
`".`     | Last inserted text
`":`     | Last Ex command
`"/`     | Last search pattern

· 11: Macros

page 236:

Keystrokes Buffer        | Contents
-------------------------+------------------
`:let i=1`               | [p]artridge in a pear tree    
`qa`                     | [p]artridge in a pear tree    
`I<C-r>= i <CR> )<Esc>`  | 1)[ ]partridge in a pear tree 
`:let i += 1`            | 1)[ ]partridge in a pear tree 
`q`                      | 1)[ ]partridge in a pear tree 

· 12: Matching Patterns and Literals

page 252:

page 256:

Keystrokes              | Buffer Contents
------------------------+-----------------------------------------
`{start}`               | Match "quoted words"---not quote marks. 
`/\v"[^"]+" <CR>`       | Match "quoted words"---not quote marks. 
`/\v"\zs[^"]+\ze" <CR>` | Match "quoted words"---not quote marks. 

page 259:

=> escape(@u, getcmdtype().'\')

· 13: Search

page 263:

Command | Effect
--------+----------------------------------------------------
`n`     | Jump to next match, preserving direction and offset
`N`     | Jump to previous match, preserving direction and offset
`/<CR>` | Jump forward to next match of same pattern
`?<CR>` | Jump backward to previous match of same pattern
`gn`    | Enable character-wise Visual mode and select next search match
`gN`    | Enable character-wise Visual mode and select previous search match

page 268:

page 273:

xnoremap * :<C-u>call <SID>VSetSearch(' /')<CR>/<C-R>=@/<CR><CR>
xnoremap # :<C-u>call <SID>VSetSearch(' ?')<CR>?<C-R>=@/<CR><CR>

function! s:VSetSearch(cmdtype)
  let temp = @s
  norm! gv"sy
  let @/ = '\V' . substitute(escape(@s, a:cmdtype.' \'), '\ n ' , '\\n ' , 'g' )
  let @s = temp
endfunction

· 14: Substitution

page 281:

page 282:

Symbol           | Represents
-----------------+-------------------------
`\r`             | Insert a carriage return
`\t`             | Insert a tab character
`\\`             | Insert a single backslash
`\1`             | Insert the first submatch
`\2`             | Insert the second submatch (and so on, up to \9)
`\0`             | Insert the entire matched pattern
`&`              | Insert the entire matched pattern
`~`              | Use {string} from the previous invocation of :substitute
`\={Vim script}` | Evaluate {Vim script} expression; use result as replacement {string}

page 284:

page 285:

Trigger | Effect
--------+----------------------
`y`     | Substitute this match
`n`     | Skip this match
`q`     | Quit substituting
`l`     | last”—Substitute this match, then quit
`a`     | all”—Substitute this and any remaining matches
`<C-e>` | Scroll the screen up
`<C-y>` | Scroll the screen down

page 287:

page 288:

page 290:

=> :%s/Pragmatic Vim/Practical Vim/g
=> :let @/='Pragmatic Vim'
=> :let @a='Practical Vim'
=> :%s//\=@a/g

page 292:

page 294:

page 295:

nnoremap & :&&<CR>
xnoremap & :&&<CR>

page 296:

last name,first name,email
neil,drew,drew@vimcasts.org
doe,john,john@example.com
=> `/\v^([^,]*),([^,]*),([^,]*)$`
=> `:%s//\3,\2,\1`
email,first name,last name
drew@vimcasts.org,drew,neil
john@example.com,john,doe

page 298:

page 299:

=> :let swapper={"dog":"man","man":"dog"}
=> :echo swapper["dog"]
<= man
=> :echo swapper["man"]
<= dog
=> /\v(<man>|<dog>)
=> :%s//\={"dog":"man","man":"dog"}[submatch(1)]/g

· 15: Global Commands

page 306:

page 308:

page 309:

page 310:

:reg a
--- Registers ---
 "a
:g/TODO/yank A
:reg a
"a TODO: Cache this regexp for certain depths.
TODO: No matching end code found - warn!

page 312:

page 313:

· 16: Index and Navigate Source Code with ctags

page 317:

· 17:Compile Code and Navigate Errors with the Quickfix List

page 337:

· 18: Search Project-Wide with grep, vimgrep, and Others

page 345:

page 346:

=> :args *.txt
=> :vim /going/g ##

· 19: Dial X for Autocompletion

· 20: Find and Fix Typos with Vim’s Spell Checker

· 21: Now What?

· Appendix 1