Remove all trailing whitespace

pull/48/head
Florian Rager 4 years ago
parent ef1fc2f3a4
commit 7aba28c573

@ -2,7 +2,7 @@
## What is this about?
*Learn Vim (the Smart Way)* is a book to learn the good parts of Vim.
*Learn Vim (the Smart Way)* is a book to learn the good parts of Vim.
Follow [@learnvim](https://twitter.com/learnvim) for updates, Vim tips, etc.
@ -47,7 +47,7 @@ Follow [@learnvim](https://twitter.com/learnvim) for updates, Vim tips, etc.
# Translations
- [Learn-Vim 中文翻译](https://github.com/wsdjeg/Learn-Vim_zh_cn)(`zh-CN`)
- [Learn-Vim Spanish](https://github.com/victorhck/learn-Vim-es)(`es`)
- [Learn-Vim Spanish](https://github.com/victorhck/learn-Vim-es)(`es`)
# License & Copyright
The materials here are all ©2020 Igor Irianto.

@ -56,7 +56,7 @@ To quit without saving any changes, add `!` after `:q` to force quit:
:q!
```
There are other ways to exit Vim, but these are the ones you will use daily.
There are other ways to exit Vim, but these are the ones you will use daily.
## Help

@ -1,12 +1,12 @@
# Ch 03. Opening And Searching Files
The goal of this chapter is to introduce you to opening and searching files in Vim. Being able to search quickly is a great way to jump-start your Vim productivity. One reason it took me a long time to get onboard with Vim is because I didn't know how to find things quickly like many popular text editors.
The goal of this chapter is to introduce you to opening and searching files in Vim. Being able to search quickly is a great way to jump-start your Vim productivity. One reason it took me a long time to get onboard with Vim is because I didn't know how to find things quickly like many popular text editors.
This chapter is divided into two parts. In the first part, I will show you how to open and search files without plugins. In the second part, I will show you how to open and search files with [FZF.vim](https://github.com/junegunn/fzf.vim) plugin. Feel free to jump to whichever section you need to learn. However, I highly recommend you to go through everything. With that said, let's get started!
## Opening And Editing Files With `:edit`
`:edit` is the simplest way to open a file in Vim.
`:edit` is the simplest way to open a file in Vim.
```
:edit file.txt
@ -107,7 +107,7 @@ You might be thinking to add the entire project directories so when you press `t
`$PWD` is the current working directory. If you try to add your entire project to `path` so all files are reachable upon a `tab` press, although this may work for a small project, doing this may slow down your search significantly if you have many files in your project. I recommend adding only the `path` of your most visited files / directories.
Updating `path` takes only a few seconds and doing this will save you a lot of time.
Updating `path` takes only a few seconds and doing this will save you a lot of time.
## Searching In Files With `:grep`
@ -129,7 +129,7 @@ For example, to look for all occurrences of "foo" string inside all ruby files (
```
:vim /foo/ app/controllers/**/*.rb
```
After running that command, you will be redirected to the first result. Vim's `vim` search command uses `quickfix` operation. To see all search results, run `:copen`. This opens a `quickfix` window. Here are some useful quickfix commands to get you productive immediately:
```
@ -262,7 +262,7 @@ nnoremap <silent> <C-f> :Files<CR>
```
## Finding In Files
To search inside files, you can use the `:Rg` command.
To search inside files, you can use the `:Rg` command.
<p align="center">
<img alt="FInding in Files in FZF" width="900" height="auto" src="./img/fzf-in-files.gif"/>
@ -273,7 +273,7 @@ Again, since you will probably use this frequently, let's map it. I map mine wit
```
nnoremap <silent> <Leader>f :Rg<CR>
```
```
## Other Searches
@ -290,14 +290,14 @@ nnoremap <silent> <Leader>g :Commits<CR>
nnoremap <silent> <Leader>H :Helptags<CR>
nnoremap <silent> <Leader>hh :History<CR>
nnoremap <silent> <Leader>h: :History:<CR>
nnoremap <silent> <Leader>h/ :History/<CR>
nnoremap <silent> <Leader>h/ :History/<CR>
```
## Replacing `grep` With `rg`
As I mentioned earlier, Vim has two ways to search in files: `:vim` and `:grep`. `:grep` uses external search tool that you can reassign using `grepprg` keyword. I will show you how to configure Vim to use ripgrep instead of terminal grep when running the `:grep` command.
Now let's setup `grepprg` so `:grep` uses ripgrep. Add this in your `vimrc`.
Now let's setup `grepprg` so `:grep` uses ripgrep. Add this in your `vimrc`.
```
set grepprg=rg\ --vimgrep\ --smart-case\ --follow
```
@ -336,10 +336,10 @@ The second method is to search and replace in select files. With this method, yo
## Learn Search The Smart Way
Searching is the bread-and-butter of text editing. Learning how to search well in Vim will help your text editing workflow.
Searching is the bread-and-butter of text editing. Learning how to search well in Vim will help your text editing workflow.
FZF.vim is a game-changer. I can't imagine using Vim without it. I think it is very important to have a good search tool when starting Vim. I've seen people struggling to transition to Vim because it is missing critical features modern text editors have, like a powerful and easy search. I was one. I hope this chapter addresses one of the issues and help to make the transition to Vim easier. To improve your searching prowess even more, I suggest to check out [fzf repo](https://github.com/junegunn/fzf).
You also just saw Vim's extensibility in action - the ability to extend search functionality with a plugin and / or an external program. In the future, keep in mind of what other features you wish to extend in Vim. Chances are, someone has created a plugin or there is a program for it already.
You also just saw Vim's extensibility in action - the ability to extend search functionality with a plugin and / or an external program. In the future, keep in mind of what other features you wish to extend in Vim. Chances are, someone has created a plugin or there is a program for it already.
Next, let's talk about a very important topic in Vim: grammar.

@ -22,7 +22,7 @@ You only need to know one grammar rule to speak Vim language:
verb + noun
```
That's it!
That's it!
This is equivalent to saying these English phrases:
@ -62,7 +62,7 @@ c Delete text, save to register, and start insert mode
Now that you know basic nouns and verbs, let's apply our grammar rule! Suppose you have this expression:
```
const learn = "vim";
const learn = "vim";
```
- To yank everything from your current location to the end of the line: `y$`.
- To delete from your current location to the beginning of the next word: `dw`.
@ -84,7 +84,7 @@ I hope everything starts to make sense. But I am not quite done yet. Vim has one
Imagine you are somewhere inside a pair of parentheses like `(hello vim)` and you need to delete the entire phrase inside the parentheses. How can you quickly do it? Is there a way to delete the "group" you are inside of?
The answer is yes. Texts often come structured. They are often put inside parentheses, quotes, brackets, braces, and so on. Vim has a way to capture this structure with text objects.
The answer is yes. Texts often come structured. They are often put inside parentheses, quotes, brackets, braces, and so on. Vim has a way to capture this structure with text objects.
Text objects are used with operators. There are two types of text objects:
@ -101,16 +101,16 @@ Let's look at a different example. Suppose you have this Javascript function and
```
const hello = function() {
console.log("Hello Vim");
console.log("Hello Vim");
return true;
}
```
- To delete the entire "Hello Vim": `di(`.
- To delete the content of function (surrounded by `{}`): `di{`.
- To delete the "Hello" string: `diw`.
- To delete the "Hello" string: `diw`.
Text objects are powerful because you can target different objects from one location. You can delete the objects inside the pair of parentheses, the function block, or the whole word. Moreover, when you see `di(`, `di{`, and `diw`, you get a pretty good idea what text objects they represent (a pair of parentheses, a pair of braces, and a word).
Text objects are powerful because you can target different objects from one location. You can delete the objects inside the pair of parentheses, the function block, or the whole word. Moreover, when you see `di(`, `di{`, and `diw`, you get a pretty good idea what text objects they represent (a pair of parentheses, a pair of braces, and a word).
Let's look at one last example. Suppose you have these HTML tags:
```
@ -179,7 +179,7 @@ Result:
03 Bunny Ok
```
Great! Even piping works from inside Vim.
Great! Even piping works from inside Vim.
This is the power of Vim's composability. The more you know your operators, motions, and terminal commands, your ability to compose complex actions is *multiplied*.
@ -199,6 +199,6 @@ verb + noun
```
One of my biggest Vim "AHA!" moments was when I had just learned about the uppercase (`gU`) operator and wanted to uppercase a word, I instinctively ran `gUiw` and it worked! The word I was on was uppercased. I finally began to understand Vim. My hope is that you will have your own "AHA!" moment soon, if not already.
The goal is this chapter is to show you the `verb + noun` pattern in Vim so you will approach learning Vim like learning a new language instead of memorizing every command combinations.
The goal is this chapter is to show you the `verb + noun` pattern in Vim so you will approach learning Vim like learning a new language instead of memorizing every command combinations.
Learn the pattern and understand the implications. That's the smart way to learn.

@ -17,7 +17,7 @@ l Right
You can also move with directional arrows. If you are just starting, feel free to use any method you're most comfortable with.
I prefer `hjkl` because my right hand can stay in home row. Doing this gives me shorter reach to surrounding keys.
I prefer `hjkl` because my right hand can stay in home row. Doing this gives me shorter reach to surrounding keys.
To get used to it, I actually disabled the arrow buttons when starting out by adding these in `~/.vimrc`:
```
@ -50,7 +50,7 @@ This is 100% personal preference. Experiment with `relativenumber` / `norelative
## Count Your Move
Let's talk about "count" argument. Motions accept a preceding numerical argument. I mentioned above that you can go down 12 lines with `12j`. The 12 in `12j` is the count number.
Let's talk about "count" argument. Motions accept a preceding numerical argument. I mentioned above that you can go down 12 lines with `12j`. The 12 in `12j` is the count number.
The syntax to use count with your motion is:
@ -113,7 +113,7 @@ T Search backward for a match in the same line, stopping before match
, Repeat the last search in the same line backwards
```
Back at the previous example:
Back at the previous example:
```
const hello = "world";
@ -125,7 +125,7 @@ With your cursor at the start of the line, you can go to the last character in c
Next two navigation units are sentence and paragraph.
Let's talk about what a sentence is first. A sentence ends with either `. ! ?` followed by an end-of-line, a space, or a tab. You can jump to the next sentence with `)` and the previous sentence with `(`.
Let's talk about what a sentence is first. A sentence ends with either `. ! ?` followed by an end-of-line, a space, or a tab. You can jump to the next sentence with `)` and the previous sentence with `(`.
```
( Jump to the previous sentence
) Jump to the next sentence
@ -167,7 +167,7 @@ Check out `:h sentence` and `:h paragraph` to learn more.
## Match Navigation
Programmers often edit files containing codes. It may contain many parentheses, braces, and brackets and it can get confusing to know which parentheses you're inside of.
Programmers often edit files containing codes. It may contain many parentheses, braces, and brackets and it can get confusing to know which parentheses you're inside of.
Many programming languages use parentheses, braces, and brackets and you can get lost in them. If you're inside one of them, you can jump to the other pair (if it exists) with `%`. You can also use this to find out whether you have matching parentheses, braces, and brackets.
```
@ -239,7 +239,7 @@ Very often you know that a phrase exists inside a file. You can use search navig
```
/ Search forward for a match
? Search backward for a match
n Repeat last search (same direction of previous search)
n Repeat last search (same direction of previous search)
N Repeat last search (opposite direction of previous search)
```
@ -255,7 +255,7 @@ let onetwo = 12;
If you are searching for "let", you can do `/let`. To quickly search for "let" again, you can just do `n`. To search for "let" again in opposite direction, you can do `N`. If you used `?let` to search, it will search for it backwards. If you use `n`, it will also search backwards, the same direction as `?let` (`N` will search for "let" forwards now).
You can enable search highlight with `:set hlsearch`. Now when you search for `/let`, it will highlight *all* matching phrases in the file. In addition, you can set incremental search with `:set incsearch`. This will highlight the pattern as you're still typing it. By default, your matching phrases will remain highlighted until you search for another phrase. This can quickly turn into an annoyance. To disable highlight, you can run `:nohlsearch`. Because I use this no-highlight feature frequently, I created a mapping:
You can enable search highlight with `:set hlsearch`. Now when you search for `/let`, it will highlight *all* matching phrases in the file. In addition, you can set incremental search with `:set incsearch`. This will highlight the pattern as you're still typing it. By default, your matching phrases will remain highlighted until you search for another phrase. This can quickly turn into an annoyance. To disable highlight, you can run `:nohlsearch`. Because I use this no-highlight feature frequently, I created a mapping:
```
nnoremap <esc><esc> :noh<return><esc>
@ -284,7 +284,7 @@ ma Mark position with mark "a"
There is a difference between marking with lowercase letters (a-z) and uppercase letters (A-Z). Lowercase alphabets are local marks and uppercase alphabets are global marks (sometimes known as file marks).
Let's talk about local marks. Each buffer can have its own set of local marks. If I have two files opened, I can set a mark "a" (`ma`) in the first file and another mark "a" (`ma)` in the second file.
Let's talk about local marks. Each buffer can have its own set of local marks. If I have two files opened, I can set a mark "a" (`ma`) in the first file and another mark "a" (`ma)` in the second file.
Unlike local marks where you can have a set of marks in each buffer, you only get one set of global marks. If you set `mA` inside `myFile.txt`, the next time you set `mA` in a different file, it will overwrite the "A" mark. One advantage of global marks is you can jump to any global mark even if you are inside a completely different project. Global marks can travel across files.
@ -300,13 +300,13 @@ To view all marks, use `:marks`. You may notice from the marks list there are mo
`0 Jump back to the last edited file when exiting vim
```
There are more marks than the ones listed above. I won't cover them here because I think they are rarely used, but if you're curious, check out `:h marks`.
There are more marks than the ones listed above. I won't cover them here because I think they are rarely used, but if you're curious, check out `:h marks`.
## Jump
Lastly, let's talk about jumps in Vim. In Vim, you can "jump" to a different file or different part of a file with certain motions. Not all motions count as a jump, though. Going down with `j` does not count as a jump, even if you go 10 steps down with `10j`. Going to line 10 with `10G` counts as a jump.
Lastly, let's talk about jumps in Vim. In Vim, you can "jump" to a different file or different part of a file with certain motions. Not all motions count as a jump, though. Going down with `j` does not count as a jump, even if you go 10 steps down with `10j`. Going to line 10 with `10G` counts as a jump.
Here are the commands Vim consider as "jump" commands:
Here are the commands Vim consider as "jump" commands:
```
' Go to the marked line
@ -328,7 +328,7 @@ H Go to the top line of displayed window
]] Go to the next section
:s Substitute
:tag Jump to tag definition
```
```
I don't recommend memorizing this list. A good rule of thumb is, any motion that moves farther than a word and current line navigation is probably a jump. Vim keeps track of where you've been when you move around and you can see this list inside `:jumps`. For more, check out `:h jump-motions`.
@ -343,9 +343,9 @@ I think the best way to get started is to memorize a few essential motions. I re
To get better at navigation, I can offer two suggestions:
1. Watch for repeated actions. If you find yourself doing `l` repeatedly, look for a motion that will take you forward faster. You will find that you can use `w` to move between words. If you catch yourself repeatedly doing `w`, look if there is a motion that will take you to the end of the line immediately. You will find that you can use `$`. If you can describe your need verbally, there is a good chance Vim has a way to do it.
1. Watch for repeated actions. If you find yourself doing `l` repeatedly, look for a motion that will take you forward faster. You will find that you can use `w` to move between words. If you catch yourself repeatedly doing `w`, look if there is a motion that will take you to the end of the line immediately. You will find that you can use `$`. If you can describe your need verbally, there is a good chance Vim has a way to do it.
2. Whenever you learn a new move, spend a considerable amount of time until you can do it without thinking.
Finally, you do not need to know every single Vim command to be productive. Most Vim users don't. I don't. Learn the commands that will help you accomplish your task at that moment.
Take your time. Navigation skill is a very important skill in Vim. Learn one small thing every day and learn it well.
Take your time. Navigation skill is a very important skill in Vim. Learn one small thing every day and learn it well.

@ -2,7 +2,7 @@
Insert mode is the default mode of many text editors. In this mode, what you type is what you get.
In this chapter, you will learn how to use features in Vim insert mode to improve your typing efficiency.
In this chapter, you will learn how to use features in Vim insert mode to improve your typing efficiency.
## Ways To Go To Insert Mode
@ -31,7 +31,7 @@ Ctrl-[ Exits insert mode and go to normal mode
Ctrl-c Like Ctrl-[ and <esc>, but does not check for abbreviation
```
I find `esc` key too far to reach, so I map my computer `caps lock` to behave like `esc`. If you search for Bill Joy's ADM-3A keyboard (Vi creator), you will see that `esc` key is not located on far top left like modern keyboards, but to the left of `q` key. This is why I think it makes sense to map `caps lock` to `esc`.
I find `esc` key too far to reach, so I map my computer `caps lock` to behave like `esc`. If you search for Bill Joy's ADM-3A keyboard (Vi creator), you will see that `esc` key is not located on far top left like modern keyboards, but to the left of `q` key. This is why I think it makes sense to map `caps lock` to `esc`.
Another common convention I have seen Vim users do is to map `esc` to `jj` or `jk` in insert mode.

@ -4,7 +4,7 @@ When editing a text, as much as you can, avoid redoing what you just did. In thi
## Usage
Just like its name, you can use the dot command by pressing the dot key (`.`).
Just like its name, you can use the dot command by pressing the dot key (`.`).
For example, if you want to replace all "let" with "const" in the following expressions:
```

@ -2,7 +2,7 @@
Learning Vim registers is like learning algebra for the first time. You don't think you need them until you learn them.
You've probably used Vim registers when you yanked or deleted a text then pasted it with `p` or `P`. However, did you know that Vim has 10 different types of registers?
You've probably used Vim registers when you yanked or deleted a text then pasted it with `p` or `P`. However, did you know that Vim has 10 different types of registers?
In this chapter, I will go over all Vim register types and how to use them efficiently.
@ -86,7 +86,7 @@ If you:
The yanked register will have the text from step three.
One last tip, while in insert mode, you can quickly paste the text you just yanked using `Ctrl-r 0`.
One last tip, while in insert mode, you can quickly paste the text you just yanked using `Ctrl-r 0`.
## The Numbered Registers (`"1-9`)
@ -107,7 +107,7 @@ The numbered registers are automatically incremented when using the dot command.
- Do `.` to paste the content from the numbered register two (`"2`).
- Do `.` to paste the content from the numbered register three (`"3`).
During each sequential dot command call, Vim automatically increments the numbered registers. This trick works with any numbered register. If you started with `"5P`, `.` would do `"6P`, `.` again would do `"7P`, and so on.
During each sequential dot command call, Vim automatically increments the numbered registers. This trick works with any numbered register. If you started with `"5P`, `.` would do `"6P`, `.` again would do `"7P`, and so on.
Small deletions like a word deletion (`dw`) or word change (`cw`) do not get stored in the numbered registers. They are stored in the small delete register (`"-`), which I will discuss next.
@ -185,7 +185,7 @@ Ctrl-r =@a
You can also evaluate Vim scripts with the expression register. If you define a variable `i` by running `:let i = 1`, you can get it with `"=i`, press return, then `p`. To get it while in insert mode, run `Ctrl-r=i`.
Suppose you have a function:
Suppose you have a function:
```
function! HelloFunc()
return "Hello Vim Script!"
@ -214,7 +214,7 @@ Now when I copy a text from an external program, I can paste it with the unnamed
Everytime you delete or change a text, that text is stored in Vim register automatically. Sometimes you just don't want to save anything into the register. How can you do that?
You can use the black hole register (`"_`). To delete a line and not have Vim store the deleted line into any register, use `"_dd`. Its the `/dev/null` of registers.
You can use the black hole register (`"_`). To delete a line and not have Vim store the deleted line into any register, use `"_dd`. Its the `/dev/null` of registers.
## The Last Search Pattern Register (`"/`)
@ -243,12 +243,12 @@ You can use the `:put` command to paste the content of any one register. For exa
You made it to the end. Congratulations! That was a lot to take. If you are feeling overwhelmed by the sheer information, you are not alone. I was too, when I first started learning about Vim registers.
I don't think you should memorize everything right away. To become productive, you can start by using only these 3 registers:
I don't think you should memorize everything right away. To become productive, you can start by using only these 3 registers:
1. The unnamed register (`""`).
2. The named registers (`"a-z`).
3. The numbered registers (`"0-9`).
Since the unnamed register defaults to `p` or `P`, you only have to learn two registers: the named registers and the numbered registers. Gradually learn more when you need it. Take your time.
Since the unnamed register defaults to `p` or `P`, you only have to learn two registers: the named registers and the numbered registers. Gradually learn more when you need it. Take your time.
The average human has a limited short-term memory capacity, about seven items at once. That is why in my everyday editing, I only use about three to seven named registers. There is no way I can remember all twenty-six in my head. I normally start with register "a", then "b", ascending the alphabetical order. Try it and experiment around to see what technique works best for you.

@ -71,7 +71,7 @@ Here's the breakdown of the command above:
- `q` stops recording.
I like to overcount my macro calls, so I usually would call it ninety-nine times (`99@a`). With this command, Vim does not actually run this macro ninety-nine times. When Vim reaches the last line and runs `j` action, it finds no more lines to go down to, sees an error, and stops the macro execution.
I like to overcount my macro calls, so I usually would call it ninety-nine times (`99@a`). With this command, Vim does not actually run this macro ninety-nine times. When Vim reaches the last line and runs `j` action, it finds no more lines to go down to, sees an error, and stops the macro execution.
The fact that macro execution stops upon the first error encounter is a good feature, otherwise Vim will continue to execute this macro ninety-nine times even though it already reaches the end of the line.
@ -83,7 +83,7 @@ The `:normal` command accepts range as arguments. You can use this to run macro
## Executing A Macro Across Multiple Files
Suppose you have multiple `.txt` files, each containing different lists. Moreover, you need to uppercase the first word only on lines containing the word "donut". How can we execute macros across multiple files on select lines?
Suppose you have multiple `.txt` files, each containing different lists. Moreover, you need to uppercase the first word only on lines containing the word "donut". How can we execute macros across multiple files on select lines?
First file:
```
@ -140,13 +140,13 @@ Here is the breakdown of the steps:
- `@a` executes macro "a". When recording this, `@a` should be empty because you had just called `qaq`.
- `q` stops recording.
Now you can just run `@a` and watch Vim execute the macro recursively.
Now you can just run `@a` and watch Vim execute the macro recursively.
How does the macro know when to stop? When the macro is on the last line, it tries to run `j`, finds no extra line to go to, and stops the macro execution.
## Appending A Macro
If you need to add more actions to an existing macro, instead of redoing it, you can append actions to it. In the register chapter, you learned that you can append a named register by using its uppercased symbol. To append actions to a macro in register "a", use register "A". Suppose in addition to toggling the case of the first word, you also want to add a dot at the end of the line.
If you need to add more actions to an existing macro, instead of redoing it, you can append actions to it. In the register chapter, you learned that you can append a named register by using its uppercased symbol. To append actions to a macro in register "a", use register "A". Suppose in addition to toggling the case of the first word, you also want to add a dot at the end of the line.
Assume you have the following actions stored as a macro in register "a":

@ -18,13 +18,13 @@ one
two
```
If you do `u`, Vim undoes the text "two".
If you do `u`, Vim undoes the text "two".
How does Vim know how much to undo? Vim undoes a single "change" at a time, similar to a dot command's change (unlike the dot command, command-line commands also count as change).
How does Vim know how much to undo? Vim undoes a single "change" at a time, similar to a dot command's change (unlike the dot command, command-line commands also count as change).
To redo the last change, run `Ctrl-r` or `:redo`. After you undo the text above to remove "two", you can run `Ctrl-r` to get the removed text back.
Vim also has UNDO that you can run with `U`. It undoes all latest changes.
Vim also has UNDO that you can run with `U`. It undoes all latest changes.
How is `U` different from `u`? First, `U` removes *all* the changes on the latest changed line, while `u` only removes one change at a time. Second, while doing `u` does not count as a change, doing `U` counts as a change.
@ -198,7 +198,7 @@ Now create your undo file. The syntax is `:wundo myundofile`. If you need to ove
:wundo! mynumbers.undo
```
Then exit Vim.
Then exit Vim.
By now you should have `mynumbers.txt` and `mynumbers.undo` files in your directory. Open up `mynumbers.txt` again and try pressing `u`. You can't. You haven't made any changes since you opened the file. Now load your undo history by reading the undo file with `:rundo`:
@ -237,7 +237,7 @@ If you had typed "two" less than ten seconds ago, you can go back to the state w
:earlier 10s
```
You can use `:undolist` to see when the last change was made. `:earlier` also accepts minutes (`m`), hours (`h`), and days (`d`) as arguments.
You can use `:undolist` to see when the last change was made. `:earlier` also accepts minutes (`m`), hours (`h`), and days (`d`) as arguments.
```
:earlier 10s go to the state 10 seconds before

@ -75,7 +75,7 @@ one
three
```
Is there a way to freely expand visual selection to go to any direction you want?
Is there a way to freely expand visual selection to go to any direction you want?
The answer is yes. Let's back up a little bit to where you have the line "two" and "three" highlighted.
@ -178,10 +178,10 @@ const three = "three";
```
Notice I said you can do this with *any* visual mode. You do not have to highlight the entire line to run Ex command on that line. As long as you select at least a character on each line, the Ex command will be applied.
## Editing Across Multiple Lines
## Editing Across Multiple Lines
You can edit text across multiple lines in Vim using the block-wise visual mode. If you need to add a semicolon at the end of each line:
```
const one = "one"
const two = "two"
@ -201,7 +201,7 @@ Alternatively, you can also use the `:normal` command:
- Highlight all 3 lines (`vjj`).
- Type `:normal! A;`.
Remember, `:normal` command executes normal mode commands. You can instruct it to run `A;` to append text ";" at the end of the line.
Remember, `:normal` command executes normal mode commands. You can instruct it to run `A;` to append text ";" at the end of the line.
## Incrementing Numbers
@ -291,7 +291,7 @@ gH Line-wise select mode
gCtrl-h Block-wise select mode
```
Select mode emulates a regular editor's text highlighting behavior closer than Vim's visual mode does.
Select mode emulates a regular editor's text highlighting behavior closer than Vim's visual mode does.
In a regular editor, after you highlight a text block and type a letter, say the letter "y", it will delete the highlighted text and insert the letter "y".
@ -303,6 +303,6 @@ I personally never used select mode, but it's good to know that it exists.
## Learn Visual Mode The Smart Way
The visual mode is Vim's representation of the text highlighting procedure.
The visual mode is Vim's representation of the text highlighting procedure.
If you find yourself using visual mode operation far more often than normal mode operations, be careful. I think this is an anti-pattern. It takes more keystrokes to run a visual mode operation than its normal mode counterpart. If you need to delete an inner word, why use four keystrokes, `viwd` (visually highlight an inner word then delete), if you can accomplish it with just three keystrokes (`diw`)? The latter is more direct and concise. Of course, there will be times when visual modes are appropriate, but in general, favor a more direct approach.

@ -12,7 +12,7 @@ However, there are times when you need to search for a case specific phrase. One
Is there a setting that allows you to do case insensitive search most of the time, but also know to do case sensitive search when you need it? Turns out there is a way.
Vim has a `smartcase` option to override `ignorecase` if the search pattern *contains at least one uppercase character*. You can combine both `ignorecase` and `smartcase` to perform a case insensitive search when you enter all lowercase characters and a case sensitive search when you enter one or more uppercase characters.
Vim has a `smartcase` option to override `ignorecase` if the search pattern *contains at least one uppercase character*. You can combine both `ignorecase` and `smartcase` to perform a case insensitive search when you enter all lowercase characters and a case sensitive search when you enter one or more uppercase characters.
Inside your vimrc, add:
@ -44,7 +44,7 @@ If you have this text:
hello hello
```
You can target the first "hello" with `/^hello`. The character that follows `^` must be the first character in a line. To target the last "hello", run `/hello$`. The character before `$` must be the last character in a line.
You can target the first "hello" with `/^hello`. The character that follows `^` must be the first character in a line. To target the last "hello", run `/hello$`. The character before `$` must be the last character in a line.
If you have this text:
@ -75,7 +75,7 @@ salve vim
bonjour vim
```
To match both "hello" and "hola", you can do `/hello\|hola`. You have to escape (`\`) the pipe (`|`) operator, otherwise Vim will literally search for the string "|".
To match both "hello" and "hola", you can do `/hello\|hola`. You have to escape (`\`) the pipe (`|`) operator, otherwise Vim will literally search for the string "|".
If you don't want to type `\|` every time, you can use the `magic` syntax (`\v`) at the start of the search: `/\vhello|hola`. I will not cover `magic` in this chapter, but with `\v`, you don't have to escape special characters anymore. To learn more about `\v`, feel free to check out `:h \v`.
@ -113,11 +113,11 @@ If you need to search for the "foo" in "foobaz" but not in "foobar", run:
All your search terms up to this point have been a literal word search. In real life, you may have to use a general pattern to find your text. The most basic pattern is the character range, `[ ]`.
If you need to search for any digit, you probably don't want to type `/0\|1\|2\|3\|4\|5\|6\|7\|8\|9\|0` every single time. Instead, use `/[0-9]` to match for a single digit. The `0-9` expression represents a range of numbers 0-9 that Vim will try to match, so if you are looking for digits between 1 to 5 instead, use `/[1-5]`.
If you need to search for any digit, you probably don't want to type `/0\|1\|2\|3\|4\|5\|6\|7\|8\|9\|0` every single time. Instead, use `/[0-9]` to match for a single digit. The `0-9` expression represents a range of numbers 0-9 that Vim will try to match, so if you are looking for digits between 1 to 5 instead, use `/[1-5]`.
Digits are not the only data types Vim can look up. You can also do `/[a-z]` to search for lowercase alphas and `/[A-Z]` to search for uppercase alphas.
Digits are not the only data types Vim can look up. You can also do `/[a-z]` to search for lowercase alphas and `/[A-Z]` to search for uppercase alphas.
You can combine these ranges together. If you need to search for digits 0-9 and both lowercase and uppercase alphas from a to f (a hex), you can do `/[0-9a-fA-F]`.
You can combine these ranges together. If you need to search for digits 0-9 and both lowercase and uppercase alphas from a to f (a hex), you can do `/[0-9a-fA-F]`.
To do a negative search, you can add `^` inside the character range brackets. To search for a non-digit, run `/[^0-9]`. Vim will match any character as long as it is not a digit. Beware that the caret (`^`) inside the range brackets is different from the beginning-of-a-line caret (ex: `/^hello`). If a caret is outside of a pair of brackets and is the first character in the search term, it means "the first character in a line". If a caret is inside a pair of brackets and it is the first character inside the brackets, it means a negative search operator. `/^abc` matches the first "abc" in a line and `/[^abc]` matches any character except for an "a", "b", or "c".
@ -182,11 +182,11 @@ Run this:
Let's break it down:
- `"` is a literal double quote. It matches the first double quote.
- `[^"]` means any character except for a double quote. It matches any alphanumeric and whitespace character as long as it is not a double quote.
- `[^"]` means any character except for a double quote. It matches any alphanumeric and whitespace character as long as it is not a double quote.
- `\+` means one or more. Since it is preceded by `[^"]`, Vim looks for one or more character that is not a double quote.
- `"` is a literal double quote. IT matches the closing double quote.
When sees the first `"`, it begins the pattern capture. The moment Vim sees the second double quote in a line, it matches the second `"` pattern and stops the pattern capture. Meanwhile, all non-`"` characters between the two `"` are captured by the `[^"]\+` pattern, in this case, the phrase `Vim is awesome!`. This is a common pattern to capture a phrase surrounded by a pair of similar delimiters: to capture a phrase surrounded by a single quote, you can use `/'[^']\+'`.
When sees the first `"`, it begins the pattern capture. The moment Vim sees the second double quote in a line, it matches the second `"` pattern and stops the pattern capture. Meanwhile, all non-`"` characters between the two `"` are captured by the `[^"]\+` pattern, in this case, the phrase `Vim is awesome!`. This is a common pattern to capture a phrase surrounded by a pair of similar delimiters: to capture a phrase surrounded by a single quote, you can use `/'[^']\+'`.
## Capturing A Phone Number
@ -206,7 +206,7 @@ You can avoid typing escapes with `\v`:
/\v\d{3}-\d{3}-\d{4}
```
This pattern is also useful to capture any repeating digits, such as IP addresses and zip codes.
This pattern is also useful to capture any repeating digits, such as IP addresses and zip codes.
That covers the search part of this chapter. Now let's move to substitution.
@ -232,7 +232,7 @@ vim is awesome
## Repeating The Last Substitution
You can repeat the last substitute command with either the normal command `&` or by running `:s`. If you have just run `:s/good/awesome/`, running either `&` or `:s` will repeat it.
You can repeat the last substitute command with either the normal command `&` or by running `:s`. If you have just run `:s/good/awesome/`, running either `&` or `:s` will repeat it.
Also, earlier in this chapter I mentioned that you can use `//` to repeat the previous search pattern. This trick works with the substitution command. If `/good` was done recently and you leave the first substitute pattern argument blank, like in `:s//awesome/`, it is the same as running `:s/good/awesome/`.
@ -299,7 +299,7 @@ let five = "5";
Let's break down the command:
- `:%s` targets the entire file to perform substitution.
- `\d` is Vim's predefined range for digits (`[0-9]`).
- `\d` is Vim's predefined range for digits (`[0-9]`).
- `"\0"` the double quotes are literal double quotes. `\0` is a special character representing "the whole matched pattern". The matched pattern here is a single digit number, `\d`. On line one, `\0` has the value of "1". On line two, value of "2". On line three, value of "3", and so on.
Alternatively, `&` also represents "the whole matched pattern" like `\0`. `:s/\d/"&"/` would have also worked.
@ -396,7 +396,7 @@ The command above will only substitute the first match, giving you:
chocolate donut, strawberry pancake, blueberry pancake
```
There are two ways to solve this. First, you can run the substitute command twice more. Second, you can pass it a global (`g`) flag to substitute all of the matches in a line.
There are two ways to solve this. First, you can run the substitute command twice more. Second, you can pass it a global (`g`) flag to substitute all of the matches in a line.
Let's talk about the global flag. Run:
@ -653,13 +653,13 @@ Assume your directory structure looks like this:
First, capture both `food.txt` and `animal.txt` inside `:args`. Recall from earlier chapters that `:args` can be used to create a list of file names. There are several ways to do this from inside Vim:
```
:args *.txt captures all txt files in current location
:args *.txt captures all txt files in current location
:args food.txt animal.txt captures only index and server js files
:args **/*.txt captures every txt files
:args ** captures everything
:args ** captures everything
```
You can also run the commands above from outside Vim, passing the files as *arguments* for Vim (hence it is called the "args" command). From the terminal, run
You can also run the commands above from outside Vim, passing the files as *arguments* for Vim (hence it is called the "args" command). From the terminal, run
```
vim food.txt animal.txt

@ -1,12 +1,12 @@
# Ch 13. The Global Command
So far you have learned how to repeat the last change with the dot command (`.`), to replay actions with macros (`q`), and to store texts in the registers (`"`).
So far you have learned how to repeat the last change with the dot command (`.`), to replay actions with macros (`q`), and to store texts in the registers (`"`).
In this chapter, you will learn how to repeat a command-line command with the global command. Run once, apply everywhere (in a buffer).
## Global Command Overview
Vim's global command is used to running a command-line command on multiple lines simultaneously.
Vim's global command is used to running a command-line command on multiple lines simultaneously.
By the way, you may have heard of the term "Ex Commands" before. In this book, I refer them as command-line commands, but both Ex commands and command-line commands are the same. They are the commands that start with a colon (`:`). In the last chapter, you learned about the substitute command. It was an example of an Ex command. They are called Ex because they originally came from the Ex text editor. I will continue to refer to them as command-line commands in this book. For a full list of Ex commands, check out `:h ex-cmd-index`.
@ -146,7 +146,7 @@ In addition to numbers, you can also use these symbols as range:
- `$` means the last line in the file. `3,$` range means between line 3 and the last line.
- `+n` means n lines after the current line. You can use it with `.` or without. `3,+1` or `3,.+1` means between line 3 and the line after the current line.
If you don't give it any range, by default it affects the entire file. This is actually not the norm. Most of Vim's command-line commands run on only the current line if you don't pass it any range. The two notable exceptions are the global (`:g`) and the save (`:w`) commands.
If you don't give it any range, by default it affects the entire file. This is actually not the norm. Most of Vim's command-line commands run on only the current line if you don't pass it any range. The two notable exceptions are the global (`:g`) and the save (`:w`) commands.
## Normal Command
@ -267,7 +267,7 @@ Here the global command will look for all lines containing "one". The substitute
## The Default Command
What happens if you don't specify any command-line command in the global command?
What happens if you don't specify any command-line command in the global command?
The global command will use the print (`:p`) command to print the current line's text. If you run:
@ -287,7 +287,7 @@ By the way, here is one interesting fact. Because the default command used by th
- `re` = the regex pattern
- `p` = the print command
It spells *"grep"*, the same `grep` from the command line. This is **not** a coincidence. The `g/re/p` command originally came from the Ed Editor, one of the first line text editors. The `grep` command got its name from Ed.
It spells *"grep"*, the same `grep` from the command line. This is **not** a coincidence. The `g/re/p` command originally came from the Ed Editor, one of the first line text editors. The `grep` command got its name from Ed.
Your computer probably still has the Ed editor. Run `ed` from the terminal (hint: to quit, type `q`).
@ -298,7 +298,7 @@ Your computer probably still has the Ed editor. Run `ed` from the terminal (hint
To reverse the entire file, run:
```
:g/^/m 0
:g/^/m 0
```
`^` is a pattern for the "beginning of a line". Use `^` to match all lines, including empty lines.
@ -476,7 +476,7 @@ e
c
```
You can sort them by running `:sort`. If you give it a range, it will sort only the lines within that range. For example, `:3,5sort` sorts only between lines three and five.
You can sort them by running `:sort`. If you give it a range, it will sort only the lines within that range. For example, `:3,5sort` sorts only between lines three and five.
If you have the following expressions:
@ -537,7 +537,7 @@ const arrayA = [
This is great! But the command looks complicated. Let's break it down. The command consists of three main parts: the global command pattern, the sort command range, and the sort command.
`:g/\[/` is the global command pattern.
`:g/\[/` is the global command pattern.
- `:g` is the global command.
- `/\[/` is the pattern used by the global command. `\[` looks for a literal "[" string.
@ -552,7 +552,7 @@ If you are still confused by the command, do not worry. It took me a long time t
## Learn The Global Command The Smart Way
The global command executes the command-line command against all matching lines. With it, you only need to run a command once and Vim will do the rest for you. To become proficient at the global command, two things are required: a good vocabulary of command-line commands and a knowledge of regular expressions. As you spend more time using Vim, you will naturally learn more command-line commands. A regular expression knowledge will require a more active approach. But once you become comfortable with regular expressions, you will be ahead of many.
The global command executes the command-line command against all matching lines. With it, you only need to run a command once and Vim will do the rest for you. To become proficient at the global command, two things are required: a good vocabulary of command-line commands and a knowledge of regular expressions. As you spend more time using Vim, you will naturally learn more command-line commands. A regular expression knowledge will require a more active approach. But once you become comfortable with regular expressions, you will be ahead of many.
Some of the examples here are complicated. Do not be intimidated. Really take your time to understand them. Learn to read the patterns. Make sure you know what each letter in each command represent. Do not give up.

@ -78,7 +78,7 @@ Make sure you have [node](https://nodejs.org/en/) installed in your machine, the
:w !node
```
Vim will use `node` to execute the Javascript expressions to print "Hello Vim" and "Vim is awesome".
Vim will use `node` to execute the Javascript expressions to print "Hello Vim" and "Vim is awesome".
When using the `:w` command, Vim uses all texts in the current buffer, similar to the global command (most command-line commands, if you don't pass it a range, only executes the command against the current line). If you pass `:w` a specific address:
@ -155,7 +155,7 @@ hello
The breakdown:
- `:%!` executes the filter command on all lines (`%`).
- `awk "{print $1}"` prints only the first column of the match. In this case, the word "hello".
- `awk "{print $1}"` prints only the first column of the match. In this case, the word "hello".
You can chain multiple commands with the chain operator (`|`) just like in the terminal. Let's say you have a file with these delicious breakfast items:
@ -203,7 +203,7 @@ To uppercase the current line and the line below, you can run:
```
The breakdown:
- `!j` runs the normal command filter operator (`!`) targetting the current line and the line below it. Recall that because it is a normal mode operator, the grammar rule `verb + noun` applies.
- `!j` runs the normal command filter operator (`!`) targetting the current line and the line below it. Recall that because it is a normal mode operator, the grammar rule `verb + noun` applies.
- `tr '[a-z]' '[A-Z]'` replaces the lowercase letters with the uppercase letters.
The filter normal command only works on motions / text objects that are at least one line or longer. If you had tried running `!iwtr '[a-z]' '[A-Z]'` (execute `tr` on inner word), you will find that it applies the `tr` command on the entire line, not the word your cursor is on.

@ -12,14 +12,14 @@ There are 4 different commands you can use to enter the command-line mode:
- Command-line commands (`:`)
- External commands (`!`)
You can enter the command-line mode from the normal mode or the visual mode.
You can enter the command-line mode from the normal mode or the visual mode.
To leave the command-line mode, you can use `<esc>`, `Ctrl-c, or Ctrl-[`.
*Sometimes other literatures might refer the "Command-line command" as "Ex command" and the "External command" as "filter command" or "bang operator".*
## Repeating The Previous Command
You can repeat the previous command-line command or external command with `@:`.
You can repeat the previous command-line command or external command with `@:`.
If you just ran `:s/foo/bar/g`, running `@:` repeats that substitution.
@ -76,7 +76,7 @@ When you are in the command-line mode, you can traverse this history list by pre
53 s/foo//g
```
If you press `:` then press `Up` once, you'll see `:s/foo//g`. Press `Up` one more time to see `:s/foo/baz/g`. Vim goes up the history list.
If you press `:` then press `Up` once, you'll see `:s/foo//g`. Press `Up` one more time to see `:s/foo/baz/g`. Vim goes up the history list.
Similarly, to view the search history, run `:his /`. You can also traverse the history stack by pressing `Up` or `Down` after running the history command `/`.

@ -59,7 +59,7 @@ Whoops, Vim could not find the tag file. You need to generate the tag file first
Modern Vim does not come with tag generator, so you will have to download an external tag generator. There are several options to choose:
- ctags = C only. Available almost everywhere.
- exuberant ctags = One of the most popular ones. Has many language support.
- exuberant ctags = One of the most popular ones. Has many language support.
- universal ctags = Similar to exuberant ctags, but newer.
- etags = For Emacs. Hmm...
- JTags = Java
@ -198,7 +198,7 @@ class One
puts "Initialized"
end
def donut
def donut
puts "one donut"
end

@ -8,7 +8,7 @@ In this chapter, you will learn how to use different folding methods.
Imagine that you are folding a sheet of paper to cover some text. The actual text does not go away, it is still there. Vim fold works the same way. It *folds* a range of text, hiding it from display without actually deleting it.
The fold operator is `z`. When you fold a paper, the fold looks like the letter "z" too.
The fold operator is `z`. When you fold a paper, the fold looks like the letter "z" too.
Suppose you have this text:
@ -134,7 +134,7 @@ One
+-- 2 lines: Three -----
```
What's this? A fold within a fold?
What's this? A fold within a fold?
You can have nested folds. The text "Two" and "Two again" have fold level of one. The text "Three" and "Three again" have fold level of two. If you have a foldable text with a higher fold level within a foldable text, you can have multiple fold layers.
@ -315,7 +315,7 @@ vim is awesome
vim is awesome
vim is awesome
vim is awesome
[vim is awesome] / [emacs is ok]
[vim is awesome] / [emacs is ok]
```
Vim automatically folds some of the identical lines. When you are running the `vimdiff` command, Vim automatically uses `foldmethod=diff`. If you run `:set foldmethod?`, it will return `diff`.

@ -41,7 +41,7 @@ all:
echo "Hello all"
foo:
echo "Hello foo"
list_pls:
list_pls:
ls
```
@ -75,7 +75,7 @@ all:
echo "Hello all"
foo:
echo "Hello foo"
list_pls:
list_pls:
ls
```
@ -209,7 +209,7 @@ Recall that if you run `:make`, Vim executes whatever command is assigned to `ma
Vim runs the `$VIMRUNTIME/compiler/ruby.vim` script and changes the `makeprg` to use the `ruby` command. Now if you run `:set makeprg?`, it should say `makeprg=ruby` (this depends on what is inside your `$VIMRUNTIME/compiler/ruby.vim` file or if you have another custom ruby compilers. Yours might be different). The `:compiler <your-lang>` command allows you to switch to different compilers quickly. This is useful if your project uses multiple languages.
You don't have to use the `:compiler` and `makeprg` to compile a program. You can run a test script, lint a file, send a signal, or anything you want.
You don't have to use the `:compiler` and `makeprg` to compile a program. You can run a test script, lint a file, send a signal, or anything you want.
## Creating A Custom Compiler
@ -247,7 +247,7 @@ CompilerSet makeprg=tsc
CompilerSet errorformat=%f:\ %m
```
The first line sets the `makeprg` to run the `tsc` command. The second line sets the error format to display the file (`%f`), followed by a literal colon (`:`) and an escaped space (`\ `), followed by the error message (`%m`). To learn more about the error formatting, check out `:h errorformat`.
The first line sets the `makeprg` to run the `tsc` command. The second line sets the error format to display the file (`%f`), followed by a literal colon (`:`) and an escaped space (`\ `), followed by the error message (`%m`). To learn more about the error formatting, check out `:h errorformat`.
You should also read some of the pre-made compilers to see how others do it. Check out `:e $VIMRUNTIME/compiler/<some-language>.vim`.
@ -336,7 +336,7 @@ Vim-dispatch has `b:dispatch` buffer variable that you can configure to evaluate
autocmd BufEnter *_spec.rb let b:dispatch = 'bundle exec rspec %'
```
Now each time you enter a file (`BufEnter`) that ends with `_spec.rb`, running `:Dispatch` automatically executes `bundle exec rspec <your-current-ruby-spec-file>`.
Now each time you enter a file (`BufEnter`) that ends with `_spec.rb`, running `:Dispatch` automatically executes `bundle exec rspec <your-current-ruby-spec-file>`.
## Learn Compile The Smart Way

@ -272,7 +272,7 @@ To check your runtimepath, run `:set runtimepath?`
If you use Vim-Plug or popular external plugin managers, it should display a list of directories. For example, mine shows:
```
runtimepath=~/.vim,~/.vim/plugged/vim-signify,~/.vim/plugged/base16-vim,~/.vim/plugged/fzf.vim,~/.vim/plugged/fzf,~/.vim/plugged/vim-gutentags,~/.vim/plugged/tcomment_vim,~/.vim/plugged/emmet-vim,~/.vim/plugged/vim-fugitive,~/.vim/plugged/vim-sensible,~/.vim/plugged/lightline.vim, ...
runtimepath=~/.vim,~/.vim/plugged/vim-signify,~/.vim/plugged/base16-vim,~/.vim/plugged/fzf.vim,~/.vim/plugged/fzf,~/.vim/plugged/vim-gutentags,~/.vim/plugged/tcomment_vim,~/.vim/plugged/emmet-vim,~/.vim/plugged/vim-fugitive,~/.vim/plugged/vim-sensible,~/.vim/plugged/lightline.vim, ...
```
One of the things plugin managers does is adding each plugin into the runtime path. Each runtime path can have its own directory structure similar to `~/.vim/`. If you have an arbitrary directory `~/box/of/donuts/` and you want to add that directory to your runtime path, you can add this to your vimrc:

Loading…
Cancel
Save