强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

Vim / Neovim 完全指南 / 07 - 窗口与标签页

“Buffers, windows, and tabs — the holy trinity of Vim’s layout system.”

7.1 缓冲区(Buffer)

7.1.1 什么是缓冲区

缓冲区是文件在内存中的表示。每个打开的文件对应一个缓冲区。

文件系统                  内存
┌──────────┐         ┌──────────┐
│ main.py  │ ──────→ │ Buffer 1 │
│ util.py  │ ──────→ │ Buffer 2 │
│ config   │ ──────→ │ Buffer 3 │
└──────────┘         └──────────┘

7.1.2 缓冲区操作

:e file.py       " 打开文件到缓冲区
:ls              " 列出所有缓冲区
:buffers         " 同 :ls
:bn              " 下一个缓冲区(buffer next)
:bp              " 上一个缓冲区(buffer previous)
:bfirst          " 第一个缓冲区
:blast           " 最后一个缓冲区
:b 3             " 切换到 3 号缓冲区
:b main          " 切换到名字包含 "main" 的缓冲区
:bd              " 关闭当前缓冲区(buffer delete)
:bd 3            " 关闭 3 号缓冲区
:bufdo cmd       " 对所有缓冲区执行命令

7.1.3 缓冲区状态

:ls 输出示例:
  1  h   "main.py"                    line 15
  2 #h  "config.toml"                 line 1
  3 %a  "utils.py"                    line 42
  4     "README.md"                   line 0

符号含义:
  %    当前窗口中的缓冲区
  #    轮换缓冲区(上次编辑的)
  a    活跃(已加载且可见)
  h    隐藏(有修改但不显示)
  +    有未保存修改
  -    不可修改

7.2 窗口(Window)

7.2.1 窗口分割

" 水平分割(上下)
:sp filename     " 分割并打开文件(split)
:split           " 分割当前文件
<C-w>s           " 分割当前文件

" 垂直分割(左右)
:vsp filename    " 垂直分割并打开文件(vsplit)
:vsplit          " 垂直分割当前文件
<C-w>v           " 垂直分割当前文件

7.2.2 窗口导航

" 方法一:Ctrl-w 前缀
<C-w>h    " 切换到左边窗口
<C-w>j    " 切换到下方窗口
<C-w>k    " 切换到上方窗口
<C-w>l    " 切换到右边窗口

" 方法二:直接映射(推荐配置)
" 在 init.lua 中设置:
" nnoremap <C-h> <C-w>h
" nnoremap <C-j> <C-w>j
" nnoremap <C-k> <C-w>k
" nnoremap <C-l> <C-w>l

" 循环切换
<C-w>w    " 切换到下一个窗口
<C-w>W    " 切换到上一个窗口
<C-w>p    " 切换到上次访问的窗口

7.2.3 窗口调整

" 调整大小
<C-w>=          " 所有窗口等大
<C-w>_          " 最大化当前窗口高度
<C-w>|          " 最大化当前窗口宽度
<C-w>_10        " 设置窗口高度为 10 行
<C-w>|30        " 设置窗口宽度为 30 列

" 交互式调整
:resize +5      " 增加 5 行高度
:resize -5      " 减少 5 行高度
:vertical resize +10  " 增加 10 列宽度
:vertical resize -10  " 减少 10 列宽度

7.2.4 窗口管理

<C-w>o    " 关闭其他窗口(only)
:only     " 同上
:hide     " 隐藏当前窗口(不关闭缓冲区)
<C-w>c    " 关闭当前窗口
:q        " 关闭当前窗口(如果只有一个窗口则退出)

" 移动窗口
<C-w>H    " 当前窗口移到最左
<C-w>J    " 当前窗口移到最下
<C-w>K    " 当前窗口移到最上
<C-w>L    " 当前窗口移到最右
<C-w>r    " 旋转窗口(向下)
<C-w>R    " 旋转窗口(向上)

7.3 标签页(Tab)

7.3.1 标签页操作

" 创建与关闭
:tabnew file.py     " 新标签页打开文件
:tabnew             " 新标签页(空文件)
:tabclose           " 关闭当前标签页
:tabclose 2         " 关闭第 2 个标签页
:tabonly             " 关闭其他标签页

" 导航
gt              " 下一个标签页
gT              " 上一个标签页
3gt             " 跳到第 3 个标签页
:tabn 3         " 跳到第 3 个标签页
:tabp           " 上一个标签页
:tabfirst       " 第一个标签页
:tablast        " 最后一个标签页

" 管理
:tabs           " 列出所有标签页
:tabmove 0      " 移到第一个位置
:tabmove        " 移到最后
:tabdo cmd      " 对所有标签页执行命令

7.3.2 标签页 vs 窗口

标签页(Tab):
┌──────────────────────────────────────┐
│ [Tab1] [Tab2] [Tab3]                 │
├──────────────────────────────────────┤
│                                      │
│  每个标签页可包含多个窗口            │
│  类似于"工作空间"                    │
│                                      │
└──────────────────────────────────────┘

窗口(Window):
┌──────────────┬───────────────┐
│              │               │
│   窗口 1     │    窗口 2     │
│              │               │
├──────────────┤               │
│   窗口 3     │               │
│              │               │
└──────────────┴───────────────┘

7.4 终端窗口

:terminal          " 打开终端(水平分割)
:terminal bash     " 指定 shell
:vert terminal     " 垂直分割终端

" 终端中的模式切换
<C-\><C-n>         " 从终端模式切换到 Normal 模式
i / a              " 在终端 Normal 模式中回到终端模式

7.5 浮动窗口(Neovim)

-- Neovim Lua 创建浮动窗口
local buf = vim.api.nvim_create_buf(false, true)
local opts = {
  relative = "editor",
  width = 60,
  height = 20,
  row = 5,
  col = 10,
  style = "minimal",
  border = "rounded",
}
vim.api.nvim_open_win(buf, true, opts)

7.6 布局管理配置

7.6.1 实用快捷键配置

-- ~/.config/nvim/lua/config/keymaps.lua
local map = vim.keymap.set

-- 窗口导航
map("n", "<C-h>", "<C-w>h", { desc = "左窗口" })
map("n", "<C-j>", "<C-w>j", { desc = "下窗口" })
map("n", "<C-k>", "<C-w>k", { desc = "上窗口" })
map("n", "<C-l>", "<C-w>l", { desc = "右窗口" })

-- 窗口大小
map("n", "<C-Up>", ":resize -2<CR>", { desc = "缩小高度" })
map("n", "<C-Down>", ":resize +2<CR>", { desc = "增大高度" })
map("n", "<C-Left>", ":vertical resize -2<CR>", { desc = "缩小宽度" })
map("n", "<C-Right>", ":vertical resize +2<CR>", { desc = "增大宽度" })

-- 缓冲区
map("n", "<S-l>", ":bnext<CR>", { desc = "下一缓冲区" })
map("n", "<S-h>", ":bprevious<CR>", { desc = "上一缓冲区" })
map("n", "<leader>bd", ":bdelete<CR>", { desc = "关闭缓冲区" })

-- 标签页
map("n", "<leader>tn", ":tabnew<CR>", { desc = "新标签页" })
map("n", "<leader>tc", ":tabclose<CR>", { desc = "关闭标签页" })
map("n", "<leader>to", ":tabonly<CR>", { desc = "仅保留当前标签页" })

7.6.2 常用布局场景

场景一:代码 + 测试

:vsplit     " 垂直分割
<C-w>l      " 切换到右窗口
:e test.py  " 打开测试文件
<C-w>h      " 回到左窗口

场景二:代码 + 终端

:split      " 水平分割
<C-w>j      " 切换到下方窗口
:terminal   " 打开终端
<C-w>k      " 回到上方代码窗口

场景三:三栏布局

:vsplit     " 垂直分割
:vsplit     " 再分一次(三栏)
<C-w>=      " 等大
" 左:文件树,中:主代码,右:参考文档

7.7 业务场景

场景布局方案
日常开发2 垂直窗口 + 底部终端
代码审查左右对比(vimdiff 或双窗口)
前端开发上代码下预览/终端
多文件项目多标签页(按功能分组)
调试代码 + 终端 + 日志

7.8 总结

概念核心命令
缓冲区:ls :bn :bp :bd :b N
窗口分割:sp :vsp <C-w>s <C-w>v
窗口导航<C-w>hjkl <C-w>w <C-w>p
窗口管理<C-w>= <C-w>c <C-w>o <C-w>HJKL
标签页:tabnew gt gT :tabclose :tabmove
终端:terminal <C-\><C-n>

下一步第 08 章 - 搜索与替换 → 掌握 Vim 的搜索模式、正则表达式、全局命令。


扩展阅读

  • :h windows — 窗口命令
  • :h buffers — 缓冲区命令
  • :h tabpage — 标签页命令
  • :h terminal — 终端功能
  • Neovim 浮动窗口 API