añadir capítulos 20 y 21 e imagen

This commit is contained in:
Victorhck 2020-11-14 20:48:48 +01:00
parent 89529f17b5
commit f11f83e44e
3 changed files with 649 additions and 0 deletions

View file

@ -0,0 +1,406 @@
# Ch 20. Views, Sessions, and Viminfo
After you worked on a project for a while, you may find that the project to gradually take shape with its own settings, folds, buffers, layouts, etc. It's like decorating your apartment to make it feel like home.
The problem is, when you close Vim, you lose those changes. Wouldn't it be nice if you can keep those changes so the next time you open Vim, it looks just like you had never left?
Vim has three tools for this: View, Session, and Viminfo. In this chapter, you will learn how to leverage all three to take a "snapshot" of your project.
## Views
A View is the smallest subset of the three (View, Session, Viminfo). A Vim View is a collection of settings for one window. If you spend a long time working on a window and you want to preserve the mappings and folds, you can use a View.
Let's create a file called `foo.txt`:
```
foo1
foo2
foo3
foo4
foo5
foo6
foo7
foo8
foo9
foo10
```
In this file, create three changes:
1. On line 1, create a manual fold `zf4j` (fold the next 4 lines).
2. Change the `number` setting: `setlocal nonumber norelativenumber`.
3. Create a local mapping to go down two lines each time you press `j` instead of one: `:nnoremap <buffer> j jj`.
Your file should look like this:
```
+-- 5 lines: foo1 -----
foo6
foo7
foo8
foo9
foo10
```
Now, your display won't have any numbers on the left side and pressing the `j` key goes down two lines instead of one line.
## Configuring View Attributes
Run:
```
:set viewoptions?
```
By default it should say:
```
viewoptions=folds,cursor,curdir
```
Yours might look different. Let's configure `viewoptions`. The three attributes you want to preserve are the folds, the mapping, and the local set option. If your setting looks like mine, you already have the `folds` option. You need to tell View to remember the `localoptions`. Run:
```
:set viewoptions+=localoptions
```
To learn what other options are available for `viewoptions`, check out `:h viewoptions`. Now if you run `:set viewoptions?`, you should see:
```
viewoptions=folds,cursor,curdir,localoptions
```
## Saving the View
With the `foo.txt` window properly folded and having `nonumber norelativenumber` options, let's save the View. Run:
```
:mkview
```
Vim creates a View file.
## View Files
You might wonder, "Where did Vim save this View file?" To see where Vim saves it, run:
```
:set viewdir?
```
The default should say `~/.vim/view` (if you have a different OS, it might show a different path. Check out `:h viewdir` for more). If you want to change it to a different path, add this into your vimrc:
```
set viewdir=$HOME/else/where
```
## Loading the View File
Close the `foo.txt` if you haven't, then open `foo.txt` again. You should see the original text without the changes. That's expected. Let's load the View file. Run:
```
:loadview
```
Now you should see:
```
+-- 5 lines: foo1 -----
foo6
foo7
foo8
foo9
foo10
```
The folds, local settings, and local mappings are restored. If you notice, your cursor should also be on the line where you left it when you ran `:mkview`. As long as you have the `cursor` option, View also remembers your cursor position.
## Multiple Views
Vim lets you save 9 numbered Views (1-9).
Suppose you want to make an additional fold (say you want to fold the last two lines) with `:9,10 fold`. Let's save this as View 1. Run:
```
:mkview 1
```
If you want to make one more fold with `:6,7 fold` and save it as a different View, run:
```
:mkview 2
```
Close the file. When you open `foo.txt` and you want to load View 1, run:
```
:loadview 1
```
To load View 2, run:
```
:loadview 2
```
To load the original View, run:
```
:loadview
```
## Automating View Creation
One of the worst things that can happen is, after spending countless hours organizing a large file with folds, you accidentally close the window and lose all fold information. To prevent this, you might want to automatically create a View each time you close a buffer. Add this in your vimrc:
```
au BufWinLeave *.txt mkview
```
Additionally, it might be nice to load View when you open a buffer:
```
au BufWinEnter *.txt silent loadview
```
Now you don't have to worry about creating and loading View anymore when you are working with `txt` files. Keep in mind that over time, your `~/.vim/view` might start to accumulate View files. It's good to clean it up once every few months.
## Sessions
If a View saves the settings of a window, a Session saves the information of all windows (including the layout).
## Creating a New Session
Suppose you are working with these 3 files in a `foobarbaz` project:
`foo.txt`:
```
foo1
foo2
foo3
foo4
foo5
foo6
foo7
foo8
foo9
foo10
```
`bar.txt`:
```
bar1
bar2
bar3
bar4
bar5
bar6
bar7
bar8
bar9
bar10
```
and `baz.txt`:
```
baz1
baz2
baz3
baz4
baz5
baz6
baz7
baz8
baz9
baz10
```
And you've been working on these 3 files for a while, so that your windows layout look like (using strategically placed `split` and `vsplit`):
![./img/session-layout.png](./img/session-layout.png)
To save the Session, run:
```
:mksession
```
Unlike `mkview` where it saves to `~/.vim/view` by default, `mksession` saves a Session file (`Session.vim`) in the current directory. Check out the file if you're curious what's inside.
If you want to save the Session file somewhere else, you can pass an argument to `mksession`:
```
:mksession ~/some/where/else.vim
```
If you want to overwrite the existing Session file, call the command with a `!` (`:mksession! ~/some/where/else.vim`).
## Loading a Session
To load a Session, run:
```
:source Session.vim
```
`Session.vim` is the Session file. Now Vim looks like the way you left it. Alternatively, you can also load a Session file from the terminal:
```
vim -S Session.vim
```
## Configuring Session Attributes
You can configure the attributes Session saves. To see what is currently being saved, run:
```
:set sessionoptions?
```
Mine says:
```
blank,buffers,curdir,folds,help,tabpages,winsize,terminal
```
Yours might look different. To add or remove an option, you can use `+=` or `=`.
If you don't want to save `terminal` when you save a Session, run:
```
:set sessionoptions-=terminal
```
If you want to add an `options` when you save a Session, run:
```
:set sessionoptions+=options
```
Here are some attributes that `sessionoptions` can store:
- `blank` stores empty windows
- `buffers` stores buffers
- `folds` stores folds
- `globals` stores global variables (must start with an uppercase letter and contain at least one lowercase letter)
- `options` stores options and mappings
- `resize` stores window lines and columns
- `winpos` stores window position
- `winsize` stores window sizes
- `tabpages` stores tabs
- `unix` stores files in Unix format
For the complete list check out `:h 'sessionoptions'`.
Session is a useful tool to preserve your project's external attributes. However, there are a number of internal attributes that Session doesn't save: local marks, registers, histories, etc.
To save them, you need to use Viminfo!
## Viminfo
After yanking a word into register a and quitting Vim, the next time you open Vim you can immediately paste the text from register a. This is actually one of Viminfo's features. Without it, Vim won't remember the register after you close.
If you use Vim 8 or higher, Vim enables Viminfo by default, so you may have been using Vim info this whole time without knowing it!
You might ask: "What does Viminfo save? How does it differ from Session?"
You just learned the things that Session saves from `sessionoptions`. To use Viminfo, first you need to have `+viminfo` feature available (`:version`). Viminfo stores:
- The command-line history.
- The search string history.
- The input-line history.
- Contents of non-empty registers.
- Marks for several files.
- File marks, pointing to locations in files.
- Last search / substitute pattern (for 'n' and '&').
- The buffer list.
- Global variables.
When comparing the items that can be saved for Session and Viminfo, you will notice that `sessionoptions`, in general, saves the "external" attributes while `viminfo` saves the "internal" attributes.
Unlike Session where you can have one Session file per project, you normally will use one Viminfo file per computer. Viminfo is project-agnostic.
The default Viminfo location for Unix is `$HOME/.viminfo` (`~/.viminfo`). If you use a different OS, your Viminfo location might be different. Check out `:h viminfo-file-name`. Each time you make "internal" changes, like yanking a text into a register, Vim automatically updates the Viminfo file.
*Make sure that you have `nocompatible` option set (`set nocompatible`), otherwise your Viminfo will not work.*
## Writing and Reading Viminfo
Although you will use only one Viminfo file, you can create multiple Viminfo files. To write a Viminfo file, use the `:wviminfo` command (`:wv` for short).
```
:wv ~/.viminfo_extra
```
To overwrite an existing Viminfo file, add a bang to the `wv` command:
```
:wv! ~/.viminfo_extra
```
By default Vim will read from `~/.viminfo` file. To read from a different Viminfo file, run `:rviminfo`, or `:rv` for short:
```
:rv ~/.viminfo_extra
```
You can also start Vim with a different Viminfo file from the terminal with the `i` flag:
```
vim -i viminfo_extra
```
Multiple Viminfo files can be used to create several different settings for different text editing needs:
```
vim -i viminfo_writing
vim -i viminfo_coding
```
## Starting Vim Without Viminfo
To start Vim without Viminfo data, you can run from the terminal:
```
vim -i NONE
```
To make it permanent, you can add this in your `vimrc` file:
```
set viminfo="NONE"
```
## Configuring Viminfo Attributes
Similar to `viewoptions` and `sessionoptions`, you can instruct what attributes to save with the `viminfo` option. Run:
```
:set viminfo?
```
You will get:
```
!,'100,<50,s10,h
```
This looks cryptic. Let's break it down:
- `!` saves global variables that start with an uppercase letter and don't contain lowercase letters. Recall that `g:` indicates a global variable. For example, if you call `:let g:FOO = "foo"`, Viminfo will save the global variable `FOO`. However if you do `:let g:Foo = "foo"`, Viminfo will not save this global variable because it contains lowercase letters. Without `!`, Vim won't safe those global variables.
- `'100` represents marks. In this case, Viminfo will save the local marks (a-z) of the last 100 files. Be aware that if you tell Viminfo to save too many files, Vim can start slowing down. 100-1000 files is a good range.
- `<50` tells Viminfo how many lines are saved for each registers (50 or less in this case). If I yank 100 lines of text into register a (`"ay99j`) and close Vim, the next time I open Vim and paste from register a (`"ap`), Vim will only paste 50 lines max. If you don't give it anything, *all* lines will be saved (it might slow down Vim). If you give it a 0, nothing will be saved.
- `s10` sets a size limit (in kb) for a register. In this case, any register greater than 10kb size will be excluded.
- `h` disables highlighting (from `hlsearch`) when Vim starts.
There are other options. To learn more, check out `:h 'viminfo'`.
## Using Views, Sessions, and Viminfo the Smart Way
Vim has View, Session, and Viminfo to take different level of "snapshot" of your Vim environment. For small projects, use Views. For larger projects, use Sessions. You should take your time to check out all the options that View, Session, and Viminfo offers.
Create your own View, Session, and Viminfo for your own editing style. Store them in your dotfiles. If you ever need to use Vim outside of your computer, you can just load your settings and you will immediately feel at home!

