refactor the wording on ch2

This commit is contained in:
Igor Irianto 2021-01-16 10:31:56 -06:00
parent 4532834754
commit 45943ce9be

View file

@ -1,10 +1,8 @@
# Ch02. Buffers, Windows, and Tabs
If you have used a modern text editor, you are probably familiar with windows and tabs. Vim has three abstractions instead of two: buffers, windows, and tabs. In this chapter, I will explain how buffers, windows, and tabs work in Vim.
If you have used a modern text editor, you are probably familiar with windows and tabs. Vim uses three display abstractions instead of two: buffers, windows, and tabs. In this chapter, I will explain what buffers, windows, and tabs are and how they work in Vim.
Before you start, make sure you have the `set hidden` option. Without this, whenever you switch buffers, Vim will prompt you to save the file (you don't want that if you want to move quickly between buffers). For more information, check out `:h hidden`.
If you don't have a vimrc, create one (to see where you should create the vimrc, check out `:h vimrc`; in my Mac, I have it on `~/.vimrc`). Inside, add:
Before you start, make sure you have the `set hidden` option in vimrc. Without it, whenever you switch buffers and your current buffer is not saved, Vim will prompt you to save the file (you don't want that if you want to move quickly). I haven't cover vimrc yet. If you don't have a vimrc, create one. It is usually placed at the root directory and named `.vimrc`. I have mine on `~/.vimrc`. To see where you should create your vimrc, check out `:h vimrc`. Inside it, add:
```
set hidden
@ -14,11 +12,11 @@ Save it, then source it (run `:source %` from inside the vimrc).
## Buffers
A buffer is an in-memory space where you can write and edit some text. When you are opening a new file in Vim its content will be bound to a new buffer:
1. From within Vim, open a new buffer `:new` (create a new empty buffer)
2. From your terminal, open a new file `file1.js` (create a new buffer with `file1.js` bound to it)
What is a *buffer*?
If your buffer isn't bound to a file yet but you want to save its content, you can save it with `:w </path/to/file>`.
A buffer is an in-memory space where you can write and edit some text. When you open a file in Vim, it is bound to a buffer. When you open 3 files in Vim, you have 3 buffers.
Have two empty files, `file1.js` and `file2.j` (if possible, create them with Vim) available. Run this in the terminal:
```bash
vim file1.js
@ -26,62 +24,71 @@ vim file1.js
![one buffer displayed with highlight](./img/screen-one-buffer-file1-highlighted.png)
What you are seeing is `file1.js` *buffer*. Whenever we open a new file, Vim creates a new buffer.
What you are seeing is `file1.js` *buffer*. Whenever you open a new file, Vim creates a new buffer.
Exit Vim. This time, open two new files:
```bash
vim file1.js file2.js
```
![one buffer displayed.png](./img/screen-one-buffer.png)
Vim displays `file1.js` buffer, but it actually creates two buffers: `file1.js` buffer and `file2.js` buffer. You can see all buffers with `:buffers` (alternatively, you can use `:ls` or `:files` too).
Vim displays `file1.js` buffer, but it actually creates two buffers: `file1.js` buffer and `file2.js` buffer. Run `:buffers` to see all the buffers (alternatively, you can use `:ls` or `:files` too).
![buffers command showing 2 buffers](./img/screen-one-buffer-buffers-command.png)
There are several ways you can traverse buffers:
1. `:bnext` in short you can use `:bn` to go to the next buffer (`:bprevious` or `:bp` in short, to go to the previous buffer).
2. `:buffer` + filename. Or instead `:buffer` `:b` in short. Vim can autocomplete filename with `tab`.
3. `:buffer` + `n`, where `n` is the buffer number. Or instead `:buffer` `:b` in short. For example, typing `:buffer 2` (or `:b 2`) will take you to buffer #2.
4. Jump to the older position in jump list with `Ctrl-o` and to the newer position with `Ctrl-i`. These are not buffer specific methods, but they can be used to jump between different buffers. I will talk more about jumps in Chapter 5.
5. Go to the previously edited buffer with `Ctrl-^`.
- `:bnext` to go to the next buffer (`:bprevious` to go to the previous buffer).
- `:buffer` + filename. Vim can autocomplete filename with `<Tab>`.
- `:buffer` + `n`, where `n` is the buffer number. For example, typing `:buffer 2` will take you to buffer #2.
- Jump to the older position in jump list with `Ctrl-o` and to the newer position with `Ctrl-i`. These are not buffer specific methods, but they can be used to jump between different buffers. I will talk more about jumps in Chapter 5.
- Go to the previously edited buffer with `Ctrl-^`.
Once Vim creates a buffer, it will remain in your buffers list. To remove it, you can type `:bdelete`. It accepts either a buffer number (`:bdelete 3` to delete buffer #3) or a filename (`:bdelete` then use `<Tab>` to autocomplete).
Once Vim creates a buffer, it will remain in your buffers list. To remove it, you can type `:bdelete`. It accepts either a buffer number (`:bdelete 3` to delete buffer #3) or a filename (`:bdelete` then use `tab` to autocomplete).
The hardest thing for me when learning about buffer was visualizing how buffers worked. Imagine a deck of playing cards. If I have 2 buffers, I have a stack of 2 cards. The card on top is the card I see. If I see `file1.js` buffer displayed then the `file1.js` card is on the top of the deck. I can't see the other card, `file2.js`. If I switch buffers to `file2.js`, that `file2.js` card is now on the top of the deck and `file1.js` card is at the bottom.
The hardest thing for me when learning about buffer was visualizing how it worked. One way to think of it is by imagining my buffers as a deck of cards. If I have 3 buffers, I have a stack of 3 cards. If I see `file1.js` buffer displayed, then the `file1.js` card is at the top of the deck. I can't see `file2.js` and `file3.js` cards, but I know they are in the deck. If I switch to `file3.js` buffer, I am putting `file1.js` card in the deck and putting `file3.js` card to the top of the deck.
If you haven't used Vim before, this is a new concept. Take your time to understand it. When you're ready, let's move on to windows.
If you haven't used Vim before, this is a new concept. Take your time to understand it.
## Exiting Vim
If you have multiple buffers opened and have made some changes, you can close all of them and exit Vim with:
By the way, if you have multiple buffers opened, you can close all of them with quit-all:
```
:qall
```
If you want to exit without saving your changes, just add `!` at the end:
If you want to close without saving your changes, just add `!` at the end:
```
:qall!
```
To save and quit all, run:
```
:wqall
```
## Windows
A window is a viewport on a buffer. You can have multiple windows. Most text editors have the ability to display multiple windows. Below you see a VSCode with 3 windows.
A window is a viewport on a buffer. You can have multiple windows. Most text editors have the ability to display multiple windows. Below you see a VSCode with 3 windows:
![VSCode showing 3 windows](./img/screen-vscode-3-windows.png)
Let's open `file1.js` from the terminal again:
```bash
vim file1.js
```
![one buffer displayed.png](./img/screen-one-buffer.png)
Earlier I said that you're looking at `file1.js` buffer. While that was correct, it was incomplete. You are looking at `file1.js` buffer displayed through **a window**. A window is what you are seeing a buffer through.
Don't quit Vim yet. Run:
```
:split file2.js
```
@ -90,17 +97,17 @@ Don't quit Vim yet. Run:
Now you are looking at two buffers through **two windows**. The top window displays `file2.js` buffer. The bottom window displays `file1.js` buffer.
By the way, if you want to navigate between windows, you can use these commands:
If you want to navigate between windows, use these shortcuts:
```
Ctrl-w h Moves the cursor to the left window
Ctrl-w j Moves the cursor to the window below
Ctrl-w k Moves the cursor to the window upper
Ctrl-w l Moves the cursor to the right window
Ctrl-W H Moves the cursor to the left window
Ctrl-W J Moves the cursor to the window below
Ctrl-W K Moves the cursor to the window upper
Ctrl-W L Moves the cursor to the right window
```
Now run:
```
:vsplit file3.js
```
@ -117,31 +124,34 @@ You can have multiple windows displaying the same buffer. While you're on the to
![split window vertically and horizontally with two file2.js](./img/screen-split-window-vertically-and-horizontally-two-file2.png)
Now both top left and top right windows are displaying `file2.js` buffer. If you start typing on the top left, you'll see that the content on both top left and top right window are changing in real time.
Now both top left and top right windows are displaying `file2.js` buffer. If you start typing on the top left, you can see that the content on both top left and top right window are being updated in real-time.
To close the current window, you can run `Ctrl-w c` or type `:quit`. When you close a window, the buffer will still be there (again, to view your buffers, you can use `:buffers, :ls, :files`).
To close the current window, you can run `Ctrl-W C` or type `:quit`. When you close a window, the buffer will still be there (run `:buffers` to confirm this).
Here are some useful normal-mode window commands:
Here are some useful normal mode window commands:
```
Ctrl-w v Opens a new vertical split
Ctrl-w s Opens a new horizontal split
Ctrl-w c Closes a window
Ctrl-w o Makes the current window the only one on screen and closes other windows
Ctrl-W V Opens a new vertical split
Ctrl-W S Opens a new horizontal split
Ctrl-W C Closes a window
Ctrl-W O Makes the current window the only one on screen and closes other windows
```
And here is a list of useful window Ex commands:
And here is a list of useful window command-line commands:
```
:vsplit filename Split window vertically
:split filename Split window horizontally
:new filename Create new window
```
For more, check out `:h window`. Take your time to understand them.
Take your time to understand them. For more, check out `:h window`.
## Tabs
A tab is a collection of windows. Think of it like a layout for windows. In most modern text editors (and modern internet browsers), a tab means an open file/ page and when you close it, that file/page goes away. In Vim, a tab does not represent an open file. When you close a tab in Vim, you are not closing a file. Remember, Vim stores files in-memory via buffers. Closing a tab (or a window) does not make that file disappear from the buffers.
A tab is a collection of windows. Think of it like a layout for windows. In most modern text editors (and modern internet browsers), a tab means an open file / page and when you close it, that file / page goes away. In Vim, a tab does not represent an open file. When you close a tab in Vim, you are not closing a file. You are only closing the layout. The data for those files are stored in-memory in buffers. The buffers are still there.
Let's see Vim tabs in action. Open `file1.js`:
```bash
vim file1.js
```
@ -151,20 +161,22 @@ To open `file2.js` in a new tab:
```
:tabnew file2.js
```
![screen displays tab 2](./img/screen-tab2.png)
You can also let Vim autocomplete the file you want to open in a *new tab* by pressing `tab` (no pun intended).
You can also let Vim autocomplete the file you want to open in a *new tab* by pressing `<Tab>` (no pun intended).
Below is a list of useful tab navigations:
```
:tabnew file.txt open file.txt in a new tab
:tabnew file.txt Open file.txt in a new tab
:tabclose Close the current tab
:tabnext Go to next tab
:tabprevious Go to previous tab
:tablast Go to last tab
:tabfirst Go to first tab
```
You can also run `gt` to go to next tab page (you can go to previous tab with `gT`). You can pass count as argument to `gt`, where count is tab number. To go to the third tab, do `3gt`.
One advantage of having multiple tabs is you can have different window arrangements in different tabs. Maybe you want your first tab to have 3 vertical windows and second tab to have a mixed horizontal and vertical windows layout. Tab is the perfect tool for the job!
@ -174,16 +186,18 @@ One advantage of having multiple tabs is you can have different window arrangeme
![second tab with multiple windows](./img/tabs-file2js.png)
To start Vim with multiple tabs, you can do this from the terminal:
```bash
vim -p file1.js file2.js file3.js
```
## Moving In 3D
Moving between windows is like traveling two-dimensionally along X-Y axis in a Cartesian coordinate. You can move to the top, right, bottom, and left window with `Ctrl-w h/j/k/l`.
Moving between windows is like traveling two-dimensionally along X-Y axis in a Cartesian coordinate. You can move to the top, right, bottom, and left window with `Ctrl-W H/J/K/L`.
![cartesian movement in x and y axis](./img/cartesian-xy.png)
Moving between buffers is like traveling across the Z axis in a Cartesian coordinate. Imagine your buffer files are lined up across the Z axis. You can traverse the Z axis one buffer at a time with `:bnext` and `:bprevious`. You can jump to any coordinate in Z axis with `:buffer filename/buffernumber`.
Moving between buffers is like traveling across the Z axis in a Cartesian coordinate. Imagine your buffer files lining up across the Z axis. You can traverse the Z axis one buffer at a time with `:bnext` and `:bprevious`. You can jump to any coordinate in Z axis with `:buffer filename/buffernumber`.
![cartesian movement in z axis](./img/cartesian-z.png)
@ -191,15 +205,13 @@ You can move in *three-dimensional space* by combining window and buffer movemen
![cartesian movement in x, y, and z axis](./img/cartesian-xyz.png)
## Using Buffers, Windows, and Tabs The Smart Way
You have learned how buffers, windows, and tabs work in Vim. To use them efficiently, you need to understand what they are designed for and apply them in your own workflow.
You have learned what buffers, windows, and tabs are and how they work in Vim. Now that you understand them better, you can use them in your own workflow.
Everyone has a different workflow, here is one example:
- I use buffers to open up all required files to get the current task done. This task may require opening seven or seventy buffer files, but the number of opened buffer doesn't really matter because Vim can handle many buffers before it starts slowing down. Plus having many buffers opened won't crowd my screen. I am only seeing one buffer (assuming I have only one window) at any time and I can quickly fly to any buffer I wish.
- I use multiple windows to view multiple buffers at once, usually when diffing files, comparing codes, or following a code flow. I usually don't keep more than three windows opened at the same time because my screen will get crowded. When I am done, I would close any extra windows. I prefer having as few opened windows as possible.
- I don't use tabs in my workflow. I use [tmux](https://github.com/tmux/tmux/wiki) windows instead of Vim tabs. I have multiple tmux windows, one tmux window for client-side codes and another window for back-end codes. You could use a tab to handle client-side codes and a separate tab for back-end codes.
My workflow may look different than yours based on your editing style and that's fine. Experiment around to discover your own flow and find what works for you best.
Everyone has a different workflow, here is mine for example:
- First I use buffers to store all the required files for the current task. Vim can handle many open buffers before it starts slowing down. Plus having many buffers opened won't crowd my screen. I am only seeing one buffer (assuming I have only one window) at any time, allowing me to focus on one screen. When I need to go somewhere, I can quickly fly to any open buffer anytime.
- I use multiple windows to view multiple buffers at once, usually when diffing files, reading docs, or following a code flow. I try to keep the number of windows opened to no more than three because my screen will get crowded (I use a small laptop). When I am done, I close any extra windows. Fewer windows means less distractions.
- Instead of tabs, I use [tmux](https://github.com/tmux/tmux/wiki) windows. I usually use multiple tmux windows at once. For example, one tmux window for client-side codes and another for backend codes.
My workflow may look different than yours based on your editing style and that's fine. Experiment around to discover your own flow suited for your coding style.