Post

一文看懂vim

一文看懂vim

Throughout the time you’re using vim, make sure to look things up as you go. If you ever get to a point where you’re like:

“Ohh, this is a really inefficient way of doing things, is there a better way?”

the answer is almost always “YES”, because vim is written by programmers and for programmers, so people ran same kind of issues and fixed them so you don’t need to deal with these anymore.

— the missing semester of your CS education

Vim is a modal editor: it has different modes for inserting text vs manipulating text.

modepurposeshortcut
Normalfor moving around a file and making editsEsc
Insertfor inserting textI, i, A, a
Replacefor replacing textR
Visual (plain, line, or block)for selecting blocks of textv, V, Ctrl-v
Command-linefor running a command:

文件管理

在 Vim 中,Buffers、Tabs 和 Windows 是三种管理文件的不同方式。它们的关系如下:

  1. Buffer = 文件(后台数据,可能未显示)
  2. Window = 视图(允许你查看 Buffers)
  3. Tab = 一组 Windows(用于组织不同任务)

如何选择合适的方式?

  1. 用 Buffers 📜:如果你想一次性打开多个文件,但不需要同时查看。
  2. 用 Windows 🪟:如果你想并排查看多个文件,或者同时编辑多个文件。
  3. 用 Tabs 🏷️:如果你在处理多个任务(不同项目),并需要对任务进行分组。

Buffers(缓冲区)

Buffer 是 Vim 打开的文件,即使它没有在窗口中显示,它仍然在内存中存在,你可以打开多个 Buffer,并在它们之间切换。关闭窗口不会关闭 Buffer,除非你手动删除它。

Buffer 相关命令如下:

命令作用
:e filename打开 filename 并加载到 Buffer
:ls 或 :buffers显示所有已加载的 Buffer
:bn(ext)切换到下一个 Buffer
:bp(revious)切换到上一个 Buffer
:bd(elete)关闭当前 Buffer(不影响窗口)

Tabs(标签页)

Tabs 相关命令和快捷键如下:

命令作用
:tabnew新建一个空的 Tab
:tabe(dit) filename在新 Tab 中打开 filename
gt/gT切换到下/上一个 Tab
:tabn(ext)切换到下一个 Tab
:tabp(revious)切换到上一个 Tab
:tabfirst跳到第一个 Tab
:tablast跳到最后一个 Tab
:tabn N切换到第 N 个 Tab
:tabclose关闭当前 Tab
:tabclose N关闭第 N 个 Tab

Windows(窗口)

Windows 允许你同时查看多个 Buffers。你可以水平或垂直分割窗口,每个窗口可以显示相同或不同的 Buffer。关闭一个窗口不会影响 Buffer,Buffer 仍然存在。

Window 相关命令和快捷键如下: | 命令 | 作用 | | ——————- | ———————————————- | | :sp(lit) filename1 | 水平分屏打开 filename1 | | :vsp(lit) filename2 | 垂直分屏打开 filename2 | | :new | 水平新建一个空窗口 | | :vnew | 垂直新建一个空窗口 | | :q | 关闭当前窗口(如果是最后一个窗口,则关闭 Vim) | | :close | 关闭当前窗口,但不会关闭 Vim | | Ctrl + w w | 在窗口之间循环切换 | | Ctrl + w h/l/j/k | 切换到左/右/下/上窗口 | | Ctrl + w = | 让所有窗口等宽等高 | | Ctrl + w - | 减小当前窗口高度 | | Ctrl + w + | 增加当前窗口高度 | | Ctrl + w < | 减小当前窗口宽度 | | Ctrl + w > | 增加当前窗口宽度 |

快速打开多个文件

如果你想一次性打开多个文件,并用 Tab 或 Split 方式显示:

1
2
3
vim -p file1.txt file2.txt file3.txt   # 在不同 Tab 里打开
vim -O file1.txt file2.txt              # 垂直分屏打开
vim -o file1.txt file2.txt              # 水平分屏打开

Common commands in Command-line

commandpurpose
:wsave (“write”)
:qquit (close window)
:e {name of file}open file for editing
:lsshow open buffers
:help {topic}open help
:help :wopens help for the :w command
:help wopens help for the w movement

Vim’s interface is a programming language

Keystrokes (with mnemonic names) are commands, and these commands compose.

Movement

Movements in Vim are also called “nouns”, because they refer to chunks of text.

类别命令说明
基本移动h / j / k / l左 / 下 / 上 / 右
单词移动w / b / e下一个单词 / 单词开头 / 单词结尾
行内移动0 / ^ / $行首 / 第一个非空字符 / 行尾
屏幕移动H / M / L屏幕顶部 / 屏幕中部 / 屏幕底部
滚动Ctrl-u / Ctrl-d向上滚动 / 向下滚动
文件移动gg / G跳转到文件开头 / 跳转到文件结尾
行号跳转:{number} / {number}G跳转到第 {number}
其他%匹配对应符号,例如左右括号
查找f{字符} / t{字符} / F{字符} / T{字符}查找(find)/跳转(to)到指定字符(向前/向后)
查找匹配, / ;在匹配项间导航
搜索/{正则表达式}进行搜索
搜索导航n / N在匹配项间前进 / 后退

Edit

Vim’s editing commands are also called “verbs”, because verbs act on nouns.

类别命令说明
插入模式i进入插入模式
新建行o / O在当前行下方 / 上方插入新行
删除d{motion}删除 {motion} 指定范围
示例dw / d$ / d0删除单词 / 删除至行尾 / 删除至行首
修改c{motion}修改 {motion} 指定范围(相当于 d{motion} 后跟 i
示例cw修改单词
字符删除x删除当前字符(等同于 dl
字符替换s替换当前字符(等同于 cl
删除/修改d / c在可视模式下删除 / 修改选中文本
撤销/重做u / <C-r>撤销 / 重做
复制/粘贴y / p复制(yank)/ 粘贴
大小写切换~切换当前字符大小写

Count

You can combine nouns and verbs with a count, which will perform a given action a number of times.

命令说明
3w向前移动 3 个单词
5j向下移动 5 行
7dw删除 7 个单词

Modifiers

You can use modifiers to change the meaning of a noun.

  • i(inner / inside):操作括号、引号等内部内容,不包括外围符号。
  • a(around):操作括号、引号等内部内容,并包括外围符号。
命令说明
ci(修改当前圆括号内的内容
ci[修改当前方括号内的内容
da'删除单引号包裹的字符串,包括单引号

Customize Vim

Vim is customized through a plain-text configuration file in ~/.vimrc.

There are tons of plugins for extending Vim. Contrary to outdated advice that you might find on the internet, you do not need to use a plugin manager for Vim.

Instead, you can use the built-in package management system. Simply create the directory ~/.vim/pack/vendor/start/, and put plugins in there (e.g. via git clone).

Here are some of our favorite plugins:

  • ctrlp.vim: fuzzy file finder
  • ack.vim: code search
  • nerdtree: file explorer
  • vim-easymotion: magic motions

Advanced Vim

Use Vim-mode in other programs

  • Shell: If you’re a Bash user, use set -o vi. If you use Zsh, bindkey -v. Additionally, no matter what shell you use, you can export EDITOR=vim. This is the environment variable used to decide which editor is launched when a program wants to start an editor.

Search and replace

:s (substitute) command.

命令作用
:s/foo/bar/替换当前行第一个 foo 为 bar
:s/foo/bar/g替换当前行所有 foo 为 bar
:%s/foo/bar/g替换整个文件所有 foo 为 bar
:3,5s/foo/bar/g替换第 3 到 5 行的 foo 为 bar
:.,$s/foo/bar/g从当前行.到最后一行,替换 foo 为 bar
:%s/foo/bar/gc交互式确认替换
:%s/foo/bar/gi忽略大小写替换
:%s/\<foo\>/bar/g仅匹配完整单词 foo
:%s/foo/PRE-&/g在匹配项前加 PRE-
:&&重复上一次 :s 命令

best practices:

1
2
3
# 为当前行和218之间的所有:开头的命令前后添加`
:.,218s/(:[\S]*)/`\1`

Macros

  • q{character} to start recording a macro in register {character}
  • q to stop recording
  • @{character} replays the macro
  • Macro execution stops on error
  • {number}@{character} executes a macro {number} times

Useful tips

A demo

Watch a practice demo in the missing semester lecture from 37:35.

  • 使用.快速重复上次的操作
  • 使用vim golf练习vim命令

多行批量编辑文本

  • 按 Ctrl-v 进入 Visual Block 模式,选择多行。
  • 批量插入:按 I(大写 i),输入文本,然后按 Esc,Vim 会在所有选中的行插入相同的文本。
  • 批量追加:按 A(大写 a),输入文本,然后按 Esc,Vim 会在所有选中的行末尾追加相同的文本。
  • 批量删除:按 d 删除选中的块。

Resources

  1. Vim Tips Wiki
  2. Vim Golf
  3. Vi/Vim Stack Exchange
  4. missing semester of your CS education
This post is licensed under CC BY 4.0 by the author.