243
ch21_vimrc.md Normal file
View file

@ -0,0 +1,243 @@
# Ch 21. Vimrc
In the previous chapters, you learned how to use Vim. From now on, you will learn how to customize Vim to fit your coding style.
In this chapter, you will learn how to configure and organize vimrc.
## How Vim Finds Vimrc
The conventional wisdom to configure vimrc is to add a `.vimrc` dotfile in the root directory of your computer (`~/.vimrc`).
Behind the scene, Vim looks at multiple places for a vimrc file, not only the root directory. Here are the places that Vim checks:
- `$VIMINIT`
- `$HOME/.vimrc`
- `$HOME/.vim/vimrc`
- `$EXINIT`
- `$HOME/.exrc`
- `$HOME/.vim/exrc`
- `$VIMRUNTIME/default.vim`
When you start Vim, it will check the above seven locations in that order for a "vimrc" file (in this chapter, I will refer to the runtime command file Vim uses at start-time as vimrc, regardless what the file is actually named). The first vimrc file found will be used and the rest is ignored. First Vim will look for `$VIMINIT`. If there is nothing there, Vim checks for `$HOME/.vimrc`. If there is nothing there, Vim checks for `$HOME/.vim/vimrc`. If Vim finds it, it will stop looking and use `$HOME/.vim/vimrc`. Let's break down what each path means.
The first, `$VIMINIT`, is an environment variable. By default it is undefined. If you want to use `~/dotfiles/hellovim` as your `$VIMINIT` value, you can define it as follows:
1. Create a `~/.dotfiles/hellovim` and inside it have:
```
set nocompatible
set relativenumber number
```
2. In the terminal, run `export VIMINIT='let $MYVIMRC="$HOME/dotfiles/hellovim" | source $MYVIMRC'`
Now when you run Vim from the terminal, it will use `~/dotfiles/hellovim` as a vimrc file.
The second, `$HOME/.vimrc`, is the conventional path for many Vim users. `$HOME` in most cases is your root directory (`~`). If you drop the vimrc in this path, `~/.vimrc`, Vim will use this file.
The third, `$HOME/.vim/vimrc`, is located inside the `~/.vim` directory. You might have the `~/.vim` directory already for your plugins, custom scripts, or View files. Note that there is no dot in `vimrc` file name (`$HOME/.vim/.vimrc` doesn't work, but `$HOME/.vim/vimrc` does).
The fourth, `$EXINIT` is similar to `$VIMINIT`. The fifth and sixth, `$HOME/.exrc` and `$HOME/.vim/exrc` are also similar to `$HOME/.vimrc` and `$HOME/.vim/exrc`.
The seventh, `$VIMRUNTIME/defaults.vim` is the default vimrc that comes with your Vim build. In my case, I have Vim 8.2 installed, so my path is (`/usr/local/share/vim/vim82`). If Vim does not find any of the previous six vimrc file, it will use this file.
## Installing Plugins
For the remaining of this chapter, I am assuming that the vimrc follows the `~/.vimrc` path. Regardless where you actually put your vimrc, you should be able to follow along.
In the previous chapters, I have ocassionally mentioned different plugins, like [fzf.vim](https://github.com/junegunn/fzf.vim), [vim-mundo](https://github.com/simnalamburt/vim-mundo), and [vim-fugitive](https://github.com/tpope/vim-fugitive).
Let's talk about different ways to install plugins. Ten years ago, managing plugins was a nightmare. However, with the emergence of modern plugin managers, installing plugins can now be done within seconds. I am currently using [vim-plug](https://github.com/junegunn/vim-plug) as my plugin manager, so I will use it in this section. The concept should be similar with other popular plugin managers. I would strongly recommend you to check out different ones, such as:
- [vundle.vim](https://github.com/VundleVim/Vundle.vim)
- [vim-pathogen](https://github.com/tpope/vim-pathogen)
- [dein.vim](https://github.com/Shougo/dein.vim)
There are more plugin managers than the ones listed above. To install vim-plug, if you have a Unix machine, run:
```
curl -fLo ~/.vim/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
```
To add new plugins, drop your plugin names (`Plug 'github-username/repository-name'`) between the `call plug#begin()` and the `call plug#end()` lines. So if you want to install `emmet-vim` and `nerdtree`, put the following snippet down in your vimrc:
```
call plug#begin('~/.vim/plugged')
Plug 'mattn/emmet-vim'
Plug 'preservim/nerdtree'
call plug#end()
```
Save the changes, source it (`:source %`), and run `:PlugInstall` to install them.
In the future if you need to remove unused plugins, you just need to remove the plugin names from the `call` block, save and source, and run the `:PlugClean` command to remove it from your machine.
Vim 8 has its own built-in package managers. You can check out `:h packages` for more information. In a later chapter, I will show you how to use it.
## Modifying vimrc
A vimrc is nothing but a collection of command-line commands. For example, to display `number` and `relativenumber` settings, you can run `:set relativenumber number` command from the current buffer. But this command is not permanent, you will lose it when you close Vim. You need to add them to your vimrc:
```
set relativenumber
set number
```
Alternatively, you can also put them in one line:
```
set relativenumber number
```
Both do the same thing. It comes down to your personal preference.
It is common to put mappings in your vimrc. I personally like to use `<space>` as the leader key instead of Vim's default. To change your leader key to a backslash, you can add this in your vimrc:
```
let mapleader = "\<space>"
```
I find myself opening, editing, and sourcing vimrc quite often in the middle of a programming session. Having to manually find vimrc can take a lot of effort, so I add this in my vimrc:
```
nnoremap <Leader>ve :vsplit $MYVIMRC<CR>
nnoremap <Leader>vs :source $MYVIMRC<CR>
```
Recall that `nnoremap` adds a non-recursive Normal-mode mapping. Vim has the environment variable `$MYVIMRC` to store the path of your vimrc. I can quickly open my vimrc file with `<leader>ve` ("vimrc edit" mnemonic) and source it with `<leader>vs` ("vimrc source" mnemonic).
## Organizing Vimrc
Over time, your vimrc will grow large and start to become convoluted. There are two ways to keep your vimrc to look clean:
- Split your vimrc into several files.
- Fold your vimrc file based on categories.
### Splitting Your Vimrc
You can split your vimrc to multiple files using Vim's `source` command. This command reads command-line commands from the given file argument.
Let's create a file inside the `~/.vim` directory and name it `/settings` (`~/.vim/settings`). The name itself is arbitrary and you can name it whatever you like.
You are going to split it into three components:
- Third-party plugins (`~/.vim/settings/plugins.vim`).
- General settings (`~/.vim/settings/configs.vim`).
- Key mappings (`~/.vim/settings/mappings.vim`) .
Inside `~/.vimrc`:
```
source $HOME/.vim/settings/plugins.vim
source $HOME/.vim/settings/configs.vim
source $HOME/.vim/settings/mapppings.vim
```
Inside `~/.vim/settings/plugins.vim`:
```
call plug#begin('~/.vim/plugged')
Plug 'mattn/emmet-vim'
Plug 'preservim/nerdtree'
call plug#end()
```
Inside `~/.vim/settings/configs.vim`:
```
set relativenumber
set number
```
Inside `~/.vim/mappings.vim`:
```
nnoremap <Leader>vs :source $MYVIMRC<CR>
nnoremap <Leader>ve :vsplit $MYVIMRC<CR>
```
Your vimrc should works as usual, but now it is only three lines long!
With this setup, you easily know where to go. If you need to add more mappings, simple head to the `/mappings.vim` file. In the future, you can always add more directories as your vimrc grows. For example, if you have many custom functions, you can store them inside `/functions.vim`.
### Keeping One Vimrc File
You may prefer to keep one vimrc file to keep it portable but your vimrc file is growing uncontrollably large. How do you manage this?
You use marker folds. Add this at the top of your vimrc:
```
" setup folds {{{
augroup filetype_vim
autocmd!
autocmd FileType vim setlocal foldmethod=marker
augroup END
" }}}
```
Vim can detect what kind of filetype the current buffer has (`:set filetype?`). If it is a `vim` filetype, you can use a marker fold method. Recall that a marker fold uses `{{{` and `}}}` to indicate the starting and ending folds.
Add `{{{` and `}}}` folds to the rest of your vimrc (don't forget to comment them with `"`):
```
" setup folds {{{
augroup filetype_vim
autocmd!
autocmd FileType vim setlocal foldmethod=marker
augroup END
" }}}
" plugins {{{
call plug#begin('~/.vim/plugged')
Plug 'mattn/emmet-vim'
Plug 'preservim/nerdtree'
call plug#end()
" }}}
" configs {{{
set nocompatible
set relativenumber
set number
" }}}
" mappings {{{
nnoremap <Leader>vs :source $MYVIMRC<CR>
nnoremap <Leader>ve :vsplit $MYVIMRC<CR>
" }}}
```
Your vimrc should look like this:
```
+-- 6 lines: setup folds -----
+-- 6 lines: plugins ---------
+-- 5 lines: configs ---------
+-- 4 lines: mappings --------
```
## Running vim without vimrc
If you need to run Vim without any vimrc, run this from the terminal:
```
vim -u NONE
```
If you need to run Vim with a *different* vimrc, say `~/.vimrc-extra`, run this from the terminal:
```
vim -u ~/.vimrc-extra
```
The `u` flag overwrites all the seven vimrc paths mentioned earlier.
## Configure Vimrc The Smart Way
In the beginning, there is a strong temptation to copy other people's vimrc. Resist it. By copying other people's vimrc, you might not always know what you're copying. It doesn't matter if other developer has over 1000 lines of vimrc while yours only have 10. As long as you get the job done, that's all that matters.
Vimrc is an important component of Vim customization. It should be tailored to fit your thinking framework and editing style.
Whenever you find that you are doing the same thing repeatedly, it is a good indication that you need a new mapping or function in your vimrc. To do that, you will need to learn how to create your own Vimscript functions and that's what the rest of this book is for.

BIN
img/session-layout.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB