237 lines
8.2 KiB
Markdown
237 lines
8.2 KiB
Markdown
# vim
|
||
## Buffers,Windows,Tabs
|
||
在现代的文本编辑器,通常会存在`windows`和`tabs`两种抽象。但是,vim和常用的文本编辑器不同,其抽象组成如下:
|
||
- windows
|
||
- tabs
|
||
- buffers
|
||
|
||
### Buffer
|
||
buffer是一个内存空间,可以向buffer`写文本`或`编辑文本`。当通过vim打开一个文件后,文件的内容就被关联到buffer中,当打开3个文件,就存在3个buffer。
|
||
|
||
可以通过如下命令打开多个buffer:
|
||
```bash
|
||
vim file1.txt file2.txt
|
||
```
|
||
每当通过vim打开一个新文件,都会为vim创建一个buffer。
|
||
|
||
如果想要在多个buffer之间进行切换,可以使用如下方式。
|
||
|
||
#### `:bnext` `:bprevious`
|
||
通过`:bnext`和`:bprevious`命令,其支持在多个buffer之间进行切换,切换到前一个/后一个buffer。
|
||
|
||
#### `:buffer {filename}`
|
||
通过`:buffer {filename}`的方式,可以切换到`{filename}`关联的buffer。
|
||
|
||
> filename可以通过`tab`进行自动补全。
|
||
|
||
#### `:buffer {n}`
|
||
通过`:buffer {n}`的形式,可以通过数字来进行buffer的跳转。
|
||
|
||
#### `ctrl + ^`
|
||
通过`ctrl + ^`的快捷键组合能够跳转到上次编辑的buffer。
|
||
|
||
如果想要对查看所有buffer,可以通过如下方式:
|
||
- `:ls`
|
||
- `:files`
|
||
- `:buffers`
|
||
|
||
#### `:bdelete`
|
||
一旦vim创建了buffer,其将会存在于buffer list中。如果想要移除buffer list中的buffer,可以通过`:bdelete`的方式移除,其支持接收buffer number和file name,示例如下:
|
||
|
||
```bash
|
||
:bdelete 1
|
||
```
|
||
|
||
```bash
|
||
:bdelete file1.txt
|
||
```
|
||
|
||
#### exit vim with all buffers closed
|
||
如果存在多个buffer,想要关闭所有buffers,可以使用如下方式:
|
||
```bash
|
||
:qall
|
||
```
|
||
|
||
关闭所有buffer,并且不保存修改
|
||
```bash
|
||
:qall!
|
||
```
|
||
|
||
保存并关闭所有buffer
|
||
```bash
|
||
:wqall
|
||
```
|
||
|
||
#### `:e {filepath}`
|
||
在当前存在buffer list的同时,还想打开新的文件,可以通过`:e {filepath}`的命令来实现
|
||
|
||
```bash
|
||
:e ~/f2.txt
|
||
```
|
||
|
||
### windows
|
||
window是一个buffer的viewport。和目前主流的编辑器类似,vim同样支持打开多个windows,在界面同时展示多个buffer的内容。
|
||
|
||
#### `:split {filename}`
|
||
在当前已经存在buffer被展示到window的情况下,如果想要同时展示多个window,可以使用`:split {filename}`,示例如下:
|
||
|
||
```bash
|
||
# 打开一个文件
|
||
vim f1
|
||
|
||
# 打开f1后,此时目前只有一个buffer和一个window,如果此时想要再打开一个window
|
||
|
||
# 打开f2并展示到f1 window的上部分
|
||
:split f2
|
||
|
||
# 执行完上述命令后,vim被分割为两个window,上面为f2,下面为f1
|
||
```
|
||
|
||
#### 切换窗口
|
||
如果想要在多个window之间切换焦点,可以使用如下快捷键(仅在normal模式下)
|
||
- `ctrl + w + h`:切换到左侧窗口
|
||
- `ctrl + w + l`:切换到右侧窗口
|
||
- `ctrl + w + j`:切换到下侧窗口
|
||
- `ctrl + w + k`:切换到上侧窗口
|
||
|
||
之后,可以运行如下命令
|
||
```bash
|
||
:vsplit f3
|
||
```
|
||
运行之后,vim会展示3个窗口,上半部分展示`f3, f2`两个窗口,下半部分展示`f1`窗口。
|
||
|
||
#### 关闭窗口
|
||
如果想要关闭当前窗口,可以调用`ctrl + w + c`快捷键,或是通过`:q`命令。`即使关闭window,关闭文件的buffer仍然存在于buffers中`。
|
||
|
||
#### split窗口快捷键
|
||
- `ctrl + w + s`: 水平方向针对当前buffer打开一个window
|
||
- `ctrl + w + v`: 垂直方向对当前buffer打开一个window
|
||
- `ctrl + w + c`:关闭当前window
|
||
- `ctrl + w + o`:关闭其他window,仅保留当前window
|
||
|
||
#### 窗口相关命令行
|
||
- `:vsplit {filename}`
|
||
- `:split {filename}`
|
||
- `:new {filename}`
|
||
|
||
### tabs
|
||
vim除了支持同时展示多个windows之外,也同样支持`tab`。在vim中,tab和浏览器/现代编辑器类似,tab为对window的布局(垂直/水平多个window的布局)。
|
||
|
||
在vim中,tab并不表示打开的文件,即使当tab被关闭,文件的buffer仍然会存在。
|
||
|
||
tab的常用命令如下
|
||
|
||
#### `:tabnew`
|
||
`:tabnew {filename}`用于在新tab中打开文件,使用示例如下:
|
||
|
||
```bash
|
||
:tabnew file1.txt
|
||
```
|
||
|
||
`:tabnew`并不实际依托于buffer存在,可以直接调用`:tabnew`先创建一个tab,然后在新tab中调用`:e`打开文件进行编辑。
|
||
|
||
```bash
|
||
:tabnew
|
||
|
||
:e file2.txt
|
||
```
|
||
|
||
#### `:tabclose`
|
||
`:tabclose`命令用于关闭当前tab
|
||
|
||
#### `:tabnext`
|
||
`:tabnext`命令用于切换到下个tab
|
||
|
||
#### `:tabprevious`
|
||
`:tabprevious`命令用于切换到前一个tab
|
||
|
||
#### `:tablast`
|
||
`:tablast`用于切换到最后一个tab
|
||
|
||
#### `:tabfirst`
|
||
`:tabfirst`用于切换到第一个tab
|
||
|
||
#### `gt`
|
||
除了通过命令外,还可以通过快捷键`gt`切换到`下一个tab页面`。
|
||
|
||
#### `gT`
|
||
快捷键`gT`则是可以切换到`前一个tab页面`。
|
||
|
||
#### `{n}gt`
|
||
`{n}gt`支持通过tab序号快速切换tab,例如`3gt`可以切换到第三个tab。
|
||
|
||
|
||
#### `vim -p`
|
||
在进入vim时,如果想打开多个tab,可以添加`-p`选项,示例如下
|
||
|
||
```bash
|
||
vim -p f1.txt f2.txt f3.txt
|
||
```
|
||
|
||
### window和buffer的组合
|
||
vim支持同时打开多个window,并且,`每一个window都包含了一个buffer`。可以通过`ctrl + w + {dir}`快捷键的方式在window之间切换,但是,`对于当前的焦点window,仍可以通过 :buffer {filename} 的方式来切换当前焦点window对应的buffer`。
|
||
|
||
例如,当前存在三个windows,`w1, w2, w3`,其打开文件分别为`f1, f2, f3`,可以切换到`w2` window,并且调用`:b f3`命令,此时会将当前的`w2`的buffer切换到`f3`,此时,`w1, w2, w3`对应的打开文件则变成了`f1, f3, f3`。
|
||
|
||
> 通常,在图形操作系统中使用vim,其`terminal`(如`windows系的Windows Terminal`和`Linux系的KConsole`,其终端本身就支持`tab`功能,此时可以无需使用vim本身的tab功能。
|
||
>
|
||
> 但是,在非图形化系统(如通过ssh访问服务器),此时在服务端未提供图形支持的前提下,可以使用vim tab来实现多tab打开。
|
||
|
||
## Registers
|
||
### Register Types
|
||
vim中拥有如下10中register类型:
|
||
- `unnamed register`: `""`
|
||
- `numbered register`: `"0-9`
|
||
- `small delete register`: `"-`
|
||
- `named register`: `"a-z`
|
||
- `read only register`: `":`, `".`, `"%`
|
||
- `alternate file register`: `"#`
|
||
- `expression register`: `"=`
|
||
- `selection register`: `"*`, `"+`
|
||
- `black hole register`: `"_`
|
||
- `last search pattern register`: `"/`
|
||
|
||
### register operators
|
||
在使用register之前,必须通过操作向register中存储值。可以通过如下操作向register中存值:
|
||
- `y`: `yank(copy)`
|
||
- `c`: `delete text and start isnert mode`
|
||
- `d`: `delete text`
|
||
|
||
通常,在操作删除文本时,都会将文本保存在register中。
|
||
|
||
为了粘贴存储在register中的文本,可以使用如下方式:
|
||
- `p`: 在cursor之后粘贴文本内容
|
||
- `P`: 在cursor之前粘贴文本内容
|
||
|
||
`p`和`P`都接收一个`count`和`register symbol`作为参数,例如,
|
||
- `10p`: 将register中的文本粘贴10次
|
||
- `"ap`: 从`register a`中粘贴文本
|
||
- `10"ap`:从`register a`中获取文本并粘贴10次
|
||
|
||
### Calling register from insert mode
|
||
当处于insert mode,并且需要从指定register中粘贴时,可以使用如下方式:
|
||
- `Ctrl + R a`:其会将`register a`中的内容粘贴到cursor之后
|
||
|
||
### unnamed register
|
||
在unnamed register中,存储着最后一次`delete`, `yank`, `change`的内容,可以通过`""p`。
|
||
|
||
如果做了多次yank/delete/change操作,那么新操作的text会自动覆盖旧操作的text。
|
||
|
||
默认情况下,`p/P`命令会默认关联unnamed register。
|
||
|
||
### numbered register
|
||
numbered register会自动按照升序对其自身进行填充,存在两种不同类型的numbered register,
|
||
- `yanked register`: `0`
|
||
- `numbered register 1-9`: `1-9`
|
||
|
||
#### yanked register
|
||
如果通过`yy`进行了整行复制,那么vim实际会将文本保存在两个regiser中:
|
||
- unnamed register:通过`p`粘贴
|
||
- yanked register:通过`"0p`粘贴
|
||
|
||
`当之后再次yank一个不同text时,vim会对yanked register和unnamed register都随之变化。`
|
||
|
||
除了yank之外的操作都不会被存储到register 0。`故而,即使yank操作后发生了delete/change操作,register 0中的内容也不会被修改`。
|
||
|
||
当处于insert mode时,可以通过`ctrl + R 0`来快速粘贴register 0中的内容。
|