Vim 与 Tmux 终端编辑器工作流

Vim 与 Tmux 终端编辑器工作流


1. Vim 基础概念体系:Buffer / Window / Tab / Mark / Register / Plugin / VimScript

1.1 Buffer(缓冲区)

Buffer 为 Vim 内存中承载文本内容的区域,文本来源可以是磁盘文件,也可以是无关联文件的空白缓冲区。

A buffer is an area of Vim's memory used to hold text read from a file. In addition, an empty buffer with no associated file can be created to allow the entry of text.

缓冲区是 Vim 内存中的一块区域,用于保存从文件中读取的文本。此外,可以创建一个没有关联文件的空缓冲区,以允许输入文本。

执行 vim test1 test2 test3 时,Vim 会为每一个文件创建独立缓冲区,启动后默认渲染第一个缓冲区内容,其余缓冲区驻留内存等待切换。

缓冲区管理命令:

复制代码
:ls          " 列出全部缓冲区,附带缓冲区编号
:bn          " 切换至下一个缓冲区
:bp          " 切换至上一个缓冲区
:b {number}  " 按编号跳转至目标缓冲区
:b {pattern} " 按文件名/正则匹配跳转缓冲区

1.2 Window(窗口)

Window 是缓冲区的视图载体。同一个缓冲区可以被多个窗口同时加载渲染,单个窗口同一时刻仅绑定一个缓冲区。分屏本质为创建多个独立窗口。

1.3 Tab(标签页)

Tab 是窗口的分组容器,单个标签页内可承载任意数量的分屏窗口,标签页之间窗口集合相互隔离,对标浏览器标签的分组逻辑。

标签页管理命令:

复制代码
:tabnew [name] " 创建新标签页,可附带初始名称
:tabc          " 关闭当前标签页
:tabn          " 切换至下一个标签页
:tabp          " 切换至上一个标签页
:tabs          " 列出全部标签页
gt             " 正常模式快捷键,切换下一个标签页
{n}gt          " 跳转至序号为 {n} 的标签页,序号从 1 起始

1.4 Mark(标记)

Mark 为文本位置书签,用于光标快速跳转,标记名称使用 a-zA-Z 字母:

  • 小写字母标记:作用域限制在单个文件内
  • 大写字母标记:跨文件全局标记,切换缓冲区后仍然有效

标记操作命令:

复制代码
m{a-zA-Z}     " 创建标记,例如 ma 在当前光标位置创建标记 a
`{char}       " 跳转至标记原始光标精确位置
'{char}       " 跳转至标记所在行的行首
:marks        " 列出全部已定义标记
:delmarks {a b c} " 删除指定多个标记
:delmarks!    " 删除全部小写字母标记,大写标记保留

补充快捷键:连续按下两个 ```(反引号),返回上一次跳转前光标位置。

1.5 Register(寄存器)

Vim 的复制、删除操作不会直接使用系统剪贴板,文本存入寄存器。寄存器以 " 作为引导标识:

  • 无名寄存器:"",未指定寄存器时,y / d 操作默认写入该寄存器,p 默认读取
  • 命名寄存器:"a ~ "z,显式指定存储目标

寄存器操作示例:

复制代码
"ayy     " 复制当前整行,存入寄存器 a
"ap      " 读取寄存器 a 内容,在光标后方粘贴
:reg     " 查看全部寄存器内容
:reg a   " 单独查看寄存器 a 存储内容

查阅完整寄存器文档::help reg

1.6 Plugin(插件)

插件扩展 Vim 原生能力,补齐 IDE 类功能,推荐使用 vim-plug 作为插件管理器。

插件检索渠道:

  1. 搜索引擎检索功能关键词
  2. VimAwesome https://vimawesome.com/
  3. GitHub 开源仓库
  4. 技术社区分享资源

1.7 VimScript

VimScript 为 Vim 内置脚本语言,绝大多数 Vim 插件基于该语言实现。

推荐学习资源:


2. Vim 模式定义与模式切换

Vim 原生划分四类工作模式:

  1. 正常模式(Normal-mode) :Vim 启动默认进入,用于光标移动、复制、删除、快捷键调度;任意模式按下 <Esc> 返回正常模式,可配置映射 inoremap jj <Esc>,在插入模式连续按 jj 替代 <Esc>;<C-[> 等价于 <Esc>。
  2. 插入模式(Insert-mode) :文本录入模式,底部状态栏显示 INSERT。
  3. 命令模式(Command-mode) :按下 : 或 / 进入,执行 Ex 命令、检索文本,回车执行,取消按 <Esc>。
  4. 可视模式(Visual-mode) :文本选区模式,分为字符可视、行可视、块可视三类,状态栏对应提示 VISUAL / VISUAL LINE / VISUAL BLOCK。

简化理解视角:操作模式(正常/可视/命令)、编辑模式(插入)。


3. Vim 文件打开、多文件、分屏操作

3.1 基础打开

复制代码
vim file1             " 打开单个文件
vim file1 file2 file3 " 批量打开多个文件,默认渲染 file1

3.2 启动时分屏

复制代码
vim -On file1 file2 " 水平分屏(左右),O 大写,n 为分屏数量
vim -on file1 file2 " 垂直分屏(上下),o 小写,n 为分屏数量

3.3 运行时分屏

复制代码
<C-w>s       " 上下分割当前窗口
:sp [file]   " 上下分屏,可选打开新文件
<C-w>v       " 左右分割当前窗口
:vsp [file]  " 左右分屏,可选打开新文件

3.4 分屏光标跳转与窗口移位

复制代码
<C-w>h       " 光标移动至左侧窗口
<C-w>l       " 光标移动至右侧窗口
<C-w>j       " 光标移动至下方窗口
<C-w>k       " 光标移动至上方窗口

<C-w>H       " 当前窗口移动至最左侧
<C-w>L       " 当前窗口移动至最右侧
<C-w>J       " 当前窗口移动至最下方
<C-w>K       " 当前窗口移动至最上方

3.5 关闭分屏

复制代码
<C-w>c       " 关闭当前窗口,Vim 进程不退出
<C-w>q       " 关闭当前窗口;最后一个窗口时,退出 Vim

4. Vim 退出、保存与文件操作命令

复制代码
:w           " 保存修改,不退出
:w!          " 强制保存,不退出
:w {file}    " 将当前缓冲区另存为 {file}
:q!          " 放弃修改,退出
:qa!         " 放弃全部缓冲区修改,全部退出
:wq          " 保存并退出
:x           " 保存并退出,无修改时不触发写入
ZZ           " 正常模式快捷键,有修改则保存退出,无修改直接退出
:e {file}    " 在当前窗口打开新文件
:e!          " 放弃缓冲区未保存修改,回退至磁盘版本
:saveas {file} " 另存为目标文件

5. Vim 插入模式进入方式

在正常模式下执行以下按键,切换至插入模式:

  • i:光标前插入
  • I:当前行行首插入
  • a:光标后插入
  • A:当前行行尾插入
  • o:在当前行下方新建一行并插入
  • O:在当前行上方新建一行并插入
  • s:删除光标处单个字符,进入插入
  • S:删除当前整行,在行首进入插入
  • cw:删除光标至单词末尾内容,进入插入

6. Vim 命令模式操作集

6.1 行号控制

复制代码
:set nu      " 开启行号显示
:set nonu    " 关闭行号显示
:{n}         " 跳转至第 {n} 行

6.2 文本检索

复制代码
/{pattern}   " 正向搜索目标字符串
n            " 跳转至下一个匹配项
N            " 跳转至上一个匹配项
:set ic      " 检索忽略大小写
:set noic    " 检索区分大小写

6.3 删除区间

复制代码
:{n1},{n2}d  " 删除 n1 行至 n2 行内容

6.4 替换语法

通用模板:

复制代码
:{range}s/{search}/{replace}/{flags}
  • %:全文范围
  • n1,n2:行区间
  • '<,'>:可视模式选中区域,进入命令模式自动补全

标志位:

  • g:区间内全部匹配项替换;无 g 仅替换每行第一个匹配
  • i:匹配忽略大小写
  • I:匹配区分大小写
  • c:每次替换前交互式确认

示例:

复制代码
:s/a/b          " 当前行,首个 a 替换为 b
:s/a/b/g        " 当前行全部 a 替换为 b
:%s/a/b/g       " 全文全部 a 替换为 b
:%s/a/b/gi      " 全文全部 a 替换为 b,忽略大小写
:%s/a/b/gc      " 全文替换,每次确认
:'<,'>s/a/b/g   " 可视选区内部全局替换

6.5 调用外部 Shell 命令

复制代码
:!{cmd}        " 执行外部命令,输出打印至终端,不写入缓冲区
:r !{cmd}      " 执行外部命令,将命令输出插入至光标下方

示例:

复制代码
:!date
:r !ls

6.6 缩写与映射

复制代码
:ab {abbr} {full}  " 插入模式缩写展开,输入缩写自动替换长文本
:map {key} {action}" 普通映射

缩写示例::ab email test@example.com;映射中特殊键如 ^M 通过 <C-v><C-m> 录入。


7. Vim 正常模式光标移动、文本修改、复制粘贴、撤销重做

7.1 基础光标移动

复制代码
h j k l        " 左、下、上、右
0              " 行首
^              " 本行第一个非空白字符
$              " 行尾
g_             " 本行最后一个非空白字符

w              " 下一个单词开头
e              " 下一个单词结尾
f{c}           " 本行向后查找字符 c,跳转至 c
F{c}           " 本行向前查找字符 c,跳转至 c
t{c}           " 向后跳转至 c 的前一个字符
T{c}           " 向前跳转至 c 的后一个字符
;              " 重复上一次 f/F/t/T 同向跳转
,              " 重复上一次 f/F/t/T 反向跳转

gg             " 文件第一行行首
G              " 文件最后一行行首
{n}G           " 跳转至第 n 行
H              " 可视区域第一行
M              " 可视区域中间行
L              " 可视区域最后一行
zt             " 当前行置顶
zz             " 当前行居中
zb             " 当前行置底
%              " 匹配成对括号 `() [] {}`
*              " 查找光标下单词,下一处匹配
#              " 查找光标下单词,上一处匹配

<C-f>          " 向下翻页
<C-b>          " 向上翻页

7.2 删除、复制、粘贴

  • d:删除,删除内容存入寄存器
  • y:复制,内容存入寄存器
  • p:光标后方粘贴
  • P:光标前方粘贴

常用操作:

复制代码
dw             " 删除光标至单词末尾
daw            " 删除光标所在整个单词(包含单词两侧空白)
dd             " 删除当前整行
{n}dd          " 从当前行向下删除 n 行
d$             " 删除光标至行尾
dG             " 删除当前行至文件末尾

yw             " 复制光标至单词末尾
yaw            " 复制光标所在整个单词
yy             " 复制当前整行
{n}yy          " 向下复制 n 行
y$             " 复制光标至行尾
yG             " 复制当前行至文件末尾

x              " 删除光标下单个字符
r{c}           " 将光标字符替换为 c
R              " 连续覆盖替换,<Esc> 退出

7.3 大小写转换

复制代码
~              " 翻转光标字符大小写
{n}~           " 向后翻转 n 个字符大小写
g~~            " 翻转当前行全部字符大小写
gUU            " 当前行全部转为大写
guu            " 当前行全部转为小写
gUw            " 当前单词转为大写
guw            " 当前单词转为小写

7.4 撤销与重做

复制代码
u              " 撤销上一次修改
<C-r>          " 重做已撤销修改
.              " 重复上一次修改命令
{n}{cmd}       " 将命令 {cmd} 重复执行 n 次

8. Vim 可视模式与块编辑

可视模式入口:

  • v:字符可视模式,逐字符选区
  • V:行可视模式,以行为单位选区
  • <C-v>:块可视模式,矩形选区

选区内基础操作:

  • d:删除选中区域
  • y:复制选中区域
  • p:粘贴至选中区域

文本对象选择(光标位于引号/括号内部时使用):

  • a:选中对象包含边界符号
  • i:选中对象不包含边界符号

示例:

复制代码
va"       " 选中一对双引号,引号一并纳入选区
vi"       " 选中一对双引号内部文本,排除引号
va[       " 选中一对方括号,括号一并纳入选区
vi[       " 选中一对方括号内部文本,排除括号

块可视模式扩展:矩形选中后按下 I 在块前批量插入、按下 A 在块后批量插入,完成输入后按 <Esc> 同步至全部选中行。


9. Vim 宏录制

宏用于录制一组序列操作,批量重复执行。

录制流程(正常模式):

  1. q{char}:启动录制,宏标识为 {char}
  2. 执行需要录制的完整操作序列
  3. q:结束录制

回放:

复制代码
@{char}    " 执行一次该宏
{n}@{char} " 连续执行 n 次该宏
@@         " 重复执行上一条宏

示例:在每行开头添加 Tab

  1. 光标置于首行,qa 开启录制
  2. I 进入行首插入,输入 Tab
  3. <Esc> 返回正常模式
  4. j 下移一行
  5. q 停止录制
  6. @a 逐行回放,10@a 连续回放 10 次

10. Vim 管道过滤、二进制查看、大文件处理附加功能

Vim 支持 :%!{filter} 管道语法:将整个缓冲区作为标准输入传递给外部程序,程序输出覆盖当前缓冲区。

典型场景:

复制代码
:%!jq        " JSON 格式化
:%!sort      " 文本行排序
:%!clang-format " C / C++ 代码格式化
:%!xxd       " 转为十六进制二进制视图,查看不可见字符

Vim 对超大日志文件具备稳定处理能力,打开耗时随文件体积上升,但加载完成后的检索、浏览操作不会持续卡顿。


11. ~/.vimrc 配置重载、局部命令执行方案

$MYVIMRC 为内置变量,指向当前加载的 Vim 配置文件路径。

基础重载命令:

复制代码
:edit $MYVIMRC        " 在当前窗口打开配置文件
:vsplit $MYVIMRC      " 分屏打开配置文件
:source $MYVIMRC      " 重新加载完整配置
:echo $MYVIMRC        " 打印配置文件路径

配套映射,快速编辑与重载:

复制代码
nnoremap <leader>ev :vsplit $MYVIMRC<cr>
nnoremap <leader>sv :source $MYVIMRC<cr>

备注:简单单行修改使用 :source 可即时生效;包含插件初始化、状态检测逻辑的复杂配置,部分模块无法被安全重载,此时需要重启 Vim。

局部命令执行脚本,用于单行/选区 VimL / Lua 即时运行,避免全量重载:

复制代码
command! -range ExecVimL call execute(substitute(join(getline(<line1>, <line2>), " \n "), '\n\s*\\', ' ', 'g'), '')
command! -range ExecLua call execute('lua ' . join(getline(<line1>, <line2>), " \n "), '')
" 按 <space>r<space> 执行 VimL
nnoremap <silent> <space>r<space> :ExecVimL<cr>:<c-u>echo "Current line executed"<cr>
xnoremap <silent> <space>r<space> :ExecVimL<cr>:<c-u>echo "Selected range executed"<cr>
" 按 <space>rl<space> 执行 Lua(Neovim)
nnoremap <silent> <space>rl<space> :ExecLua<cr>:<c-u>echo "Current line executed"<cr>
xnoremap <silent> <space>rl<space> :ExecLua<cr>:<c-u>echo "Selected range executed"<cr>
" 自动检测文件类型执行对应脚本
nnoremap <silent> <expr> ,r ((&ft=='lua' ? ':ExecLua' : ':ExecVimL') . '<cr>:<c-u>echo "Current line executed"<cr>')
xnoremap <silent> <expr> ,r ((&ft=='lua' ? ':ExecLua' : ':ExecVimL') . '<cr>:<c-u>echo "Selected range executed"<cr>')

快捷加载预设脚本文件:

复制代码
nnoremap ,tff :sp <C-R>=printf("%s/preset-commands.vim", stdpath("config"))<CR><CR><C-L>:setl bh=delete noswf noma<cr>

11.1 Neovim Man 页面集成

将 Neovim 设置为手册分页器:

复制代码
export MANPAGER="nvim +Man!"

Vim 内直接阅读手册::Man {prog}


12. Tmux 基础名词:Session / Window / Pane

Tmux 三层结构:

  1. Session(会话):后台持久化任务容器,脱离终端进程后任务持续运行,可随时重新接入
  2. Window(窗口):会话内独立终端视图,一个会话可包含多个窗口
  3. Pane(窗格):窗口切割后的子终端区域,一个窗口可分割为多个窗格

层级关系:Session → 多个 Window → 每个 Window 分割为多个 Pane


13. Tmux 前缀键与会话操作

Tmux 所有快捷键默认由前缀键 <C-b> 触发;前缀键可在 .tmux.conf 中修改。

会话管理:

复制代码
tmux                      " 创建匿名会话
tmux new -s {name}        " 创建命名会话
tmux detach               " 脱离会话,后台保持运行
<C-b> d                   " 快捷键脱离会话
tmux ls                   " 列出全部会话
<C-b> s                   " 快捷键唤起会话列表选择器
tmux attach -t {name}     " 接入指定会话,简写 tmux a -t {name}
tmux kill-session -t {name} " 销毁指定会话
<C-d>                     " 在会话内关闭,窗格归零后销毁会话
tmux switch -t {name}     " 切换至另一个会话
tmux rename-session -t {old} {new} " 重命名会话
<C-b> $                   " 快捷键重命名当前会话

14. Tmux 窗格操作

复制代码
tmux split-window         " 垂直分割,上下窗格
tmux split-window -h      " 水平分割,左右窗格
<C-b> "                   " 快捷键垂直分割
<C-b> %                   " 快捷键水平分割

tmux select-pane -U       " 光标移至上方窗格
tmux select-pane -D       " 光标移至下方窗格
tmux select-pane -L       " 光标移至左侧窗格
tmux select-pane -R       " 光标移至右侧窗格
<C-b> 方向键              " 快捷键切换窗格
<C-b> ;                   " 跳转至上一次活跃窗格
<C-b> o                   " 循环切换窗格

tmux swap-pane -U         " 当前窗格向上换位
tmux swap-pane -D         " 当前窗格向下换位
<C-b> x                   " 关闭当前窗格
<C-b> z                   " 放大/复原当前窗格
<C-b> t                   " 在窗格内展示时钟,回车恢复终端

15. Tmux 窗口操作

复制代码
tmux new-window -n {name} " 创建命名窗口
<C-b> c                   " 快捷键新建窗口
tmux select-window -t {name} " 切换至目标窗口
<C-b> w                   " 唤起窗口列表选择器
<C-b> n                   " 下一个窗口
<C-b> p                   " 上一个窗口
tmux rename-window {name} " 重命名窗口
<C-b> ,                   " 快捷键重命名当前窗口
tmux kill-window -t {name}" 销毁指定窗口
<C-b> &                   " 快捷键关闭当前窗口
<C-b> ?                   " 打开 Tmux 快捷键帮助面板,q / <Esc> 退出

16. Tmux .tmux.conf 基础配置

配置文件路径:~/.tmux.conf,不存在时手动创建。

示例配置,将前缀键修改为 <C-x>,并配置窗格快速切换:

复制代码
# 修改前缀按键,替换默认 Ctrl + b
set -g prefix C-x
unbind C-b
bind C-x send-prefix

# 窗格切换快捷键,前缀 + h/j/k/l
bind-key k select-pane -U
bind-key j select-pane -D
bind-key h select-pane -L
bind-key l select-pane -R

配置修改完成后,在 Tmux 内部执行 :source-file ~/.tmux.conf 重载配置。


Reference