25.06.2015 Views

vim使用进阶

vim使用进阶

vim使用进阶

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

vim 使 用 进 阶<br />

使 用 vim 提 高 你 的 文 本 编 辑 效 率<br />

Easwy Yang


vim 使 用 进 阶 : 使 用 vim 提 高 你 的 文 本 编 辑 效 率<br />

Easwy Yang<br />

版 权 © 2007, 2008, 2009<br />

本 文 采 用 署 名 - 非 商 业 性 使 用 - 相 同 方 式 共 享 [http://creativecommons.org/licenses/by-nc-sa/2.5/cn/] 的 创 作 共 用 许 可 协 议 发 布 ,<br />

转 载 本 文 必 须 也 遵 循 署 名 - 非 商 业 性 使 用 - 相 同 方 式 共 享 。<br />

转 载 请 注 明 : 转 载 自 Easwy 的 博 客 [http://easwy.com/blog/] [ http://easwy.com/blog/ ]


目 录<br />

1. 目 录 ........................................................................ 1<br />

2. 序 言 ........................................................................ 5<br />

3. 使 用 会 话 (session) 和 viminfo ................................................... 8<br />

4. vimrc 初 步 .................................................................. 10<br />

5. 保 存 项 目 相 关 配 置 ........................................................... 14<br />

6. 使 用 标 签 (tag) 文 件 .......................................................... 17<br />

7. 使 用 taglist 插 件 ............................................................ 21<br />

8. 文 件 浏 览 和 缓 冲 区 浏 览 ....................................................... 25<br />

9. 使 用 lookupfile 插 件 ......................................................... 30<br />

10. 开 启 文 件 类 型 检 测 .......................................................... 35<br />

11. 乱 花 渐 欲 迷 人 眼 - 语 法 高 亮 ................................................. 38<br />

12. 程 序 员 的 利 器 - cscope ..................................................... 42<br />

13. 剑 不 离 手 - quickfix ....................................................... 46<br />

14. 智 能 补 全 .................................................................. 50<br />

15. 自 动 补 全 .................................................................. 56<br />

16. 指 随 意 动 , 移 动 如 飞 ( 一 ) ................................................... 59<br />

17. 指 随 意 动 , 移 动 如 飞 ( 二 ) ................................................... 63<br />

18. 在 vim 中 使 用 gdb 调 试 ........................................................ 69<br />

19. vim 编 译 中 遇 到 的 问 题 及 解 决 方 法 .............................................. 77<br />

iii


第 1 章 目 录<br />

本 系 列 文 章 , 是 原 来 我 在 CSDN 的 Easwy 专 栏 [http://blog.csdn.net/easwy] 撰 写 的 " 使 用 VIM 开 发<br />

软 件 项 目 " 系 列 。Easwy 的 博 客 [http://easwy.com/blog/] 搬 家 以 后 , 就 把 CSDN 上 的 文 章 全 部 移<br />

到 此 处 。<br />

写 本 系 列 文 章 的 最 初 想 法 , 是 介 绍 如 何 用 vim 开 发 软 件 。 但 纵 观 整 个 系 列 , 讲 述 的 其 实 和 软 件 开<br />

发 关 系 并 不 大 , 基 本 都 在 讲 vim 的 使 用 技 巧 、vim 的 配 置 及 vimrc、vim 的 命 令 和 vim 的 插 件 。 因<br />

此 , 把 文 章 移 到 新 站 后 , 我 把 本 系 列 的 名 字 改 为 "vim 使 用 进 阶 ", 希 望 大 家 一 如 既 往 的 支 持 该 系<br />

列 。<br />

本 文 是 这 一 系 列 文 章 的 总 目 录 , 可 由 此 访 问 本 系 列 所 有 文 章 。<br />

我 使 用 docbook 重 新 整 理 了 一 下 这 些 文 章 , 你 可 以 在 这 里 下 载 html 版 本 的 vim 使 用 进 阶 2009 年 前 文<br />

章 打 包 [http://easwy.com/blog/uploads/vim/advanced_vim_skills_html.zip], 现 在 也 提<br />

供 PDF 版 本 [http://easwy.com/blog/uploads/vim/advanced_vim_skills_pdf.zip] 下 载 。<br />

[ 目 录 ]<br />

• vim 使 用 进 阶 : 序 言 [http://easwy.com/blog/archives/advanced-vim-skills-prologue/]<br />

本 文 是 本 系 列 的 序 言 , 讲 述 我 使 用 vim 的 经 历 和 心 得 , 以 及 对 vim 初 学 者 的 一 些 建 议 。 文 中 的 抓<br />

图 展 示 了 我 的 vim 使 用 环 境 。<br />

• vim 使 用 进 阶 : 使 用 会 话 和 viminfo [http://easwy.com/blog/archives/advanced-vimskills-session-file-and-viminfo/]<br />

本 文 介 绍 如 何 使 用 vim 的 会 话 (session) 和 viminfo 来 恢 复 vim 的 使 用 环 境 。 如 果 你 需 要 经 常 恢<br />

复 到 相 同 工 作 环 境 , 此 功 能 非 常 有 用 , 你 不 必 一 次 次 重 新 打 开 文 件 、 设 置 你 的 工 作 环 境 。<br />

• vim 使 用 进 阶 : vimrc 初 步 [http://easwy.com/blog/archives/advanced-vim-skillsintroduce-vimrc/]<br />

本 文 简 要 介 绍 了 vimrc 的 知 识 以 及 如 何 使 用 vimrc 保 存 vim 的 配 置 。 文 中 还 提 供 了 一 些 键 映 射<br />

(map), 使 用 这 些 映 射 可 以 快 速 编 辑 和 加 载 vimrc。 关 于 vimrc 的 更 多 应 用 , 参 见 本 系 列 其 它 文<br />

章 。<br />

• vim 使 用 进 阶 : 保 存 项 目 相 关 配 置 [http://easwy.com/blog/archives/advanced-vim-skillssave-project-configuration/]<br />

本 篇 主 要 以 path 选 项 为 例 , 讲 述 如 何 保 存 和 恢 复 项 目 相 关 的 配 置 。 在 使 用 vim 的 过 程 中 , 你 可<br />

能 同 时 打 开 几 个 project, 每 个 project 的 配 置 可 能 都 不 相 同 , 文 中 介 绍 了 两 种 方 法 来 保 存 每 个<br />

project 自 身 的 独 有 配 置 。 一 种 是 使 用 一 个 固 定 的 vim 配 置 脚 本 保 存 project 相 关 的 path 设 置 、<br />

按 键 映 射 等 ; 另 外 一 种 是 利 用 前 面 文 章 所 介 绍 的 会 话 (session) 机 制 。<br />

• vim 使 用 进 阶 : 使 用 标 签 (tag) 文 件 [http://easwy.com/blog/archives/advanced-vimskills-use-ctags-tag-file/]<br />

本 文 介 绍 了 如 何 使 用 Exuberant ctags 生 成 tag 文 件 以 及 在 vim 中 如 何 使 用 tag 文 件 进 行 跳 转 、 查<br />

找 等 操 作 。 还 简 要 介 绍 了 tag 文 件 的 格 式 , 在 后 面 介 绍 的 Lookupfile 插 件 中 , 会 利 用 tag 文 件 便<br />

捷 的 查 找 、 打 开 文 件 。<br />

• vim 使 用 进 阶 : 使 用 taglist 插 件 [http://easwy.com/blog/archives/advanced-vim-skillstaglist-plugin/]<br />

1


目 录<br />

本 文 介 绍 如 何 使 用 taglist 插 件 (plugin) 来 查 看 程 序 中 的 标 签 (tag), 并 介 绍 了 taglist 插 件 的<br />

配 置 和 用 法 。taglist 插 件 利 用 Exuberant ctags 程 序 生 成 标 签 文 件 , 并 提 供 像 Source Insight<br />

那 样 的 标 签 窗 口 , 可 以 方 便 的 跳 转 到 函 数 、 变 量 等 标 签 所 在 的 位 置 。<br />

• vim 使 用 进 阶 : 文 件 浏 览 和 缓 冲 区 浏 览 [http://easwy.com/blog/archives/advanced-vimskills-netrw-bufexplorer-winmanager-plugin/]<br />

本 节 介 绍 了 如 何 在 vim 中 浏 览 文 件 , 以 及 如 何 查 看 当 前 打 开 的 缓 冲 区 。 利 用 netrw 插 件 , 可 以 方<br />

便 的 在 vim 中 浏 览 各 个 目 录 、 打 开 指 定 文 件 , 而 不 用 切 换 到 文 件 浏 览 器 或 shell; 当 然 ,netrw<br />

插 件 的 作 用 并 不 仅 仅 局 限 于 此 。 利 用 bufexplorer 插 件 , 则 可 以 方 便 的 查 看 打 开 的 缓 冲 区<br />

(buffer), 在 缓 冲 区 间 进 行 切 换 。 本 文 的 最 后 介 绍 了 winmanager 插 件 , 使 用 这 个 插 件 , 可 以 把<br />

netrw 插 件 、bufexplorer 插 件 和 taglist 插 件 整 合 起 来 , 使 vim 看 起 来 更 像 一 个 集 成 开 发 环 境<br />

(IDE)。<br />

• vim 使 用 进 阶 : lookupfile 插 件 [http://easwy.com/blog/archives/advanced-vim-skillslookupfile-plugin/]<br />

如 果 你 在 开 发 一 个 大 的 项 目 , 当 你 想 在 一 大 堆 文 件 中 查 找 或 者 编 辑 指 定 文 件 时 ,Lookupfile 插<br />

件 是 必 不 可 少 的 。 使 用 它 , 可 以 快 速 查 找 项 目 文 件 、 可 以 在 缓 冲 区 查 找 指 定 文 件 、 可 以 浏 览 指<br />

定 目 录 等 。 在 查 找 时 甚 至 可 以 使 用 正 则 表 达 式 (regex), 在 你 只 记 得 部 分 文 件 名 或 目 录 名 时 ,<br />

这 可 是 救 命 的 手 段 。<br />

• vim 使 用 进 阶 : 开 启 文 件 类 型 检 测 [http://easwy.com/blog/archives/advanced-vim-skillsfiletype-on/]<br />

vim 最 吸 引 人 的 一 点 是 , 它 支 持 无 穷 多 的 文 件 类 型 , 而 且 能 够 随 意 扩 展 。 在 本 文 主 要 介 绍 如 何<br />

打 开 文 件 类 型 检 测 的 功 能 , 以 及 如 何 使 用 基 于 文 件 类 型 的 插 件 (filetype plugin)。 正 因 为 有<br />

了 文 件 类 型 检 测 的 功 能 , 我 们 才 可 能 针 对 不 同 的 类 型 的 文 件 , 定 义 不 同 的 键 映 射 (map)、 设 置<br />

不 同 的 选 项 , 进 行 语 法 高 亮 的 染 色 ( 后 续 文 章 中 介 绍 )... 你 可 以 实 现 任 意 你 想 实 现 的 功 能 。<br />

• vim 使 用 进 阶 : 乱 花 渐 欲 迷 人 眼 - 语 法 高 亮 [http://easwy.com/blog/archives/advancedvim-skills-syntax-on-colorscheme/]<br />

VIM 并 不 是 只 有 黑 色 两 色 。 正 相 反 , 它 提 供 了 非 常 灵 活 的 机 制 允 许 用 户 自 定 义 色 彩 。 运 行 在 终<br />

端 中 的 VIM, 由 于 终 端 本 身 的 限 制 , 只 能 使 用 若 干 种 固 定 的 颜 色 ; 但 对 于 GVIM 来 讲 , 你 可 以 根<br />

据 你 的 喜 好 调 出 任 意 的 颜 色 。 本 文 介 绍 的 , 正 是 vim 的 语 法 高 亮 功 能 。<br />

• vim 使 用 进 阶 : 程 序 员 的 利 器 - cscope [http://easwy.com/blog/archives/advanced-vimskills-cscope/]<br />

在 前 面 的 文 章 中 介 绍 了 利 用 ctags 生 成 的 tag 文 件 , 跳 转 到 标 签 定 义 的 地 方 。 但 如 果 想 查 找 函 数<br />

在 哪 里 被 调 用 , 或 者 标 签 在 哪 些 地 方 出 现 过 ,ctags 就 无 能 为 力 了 , 这 时 需 要 使 用 更 为 强 大 的<br />

cscope。 本 文 就 介 绍 如 何 使 用 cscope, 有 了 它 , 你 可 以 把 source insight 抛 到 一 边 去 了 。<br />

• vim 使 用 进 阶 : 剑 不 离 手 - quickfix [http://easwy.com/blog/archives/advanced-vimskills-quickfix-mode/]<br />

vim 由 一 个 程 序 员 开 发 , 并 且 为 更 多 的 程 序 员 所 使 用 , 所 以 vim 对 开 发 人 员 的 强 大 支 持 , 也 就 可<br />

以 理 解 了 。quickfix 模 式 的 引 入 就 是 一 个 例 子 。quickfix 模 式 , 是 一 种 加 速 你 开 发 的 工 作 方<br />

式 , 使 你 不 必 离 开 vim, 就 可 以 快 速 的 完 成 " 编 辑 - 编 译 - 修 正 " 你 的 程 序 。 它 不 仅 仅 对 开 发 人 员<br />

有 用 , 只 要 你 的 工 作 有 类 似 " 编 辑 - 编 译 - 修 正 " 的 过 程 , 它 就 可 以 极 大 的 简 化 你 的 工 作 。<br />

• vim 使 用 进 阶 : 智 能 补 全 [http://easwy.com/blog/archives/advanced-vim-skills-omincomplete/]<br />

2


目 录<br />

使 用 过 Source Insight 的 人 一 定 对 它 的 自 动 补 全 功 能 印 象 深 刻 , 在 很 多 的 集 成 开 发 环 境 中 ,<br />

也 都 支 持 自 动 补 全 。vim 做 为 一 个 出 色 的 编 辑 器 , 这 样 的 功 能 当 然 少 不 了 。 本 文 主 要 介 绍 vim 的<br />

OMNI 补 全 。 将 在 下 一 篇 中 介 绍 其 它 的 补 全 方 式 。<br />

• vim 使 用 进 阶 : 自 动 补 全 [http://easwy.com/blog/archives/advanced-vim-skills-autocomplete/]<br />

本 文 继 续 介 绍 vim 的 补 全 功 能 。 作 为 一 个 通 用 的 编 辑 器 ,vim 实 现 的 补 全 功 能 并 不 仅 仅 限 于 对 程<br />

序 的 补 全 , 它 可 以 对 文 件 名 补 全 、 根 据 字 典 进 行 补 全 、 根 据 本 缓 冲 区 或 其 它 缓 冲 区 类 似 的 内 容<br />

进 行 补 全 、 根 据 文 件 语 法 补 全 等 等 , 它 甚 至 允 许 用 户 自 己 编 写 函 数 来 实 现 定 制 的 补 全 。 本 文 简<br />

要 介 绍 了 这 些 补 全 的 方 法 。<br />

• vim 使 用 进 阶 : 指 随 意 动 , 移 动 如 飞 ( 一 ) [http://easwy.com/blog/archives/advanced-vimskills-basic-move-method/]<br />

VIM 提 供 的 移 动 方 式 多 如 牛 毛 , 但 我 们 并 不 需 要 掌 握 全 部 这 些 命 令 , 只 需 要 掌 握 最 适 合 自 己 的<br />

那 些 命 令 。 本 文 介 绍 了 最 常 用 的 一 些 移 动 命 令 , 在 下 篇 文 章 中 将 介 绍 更 高 级 的 移 动 方 法 。<br />

• vim 使 用 进 阶 : 指 随 意 动 , 移 动 如 飞 ( 二 ) [http://easwy.com/blog/archives/advanced-vimskills-advanced-move-method/]<br />

本 文 介 绍 如 何 在 vim 中 移 动 , 主 要 涉 及 如 何 使 用 跳 转 表 (jump-motions)、 使 用 标 记 (mark)、 使<br />

用 折 行 (fold), 以 及 如 何 在 程 序 中 移 动 。<br />

• vim 使 用 进 阶 : 在 VIM 中 使 用 GDB 调 试 [http://easwy.com/blog/archives/advanced-vimskills-vim-gdb-vimgdb/]<br />

本 文 介 绍 了 如 何 使 用 vimgdb 补 丁 在 vim 中 用 gdb 调 试 程 序 , 同 时 还 介 绍 了 vim 的 编 译 方 法 。 然<br />

而 ,vim 只 是 一 个 编 辑 器 , 而 不 是 一 个 集 成 开 发 环 境 (IDE), 所 以 它 对 调 试 的 支 持 很 有 限 。<br />

• vim 使 用 进 阶 : vim 编 译 中 遇 到 的 问 题 及 解 决 方 法 [http://easwy.com/blog/archives/<br />

advanced-vim-skills-solve-compile-problem/]<br />

本 文 主 要 介 绍 vim 编 译 中 遇 到 的 问 题 及 解 决 办 法 。 文 中 介 绍 了 如 何 通 过 看 config.log, 来 了 解<br />

配 置 失 败 的 原 因 。 有 些 网 友 编 译 图 形 化 的 gvim 失 败 , 可 以 参 照 本 文 的 方 法 解 决 。<br />

• vim 使 用 进 阶 : 在 vim 中 使 用 拷 贝 / 粘 贴<br />

未 完 待 续<br />

• vim 使 用 进 阶 : 映 射 自 己 的 vim 按 键<br />

未 完 待 续<br />

• vim 使 用 进 阶 : 巧 用 vim 的 缩 写 功 能<br />

未 完 待 续<br />

• vim 使 用 进 阶 : 强 大 的 自 动 命 令 (autocmd)<br />

未 完 待 续<br />

• vim 使 用 进 阶 : 在 vim 中 使 用 gdb 调 试 ( 二 )<br />

未 完 待 续 , 介 绍 clewn<br />

• vim 使 用 进 阶 : 在 vim 中 使 用 gdb 调 试 ( 三 )<br />

未 完 待 续 , 介 绍 pyclewn<br />

• 其 它 你 感 兴 趣 的 话 题<br />

未 完 待 续<br />

3


目 录<br />

原 创 文 章 , 转 载 请 注 明 : 转 载 自 Easwy 的 博 客 [ http://easwy.com/blog/ ]<br />

本 文 链 接 地 址 : http://easwy.com/blog/archives/advanced-vim-skills-catalog/<br />

4


第 2 章 序 言<br />


序 言<br />

5. 有 时 间 的 话 , 一 定 要 阅 读 一 下 Bram Moolenaar(vim 的 作 者 ) 写 的 Seven habits of effective<br />

text editing( 七 个 有 效 的 文 本 编 辑 习 惯 ), 你 可 以 知 道 怎 样 提 高 你 的 编 辑 效 率 。 在 http://<br />

vimcdoc.sourceforge.net/ 下 载 PDF 格 式 的 手 册 , 在 附 录 二 你 可 以 看 到 它 的 中 文 译 本 。<br />

本 系 列 文 章 都 针 对 vim 7.0 版 本 , 如 果 这 里 介 绍 的 功 能 在 你 的 vim 中 不 存 在 , 不 妨 升 级 到 vim<br />

7.0 后 再 试 一 次 。<br />

我 以 Linux 版 本 的 vim 7.0 为 例 。vim 也 有 支 持 windows 的 版 本 , 可 以 到 vim 主 页 下 载 预 编 译 的<br />

的 windows 版 vim 7.0。<br />

文 章 尽 量 不 涉 及 具 体 的 软 件 源 代 码 , 如 果 确 实 需 要 , 则 以 vim 7.0 的 源 代 码 为 例 。 此 代 码 可<br />

以 也 可 以 在 vim 主 页 下 载 , 我 把 它 解 压 在 ~/src/vim70 目 录 下 。 后 续 文 章 以 此 目 录 为 例 进 行 讲 解 。<br />

附 图 是 我 所 使 用 vim 环 境 , 在 这 副 图 中 , 我 打 开 了 三 个 标 签 页 , 一 个 是 主 编 程 区 , 一 个 是 打 开<br />

的 .vimrc 文 件 , 另 外 一 个 是 草 稿 区 。 在 主 编 程 标 签 页 中 有 几 个 不 同 的 窗 口 , 分 别 是 当 前 打 开 的<br />

buffer, 当 前 文 件 中 的 tag,help 窗 口 ,lookupfile 窗 口 ,src/main.c 和 src/edit.c。 其 中 使 用<br />

了 三 个 vim 插 件 (plugin):winmanager, taglist, lookupfile。<br />

点 击 查 看 大 图<br />

从 这 副 图 中 可 以 看 出 vim 的 一 些 特 性 : 多 标 签 支 持 (tab)、 多 窗 口 支 持 、 插 件 支 持 (plugin)、 语<br />

法 高 亮 功 能 (syntax)、 文 本 折 叠 功 能 (folding)...... 这 些 特 性 , 以 及 其 它 数 不 清 的 特 性 , 我 都<br />

将 在 后 续 文 章 中 尽 量 给 予 介 绍 。<br />

上 图 是 GUI 界 面 的 vim, 下 图 是 控 制 台 (console) 下 的 vim 的 抓 图 。 这 是 我 通 常 的 开 发 方 式 : 使<br />

用 putty 远 程 登 录 到 linux 服 务 器 上 , 使 用 控 制 台 的 vim 开 发 软 件 :<br />

6


序 言<br />

点 击 查 看 大 图<br />

对 vim 的 了 解 有 限 , 请 多 指 教 。<br />


第 3 章 使 用 会 话 (session) 和 viminfo<br />


使 用 会 话 (session) 和 viminfo<br />

时 , 或 者 你 的 项 目 有 多 个 不 同 版 本 ( 位 于 不 同 的 目 录 ), 而 你 想 始 终 使 用 一 个 session 文 件 时 ,<br />

这 个 选 项 比 较 有 用 : 你 只 需 要 把 session 文 件 拷 贝 到 不 同 的 目 录 , 然 后 使 用 就 可 以 了 。 设 置 此 选<br />

项 后 ,session 文 件 中 保 存 的 是 文 件 的 相 对 路 径 , 而 不 是 绝 对 路 径 。<br />

我 们 在 上 面 使 用 :mksession 命 令 创 建 了 会 话 文 件 , 那 么 怎 么 使 用 会 话 文 件 恢 复 编 辑 环 境 呢 ? 很 简<br />

单 , 你 只 需 要 使 用 :source session-file 来 导 入 会 话 文 件 。 因 为 会 话 文 件 是 一 个 脚 本 , 里 面 保 存<br />

的 是 Ex 命 令 , 所 以 "source" 命 令 只 是 把 会 话 文 件 中 的 Ex 命 令 执 行 一 遍 。<br />

[viminfo]<br />

使 用 :wviminfo [file] 命 令 , 可 以 手 动 创 建 一 个 viminfo 文 件 。<br />

其 实 , 在 vim 退 出 时 , 每 次 都 会 保 存 一 个 .viminfo 文 件 在 用 户 的 主 目 录 。 我 们 使 用 :wviminfo 命 令<br />

则 是 手 动 创 建 一 个 viminfo 文 件 , 因 为 缺 省 的 .viminfo 文 件 会 在 每 次 退 出 vim 时 自 动 更 新 , 谁 知 道<br />

你 在 关 闭 当 前 软 件 项 目 后 , 又 使 用 vim 做 过 些 什 么 呢 ? 这 样 的 话 ,.viminfo 中 的 信 息 , 也 许 就 与<br />

你 所 进 行 的 软 件 项 目 无 关 了 。 还 是 手 动 保 存 一 个 保 险 。<br />

":wviminfo" 命 令 保 存 哪 些 内 容 , 以 及 保 存 的 数 量 , 由 'viminfo' 选 项 决 定 , 这 个 选 项 的 值 在<br />

windows 上 和 在 linux 上 的 缺 省 值 不 同 , 具 体 含 义 参 阅 手 册 。<br />

要 读 入 你 所 保 存 的 viminfo 文 件 , 使 用 :rviminfo [file] 命 令 。<br />

现 在 , 回 到 我 们 的 例 子 , 依 旧 是 上 篇 文 章 中 的 抓 图 , 先 看 一 下 我 们 当 前 目 录 , 执 行 :pwd, 显 示 "/<br />

home/easwy/src/vim70", 接 下 来 , 执 行 下 面 的 命 令 :<br />

:cd src<br />

:set sessionoptions-=curdir<br />

:set sessionoptions+=sesdir<br />

:mksession vim70.vim<br />

:wviminfo vim70.viminfo<br />

:qa<br />

" 切 换 到 /home/easwy/src/vim70/src 目 录<br />

" 在 session option 中 去 掉 curdir<br />

" 在 session option 中 加 入 sesdir<br />

" 创 建 一 个 会 话 文 件<br />

" 创 建 一 个 viminfo 文 件<br />

" 退 出 vim<br />

退 出 vim 后 , 在 命 令 行 下 执 行 gvim &, 再 次 进 入 vim, 这 时 看 到 的 是 一 个 空 白 窗 口 。 然 后 执 行 下 面<br />

的 命 令 :<br />

:source ~/src/vim70/src/vim70.vim ' 载 入 会 话 文 件<br />

:rviminfo vim70.viminfo ' 读 入 viminfo 文 件<br />

太 棒 了 , 又 恢 复 到 昨 天 退 出 时 的 状 态 了 ! 继 续 工 作 ~~~~<br />

不 过 , 每 次 都 要 手 工 修 改 'sessionoptions' 或 'viminfo' 吗 ? 多 麻 烦 啊 ...... 别 着 急 , 现 在 是 时<br />

候 介 绍 vimrc 了 , 请 移 步 下 一 章 : vimrc 初 步 。<br />

[ 参 考 文 档 ]<br />

1.vim 手 册<br />

2.vim 中 文 手 册<br />


第 4 章 vimrc 初 步<br />


vimrc 初 步<br />

:e $vim/_vimrc<br />

在 这 个 文 件 中 , 它 包 含 了 上 面 提 到 的 vimrc_example.vim。 同 时 , 它 会 把 vim 设 置 的 更 符 合<br />

windows 的 操 作 习 惯 。 比 如 , 支 持 CTRL-C 拷 贝 ,CTRL-V 粘 贴 等 等 。Windows 下 的 用 户 , 可 以 使 用<br />

$vim/_vimrc 来 做 为 你 的 第 一 个 vimrc。<br />

顺 便 提 一 句 , 在 unix/linux 中 , 文 件 名 可 以 以 "." 开 头 , 表 明 此 文 件 是 隐 藏 的 。 而 在 windows 中 ,<br />

不 允 许 文 件 名 以 "." 开 头 , 所 以 ,windows 版 本 的 vim, 将 读 取 _vimrc 来 做 为 自 己 的 配 置 文 件 。<br />

在 今 后 使 用 vim 的 日 子 里 , 你 会 频 繁 的 更 改 你 的 vimrc。 所 以 我 们 需 要 设 置 一 些 快 捷 方 式 , 使 我 们<br />

能 快 速 的 访 问 vimrc。<br />

把 下 面 这 段 内 容 拷 贝 到 你 的 vimrc 中 :<br />

1 "Set mapleader<br />

2 let mapleader = ","<br />

3<br />

4 "Fast reloading of the .vimrc<br />

5 map ss :source ~/.vimrc<br />

6 "Fast editing of .vimrc<br />

7 map ee :e ~/.vimrc<br />

8 "When .vimrc is edited, reload it<br />

9 autocmd! bufwritepost .vimrc source ~/.vimrc<br />

为 了 方 便 解 释 , 我 给 每 一 行 都 加 了 一 个 行 号 。<br />

• 在 vimrc 中 , 双 引 号 开 头 的 行 , 将 被 当 作 注 释 忽 略 。<br />

• 第 2 行 , 用 来 设 置 mapleader 变 量 , 当 mapleader 为 未 设 置 或 为 空 时 , 使 用 缺 省 的 "\" 来 作 为<br />

mapleader。<br />

mapleader 变 量 是 作 用 是 什 么 呢 ? 看 下 面 的 介 绍 。<br />

• 第 5 行 定 义 了 一 个 映 射 (map), 这 个 映 射 把 ss, 映 射 为 命 令 :source ~/.vimrc。 当<br />

定 义 一 个 映 射 时 , 可 以 使 用 前 缀 。 而 在 映 射 生 效 时 ,vim 会 把 替 换 成<br />

mapleader 变 量 的 值 。 也 就 是 说 , 我 们 这 里 定 义 的 ss 在 使 用 时 就 变 成 了 ",ss", 当 输 入<br />

这 一 快 捷 方 式 时 , 就 会 source 一 次 ~/.vimrc 文 件 ( 也 就 是 重 新 执 行 一 遍 .vimrc 文 件 )。<br />

• 第 7 行 , 定 义 了 ee 快 捷 键 , 当 输 入 ,ee 时 , 会 打 开 ~/.vimrc 进 行 编 辑 。<br />

• 第 9 行 , 定 义 了 一 个 自 动 命 令 , 每 次 写 入 .vimrc 后 , 都 会 执 行 这 个 自 动 命 令 ,source 一 次<br />

~/.vimrc 文 件 。<br />

有 了 上 面 的 快 捷 键 , 我 们 就 能 快 速 的 打 开 vimrc 文 件 编 辑 , 快 速 重 新 source vimrc 文 件 , 方 便 多<br />

了 。<br />

无 论 在 windows 还 是 在 linux 中 , 我 都 使 用 vim 作 为 我 的 缺 省 编 辑 器 。 并 且 , 我 想 使 用 同 一 个 vimrc<br />

文 件 。 因 此 , 我 定 义 了 一 个 MySys() 函 数 , 用 来 区 分 不 同 的 平 台 , 以 进 行 不 同 的 配 置 。<br />

另 外 , 在 编 辑 vimrc 文 件 时 , 我 更 喜 欢 新 开 一 个 标 签 页 来 编 辑 , 而 不 是 在 当 前 窗 口 中 。 因 此 , 我<br />

定 义 了 SwitchToBuf() 函 数 , 它 在 所 有 标 签 页 的 窗 口 中 查 找 指 定 的 文 件 名 , 如 果 找 到 这 样 一 个 窗<br />

口 , 就 跳 到 此 窗 口 中 ; 否 则 , 它 新 建 一 个 标 签 页 来 打 开 vimrc 文 件 。( 注 : 标 签 页 (tab) 功 能 只 有<br />

在 vim 7.0 版 本 以 上 才 支 持 。)<br />

下 面 是 我 的 vimrc 中 使 用 的 设 定 , 希 望 能 够 抛 砖 引 玉 :<br />

11


vimrc 初 步<br />

" Platform<br />

function! MySys()<br />

if has("win32")<br />

return "windows"<br />

else<br />

return "linux"<br />

endif<br />

endfunction<br />

function! SwitchToBuf(filename)<br />

"let fullfn = substitute(a:filename, "^\\~/", $HOME . "/", "")<br />

" find in current tab<br />

let bufwinnr = bufwinnr(a:filename)<br />

if bufwinnr != -1<br />

exec bufwinnr . "wincmd w"<br />

return<br />

else<br />

" find in each tab<br />

tabfirst<br />

let tab = 1<br />

while tab


vimrc 初 步<br />

" For windows version<br />

if MySys() == 'windows'<br />

source $VIMRUNTIME/mswin.vim<br />

behave mswin<br />

endif<br />

注 意 : 我 在 windows 中 也 定 义 一 个 "HOME" 环 境 变 量 , 然 后 把 _vimrc 放 在 "HOME" 环 境 变 量 所 指 向 的<br />

目 录 中 。 如 果 你 打 算 在 windows 中 使 用 上 面 的 设 定 , 也 需 要 这 样 做 !<br />

好 了 , 现 在 我 们 知 道 如 何 永 久 更 改 'sessionoptions' 选 项 和 'viminfo' 选 项 了 , 把 对 它 们 的 配 置<br />

放 入 你 的 vimrc 即 可 。<br />

vim 自 带 的 示 例 vimrc 中 , 只 定 义 最 基 本 的 配 置 。<br />

在 http://www.amix.dk/vim/vimrc.html 有 一 个 非 常 强 大 的 vimrc, 有 人 戏 称 为 " 史 上 最 强 的<br />

vimrc", 或 许 有 些 言 过 其 实 。 不 过 , 如 果 你 通 读 了 这 个 vimrc, 相 信 能 从 中 学 到 很 多 ......<br />

这 里 有 一 个 redguardtoo 修 改 过 的 版 本 , 可 以 对 照 参 考 一 下 。<br />

我 的 vimrc 也 是 基 于 Amix 的 模 板 , 然 后 自 已 做 了 很 多 修 改 。<br />

建 议 : 不 要 照 拷 这 个 vimrc! 可 能 这 个 文 件 的 设 定 并 不 符 合 你 的 习 惯 。 另 外 , 这 个 文 件 的 设 定 ,<br />

可 能 也 不 能 在 你 的 工 作 环 境 中 运 行 。<br />

[ 参 考 文 档 ]<br />

• vim 手 册<br />

• vim 中 文 手 册<br />

• http://www.amix.dk/vim/vimrc.html<br />


第 5 章 保 存 项 目 相 关 配 置<br />


保 存 项 目 相 关 配 置<br />

vim 打 开 了 ~/src/vim70/runtime/autoload/netrw.vim 文 件 。 用 这 种 方 法 打 开 文 件 真 是 太 方 便<br />

了 , 你 不 用 输 入 文 件 的 路 径 ,vim 会 自 动 在 path 选 项 定 义 的 路 径 中 搜 索 。 不 过 "find" 命 令 也 有 缺<br />

陷 , 如 果 你 只 记 得 文 件 名 的 一 部 分 , 那 么 就 没 有 办 法 用 find 命 令 打 开 这 个 文 件 了 。 而 且 find 命 令<br />

也 不 允 许 使 用 正 则 表 达 式 。 没 关 系 , 我 们 还 有 更 好 的 方 法 来 打 开 文 件 , 我 将 在 Lookupfile 插 件 中<br />

介 绍 这 些 方 法 。<br />

path 选 项 介 绍 完 了 , 我 们 进 入 正 题 , 如 何 把 本 项 目 相 关 的 配 置 保 存 起 来 , 下 次 打 开 本 项 目 时 自 动<br />

恢 复 这 些 配 置 呢 ?<br />

我 们 有 两 种 方 法 做 到 这 一 点 。<br />

[ 方 法 1]<br />

我 们 在 ~/src/vim70/ 目 录 下 建 立 一 个 文 件 , 假 定 文 件 名 为 workspace.vim, 文 件 内 容 为 :<br />

"set project path<br />

set path+=~/src/vim70/**<br />

这 个 文 件 中 保 存 了 项 目 相 关 的 信 息 , 例 如 选 项 值 , 键 映 射 , 函 数 定 义 , 自 动 命 令 , 等 等 。 我 们 的<br />

例 子 中 只 定 义 的 path 选 项 , 我 们 没 有 使 用 "set path=..." 语 句 , 在 vim 手 册 中 建 议 使 用 "set path<br />

+=..." 和 "set path-=..." 格 式 。<br />

接 下 来 , 在 你 的 vimrc 文 件 中 加 入 下 面 的 语 句 :<br />

" execute project related configuration in current directory<br />

if filereadable("workspace.vim")<br />

source workspace.vim<br />

endif<br />

以 后 , 每 次 你 在 ~/src/vim70/ 目 录 中 启 动 vim 时 ,vim 都 会 自 动 载 入 workspace.vim, 恢 复 项 目 的<br />

配 置 信 息 。<br />

[ 方 法 2]<br />

还 记 得 本 系 列 文 章 的 第 二 篇 使 用 会 话 (session) 和 viminfo 吗 ? 那 篇 文 章 中 , 我 们 介 绍 了 使 用<br />

session 文 件 和 viminfo 保 存 项 目 环 境 的 方 法 。 如 果 你 使 用 了 会 话 文 件 , 那 么 选 项 值 , 键 映 射 , 和<br />

其 它 很 多 信 息 都 已 经 保 存 了 。 但 会 话 的 功 能 毕 竟 有 限 , 不 能 把 项 目 相 关 的 配 置 全 部 保 存 下 来 , 怎<br />

么 办 呢 ?<br />

vim 的 作 者 已 经 想 到 了 这 个 问 题 , 并 提 供 了 解 决 办 法 。<br />

在 vim 载 入 会 话 文 件 的 最 后 一 步 , 它 会 查 找 一 个 额 外 的 文 件 并 执 行 其 中 的 ex 命 令 。 查 找 的 规 则<br />

是 , 把 会 话 文 件 名 的 后 缀 去 掉 , 然 后 在 后 面 加 上 "x.vim",。 假 设 你 的 会 话 文 件 名 为<br />

example.session,vim 就 会 查 找 是 否 有 examplex.vim, 如 果 找 到 , 就 会 执 行 此 文 件 中 的 ex 命 令 。<br />

好 了 , 我 们 先 创 建 我 们 的 会 话 文 件 :<br />

:cd ~/src/vim70<br />

:set sessionoptions-=curdir<br />

:set sessionoptions+=sesdir<br />

:mksession vim70s.vim<br />

' 在 session option 中 去 掉 curdir<br />

' 在 session option 中 加 入 sesdir<br />

' 创 建 一 个 会 话 文 件<br />

然 后 再 编 辑 一 个 名 为 ~/src/vim70/vim70sx.vim 的 文 件 , 文 件 的 内 容 为 ( 当 然 , 你 可 以 在 这 个 文<br />

件 中 加 入 更 多 内 容 ):<br />

15


保 存 项 目 相 关 配 置<br />

"set project path<br />

set path+=~/src/vim70/**<br />

退 出 vim 后 , 在 命 令 行 下 执 行 "gvim &", 再 次 进 入 vim, 这 时 看 到 的 是 一 个 空 白 窗 口 。 然 后 执 行 下<br />

面 的 命 令 :<br />

:source ~/src/vim70/vim70s.vim ' 载 入 会 话 文 件<br />

太 棒 了 ! 原 来 的 会 话 环 境 已 经 恢 复 , 并 且 项 目 相 关 的 配 置 也 设 置 好 了 !<br />

[ 参 考 文 档 ]<br />

1.vim 手 册<br />

2.vim 中 文 手 册<br />


第 6 章 使 用 标 签 (tag) 文 件<br />


使 用 标 签 (tag) 文 件<br />

!_TAG_FILE_SORTED1{anything}<br />

上 面 这 个 标 记 说 明 tag 文 件 是 经 过 排 序 的 , 并 且 排 序 时 区 分 了 大 小 写 , 对 排 序 的 tag,vim 会 使 用<br />

二 分 法 来 进 行 查 找 , 大 大 加 快 了 查 找 速 度 ; 如 果 值 为 0, 则 表 示 tag 文 件 未 经 排 序 ; 如 果 值 为 2,<br />

则 表 示 tag 文 件 是 忽 略 大 小 写 排 序 的 。<br />

之 所 以 在 这 里 介 绍 tag 文 件 的 格 式 , 是 因 为 我 们 在 后 面 提 到 的 lookupfile 插 件 中 , 会 自 己 生 成 tag<br />

文 件 。<br />

虽 然 ctags 有 为 数 众 多 的 选 项 , 但 通 常 我 们 所 使 用 的 非 常 简 单 。 还 是 以 vim 7.0 的 代 码 为 例 , 我 们<br />

执 行 :<br />

cd ~/src/vim70<br />

ctags –R src<br />

上 面 这 条 命 令 会 在 ~/src/vim70/ 目 录 下 生 成 一 个 名 为 tags 的 文 件 , 这 个 文 件 中 包 含 ~/src/vim70/<br />

src/ 目 录 下 所 有 .c、.h 文 件 中 的 标 签 。 它 一 个 文 本 文 件 , 你 可 以 用 vim 打 开 它 看 一 下 。 此 文 件 缺<br />

省 按 区 分 字 母 大 小 写 排 序 , 所 以 直 接 可 以 被 vim 使 用 。<br />

现 在 我 们 进 入 vim, 执 行 下 面 的 命 令 :<br />

:cd ~/src/vim70 " 切 换 当 前 目 录 为 ~/src/vim70<br />

:set tags=tags " 设 置 tags 选 项 为 当 前 目 录 下 的 tags 文 件<br />

现 在 , 我 们 设 置 好 了 tags 选 项 , 接 下 来 我 们 使 用 它 :<br />

:tag VimMain<br />

你 会 看 到 vim 打 开 了 src/main.c 文 件 , 并 把 光 标 定 位 到 第 167 行 VimMain 上 。<br />

我 们 知 道 , 一 般 主 程 序 的 函 数 名 为 main, 如 果 你 尝 试 下 面 的 命 令 :<br />

:tag main<br />

# pri kind tag file<br />

1 F f main src/xxd/xxd.c<br />

main(argc, argv)<br />

2 FS d main src/if_python.c<br />

46<br />

Choice number ( cancels):<br />

这 里 并 没 有 src/main.c 文 件 , 怎 么 回 事 呢 ? 这 是 因 为 ctags 并 不 是 编 译 器 , 它 在 处 理 编 译 预 处 理<br />

指 令 受 到 局 限 , 因 此 并 没 有 生 成 src/main.c 中 main() 函 数 的 标 签 。 你 可 以 在 生 成 tag 文 件 时 给<br />

ctags 指 定 参 数 来 解 决 这 个 问 题 。 见 ctags 手 册 。<br />

或 者 你 可 以 用 ":grep" 或 ":vimgrep" 来 查 找 main( 这 篇 文 章 讲 解 grep 及 vimgrep 的 用 法 ):<br />

:cd ~/src/vim70<br />

:vimgrep /\/ src/*.c<br />

:cw<br />

18


使 用 标 签 (tag) 文 件<br />

这 时 下 面 的 quickfix 窗 口 将 显 示 出 来 , 在 quickfix 窗 口 中 找 到 我 们 想 跳 转 的 位 置 ( 本 例 中 是 src/<br />

main.c), 按 回 车 , 就 可 以 跳 到 对 应 的 位 置 了 。<br />

点 击 查 看 大 图<br />

如 果 你 只 记 得 部 分 的 标 签 名 , 那 么 可 以 使 用 "tag" 命 令 的 搜 索 模 式 , 你 可 以 输 入 一 个 vim 正 则 表 达<br />

式 来 表 示 你 所 查 找 的 名 字 , 如 :<br />

:tag /\C\<br />

# pri kind tag file<br />

1 F f VimMain src/main.c<br />

VimMain<br />

2 F d bindtextdomain src/vim.h<br />

483<br />

3 F d bindtextdomain src/vim.h<br />

502<br />

4 F d bindtextdomain src/vim.h<br />

504<br />

5 F f main src/xxd/xxd.c<br />

main(argc, argv)<br />

6 F d textdomain src/vim.h<br />

488<br />

7 F d textdomain src/vim.h<br />

510<br />

8 F d textdomain src/vim.h<br />

512<br />

9 FS d bindtextdomain src/gui_gtk.c<br />

54<br />

10 FS d bindtextdomain src/gui_gtk_x11.c<br />

37<br />

11 FS f cmdsrv_main src/main.c<br />

cmdsrv_main(argc, argv, serverName_arg, serverStr)<br />

12 FS d main src/if_python.c<br />

46<br />

19


使 用 标 签 (tag) 文 件<br />

13 FS d textdomain src/gui_gtk.c<br />

51<br />

14 FS d textdomain src/gui_gtk_x11.c<br />

34<br />

Choice number ( cancels):<br />

这 表 示 我 想 查 找 一 个 以 一 个 或 多 个 keyword 开 始 的 标 签 , 此 标 签 以 ain 做 为 结 尾 , 在 查 找 时 区 分 大<br />

小 写 。 要 读 懂 这 个 正 则 表 达 式 , 请 ":help pattern"。<br />

vim 会 保 存 一 个 跳 转 的 标 签 栈 , 以 允 许 你 在 跳 转 到 一 个 标 签 后 , 再 跳 回 来 , 可 以 使 用 ":tags" 命 令<br />

查 找 你 处 于 标 签 栈 的 哪 个 位 置 。<br />

我 们 经 常 用 到 的 tag 跳 转 命 令 见 下 ( 一 般 只 需 要 知 道 CTRL-] 和 CTRL-T 就 可 以 了 ):<br />

:tag {ident}<br />

:tags<br />

CTRL-]<br />

CTRL-T<br />

" 跳 转 到 指 定 的 标 签<br />

" 显 示 标 签 栈<br />

" 跳 转 到 当 前 光 标 下 的 标 签<br />

" 跳 到 标 签 栈 中 较 早 的 标 签<br />

如 果 想 了 解 更 多 命 令 , 可 以 ":help<br />

usr_30.txt)。<br />

29.1"( 强 烈 建 议 程 序 员 完 整 的 阅 读 usr_29.txt 和<br />

如 果 想 更 深 入 了 解 tag 命 令 和 相 关 知 识 , 可 以 ":help tagsrch"。<br />

我 之 前 写 的 一 篇 关 于 ctags 和 cscope 的 文 章 , 参 见 :Vim + Cscope/Ctags<br />

[ 参 考 文 档 ]<br />

• vim 手 册<br />

• vim 中 文 手 册<br />


第 7 章 使 用 taglist 插 件<br />


使 用 taglist 插 件<br />

""""""""""""""""""""""""""""""<br />

" Tag list (ctags)<br />

""""""""""""""""""""""""""""""<br />

if MySys() == "windows"<br />

let Tlist_Ctags_Cmd = 'ctags'<br />

elseif MySys() == "linux"<br />

let Tlist_Ctags_Cmd = '/usr/bin/ctags'<br />

endif<br />

let Tlist_Show_One_File = 1<br />

let Tlist_Exit_OnlyWindow = 1<br />

let Tlist_Use_Right_Window = 1<br />

" 设 定 windows 系 统 中 ctags 程 序 的 位 置<br />

" 设 定 linux 系 统 中 ctags 程 序 的 位 置<br />

" 不 同 时 显 示 多 个 文 件 的 tag, 只 显 示 当 前 文 件 的<br />

" 如 果 taglist 窗 口 是 最 后 一 个 窗 口 , 则 退 出 vim<br />

" 在 右 侧 窗 口 中 显 示 taglist 窗 口<br />

这 样 配 置 后 , 当 你 输 入 ":TlistOpen" 时 , 显 示 如 下 窗 口 :<br />

点 击 查 看 大 图<br />

在 屏 幕 右 侧 出 现 的 就 是 taglist 窗 口 , 你 从 中 可 以 看 到 在 main.c 文 件 中 定 义 的 所 有 tag: 宏 、 定<br />

义 、 变 量 、 函 数 等 ; 你 也 可 以 双 击 某 个 tag, 跳 到 该 tag 定 义 的 位 置 ; 你 还 可 以 把 某 一 类 的 tag 折<br />

叠 起 来 ( 使 用 了 vim 的 折 行 功 能 ), 方 便 查 看 , 就 像 上 图 中 macro 和 variable 那 样 。 更 多 的 功 能 ,<br />

请 查 看 taglist 的 帮 助 页 , 本 文 也 会 介 绍 一 些 常 用 功 能 。<br />

下 面 介 绍 常 用 的 taglist 配 置 选 项 , 你 可 以 根 据 自 己 的 习 惯 进 行 配 置 :<br />

• Tlist_Ctags_Cmd 选 项 用 于 指 定 你 的 Exuberant ctags 程 序 的 位 置 , 如 果 它 没 在 你 PATH 变 量 所 定<br />

义 的 路 径 中 , 需 要 使 用 此 选 项 设 置 一 下 ;<br />

• 如 果 你 不 想 同 时 显 示 多 个 文 件 中 的 tag, 设 置 Tlist_Show_One_File 为 1。 缺 省 为 显 示 多 个 文 件<br />

中 的 tag;<br />

• 设 置 Tlist_Sort_Type 为 "name" 可 以 使 taglist 以 tag 名 字 进 行 排 序 , 缺 省 是 按 tag 在 文 件 中 出 现<br />

的 顺 序 进 行 排 序 。 按 tag 出 现 的 范 围 ( 即 所 属 的 namespace 或 class) 排 序 , 已 经 加 入 taglist 的<br />

TODO List, 但 尚 未 支 持 ;<br />

• 如 果 你 在 想 taglist 窗 口 是 最 后 一 个 窗 口 时 退 出 vim, 设 置 Tlist_Exit_OnlyWindow 为 1;<br />

• 如 果 你 想 taglist 窗 口 出 现 在 右 侧 , 设 置 Tlist_Use_Right_Window 为 1。 缺 省 显 示 在 左 侧 。<br />

22


使 用 taglist 插 件<br />

• 在 gvim 中 , 如 果 你 想 显 示 taglist 菜 单 , 设 置 Tlist_Show_Menu 为 1。 你 可 以 使<br />

用 Tlist_Max_Submenu_Items 和 Tlist_Max_Tag_Length 来 控 制 菜 单 条 目 数 和 所 显 示 tag 名 字 的 长<br />

度 ;<br />

• 缺 省 情 况 下 , 在 双 击 一 个 tag 时 , 才 会 跳 到 该 tag 定 义 的 位 置 , 如 果 你 想 单 击 tag 就 跳 转 , 设<br />

置 Tlist_Use_SingleClick 为 1;<br />

• 如 果 你 想 在 启 动 vim 后 , 自 动 打 开 taglist 窗 口 , 设 置 Tlist_Auto_Open 为 1;<br />

• 如 果 你 希 望 在 选 择 了 tag 后 自 动 关 闭 taglist 窗 口 , 设 置 Tlist_Close_On_Select 为 1;<br />

• 当 同 时 显 示 多 个 文 件 中 的 tag 时 , 设 置 Tlist_File_Fold_Auto_Close 为 1, 可 使 taglist 只 显 示<br />

当 前 文 件 tag, 其 它 文 件 的 tag 都 被 折 叠 起 来 。<br />

• 在 使 用 :TlistToggle 打 开 taglist 窗 口 时 , 如 果 希 望 输 入 焦 点 在 taglist 窗 口 中 , 设<br />

置 Tlist_GainFocus_On_ToggleOpen 为 1;<br />

• 如 果 希 望 taglist 始 终 解 析 文 件 中 的 tag, 不 管 taglist 窗 口 有 没 有 打 开 , 设<br />

置 Tlist_Process_File_Always 为 1;<br />

• Tlist_WinHeight 和 Tlist_WinWidth 可 以 设 置 taglist 窗 口 的 高 度 和 宽<br />

度 。Tlist_Use_Horiz_Window 为 1 设 置 taglist 窗 口 横 向 显 示 ;<br />

在 taglist 窗 口 中 , 可 以 使 用 下 面 的 快 捷 键 :<br />

跳 到 光 标 下 tag 所 定 义 的 位 置 , 用 鼠 标 双 击 此 tag 功 能 也 一 样<br />

o 在 一 个 新 打 开 的 窗 口 中 显 示 光 标 下 tag<br />

显 示 光 标 下 tag 的 原 型 定 义<br />

u 更 新 taglist 窗 口 中 的 tag<br />

s 更 改 排 序 方 式 , 在 按 名 字 排 序 和 按 出 现 顺 序 排 序 间 切 换<br />

x taglist 窗 口 放 大 和 缩 小 , 方 便 查 看 较 长 的 tag<br />

+ 打 开 一 个 折 叠 , 同 zo<br />

- 将 tag 折 叠 起 来 , 同 zc<br />

* 打 开 所 有 的 折 叠 , 同 zR<br />

= 将 所 有 tag 折 叠 起 来 , 同 zM<br />

[[ 跳 到 前 一 个 文 件<br />

]] 跳 到 后 一 个 文 件<br />

q 关 闭 taglist 窗 口<br />

显 示 帮 助<br />

可 以 用 ":TlistOpen" 打 开 taglist 窗 口 , 用 ":TlistClose" 关 闭 taglist 窗 口 。 或 者 使<br />

用 ":TlistToggle" 在 打 开 和 关 闭 间 切 换 。 在 我 的 vimrc 中 定 义 了 下 面 的 映 射 , 使 用 键 就 可 以<br />

打 开 / 关 闭 taglist 窗 口 :<br />

map :TlistToogle<br />

Taglist 插 件 还 提 供 了 很 多 命 令 , 你 甚 至 可 以 用 这 些 命 令 创 建 一 个 taglist 的 会 话 , 然 后 在 下 次 进<br />

入 vim 时 加 载 此 会 话 。<br />

Taglist 插 件 还 可 以 与 winmanager 插 件 协 同 使 用 , 这 将 在 下 篇 文 章 中 介 绍 。<br />

[ 参 考 文 档 ]<br />

• vim 手 册<br />

23


使 用 taglist 插 件<br />

• vim 中 文 手 册<br />

• taglist 手 册<br />


第 8 章 文 件 浏 览 和 缓 冲 区 浏 览<br />


文 件 浏 览 和 缓 冲 区 浏 览<br />

- 返 回 上 级 目 录<br />

c 切 换 vim 的 当 前 工 作 目 录 为 正 在 浏 览 的 目 录<br />

d 创 建 目 录<br />

D 删 除 文 件 或 目 录<br />

i 切 换 显 示 方 式<br />

R 改 名 文 件 或 目 录<br />

s 选 择 排 序 方 式<br />

x 定 制 浏 览 方 式 , 使 用 你 指 定 的 程 序 打 开 该 文 件<br />

其 它 常 用 键 , 诸 如 使 用 书 签 、 隐 藏 符 合 条 件 的 文 件 等 , 请 参 阅 netrw 帮 助 页 。<br />

上 面 我 们 用 ":e ~/src/vim70/src/" 的 方 式 打 开 netrw, 我 们 还 可 以 使 用 ":Explore" 等 Ex 命 令 来 打<br />

开 文 件 浏 览 器 。 我 的 vimrc 中 这 样 配 置 :<br />

""""""""""""""""""""""""""""""<br />

" netrw setting<br />

""""""""""""""""""""""""""""""<br />

let g:netrw_winsize = 30<br />

nmap fe :Sexplore!<br />

这 样 , 在 我 输 入 ",fe" 时 , 就 会 打 开 一 个 垂 直 分 隔 的 窗 口 浏 览 当 前 文 件 所 在 的 目 录 , 窗 口 的 宽 度<br />

为 30。<br />

浏 览 本 地 文 件 只 是 netrw 插 件 的 一 项 小 功 能 ,netrw 插 件 最 主 要 的 功 能 是 支 持 远 程 文 件 读 写 。 利 用<br />

该 插 件 , 你 可 以 通 过 ftp,ssh,http 等 多 种 协 议 来 编 辑 远 程 文 件 , 也 可 以 浏 览 远 程 机 器 的 目 录 。<br />

在 软 件 开 发 过 程 中 不 常 使 用 此 功 能 , 本 文 中 不 再 介 绍 。 参 阅 netrw 手 册 页 获 取 更 多 信 息 。<br />

[ 缓 冲 区 浏 览 ]<br />

在 开 发 过 程 中 , 经 常 会 打 开 很 多 缓 冲 区 , 尤 其 是 使 用 tag 文 件 在 不 同 函 数 间 跳 转 时 , 会 不 知 不 觉<br />

打 开 很 多 文 件 。 要 知 道 自 己 当 前 打 开 了 哪 些 缓 冲 区 , 可 以 使 用 vim 的 ":ls"Ex 命 令 查 看 。<br />

开 发 过 程 中 , 又 经 常 需 要 在 不 同 文 件 间 跳 转 。 我 习 惯 于 使 用 "CTRL-^" 来 切 换 文 件 , 这 就 需 要 知 道<br />

文 件 所 在 的 缓 冲 区 编 号 。 每 次 都 使 用 ":ls" 来 找 缓 冲 区 编 号 很 麻 烦 , 所 以 我 使 用 BufExplorer 插 件<br />

来 显 示 缓 冲 区 的 信 息 。<br />

BufExplorer 插 件 在 此 处 下 载 :http://vim.sourceforge.net/scripts/script.php?<br />

script_id=42<br />

下 载 后 , 把 该 文 件 在 ~/.vim/ 目 录 中 解 压 缩 , 这 会 在 你 的 ~/.vim/plugin 和 ~/.vim/doc 目 录 中 各 放<br />

入 一 个 文 件 :<br />

plugin/ bufexplorer.vim - bufexplorer 插 件<br />

doc/ bufexplorer.txt - bufexplorer 帮 助 文 件<br />

注 :windows 用 户 需 要 把 这 个 插 件 解 压 在 你 的 $vim/vimfiles 或 $HOME/vimfiles 目 录 。<br />

使 用 下 面 的 命 令 生 成 帮 助 标 签 ( 下 面 的 操 作 在 vim 中 进 行 ):<br />

:helptags ~/.vim/doc<br />

然 后 , 就 可 以 使 用 ":help bufexplorer" 命 令 查 看 BufExplorer 的 帮 助 文 件 了 。<br />

BufExplorer 功 能 比 较 简 单 , 这 里 就 不 做 介 绍 了 。 我 的 vimrc 里 这 样 设 置 BufExplorer 插 件 :<br />

26


文 件 浏 览 和 缓 冲 区 浏 览<br />

""""""""""""""""""""""""""""""<br />

" BufExplorer<br />

""""""""""""""""""""""""""""""<br />

let g:bufExplorerDefaultHelp=0 " Do not show default help.<br />

let g:bufExplorerShowRelativePath=1 " Show relative paths.<br />

let g:bufExplorerSortBy='mru' " Sort by most recently used.<br />

let g:bufExplorerSplitRight=0 " Split left.<br />

let g:bufExplorerSplitVertical=1 " Split vertically.<br />

let g:bufExplorerSplitVertSize = 30 " Split width<br />

let g:bufExplorerUseCurrentWindow=1 " Open in new window.<br />

autocmd BufWinEnter \[Buf\ List\] setl nonumber<br />

BufExplorer 已 经 映 射 了 几 个 键 绑 定 , 例 如 , 使 用 ",bv" 就 可 以 打 开 一 个 垂 直 分 割 窗 口 显 示 当 前 的<br />

缓 冲 区 。<br />

有 一 个 称 为 minibufexpl.vim 的 插 件 , 也 可 以 把 缓 冲 区 列 表 显 示 出 来 , 这 个 插 件 在 此 处 下<br />

载 :http://vim.sourceforge.net/scripts/script.php?script_id=159<br />

使 用 这 个 插 件 后 , 屏 幕 截 图 看 起 来 是 这 样 , 最 上 面 一 个 窗 口 就 是 minibuffer 窗 口 , 列 出 了 当 前 打<br />

开 的 缓 冲 区 :<br />

点 击 查 看 大 图<br />

这 个 插 件 没 有 帮 助 文 件 , 参 考 下 载 页 上 的 说 明 , 以 及 脚 本 代 码 来 进 行 配 置 。<br />

[winmanager 插 件 ]<br />

winmanager 插 件 可 以 把 上 面 介 绍 的 Explorer 插 件 (vim 7.0 以 前 的 文 件 浏 览 插 件 ) 和 BufExplorer 插<br />

件 集 成 在 一 起 , 我 们 上 篇 文 章 中 介 绍 过 的 taglist 插 件 也 提 供 了 对 winmanager 插 件 的 支 持 。<br />

Winmanager 插 件 在 这 里 下 载 :http://vim.sourceforge.net/scripts/script.php?script_id=95<br />

下 载 后 , 把 该 文 件 在 ~/.vim/ 目 录 中 解 压 缩 , 这 会 把 winmanager 插 件 解 压 到 ~/.vim/plugin 和<br />

~/.vim/doc 目 录 中 :<br />

27


文 件 浏 览 和 缓 冲 区 浏 览<br />

plugin/winmanager.vim – winmanager 插 件<br />

plugin/winfileexplorer.vim - 改 良 的 Explorer 插 件<br />

plugin/wintagexplorer.vim – winmanager 提 供 的 tag 插 件 , 用 处 不 大<br />

doc/winmanager.txt – 帮 助 文 件<br />

仍 然 用 ":helptags ~/.vim/doc" 命 令 来 生 成 帮 助 标 签 , 然 后 就 可 以 使 用 ":help winmanager" 来 查<br />

看 帮 助 了 。<br />

使 用 winmanager 插 件 可 以 控 制 各 插 件 在 vim 窗 口 中 的 布 局 显 示 。 我 的 vimrc 中 这 样 设 置 :<br />

""""""""""""""""""""""""""""""<br />

" winManager setting<br />

""""""""""""""""""""""""""""""<br />

let g:winManagerWindowLayout = "BufExplorer,FileExplorer|TagList"<br />

let g:winManagerWidth = 30<br />

let g:defaultExplorer = 0<br />

nmap :FirstExplorerWindow<br />

nmap :BottomExplorerWindow<br />

nmap wm :WMToggle<br />

g:winManagerWindowLayout 变 量 的 值 定 义 winmanager 的 窗 口 布 局 , 使 用 上 面 的 设 置 , 我 们 的 窗 口<br />

布 局 看 起 来 是 这 样 的 :<br />

点 击 查 看 大 图<br />

左 边 有 两 个 窗 口 , 上 面 的 是 BufExplorer 窗 口 , 下 面 是 taglist 窗 口 。FileExplorer 窗 口 和<br />

BufExplorer 共 用 一 个 窗 口 , 在 BufExplorer 窗 口 中 使 用 "CTRL-N" 可 以 切 换 到 FileExplorer 窗 口 ,<br />

再 使 用 一 次 则 又 切 换 回 BufExplorer 窗 口 。 也 就 是 说 , 在 变 量 g:winManagerWindowLayout 中 , 使<br />

用 "," 分 隔 的 插 件 , 在 同 一 个 窗 口 中 显 示 , 使 用 "CTRL-N" 在 不 同 插 件 间 切 换 ; 使 用 "|" 分 隔 的 插<br />

件 , 则 在 另 外 一 个 窗 口 中 显 示 。<br />

在 屏 幕 右 边 的 窗 口 则 是 主 编 辑 区 。<br />

在 上 面 的 vimrc 设 置 中 , 还 定 义 了 三 个 键 映 射 , 分 别 用 于 跳 到 左 上 窗 口 、 左 下 窗 口 , 以 及 显 示 / 关<br />

闭 winmanager 窗 口 。<br />

28


文 件 浏 览 和 缓 冲 区 浏 览<br />

注 : 安 装 后 , 如 果 未 设 置 g:winManagerWindowLayout 变 量 ,winmanager 插 件 需 要 与 BufExplorer<br />

插 件 一 起 才 能 使 用 。 所 以 需 要 下 载 BufExplorer。<br />

在 http://vim.sourceforge.net/scripts/script.php?script_id=1440 有 一 个 winmanager 插 件 的<br />

修 改 版 本 , 如 果 在 FileExplorer 中 打 开 文 件 时 , 它 会 使 用 与 该 文 件 相 关 联 的 程 序 来 打 开 该 文 件 ,<br />

而 不 是 使 用 vim。 我 没 有 使 用 过 这 个 插 件 , 有 兴 趣 你 可 以 试 试 。<br />

[ 参 考 文 档 ]<br />

• vim 帮 助 文 件<br />

• vim 中 文 手 册<br />


第 9 章 使 用 lookupfile 插 件<br />


使 用 lookupfile 插 件<br />

#!/bin/sh<br />

# generate tag file for lookupfile plugin<br />

echo -e "!_TAG_FILE_SORTED\t2\t/2=foldcase/" > filenametags<br />

find . -not -regex '.*\.\(png\|gif\)' -type f -printf "%f\t%p\t1\n" | \<br />

sort -f >> filenametags<br />

回 想 一 下 我 们 在 " 使 用 标 签 (tag) 文 件 " 一 文 中 介 绍 的 tag 文 件 的 格 式 。 再 对 照 脚 本 命 令 来 看 :<br />

• echo 命 令 用 来 生 成 filenametags 文 件 中 的 "!_TAG_FILE_SORTED" 行 , 表 明 此 tag 文 件 是 经 过 排 序<br />

的 。<br />

• find 命 令 用 来 查 找 所 有 类 型 为 普 通 文 件 , 文 件 后 缀 名 不 是 .png 和 .gif 的 文 件 , 找 到 的 文 件<br />

按 " 文 件 名 \t 文 件 路 径 \t1" 的 格 式 输 出 出 来 。<br />

• sort 命 令 则 把 find 命 令 的 输 出 重 新 排 序 , 然 后 写 入 filenametags 文 件 中<br />

在 ~/src/vim70/ 目 录 下 运 行 该 脚 本 , 会 生 成 一 个 名 为 filenametags 的 文 件 , 包 含 了 vim70 目 录 下<br />

的 所 有 文 件 的 名 字 及 其 所 在 目 录 。<br />

现 在 我 们 需 要 让 lookupfile 插 件 知 道 到 哪 去 找 文 件 名 tag 文 件 。 我 们 假 定 vim 当 前 工 作 目 录 为 ~/<br />

src/vim70/, 执 行 下 面 的 命 令 :<br />

:let g:LookupFile_TagExpr = '"./filenametags"'<br />

注 : 如 果 不 设 定 g:LookupFile_TagExpr 的 值 , 那 么 lookupfile 插 件 会 以 tags 选 项 定 义 的 文 件 作 为<br />

它 的 tag 文 件 。<br />

现 在 我 们 就 可 以 使 用 lookupfile 来 打 开 文 件 了 , 按 "" 或 输 入 ":LookupFile" 在 当 前 窗 口 上 方<br />

打 开 一 个 lookupfile 小 窗 口 , 开 始 输 入 文 件 名 ( 至 少 4 个 字 符 ), 随 着 你 的 输 入 , 符 合 条 件 的 文<br />

件 就 列 在 下 拉 列 表 中 了 。 文 件 名 可 以 使 用 vim 的 正 则 表 达 式 , 这 大 大 方 便 了 文 件 的 查 找 。 你 可 以<br />

用 "CTRL-N" 和 "CTRL-P"( 或 者 用 上 、 下 光 标 键 ) 来 在 下 拉 列 表 中 选 择 你 所 需 的 文 件 。 选 中 文 件<br />

后 , 按 回 车 , 就 可 以 在 之 前 的 窗 口 中 打 开 此 文 件 。<br />

下 图 是 使 用 lookupfile 插 件 查 找 文 件 的 一 个 例 子 :<br />

31


使 用 lookupfile 插 件<br />

点 击 查 看 大 图<br />

在 屏 幕 最 上 方 的 窗 口 就 是 lookupfile 窗 口 , 在 这 个 窗 口 中 输 入 "gui.*x11" 几 个 字 符 , 查 找 到 6 个<br />

匹 配 文 件 , 使 用 CTRL-N 选 中 gui_x11.c 文 件 , 然 后 按 回 车 , 就 会 在 前 一 个 vim 窗 口 中 打 开 src/<br />

gui_x11.c 文 件 ,lookupfile 窗 口 也 自 动 关 闭 了 。 是 不 是 非 常 方 便 ?!<br />

[ 缓 冲 区 查 找 ]<br />

在 开 发 过 程 中 , 我 经 常 会 同 时 打 开 数 十 甚 至 上 百 个 文 件 。 即 使 是 使 用 BufExplorer 插 件 , 想 在 这<br />

么 多 buffer 中 切 换 到 自 己 所 要 的 文 件 , 也 不 是 件 容 易 的 事 。<br />

Lookupfile 插 件 提 供 了 一 个 按 缓 冲 区 名 字 查 找 缓 冲 区 的 方 式 , 只 要 输 入 缓 冲 区 的 名 字 ( 可 以 是 正<br />

则 表 达 式 ), 它 就 可 以 把 匹 配 的 缓 冲 区 列 在 下 拉 列 表 中 , 同 时 还 会 列 出 该 缓 冲 区 内 文 件 的 路 径 ,<br />

当 你 的 buffer 中 有 多 个 同 名 文 件 时 , 这 可 以 帮 你 迅 速 找 到 你 想 要 的 文 件 。<br />

使 用 ":LUBufs" 命 令 开 始 在 缓 冲 区 中 查 找 , 输 入 缓 冲 区 的 名 字 , 在 你 输 入 的 过 程 中 , 符 合 条 件 的<br />

缓 冲 区 就 显 示 在 下 拉 列 表 中 了 , 选 中 所 需 缓 冲 区 后 , 按 回 车 , 就 会 切 换 你 所 选 的 缓 冲 区 。 下 图 是<br />

一 个 示 例 :<br />

[ 浏 览 目 录 ]<br />

点 击 查 看 大 图<br />

Lookupfile 插 件 还 提 供 了 目 录 浏 览 的 功 能 , 使 用 ":LUWalk" 打 开 lookupfile 窗 口 后 , 就 可 以 输 入<br />

目 录 ,lookupfile 会 在 下 拉 列 表 中 列 出 这 个 目 录 中 的 所 有 子 目 录 及 文 件 供 选 择 , 如 果 选 择 了 目<br />

录 , 就 会 显 示 这 个 目 录 下 的 子 目 录 和 文 件 ; 如 果 选 择 了 文 件 , 就 在 vim 中 打 开 这 个 文 件 。<br />

下 图 是 使 用 LUWalk 的 一 个 抓 图 :<br />

32


使 用 lookupfile 插 件<br />

点 击 查 看 大 图<br />

Lookupfile 插 件 还 提 供 了 LUPath 和 LUArgs 两 个 功 能 , 这 两 个 功 能 我 用 的 不 多 , 就 不 在 这 里 介 绍<br />

了 。 感 兴 趣 的 朋 友 读 一 下 lookupfile 的 手 册 。<br />

[Lookupfile 配 置 ]<br />

Lookupfile 插 件 提 供 了 一 些 配 置 选 项 , 通 过 调 整 这 些 配 置 选 项 , 使 它 更 符 合 你 的 工 作 习 惯 。 下 面<br />

是 我 的 vimrc 中 关 于 lookupfile 的 设 置 , 供 参 考 :<br />

""""""""""""""""""""""""""""""<br />

" lookupfile setting<br />

""""""""""""""""""""""""""""""<br />

let g:LookupFile_MinPatLength = 2 " 最 少 输 入 2 个 字 符 才 开 始 查 找<br />

let g:LookupFile_PreserveLastPattern = 0 " 不 保 存 上 次 查 找 的 字 符 串<br />

let g:LookupFile_PreservePatternHistory = 1 " 保 存 查 找 历 史<br />

let g:LookupFile_AlwaysAcceptFirst = 1 " 回 车 打 开 第 一 个 匹 配 项 目<br />

let g:LookupFile_AllowNewFiles = 0 " 不 允 许 创 建 不 存 在 的 文 件<br />

if filereadable("./filenametags") " 设 置 tag 文 件 的 名 字<br />

let g:LookupFile_TagExpr = '"./filenametags"'<br />

endif<br />

nmap lk LookupFile " 映 射 LookupFile 为 ,lk<br />

nmap ll :LUBufs " 映 射 LUBufs 为 ,ll<br />

nmap lw :LUWalk " 映 射 LUWalk 为 ,lw<br />

有 了 上 面 的 定 义 , 当 我 输 入 ",lk" 时 , 就 会 在 tag 文 件 中 查 找 指 定 的 文 件 名 ; 当 输 入 ",ll" 时 , 就<br />

会 在 当 前 已 打 开 的 buffer 中 查 找 指 定 名 字 的 buffer; 当 输 入 ",lw" 时 , 就 会 在 指 定 目 录 结 构 中 查<br />

找 。<br />

另 外 , 我 还 在 项 目 相 关 的 配 置 文 件 vim70sx.vim( 参 考 保 存 项 目 相 关 配 置 ) 中 加 入 了 lookupfile<br />

所 使 用 的 tag 文 件 的 信 息 :<br />

" lookup file tag file<br />

let g:LookupFile_TagExpr = '"filenametags"'<br />

33


使 用 lookupfile 插 件<br />

这 样 , 在 恢 复 前 次 会 话 时 就 给 lookupfile 插 件 定 义 了 tag 文 件 。<br />

在 用 lookupfile 插 件 查 找 文 件 时 , 是 区 分 文 件 名 的 大 小 写 的 , 如 果 想 进 行 忽 略 大 小 写 的 匹 配 , 可<br />

以 使 用 vim 忽 略 大 小 写 的 正 则 表 达 式 , 即 在 文 件 名 的 前 面 加 上 "\c" 字 符 。 举 个 例 子 , 当 你 输<br />

入 "\cab.c" 时 , 你 可 能 会 得 到 "ab.c"、"Ab.c"、"AB.c"...<br />

注 : 如 果 想 加 快 lookupfile 忽 略 大 小 写 查 找 的 速 度 , 在 生 成 文 件 名 tag 文 件 时 , 使 用 混 合 大 小 写<br />

排 序 。 这 在 文 章 使 用 标 签 (tag) 文 件 有 所 提 及 。<br />

通 常 情 况 下 我 都 进 行 忽 略 大 小 写 的 查 找 , 每 次 都 输 入 "\c" 很 麻 烦 。 没 关 系 ,lookupfile 插 件 提 供<br />

了 扩 展 功 能 , 把 下 面 这 段 代 码 加 入 你 的 vimrc 中 , 就 可 以 每 次 在 查 找 文 件 时 都 忽 略 大 小 写 查 找<br />

了 :<br />

" lookup file with ignore case<br />

function! LookupFile_IgnoreCaseFunc(pattern)<br />

let _tags = &tags<br />

try<br />

let &tags = eval(g:LookupFile_TagExpr)<br />

let newpattern = '\c' . a:pattern<br />

let tags = taglist(newpattern)<br />

catch<br />

echohl ErrorMsg | echo "Exception: " . v:exception | echohl NONE<br />

return ""<br />

finally<br />

let &tags = _tags<br />

endtry<br />

" Show the matches for what is typed so far.<br />

let files = map(tags, 'v:val["filename"]')<br />

return files<br />

endfunction<br />

let g:LookupFile_LookupFunc = 'LookupFile_IgnoreCaseFunc'<br />

有 时 在 LUBufs 时 也 需 要 忽 略 缓 冲 区 名 字 的 大 小 写 , 我 是 通 过 直 接 修 改 lookupfile 插 件 的 方 法 , 在<br />

LUBufs 查 找 的 字 符 串 前 都 加 上 "\c", 使 之 忽 略 大 小 写 。 如 果 你 不 想 这 样 , 可 以 每 次 在 缓 冲 区 名 字<br />

前 手 动 加 上 "\c"。<br />

本 文 关 于 Lookupfile 插 件 就 介 绍 这 么 多 , 请 阅 读 手 册 获 取 更 多 的 信 息 。<br />

这 是 一 个 非 常 好 的 插 件 , 希 望 能 为 更 多 人 喜 爱 !<br />

也 欢 迎 大 家 多 交 流 使 用 中 的 心 得 和 疑 问 。<br />

[ 参 考 文 档 ]<br />

• vim 手 册<br />

• vim 中 文 手 册<br />


第 10 章 开 启 文 件 类 型 检 测<br />


开 启 文 件 类 型 检 测<br />

/* vim: ft=c */<br />

这 句 话 使 用 "/* */" 注 释 起 来 了 , 因 此 不 会 影 响 编 译 。"ft" 是 "filetype" 的 缩 写 ,vim 中 很 多 命<br />

令 、 选 项 都 有 缩 写 形 式 , 以 方 便 使 用 。 注 意 "/*" 与 "vim:" 间 的 空 格 。 在 "*/" 与 "ft=c" 间 , 也 需 要<br />

有 至 少 一 个 空 格 , 这 是 模 式 行 格 式 的 要 求 , 更 多 信 息 参 阅 ":help modeline"。<br />

检 测 出 文 件 的 类 型 有 什 么 作 用 呢 ? 我 们 知 道 , 不 同 类 型 的 文 件 具 有 不 同 的 格 式 ,vim 通 过 对 文 件<br />

类 型 的 识 别 , 可 以 为 不 同 类 型 的 文 件 , 设 置 不 同 的 选 项 值 、 定 义 不 同 键 绑 定 等 。 例 如 , 对 于 c 类<br />

型 的 文 件 , 它 就 和 bash 脚 本 有 不 同 的 注 释 格 式 、 不 同 的 缩 进 格 式 、 不 同 的 关 键 字 等 。vim 在 设 置<br />

文 件 类 型 后 , 会 触 发 FileType 事 件 , 执 行 FileType 相 关 的 自 动 命 令 , 对 不 同 类 型 的 文 件 区 别 对<br />

待 。<br />

上 面 提 到 的 "filetype plugin on", 允 许 vim 加 载 文 件 类 型 插 件 。 当 这 个 选 项 打 开 时 ,vim 会 根 据<br />

检 测 到 的 文 件 类 型 , 在 runtimepath 中 搜 索 该 类 型 的 所 有 插 件 , 并 执 行 它 们 。<br />

"filetype plugin on" 命 令 , 实 际 上 是 执 行 $vimRUNTIME/ftplugin.vim 脚 本 , 有 兴 趣 可 以 读 一 下<br />

这 个 脚 本 。 这 个 脚 本 中 会 设 置 自 动 命 令 , 在 runtimepath 中 搜 索 文 件 类 型 插 件 。<br />

runtimepath 的 定 义 在 不 同 的 系 统 上 不 一 样 , 对 UNIX 系 统 来 说 , 这 些 路 径 包 括 :<br />

$HOME/.vim、$vim/vimfiles、$vimRUNTIME、$vim/vimfiles/after、$HOME/.vim/after。<br />

举 一 个 例 子 , 当 我 们 对 一 个 c 类 型 的 文 件 打 开 "filetype plugin on" 时 , 它 会 在 上 述 这 几 个 目 录<br />

的 ftplugin 子 目 录 中 搜 索 所 有 名 为 c.vim、c_*.vim, 和 c/*.vim 的 脚 本 , 并 执 行 它 们 。 在 搜 索<br />

时 , 它 按 目 录 在 runtimepath 中 出 现 的 顺 序 进 行 搜 索 。 缺 省 的 , 它 会 执 行 $vimRUNTIME/ftplugin/<br />

c.vim, 在 这 个 脚 本 里 , 会 设 置 c 语 言 的 注 释 格 式 、 智 能 补 全 函 数 等 等 。<br />

"filetype indent on" 允 许 vim 为 不 同 类 型 的 文 件 定 义 不 同 的 缩 进 格 式 。 这 条 命 令 也 是 通 过 一<br />

个 脚 本 来 完 成 加 载 :$vimRUNTIME/indent.vim。 和 "filetype plugin on" 类 似 , 它 也 通 过 设 置<br />

自 动 命 令 , 在 runtimepath 的 indent 子 目 录 中 搜 索 缩 进 设 置 。 对 c 类 型 的 文 件 来 说 , 它 只 是 打 开 了<br />

cindent 选 项 。<br />

我 们 了 解 了 文 件 类 型 检 测 的 用 途 及 它 是 如 何 工 作 的 之 后 , 就 可 以 根 据 自 己 的 需 要 , 来 对 特 定 的 文<br />

件 类 型 进 行 特 殊 设 置 。<br />

例 如 , 我 们 在 上 篇 文 章 中 介 绍 过 lookupfile 插 件 , 在 它 打 开 一 个 缓 冲 区 时 , 会 把 缓 冲 区 的<br />

filetype 设 置 为 lookupfile, 我 们 可 以 利 用 这 一 点 , 在 这 个 缓 冲 区 里 进 行 一 些 特 殊 的 配 置 。 例<br />

如 , 我 们 创 建 一 个 名 为 lookupfile.vim 的 文 件 , 其 内 容 为 :<br />

" close lookupfile window by two <br />

nnoremap q<br />

inoremap q<br />

它 定 义 了 两 个 局 部 于 缓 冲 区 的 键 绑 定 , 无 论 在 normal 模 式 还 是 插 入 模 式 , 只 要 连 按 两 次 ESC, 就<br />

关 闭 当 前 缓 冲 区 。<br />

把 这 个 文 件 保 存 到 你 的 runtimepath 所 指 向 任 一 目 录 的 ftplugin 子 目 录 中 ( 一 般 是 放 在 ~/.vim/<br />

ftplugin 目 录 中 )。 你 在 下 次 打 开 lookupfile 窗 口 时 , 试 试 连 按 两 次 ESC, 是 不 是 lookupfile 窗<br />

口 就 关 闭 了 ? 这 样 设 置 , 非 常 适 合 vim 中 按 ESC 取 消 命 令 的 习 惯 , 效 率 也 高 。<br />

如 果 你 对 vim 缺 省 文 件 类 型 插 件 的 设 置 不 太 满 意 , 那 么 可 以 把 这 个 全 局 插 件 拷 贝 到 $HOME/.vim/<br />

plugin 目 录 中 , 然 后 更 改 其 中 的 设 置 。 你 可 以 留 意 一 下 vim 缺 省 的 文 件 类 型 插 件 , 它 们 的 头 部 都<br />

有 这 样 的 代 码 :<br />

36


开 启 文 件 类 型 检 测<br />

" Only do this when not done yet for this buffer<br />

if exists("b:did_ftplugin")<br />

finish<br />

endif<br />

这 类 似 于 C 语 言 头 文 件 中 的 "#ifndef XXX | #define XXX" 的 语 句 , 可 以 防 止 该 插 件 被 执 行 多 次 。<br />

因 此 , 把 这 个 插 件 拷 贝 到 $HOME/.vim/plugin 中 ( 这 个 目 录 在 runtimepath 中 排 在 最 前 面 ), 它 将<br />

先 于 vim 的 缺 省 插 件 被 加 载 ; 而 它 加 载 后 ,vim 的 缺 省 文 件 类 型 插 件 就 不 会 再 被 加 载 了 。 这 就 达 到<br />

了 我 们 修 改 设 置 的 目 的 。<br />

不 过 我 们 通 常 不 用 这 种 方 法 。 如 果 这 样 做 , 一 旦 vim 的 缺 省 插 件 做 了 改 变 , 我 们 也 要 更 新 我 们 改<br />

过 的 插 件 才 行 。 我 们 可 以 在 载 入 全 局 插 件 以 后 否 决 一 些 设 置 。 在 Unix 上 , 我 们 可 以 把 我 们 的 设<br />

置 放 在 ~/.vim/after/ftplugin/ 目 录 中 , 这 个 目 录 中 的 脚 本 会 在 vim 的 缺 省 脚 本 后 执 行 。 这 样 就<br />

可 以 修 改 配 置 , 或 增 加 我 们 自 己 的 定 义 。<br />

举 个 例 子 , 在 多 人 一 起 开 发 项 目 时 , 为 了 使 代 码 风 格 尽 量 保 持 一 致 , 一 般 不 允 许 在 代 码 使 用 TAB<br />

符 , 而 以 4 个 空 格 代 之 。 我 们 可 以 编 辑 一 个 文 件 , 包 含 下 面 的 内 容 :<br />

set shiftwidth=4<br />

set expandtab<br />

把 这 个 文 件 保 存 为 ~/.vim/after/ftplugin/c.vim。 这 样 , 每 次 在 编 辑 c 文 件 时 , 它 的 自 动 缩 进 为<br />

4 个 空 格 ; 当 你 在 插 入 模 式 下 使 用 CTRL-D、CTRL-T 缩 进 时 , 它 也 会 调 整 4 个 空 格 的 缩 进 ; 当 你 按<br />

TAB 键 时 , 它 将 会 插 入 8 个 空 格 ...... 如 果 你 想 上 面 的 设 置 对 h 文 件 也 生 效 的 话 , 需 要 把 它 另 存 一<br />

份 :~/.vim/after/ftplugin/cpp.vim, 因 为 h 文 件 的 文 件 类 型 被 设 为 cpp。<br />

我 们 知 道 ,vim 在 设 置 文 件 类 型 时 , 会 触 发 FileType 自 动 命 令 , 因 此 , 上 面 的 例 子 可 以 用 下 面 的<br />

自 动 命 令 来 实 现 :<br />

autocmd FileType c,cpp set shiftwidth=4 | set expandtab<br />

把 这 个 命 令 放 在 你 的 vimrc 中 , 可 以 起 到 和 上 例 同 样 的 效 果 。<br />

vim 的 语 法 高 亮 功 能 , 也 要 用 到 文 件 类 型 , 来 对 不 同 的 关 键 字 进 行 染 色 。 这 我 们 将 在 下 一 篇 文 章<br />

中 介 绍 。<br />

[ 参 考 文 档 ]<br />

• vim 手 册<br />

• vim 中 文 手 册<br />


第 11 章 乱 花 渐 欲 迷 人 眼 - 语 法 高 亮<br />


乱 花 渐 欲 迷 人 眼 - 语 法 高 亮<br />

选 择 了 喜 欢 的 colorscheme 后 , 在 vimrc 中 加 入 一 条 colorscheme 命 令 , 以 后 vim 就 会 使 用 你 选 定 的<br />

配 色 方 案 了 。<br />

如 果 对 配 色 方 案 某 些 颜 色 不 太 满 意 , 那 么 你 可 以 在 原 来 配 色 方 案 的 基 础 上 , 修 改 其 中 的 一 些 定<br />

义 。 例 如 , 我 把 desert.vim 拷 到 .vim/color 目 录 , 重 命 名 为 darkblue_my.vim。 然 后 做 如 下 更 改<br />

( 只 列 出 改 变 的 内 容 ):<br />

let colors_name = "darkblue_my"<br />

hi Normal guifg=#c0c0c0 guibg=#294d4a ctermfg=gray ctermbg=black<br />

......<br />

"Omni menu colors<br />

hi Pmenu guibg=#444444<br />

hi PmenuSel ctermfg=7 ctermbg=4 guibg=#555555 guifg=#ffffff<br />

" Matched brackets<br />

hi MatchParen ctermfg=7 ctermbg=4<br />

首 先 改 变 colors_name,vim 在 某 此 情 况 会 根 据 这 个 名 字 重 新 载 入 color scheme。<br />

接 下 来 我 重 新 设 置 了 GUI 的 背 景 色 , 在 前 面 的 抓 图 中 大 家 看 到 过 这 个 颜 色 。<br />

接 下 来 的 Pmenu 和 PmenuSel 用 来 设 置 vim 下 拉 菜 单 的 颜 色 , 我 们 在 使 用 lookupfile 插 件 中 看 到 过 下<br />

拉 菜 单 。<br />

vim 7 中 , 当 光 标 移 到 括 号 上 时 ,vim 会 高 亮 与 之 匹 配 的 括 号 , 所 使 用 的 颜 色 就 是 MatchParen, 我<br />

在 这 里 也 更 改 这 个 颜 色 。<br />

Pmenu、PmenuSel, 以 及 MatchParen, 都 是 vim 定 义 的 缺 省 高 亮 组 的 名 字 , 你 可 以 用 ":help<br />

highlight-groups" 命 令 查 看 有 这 些 高 亮 组 及 其 含 义 。<br />

如 果 你 打 算 在 终 端 及 GUI 界 面 中 使 用 不 同 的 colorscheme, 可 以 这 样 设 :<br />

" color scheme<br />

if has("gui_running")<br />

colorscheme darkblue_my<br />

else<br />

colorscheme desert_my<br />

endif " has<br />

这 里 的 darkblue_my 和 desert_my 都 是 我 自 已 改 过 的 colorscheme。<br />

vim 还 提 供 了 一 个 脚 本 , 可 以 把 你 的 文 件 按 当 前 的 颜 色 定 义 转 化 成 HTML/XML 文 件 , 试<br />

试 ":TOhtml" 命 令 吧 , 更 多 信 息 请 ":help 2html.vim"。<br />

记 得 Source Insight 中 有 一 个 功 能 , 按 SHIFT+F8 可 以 把 光 标 下 的 词 高 亮 出 来 , 在 看 代 码 时 非 常 有<br />

用 。vim 下 也 有 一 个 插 件 可 以 完 成 此 功 能 , 而 且 比 Source Insight 的 这 个 功 能 强 大 多 了 。<br />

这 个 插 件 由 Yuheng Xie 所 写 , 对 这 个 插 件 有 什 么 疑 问 , 可 以 水 木 社 区 的 vim 版 找 到 他 (http://<br />

www.newsmth.net/bbsdoc.php?board=vim)。 在 这 里 下 载 此 插 件 。<br />

把 此 插 件 直 接 拷 贝 到 你 的 .vim/plugin 目 录 就 行 了 。<br />

我 在 vimrc 中 这 样 设 置 :<br />

""""""""""""""""""""""""""""""<br />

39


乱 花 渐 欲 迷 人 眼 - 语 法 高 亮<br />

" mark setting<br />

""""""""""""""""""""""""""""""<br />

nmap hl MarkSet<br />

vmap hl MarkSet<br />

nmap hh MarkClear<br />

vmap hh MarkClear<br />

nmap hr MarkRegex<br />

vmap hr MarkRegex<br />

这 样 , 当 我 输 入 ",hl" 时 , 就 会 把 光 标 下 的 单 词 高 亮 , 在 此 单 词 上 按 ",hh" 会 清 除 该 单 词 的 高 亮 。<br />

如 果 在 高 亮 单 词 外 输 入 ",hh", 会 清 除 所 有 的 高 亮 。<br />

你 也 可 以 使 用 virsual 模 式 选 中 一 段 文 本 , 然 后 按 ",hl", 会 高 亮 你 所 选 中 的 文 本 ; 或 者 你 可 以<br />

用 ",hr" 来 输 入 一 个 正 则 表 达 式 , 这 会 高 亮 所 有 符 合 这 个 正 则 表 达 式 的 文 本 。<br />

你 可 以 在 高 亮 文 本 上 使 用 ",#" 或 ",*" 来 上 下 搜 索 高 亮 文 本 。 在 使 用 了 ",#" 或 ",*" 后 , 就 可 以 直 接<br />

输 入 "#" 或 "*" 来 继 续 查 找 该 高 亮 文 本 , 直 到 你 又 用 "#" 或 "*" 查 找 了 其 它 文 本 。<br />

如 果 你 在 启 动 vim 后 重 新 执 行 了 colorscheme 命 令 , 或 者 载 入 了 会 话 文 件 , 那 么 mark 插 件 的 颜 色 就<br />

会 被 清 掉 , 解 决 的 办 法 是 重 新 source 一 下 mark 插 件 。 或 者 像 我 一 样 , 把 mark 插 件 定 义 的<br />

highlight 组 加 入 到 你 自 己 的 colorscheme 文 件 中 。 例 如 , 把 下 面 的 语 句 加 到 desert_my.vim 及<br />

darkblue_my.vim 中 :<br />

" For mark plugin<br />

hi MarkWord1 ctermbg=Cyan ctermfg=Black guibg=#8CCBEA guifg=Black<br />

hi MarkWord2 ctermbg=Green ctermfg=Black guibg=#A4E57E guifg=Black<br />

hi MarkWord3 ctermbg=Yellow ctermfg=Black guibg=#FFDB72 guifg=Black<br />

hi MarkWord4 ctermbg=Red ctermfg=Black guibg=#FF7272 guifg=Black<br />

hi MarkWord5 ctermbg=Magenta ctermfg=Black guibg=#FFB3FF guifg=Black<br />

hi MarkWord6 ctermbg=Blue ctermfg=Black guibg=#9999FF guifg=Black<br />

不 知 道 为 什 么 , 我 的 vim 7.0 在 切 换 到 其 它 缓 冲 区 然 后 再 切 换 回 来 时 , 原 来 被 标 记 的 文 本 会 失 去<br />

高 亮 。 而 作 者 说 他 并 不 存 在 此 问 题 。 如 果 你 存 在 类 似 的 问 题 , 可 以 打 上 我 所 加 的 补 丁 :<br />

--- easwy/mark.vim 2006-12-01 13:02:18.000000000 +0800<br />

+++ plugin/mark.vim 2007-03-23 10:22:02.000000000 +0800<br />

@@ -440,6 +440,43 @@<br />

endif<br />

endfunction<br />

+" easwy add<br />

+" return the mark string under the cursor. multi-lines marks not supported<br />

+function! RedoMarkWord()<br />

+ " define variables if they don't exist<br />

+ call s:InitMarkVariables()<br />

+<br />

+ let i = 1<br />

+ while i


乱 花 渐 欲 迷 人 眼 - 语 法 高 亮<br />

+ while j < strlen(quote)<br />

+ if stridx(b:mwWord{i}, quote[j]) < 0<br />

+ let quoted_regexp = quote[j] . b:mwWord{i} . quote[j]<br />

+ break<br />

+ endif<br />

+ let j = j + 1<br />

+ endwhile<br />

+ if j >= strlen(quote)<br />

+ return -1<br />

+ endif<br />

+<br />

+ " highlight the word<br />

+ exe "syntax clear MarkWord" . i<br />

+ exe "syntax match MarkWord" . i . " " . quoted_regexp . " containedin=ALL"<br />

+ endif<br />

+ let i = i + 1<br />

+ endwhile<br />

+endfunction<br />

+<br />

+augroup markword<br />

+ autocmd!<br />

+ autocmd BufWinEnter * call RedoMarkWord()<br />

+augroup END<br />

+" easwy end<br />

+<br />

" Restore previous 'cpo' value<br />

let &cpo = s:save_cpo<br />

用 法 :<br />

1. 保 存 该 patch 到 某 一 目 录 , 例 如 :/tmp/mark.vim.patch<br />

2.cd 到 你 的 .vim 目 录 :cd ~/.vim<br />

3. 运 行 命 令 :cat /tmp/mark.vim.patch | patch -p0<br />

[ 参 考 文 档 ]<br />

• vim 手 册<br />

• vim 中 文 手 册<br />


第 12 章 程 序 员 的 利 器 - cscope<br />


程 序 员 的 利 器 - cscope<br />

find . –type f > cscope.files<br />

cscope -bq<br />

这 条 命 令 把 ~src/vim70 目 录 下 的 所 有 普 通 文 件 都 加 入 了 cscope.files, 这 样 ,cscope 会 解 析 该 目<br />

录 下 的 每 一 个 文 件 。 上 面 的 cscope 命 令 并 没 有 使 用 "-R" 参 数 递 归 查 找 子 目 录 , 因 为 在<br />

cscope.files 中 已 经 包 含 了 子 目 录 中 的 文 件 。<br />

注 意 :find 命 令 输 出 的 文 件 以 相 对 路 径 表 示 , 所 以 cscope.out 的 索 引 也 相 对 于 当 前 路 径 。 如 果 你<br />

要 在 其 它 路 径 中 使 用 当 前 的 cscope.out, 需 要 使 用 下 面 介 绍 的 -P 选 项 。<br />

Cscope 只 在 第 一 次 解 析 时 扫 描 全 部 文 件 , 以 后 再 调 用 cscope, 它 只 扫 描 那 些 改 动 过 的 文 件 , 这 大<br />

大 提 高 了 cscope 生 成 索 引 的 速 度 。<br />

下 表 中 列 出 了 cscope 的 常 用 选 项 :<br />

• -R: 在 生 成 索 引 文 件 时 , 搜 索 子 目 录 树 中 的 代 码<br />

• -b: 只 生 成 索 引 文 件 , 不 进 入 cscope 的 界 面<br />

• -q: 生 成 cscope.in.out 和 cscope.po.out 文 件 , 加 快 cscope 的 索 引 速 度<br />

• -k: 在 生 成 索 引 文 件 时 , 不 搜 索 /usr/include 目 录<br />

• -i: 如 果 保 存 文 件 列 表 的 文 件 名 不 是 cscope.files 时 , 需 要 加 此 选 项 告 诉 cscope 到 哪 儿 去 找 源<br />

文 件 列 表 。 可 以 使 用 "-", 表 示 由 标 准 输 入 获 得 文 件 列 表 。<br />

• -Idir: 在 -I 选 项 指 出 的 目 录 中 查 找 头 文 件<br />

• -u: 扫 描 所 有 文 件 , 重 新 生 成 交 叉 索 引 文 件<br />

• -C: 在 搜 索 时 忽 略 大 小 写<br />

• -Ppath: 在 以 相 对 路 径 表 示 的 文 件 前 加 上 的 path, 这 样 , 你 不 用 切 换 到 你 数 据 库 文 件 所 在 的 目<br />

录 也 可 以 使 用 它 了 。<br />

要 在 vim 中 使 用 cscope 的 功 能 , 需 要 在 编 译 vim 时 选 择 "+cscope"。vim 的 cscope 接 口 先 会 调 用<br />

cscope 的 命 令 行 接 口 , 然 后 分 析 其 输 出 结 果 找 到 匹 配 处 显 示 给 用 户 。<br />

在 vim 中 使 用 cscope 非 常 简 单 , 首 先 调 用 "cscope add" 命 令 添 加 一 个 cscope 数 据 库 , 然 后 就 可 以<br />

调 用 "cscope find" 命 令 进 行 查 找 了 。vim 支 持 8 种 cscope 的 查 询 功 能 , 如 下 :<br />

• s: 查 找 C 语 言 符 号 , 即 查 找 函 数 名 、 宏 、 枚 举 值 等 出 现 的 地 方<br />

• g: 查 找 函 数 、 宏 、 枚 举 等 定 义 的 位 置 , 类 似 ctags 所 提 供 的 功 能<br />

• d: 查 找 本 函 数 调 用 的 函 数<br />

• c: 查 找 调 用 本 函 数 的 函 数<br />

• t: 查 找 指 定 的 字 符 串<br />

• e: 查 找 egrep 模 式 , 相 当 于 egrep 功 能 , 但 查 找 速 度 快 多 了<br />

• f: 查 找 并 打 开 文 件 , 类 似 vim 的 find 功 能<br />

• i: 查 找 包 含 本 文 件 的 文 件<br />

例 如 , 我 们 想 在 vim 7.0 的 源 代 码 中 查 找 调 用 do_cscope() 函 数 的 函 数 , 我 们 可 以 输 入 :":cs<br />

find c do_cscope", 回 车 后 发 现 没 有 找 到 匹 配 的 功 能 , 可 能 并 没 有 函 数 调 用 do_cscope()。 我 们<br />

43


程 序 员 的 利 器 - cscope<br />

再 输 入 ":cs find s do_cscope", 查 找 这 个 C 符 号 出 现 的 位 置 , 现 在 vim 列 出 了 这 个 符 号 出 现 的 所<br />

有 位 置 。<br />

我 们 还 可 以 进 行 字 符 串 查 找 , 它 会 双 引 号 或 单 引 号 括 起 来 的 内 容 中 查 找 。 还 可 以 输 入 一 个 正 则 表<br />

达 式 , 这 类 似 于 egrep 程 序 的 功 能 , 但 它 是 在 交 叉 索 引 数 据 库 中 查 找 , 速 度 要 快 得 多 。<br />

vim 提 供 了 一 些 选 项 可 以 调 整 它 的 cscope 功 能 :<br />

• cscopecscopeprg 选 项 用 于 设 置 cscope 程 序 的 位 置 。<br />

• cscopecscopequickfix 设 定 是 否 使 用 quickfix 窗 口 来 显 示 cscope 的 结 果 , 详 情 请 ":help<br />

cscopequickfix";<br />

• 如 果 你 想 vim 同 时 搜 索 tag 文 件 以 及 cscope 数 据 库 , 设 置 cscopecscopetag 选 项 ;<br />

• cscopecscopetagorder 选 项 决 定 是 先 查 找 tag 文 件 还 是 先 查 找 cscope 数 据 库 。 设 置 为 0 则 先 查 找<br />

cscope 数 据 库 , 设 置 为 1 先 查 找 tag 文 件 。 我 通 常 设 置 为 1, 因 为 在 tag 文 件 中 查 找 到 的 结 果 , 会<br />

把 最 佳 匹 配 列 在 第 一 位 。<br />

vim 的 手 册 中 给 出 了 使 用 cscope 的 建 议 方 法 , 使 用 命 令 ":help cscope-suggestions" 查 看 。<br />

下 面 是 我 的 vimrc 中 关 于 cscope 接 口 的 设 置 :<br />

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""<br />

" cscope setting<br />

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""<br />

if has("cscope")<br />

set csprg=/usr/bin/cscope<br />

set csto=1<br />

set cst<br />

set nocsverb<br />

" add any database in current directory<br />

if filereadable("cscope.out")<br />

cs add cscope.out<br />

endif<br />

set csverb<br />

endif<br />

nmap s :cs find s =expand("")<br />

nmap g :cs find g =expand("")<br />

nmap c :cs find c =expand("")<br />

nmap t :cs find t =expand("")<br />

nmap e :cs find e =expand("")<br />

nmap f :cs find f =expand("")<br />

nmap i :cs find i ^=expand("")$<br />

nmap d :cs find d =expand("")<br />

下 面 的 两 个 链 接 是 cscope 主 页 提 供 的 cscope 使 用 方 法 , 也 可 以 作 为 参 考 :<br />

vim/cscope 指 导 :http://cscope.sourceforge.net/cscope_vim_tutorial.html<br />

在 大 项 目 中 使 用 cscope:http://cscope.sourceforge.net/large_projects.html<br />

在 vim 的 网 站 上 有 很 多 与 cscope 相 关 的 插 件 , 有 兴 趣 可 以 去 看 一 下 。<br />

44


程 序 员 的 利 器 - cscope<br />

我 以 前 写 的 Vim + Cscope/Ctags。<br />

[ 参 考 文 档 ]<br />

• vim 帮 助 文 件<br />

• vim 中 文 手 册<br />

• http://cscope.sourceforge.net/<br />

• http://iamphet.nm.ru/cscope/<br />

• cscope 手 册<br />


第 13 章 剑 不 离 手 - quickfix<br />


剑 不 离 手 - quickfix<br />

{<br />

}<br />

int i;<br />

print("hello world\n");<br />

return 0;<br />

我 们 可 以 为 这 个 程 序 写 个 小 小 的 Makefile 文 件 , 不 过 为 了 演 示 'makeprg' 的 设 置 方 法 , 我 们 并 不<br />

用 Makefile, 而 直 接 设 置 'makeprg' 选 项 , 如 下 :<br />

:set makeprg=gcc\ -Wall\ -ohello\ hello.c<br />

上 面 的 命 令 会 把 hello.c 编 译 为 名 hello 的 可 执 行 文 件 , 并 打 开 了 所 有 的 Warnning。 如 果 编 译 命 令<br />

中 有 空 格 , 需 要 使 用 '\' 对 空 格 进 行 转 义 , 上 面 的 例 子 就 使 用 了 '\' 转 义 空 格 。<br />

我 们 设 置 好 'makeprg' 选 项 后 , 输 入 下 面 的 命 令 就 可 以 编 译 了 :<br />

:make<br />

在 使 用 ":make" 时 ,vim 会 自 动 调 用 'makeprg' 选 项 定 义 的 命 令 进 行 编 译 , 并 把 编 译 输 出 重 定 向 到<br />

一 个 临 时 文 件 中 , 当 编 译 出 现 错 误 时 ,vim 会 从 上 述 临 时 文 件 中 读 出 错 误 信 息 , 根 据 这 些 信 息 形<br />

成 quickfix 列 表 , 并 跳 转 到 第 一 个 错 误 出 现 的 地 方 。<br />

对 于 我 们 上 面 的 程 序 来 说 , 光 标 会 停 在 第 三 行 , 也 就 是 第 一 个 出 错 的 位 置 ,vim 同 时 会 提 示 出 错<br />

信 息 。 如 果 你 没 看 清 出 错 信 息 , 可 以 输 入 ":cc" 命 令 ,vim 会 更 次 显 示 此 信 息 , 或 者 干 脆 使<br />

用 ":cw" 命 令 , 打 开 一 个 quickfix 窗 口 , 把 所 有 的 出 错 信 息 显 示 出 来 , 见 下 图 :<br />

点 击 查 看 大 图<br />

现 在 我 们 知 道 错 在 哪 儿 了 , 修 正 一 下 , 然 后 使 用 ":cn" 命 令 ( 或 者 在 Quickfix List 对 应 行 上 输 入<br />

回 车 ) 跳 到 下 一 个 出 错 的 地 方 , 以 此 类 推 , 直 到 修 正 全 部 错 误 。<br />

好 了 , 千 辛 万 苦 , 我 们 的 hello world 终 于 工 作 了 。 乍 一 看 这 个 例 子 , 似 乎 Quickfix 并 没 有 提 高<br />

什 么 效 率 , 但 如 果 你 的 错 误 出 现 在 多 个 不 同 目 录 的 不 同 文 件 里 , 它 可 以 帮 你 省 很 多 时 间 , 使 你 可<br />

以 集 中 精 力 在 修 正 bug 上 。<br />

47


剑 不 离 手 - quickfix<br />

vim 可 以 同 时 记 住 最 新 的 10 个 错 误 列 表 , 也 就 是 说 你 最 近 10 次 使 用 ":make" 命 令 编 译 所 遇 到 的 错 误<br />

都 保 存 着 , 可 以 使 用 ":colder" 和 ":cnewer" 命 令 , 回 到 旧 的 错 误 列 表 , 或 者 到 更 新 的 错 误 列 表 。<br />

在 quickfix 模 式 里 经 常 用 到 的 命 令 有 :<br />

:cc 显 示 详 细 错 误 信 息 ( :help :cc )<br />

:cp 跳 到 上 一 个 错 误 ( :help :cp )<br />

:cn 跳 到 下 一 个 错 误 ( :help :cn )<br />

:cl 列 出 所 有 错 误 ( :help :cl )<br />

:cw 如 果 有 错 误 列 表 , 则 打 开 quickfix 窗 口 ( :help :cw )<br />

:col 到 前 一 个 旧 的 错 误 列 表 ( :help :col )<br />

:cnew 到 后 一 个 较 新 的 错 误 列 表 ( :help :cnew )<br />

更 多 的 命 令 , 以 及 这 些 命 令 更 详 细 的 解 释 , 请 参 见 手 册 。<br />

对 于 经 常 用 到 的 命 令 , 最 好 提 供 更 方 便 的 使 用 方 法 , 在 我 的 vimrc 中 的 定 义 :<br />

autocmd FileType c,cpp map :w:make<br />

nmap cn :cn<br />

nmap cp :cp<br />

nmap cw :cw 10<br />

现 在 使 用 ","( 先 按 , 再 按 空 格 ) 就 可 以 编 译 , 使 用 ",cp" 和 ",cn" 跳 到 上 一 个 和 下 一 个 错<br />

误 , 使 用 ",cw" 来 打 开 一 个 quickfix 窗 口 。 这 下 顺 手 多 了 !<br />

如 果 你 希 望 跳 转 到 出 错 的 文 件 时 , 使 用 一 个 分 隔 的 窗 口 打 开 , 请 参 阅 'switchbuf' 选 项 的 值 。<br />

在 vim7 中 , 每 个 窗 口 都 可 以 拥 有 自 己 的 位 置 列 表 , 这 样 , 你 就 能 够 同 时 打 开 多 个 位 置 列 表 了 , 而<br />

quickfix 列 表 在 整 个 vim 中 只 有 一 个 。 你 可 以 使 用 位 置 列 表 来 显 示 编 译 错 误 信 息 , 具 体 命 令 参 阅<br />

手 册 :":help location-list" 以 及 ":help :lmake"。<br />

[GREP]<br />

我 们 在 程 序 员 的 利 器 - cscope 中 讲 过 ,cscope 可 以 做 为 一 个 快 速 的 grep 程 序 使 用 , 对 于 我 们 的<br />

软 件 项 目 , 用 cscope 生 成 一 个 数 据 库 , 可 以 大 大 加 快 查 找 字 符 串 的 速 度 。 但 cscope 需 要 事 先 生 成<br />

一 个 数 据 库 , 对 一 些 简 单 的 查 找 , 不 需 要 专 门 为 之 生 成 数 据 库 , 这 时 候 可 以 使 用 grep。<br />

Grep 的 名 字 来 源 于 "g/re/p","re" 是 正 则 表 达 式 (regex) 的 意 思 ,"p" 是 打 印 , 也 就 是 把 匹 配 正 则<br />

表 达 式 的 行 打 印 出 来 。<br />

vim 既 可 以 使 用 外 部 的 grep 程 序 , 也 可 以 使 用 内 部 集 成 的 grep 功 能 。<br />

使 用 集 成 的 grep 命 令 非 常 简 单 , 通 常 使 用 格 式 为 :<br />

:vimgrep /main/gj **/*.c<br />

在 上 面 的 例 子 里 , 我 们 使 用 vim 内 部 集 成 的 grep 功 能 , 在 当 前 目 录 及 其 子 目 录 树 的 所 有 c 文 件 中 查<br />

找 main 字 符 串 , 如 果 一 行 中 main 出 现 了 多 次 , 每 个 匹 配 都 计 入 ; 在 查 找 到 后 , 不 立 即 跳 转 到 第 一<br />

个 匹 配 的 地 方 。<br />

使 用 内 部 集 成 的 grep 功 能 速 度 要 比 外 部 grep 慢 一 些 , 因 为 它 会 打 开 每 个 文 件 , 对 其 进 行 检 查 , 然<br />

后 关 闭 ; 但 集 成 的 grep 支 持 vim 增 强 的 正 则 表 达 式 , 可 以 利 用 它 进 行 更 为 复 杂 的 查 找 。 它 也 支 持<br />

vim 扩 展 的 文 件 通 配 符 表 示 方 式 , 见 ":help starstar-wildcard"。<br />

48


剑 不 离 手 - quickfix<br />

vimgrep 查 找 到 的 结 果 , 也 会 放 在 quickfix 列 表 中 。 下 图 是 在 vim 7.0 的 源 代 码 目 录 中 执 行 上 面 的<br />

命 令 生 成 的 quickfix 列 表 :<br />

点 击 查 看 大 图<br />

我 们 可 以 使 用 上 面 介 绍 的 quickfix 模 式 的 命 令 , 来 查 看 这 些 匹 配 。<br />

你 也 可 以 用 外 部 的 grep 程 序 来 查 找 , 如 果 你 的 系 统 中 所 用 的 不 是 标 准 的 grep 程 序 , 那 么 就 需 要 修<br />

改 'grepprg' 选 项 , 详 情 请 参 阅 手 册 。<br />

使 用 外 部 grep 的 语 法 与 grep 程 序 相 同 , 请 参 阅 grep 的 手 册 。<br />

无 论 使 用 内 部 的 vimgrep, 还 是 使 用 外 部 的 grep,vim 都 允 许 你 将 查 找 到 的 结 果 放 在 与 窗 口 相 关 联<br />

的 位 置 列 表 , 要 了 解 详 细 信 息 ,":help :lvimgrep" 及 ":help :lgrep"。<br />

在 我 的 vimrc 中 , 定 义 下 面 的 键 映 射 , 利 用 它 可 以 在 当 前 文 件 中 快 速 查 找 光 标 下 的 单 词 :<br />

nmap lv :lv /=expand("")/ %:lw<br />

[ 参 考 文 档 ]<br />

• vim 手 册<br />

• vim 中 文 手 册<br />


第 14 章 智 能 补 全<br />


智 能 补 全<br />

http://ctags.sourceforge.net/<br />

你 可 以 直 接 下 载 已 经 编 译 好 的 rpm 版 本 , 或 者 下 载 源 代 码 。 如 果 是 后 者 , 使 用 以 下 命 令 对 源 代 码<br />

进 行 编 译 :<br />

tar zvxf ctags-5.6.tar.gz<br />

cd ctags-5.6<br />

./configure<br />

make<br />

make install<br />

如 果 你 没 有 系 统 目 录 的 写 权 限 , 你 可 能 要 把 Exuberant Ctags 安 装 到 自 己 的 主 目 录 , 只 需 要 把 上<br />

面 的 "./configure" 命 令 改 为 "./configure –prefix=/home/xxx" 就 可 以 了 。<br />

Ctags 升 级 后 , 使 用 "ctags –R" 更 新 一 下 标 签 文 件 , 现 在 再 进 入 vim 就 可 以 在 C 程 序 中 全 能 补 全<br />

了 。 我 们 依 旧 以 vim 7.0 的 源 代 码 为 例 。<br />

例 如 , 我 们 在 VimMain() 函 数 中 , 输 入 "gui" 三 个 字 符 , 然 后 按 下 "CTRL-X CTRL-O", 在 vim 的 状 态<br />

行 会 显 示 "Omni Completeion", 表 明 现 在 进 行 的 是 全 能 补 全 , 同 时 会 弹 出 一 个 下 拉 菜 单 , 显 示 所<br />

有 匹 配 的 标 签 。 你 可 以 使 用 来 "CTRL-P" 和 "CTRL-N" 上 下 选 择 , 在 选 择 的 同 时 , 所 选 中 的 项 就 被 放<br />

在 光 标 位 置 , 不 需 要 再 按 回 车 来 把 它 放 在 光 标 位 置 ( 像 Source Insight 那 样 )。<br />

如 果 更 习 惯 于 使 用 Source Insight 这 种 方 式 , 你 可 以 使 用 上 、 下 光 标 键 来 选 择 项 目 , 然 后 按 回 车<br />

把 选 中 的 项 目 放 到 光 标 位 置 。 不 过 这 样 一 来 , 你 的 手 指 就 会 离 开 主 编 辑 区 , 并 且 需 要 多 输 入 一 个<br />

回 车 键 。<br />

本 文 结 尾 处 提 供 了 一 个 键 绑 定 , 允 许 在 使 "CTRL-P" 和 "CTRL-N" 时 , 输 入 回 车 表 示 补 全 结 束 , 而 不<br />

是 插 入 回 车 。<br />

如 果 补 全 处 于 激 活 状 态 , 可 以 用 "CTRL-E" 停 止 补 全 并 回 到 原 来 录 入 的 文 字 。 用 "CTRL-Y" 可 以 停 止<br />

补 全 , 并 接 受 当 前 所 选 的 项 目 。<br />

点 击 查 看 大 图<br />

51


智 能 补 全<br />

下 图 是 使 用 "CTRL-N" 选 择 的 抓 图 。 该 图 中 , 我 选 择 了 "gui_exit(" 函 数 , 接 下 来 可 以 直 接 输 入 这<br />

个 函 数 的 参 数 , 这 会 结 束 当 前 补 全 , 并 插 入 我 所 输 入 的 参 数 。<br />

下 图 是 对 结 构 的 成 员 进 行 补 全 的 抓 图 :<br />

点 击 查 看 大 图<br />

点 击 查 看 大 图<br />

缺 省 的 ,vim 会 使 用 下 拉 菜 单 和 一 个 preview 窗 口 ( 预 览 窗 口 ) 来 显 示 匹 配 项 目 , 下 拉 菜 单 列 出 所 有<br />

匹 配 的 项 目 , 预 览 窗 口 则 显 示 选 中 项 目 的 详 细 信 息 。 打 开 预 览 窗 口 会 导 致 下 拉 菜 单 抖 动 , 因 此 我<br />

一 般 都 去 掉 预 览 窗 口 的 显 示 , 这 需 要 改 变 'completeopt' 的 值 , 我 的 设 置 如 下 :<br />

set completeopt=longest,menu<br />

52


智 能 补 全<br />

上 面 的 设 置 表 明 , 只 在 下 拉 菜 单 中 显 示 匹 配 项 目 , 并 且 会 自 动 插 入 所 有 匹 配 项 目 的 相 同 文 本 。<br />

如 果 要 支 持 C++ 的 全 能 补 全 , 需 要 到 vim 主 页 下 载 OmniCppComplete 插 件 , 链 接 如 下 :<br />

http://www.vim.org/scripts/script.php?script_id=1520<br />

下 载 后 , 把 它 解 压 到 你 的 .vim 目 录 ( 在 windows 下 是 vimfiles 目 录 ), 它 会 安 装 以 下 文 件 :<br />

after\ftplugin\cpp.vim<br />

autoload\omni\common\debug.vim<br />

\utils.vim<br />

autoload\omni\cpp\complete.vim<br />

\includes.vim<br />

\items.vim<br />

\maycomplete.vim<br />

\namespaces.vim<br />

\settings.vim<br />

\tokenizer.vim<br />

\utils.vim<br />

doc\omnicppcomplete.txt<br />

确 保 你 已 关 闭 了 vi 兼 容 模 式 , 并 允 许 进 行 文 件 类 型 检 测 :<br />

set nocp<br />

filetype plugin on<br />

接 下 来 , 使 用 下 面 的 命 令 , 为 C++ 文 件 生 成 标 签 文 件 , 假 定 你 的 文 件 在 src 目 录 树 下 :<br />

ctags -R --c++-kinds=+p --fields=+iaS --extra=+q src<br />

在 对 C++ 文 件 进 行 补 全 时 ,OmniCppComplete 插 件 需 要 tag 文 件 中 包 含 C++ 的 额 外 信 息 , 因 此 上 面 的<br />

ctags 命 令 不 同 于 以 前 我 们 所 使 用 的 , 它 专 门 为 C++ 语 言 生 成 一 些 额 外 的 信 息 , 上 述 选 项 的 含 义 如<br />

下 :<br />

--c++-kinds=+p : 为 C++ 文 件 增 加 函 数 原 型 的 标 签<br />

--fields=+iaS : 在 标 签 文 件 中 加 入 继 承 信 息 (i)、 类 成 员 的 访 问 控 制 信 息 (a)、 以 及 函 数 的 指 纹 (S)<br />

--extra=+q : 为 标 签 增 加 类 修 饰 符 。 注 意 , 如 果 没 有 此 选 项 , 将 不 能 对 类 成 员 补 全<br />

现 在 , 进 入 vim, 设 置 好 tag 选 项 ( 我 在 前 面 的 文 章 中 介 绍 过 )。 好 极 了 ,vim 能 够 对 C++ 自 动 补 全<br />

了 !<br />

我 写 了 一 个 简 单 的 例 子 , 来 演 示 C++ 的 自 动 补 全 功 能 , 如 下 图 所 示 , 在 输<br />

入 "t." 后 ,OmniCppComplete 插 件 会 自 动 弹 出 struct test1 的 成 员 供 选 择 , 而 在 输 入 "b->" 后 ,<br />

又 会 自 动 弹 出 class base 的 成 员 供 选 择 , 非 常 方 便 , 连 "CTRL-X CTRL-O" 都 不 必 输<br />

入 。OmniCppComplete 插 件 的 缺 省 设 置 比 较 符 合 我 的 习 惯 , 因 此 不 须 对 其 设 置 进 行 调 整 , 如 果 你<br />

需 要 调 整 , 参 阅 OmniCppComplete 的 帮 助 页 。<br />

53


智 能 补 全<br />

点 击 查 看 大 图<br />

点 击 查 看 大 图<br />

下 表 是 我 的 vimrc 中 设 置 的 键 绑 定 , 使 用 pumvisible() 来 判 断 下 拉 菜 单 是 否 显 示 , 如 果 下 拉 菜 单<br />

显 示 了 , 键 映 射 为 了 一 个 值 , 如 果 未 显 示 , 又 会 映 射 为 另 一 个 值 。<br />

" mapping<br />

inoremap <br />

inoremap <br />

inoremap <br />

inoremap <br />

pumvisible()?"\":"\"<br />

pumvisible()?"\\\":"\"<br />

pumvisible()?"\\\":"\"<br />

pumvisible()?"\":"\"<br />

上 面 的 映 射 都 是 在 插 入 模 式 下 的 映 射 , 解 释 如 下 :<br />

• 如 果 下 拉 菜 单 弹 出 , 回 车 映 射 为 接 受 当 前 所 选 项 目 , 否 则 , 仍 映 射 为 回 车 ;<br />

54


智 能 补 全<br />

• 如 果 下 拉 菜 单 弹 出 ,CTRL-J 映 射 为 在 下 拉 菜 单 中 向 下 翻 页 。 否 则 映 射 为 CTRL-X CTRL-O;<br />

• 如 果 下 拉 菜 单 弹 出 ,CTRL-K 映 射 为 在 下 拉 菜 单 中 向 上 翻 页 , 否 则 仍 映 射 为 CTRL-K;<br />

• 如 果 下 拉 菜 单 弹 出 ,CTRL-U 映 射 为 CTRL-E, 即 停 止 补 全 , 否 则 , 仍 映 射 为 CTRL-U;<br />

在 下 一 篇 文 章 中 , 将 继 续 介 绍 vim 提 供 的 其 它 补 全 方 式 。<br />

[ 参 考 文 档 ]<br />

• vim 手 册<br />

• vim 中 文 手 册<br />

• http://www.vim.org/tips/tip.php?tip_id=1228<br />

• http://www.vim.org/tips/tip.php?tip_id=1386<br />


第 15 章 自 动 补 全<br />


自 动 补 全<br />

整 行 补 全<br />

根 据 当 前 文 件 里 关 键 字 补 全<br />

根 据 字 典 补 全<br />

根 据 同 义 词 字 典 补 全<br />

根 据 头 文 件 内 关 键 字 补 全<br />

根 据 标 签 补 全<br />

补 全 文 件 名<br />

补 全 宏 定 义<br />

补 全 vim 命 令<br />

用 户 自 定 义 补 全 方 式<br />

拼 写 建 议<br />

CTRL-X CTRL-L<br />

CTRL-X CTRL-N<br />

CTRL-X CTRL-K<br />

CTRL-X CTRL-T<br />

CTRL-X CTRL-I<br />

CTRL-X CTRL-]<br />

CTRL-X CTRL-F<br />

CTRL-X CTRL-D<br />

CTRL-X CTRL-V<br />

CTRL-X CTRL-U<br />

CTRL-X CTRL-S<br />

例 如 , 当 我 们 按 下 "CTRL-X CTRL-F" 时 ,vim 就 会 弹 出 下 拉 菜 单 , 显 示 出 当 前 目 录 下 的 可 选 目 录 和<br />

文 件 , 如 下 图 所 示 。 这 样 , 在 输 入 文 件 名 时 方 便 多 了 。<br />

点 击 查 看 大 图<br />

灵 活 的 运 用 这 些 补 全 方 式 , 甚 至 自 定 义 自 己 的 补 全 方 式 , 可 以 使 你 的 工 作 更 加 高 效 。<br />

可 以 在 vimrc 中 定 义 下 面 的 键 绑 定 , 以 减 少 按 键 次 数 :<br />

inoremap <br />

inoremap <br />

inoremap <br />

inoremap <br />

<br />

<br />

<br />

<br />

SuperTab 插 件 会 记 住 你 上 次 所 使 用 的 补 全 方 式 , 下 次 再 补 全 时 , 直 接 使 用 TAB, 就 可 以 重 复 这 种<br />

类 型 的 补 全 。 比 如 , 上 次 你 使 用 CTRL-X CTRL-F 进 行 了 文 件 名 补 全 , 接 下 来 , 你 就 可 以 使 用 TAB 来<br />

继 续 进 行 文 件 名 补 全 , 直 到 你 再 使 用 上 面 列 出 的 补 全 命 令 进 行 了 其 它 形 式 的 补 全 。 这 个 插 件 在 下<br />

面 的 链 接 下 载 :<br />

http://www.vim.org/scripts/script.php?script_id=1643<br />

下 载 后 , 把 它 放 到 .vim/plugin 目 录 就 可 以 了 。<br />

可 以 对 下 面 两 个 选 项 进 行 配 置 , 以 调 整 SuperTab 的 缺 省 行 为 :<br />

57


自 动 补 全<br />

• g:SuperTabRetainCompletionType 的 值 缺 省 为 1, 意 为 记 住 你 上 次 的 补 全 方 式 , 直 到 使 用 其 它<br />

的 补 全 命 令 改 变 它 ; 如 果 把 它 设 成 2, 意 味 着 记 住 上 次 的 补 全 方 式 , 直 到 按 ESC 退 出 插 入 模 式 为<br />

止 ; 如 果 设 为 0, 意 味 着 不 记 录 上 次 的 补 全 方 式 。<br />

• g:SuperTabDefaultCompletionType 的 值 设 置 缺 省 的 补 全 方 式 , 缺 省 为 CTRL-P。<br />

你 可 以 在 vimrc 中 设 置 这 两 个 变 量 , 例 如 :<br />

let g:SuperTabRetainCompletionType = 2<br />

let g:SuperTabDefaultCompletionType = ""<br />

现 在 你 可 以 使 用 TAB 来 进 行 补 全 了 , 就 像 在 shell 中 那 样 , 方 便 了 很 多 !<br />

[ 参 考 文 档 ]<br />

• vim 手 册<br />

• vim 中 文 手 册<br />


第 16 章 指 随 意 动 , 移 动 如 飞 ( 一 )<br />


指 随 意 动 , 移 动 如 飞 ( 一 )<br />

命 令 "G" 前 可 以 加 上 数 字 , 在 这 里 , 数 字 的 含 义 并 不 是 倍 数 , 而 是 你 打 算 跳 转 的 行 号 。 例 如 , 你<br />

想 跳 转 到 文 件 的 第 1234 行 , 只 需 输 入 "1234G"。<br />

你 还 可 以 按 百 分 比 来 跳 转 , 例 如 , 你 想 跳 到 文 件 的 正 中 间 , 输 入 "50%"; 如 果 想 跳 到 75% 处 , 输<br />

入 "75%"。 注 意 , 你 必 须 先 输 入 一 个 数 字 , 然 后 输 入 "%"。 如 果 直 接 输 入 "%", 那 含 义 就 完 全 不 同<br />

了 。":help N%" 阅 读 更 多 细 节 。<br />

在 文 件 中 移 动 , 你 可 能 会 迷 失 自 己 的 位 置 , 这 时 使 用 "CTRL-G" 命 令 , 查 看 一 下 自 己 位 置 。 这 个 命<br />

令 会 显 示 出 光 标 的 位 置 及 其 它 信 息 。 为 了 避 免 迷 失 , 你 可 以 打 开 行 号 显 示 ; 使 用 ":set<br />

number" 命 令 后 , 会 在 每 一 行 前 显 示 出 行 号 , 可 以 更 方 便 的 定 位 的 跳 转 (:help 'number')。<br />

[ 移 动 到 指 定 字 符 ]<br />

上 面 的 命 令 都 是 行 间 移 动 ( 除 h, l 外 ), 也 就 是 从 当 前 行 移 动 到 另 外 一 行 。 如 果 我 们 想 在 当 前 行 内<br />

快 速 移 动 , 可 以 使 用 f, t, F, T 命 令 。<br />

"f" 命 令 移 动 到 光 标 右 边 的 指 定 字 符 上 , 例 如 ,"fx", 会 把 移 动 到 光 标 右 边 的 第 一 个 'x' 字 符<br />

上 。"F" 命 令 则 反 方 向 查 找 , 也 就 是 移 动 到 光 标 左 边 的 指 定 字 符 上 。<br />

"t" 命 令 和 "f" 命 令 的 区 别 在 于 , 它 移 动 到 光 标 右 边 的 指 定 字 符 之 前 。 例 如 ,"tx" 会 移 动 到 光 标 右<br />

边 第 一 个 'x' 字 符 的 前 面 。"T" 命 令 是 "t" 命 令 的 反 向 版 本 , 它 移 动 到 光 标 右 边 的 指 定 字 符 之 后 。<br />

这 四 个 命 令 只 在 当 前 行 中 移 动 光 标 , 光 标 不 会 跨 越 回 车 换 行 符 。<br />

可 以 在 命 令 前 面 使 用 数 字 , 表 示 倍 数 。 例 如 ,"3fx" 表 示 移 动 到 光 标 右 边 的 第 3 个 'x' 字 符 上 。<br />

";" 命 令 重 复 前 一 次 输 入 的 f, t, F, T 命 令 , 而 "," 命 令 会 反 方 向 重 复 前 一 次 输 入 的 f, t, F, T 命<br />

令 。 这 两 个 命 令 前 也 可 以 使 用 数 字 来 表 示 倍 数 。<br />

[ 行 首 / 行 尾 ]<br />

在 vim 中 , 移 动 到 行 首 的 命 令 非 常 简 单 , 就 是 "0", 这 个 是 数 字 0, 而 不 是 大 写 字 母 O。 移 动 到 行 尾<br />

的 命 令 是 "$"。<br />

另 外 还 有 一 个 命 令 "^", 用 它 可 以 移 动 到 行 首 的 第 一 个 非 空 白 字 符 。<br />

在 正 则 表 达 式 中 我 们 会 看 到 ,"^" 字 符 代 表 行 首 , 而 "$" 字 符 代 表 行 尾 。 可 见 ,vi/vim 的 按 键 的 安<br />

排 , 的 确 是 别 具 匠 心 的 。<br />

[ 按 单 词 移 动 ]<br />

我 们 知 道 , 英 文 文 档 的 主 体 是 单 词 , 通 常 用 空 白 字 符 ( 包 括 空 格 、 制 表 符 和 回 车 换 行 符 ) 来 分 隔 单<br />

词 。vim 中 提 供 了 许 多 命 令 来 按 单 词 移 动 。<br />

要 根 据 单 词 来 移 动 , 首 先 要 把 文 本 分 隔 为 一 个 个 独 立 的 单 词 。vim 在 对 单 词 进 行 分 隔 时 , 会<br />

把 'iskeyword' 选 项 中 的 字 符 做 为 单 词 的 组 成 字 符 。 也 就 是 说 , 一 个 单 词 (word) 由 'iskeyword' 选<br />

项 中 定 义 的 字 符 构 成 , 它 前 面 、 后 面 的 字 符 不 在 'iskeyword' 选 项 定 义 的 字 符 中 。 例 如 , 如 果 我<br />

们 把 'iskeyword' 选 项 设 置 为 "a-z,A-Z,48-57,_", 那 么 "FooBar_123" 被 做 为 一 个 单 词 ,<br />

而 "FooBar-123" 被 做 为 三 个 单 词 :"FooBar", "-" 和 "123"。"a-z,A-Z,48-57,_" 中 的 48-57 表 示<br />

ASCII 码 表 中 的 数 字 0-9。<br />

vim 中 , 移 动 光 标 到 下 一 个 单 词 的 词 首 , 使 用 命 令 "w", 移 动 光 标 到 上 一 个 单 词 的 词 首 , 使 用 命<br />

令 "b"; 移 动 光 标 到 下 一 个 单 词 的 结 尾 , 用 命 令 "e", 移 动 光 标 到 上 一 个 单 词 的 结 尾 , 使 用 命<br />

令 "ge"。<br />

上 面 这 些 命 令 都 使 用 'iskeyword' 选 项 中 的 字 符 来 确 定 单 词 的 分 界 , 还 有 几 个 命 令 , 只 把 空 白 字<br />

符 当 做 " 单 词 " 的 分 界 。 当 然 , 这 里 说 的 " 单 词 " 已 经 不 是 传 统 意 义 上 的 单 词 了 , 而 是 由 非 空 白 字 符<br />

60


指 随 意 动 , 移 动 如 飞 ( 一 )<br />

构 成 一 串 字 串 。 命 令 "W" 移 动 光 标 到 下 个 字 串 的 开 始 , 命 令 "B" 移 动 到 上 个 字 串 的 开 始 ; 命<br />

令 "E" 移 动 到 下 个 字 串 的 结 尾 , 命 令 "gE" 移 动 到 上 个 字 串 的 结 尾 。 和 上 面 的 命 令 比 较 一 下 , 发 现<br />

什 么 规 律 没 有 ?<br />

[ H/M/L ]<br />

注 意 : 这 几 个 命 令 是 大 写 的 。<br />

使 用 H/M/L 这 三 个 键 , 可 以 让 光 标 跳 到 当 前 窗 口 的 顶 部 、 中 间 、 和 底 部 , 停 留 在 第 一 个 非 空 字 符<br />

上 。H 命 令 和 L 命 令 前 也 可 以 加 一 个 数 字 , 但 数 字 的 含 义 不 再 是 倍 数 , 而 是 指 距 窗 口 顶 部 、 底 部 的<br />

行 数 。 例 如 ,"3H" 表 示 光 标 移 动 到 距 窗 口 顶 部 第 3 行 的 位 置 ;"5L" 表 示 光 标 移 动 到 距 窗 口 底 部 5 行<br />

的 位 置 。<br />

[ 相 对 于 光 标 滚 屏 ]<br />

在 阅 读 代 码 时 , 有 时 我 们 需 要 根 据 光 标 所 在 的 位 置 滚 屏 , 把 光 标 所 在 行 移 动 窗 口 的 顶 端 、 中 间 或<br />

底 部 , 这 时 就 可 以 用 到 "zt"、"zz" 和 "zb"。 这 种 滚 屏 方 式 相 对 于 翻 页 来 讲 , 它 的 好 处 在 于 , 你 能<br />

够 始 终 以 当 前 光 标 位 置 做 为 参 照 , 不 会 出 现 翻 几 次 页 后 , 发 现 自 己 迷 失 了 方 向 。 ^_^<br />

[ 查 找 ]<br />

查 找 , 也 可 以 做 为 一 种 快 速 移 动 的 方 式 。<br />

在 vim 中 查 找 非 常 容 易 , 直 接 在 Normal 模 式 下 输 入 "/", 然 后 输 入 你 想 查 询 的 字 符 串 , 回 车 , 就 跳<br />

转 到 第 一 个 匹 配 的 地 方 了 。"/" 是 向 下 查 找 , 而 "?" 进 行 反 方 向 查 找 。 命 令 "n" 重 复 上 一 次 的 查 找<br />

命 令 , 而 命 令 "N" 也 重 复 上 一 次 的 查 找 命 令 , 只 不 过 它 按 相 反 方 向 查 找 。<br />

vim 保 存 了 查 找 的 历 史 记 录 , 你 可 以 在 输 入 "/" 或 "?" 后 , 用 上 、 下 光 标 键 ( 或 CTRL-P/CTRL-N) 翻 看<br />

历 史 记 录 , 然 后 再 次 执 行 这 个 查 找 。<br />

另 外 你 还 可 以 使 用 "q/" 和 "q?" 命 令 , 在 vim 窗 口 最 下 面 打 开 一 个 新 的 窗 口 , 这 个 窗 口 会 列 出 你 的<br />

查 找 历 史 记 录 , 你 可 以 使 用 任 何 vim 编 辑 命 令 对 此 窗 口 的 内 容 进 行 编 辑 , 然 后 再 按 回 车 , 就 会 对<br />

光 标 所 在 的 行 的 内 容 进 行 查 找 。<br />

点 击 查 看 大 图<br />

在 上 图 中 , 我 使 用 "q/" 命 令 打 开 了 command-line 窗 口 , 这 个 窗 口 列 出 了 我 之 前 所 查 找 的 字 符 串 。<br />

我 现 在 想 查 找 包 含 "check_swap", 于 是 先 跳 到 第 399 行 , 把 "check_tty" 改 为 "check_swap", 然 后<br />

61


指 随 意 动 , 移 动 如 飞 ( 一 )<br />

按 回 车 。 此 时 vim 就 去 查 找 包 含 "check_swap" 位 置 了 。 这 个 例 子 比 较 简 单 , 你 可 能 觉 得 commandline<br />

窗 口 没 什 么 必 要 , 但 如 果 你 要 查 找 的 内 容 是 一 个 很 长 的 正 则 表 达 式 , 你 就 会 发 现 它 非 常 有 用<br />

了 。<br />

vim 中 有 许 多 与 查 找 相 关 的 选 项 设 置 , 其 中 最 常 用 的 是 'incsearch',<br />

'ignorecase'。<br />

'hlsearch',<br />

• 'incsearch' 表 示 在 你 输 入 查 找 内 容 的 同 时 ,vim 就 开 始 对 你 输 入 的 内 容 进 行 匹 配 , 并 显 示 匹 配<br />

的 位 置 。 打 开 这 个 选 项 , 你 可 以 即 时 看 到 查 找 的 结 果 。<br />

• 'hlsearch' 选 项 表 示 对 匹 配 的 所 有 项 目 进 行 高 亮 显 示 。<br />

• 'ignorecase' 选 项 表 示 在 查 找 时 忽 略 大 小 写 。<br />

通 常 我 会 打 开 'incsearch' 和 'hlsearch' 选 项 , 关 闭 'ignorecase' 选 项 。<br />

下 一 篇 文 章 介 绍 了 在 vim 中 移 动 的 另 外 一 些 方 法 , 这 些 移 动 命 令 的 需 要 的 技 巧 更 高 一 些 。<br />

[ 参 考 文 档 ]<br />

• vim 手 册<br />

• vim 中 文 手 册<br />


第 17 章 指 随 意 动 , 移 动 如 飞 ( 二 )<br />


指 随 意 动 , 移 动 如 飞 ( 二 )<br />

设 定 一 个 标 记 很 简 单 , 使 用 命 令 "m{a-zA-Z}" 就 可 以 了 。 例 如 , 命 令 "mt" 在 把 当 前 光 标 位 置 设 定<br />

为 标 记 t; 命 令 "mT" 把 当 前 光 标 位 置 设 定 为 标 记 T。(:help m)<br />

要 跳 转 到 指 定 的 标 记 , 使 用 命 令 "'{a-zA-Z}" 或 "{a-zA-Z}"。 例 如 , 命 令 "'t" 会 跳 转 到 标 记 t; 命<br />

令 "'T" 会 跳 转 到 标 记 T。( :help ')<br />

单 引 号 和 反 引 号 的 区 别 和 上 面 所 讲 的 一 样 ,"`" 在 跳 转 时 会 精 确 到 列 , 而 "'" 不 会 回 到 跳 转 时 光 标<br />

所 在 的 那 一 列 , 而 是 把 光 标 放 在 第 一 个 非 空 白 字 符 上 。<br />

标 记 也 可 以 被 删 除 , 使 用 命 令 ":delmarks" 可 以 删 除 指 定 标 记 。 命 令 ":marks" 列 出 所 有 的 标 记 。<br />

关 于 标 记 , 有 两 个 非 常 有 用 的 插 件 , 一 个 是 ShowMarks, 另 外 一 个 叫 marks browser。<br />

ShowMarks 是 我 最 常 用 的 插 件 之 一 , 它 使 用 vim 提 供 的 sign 功 能 以 及 高 亮 功 能 显 示 出 标 记 的 位 置 。<br />

这 样 , 你 在 设 定 了 一 个 标 记 后 , 它 就 会 在 你 的 vim 窗 口 中 显 示 出 标 记 的 名 字 , 并 高 亮 这 一 行 。<br />

在 你 的 $HOME/.vim 目 录 把 它 解 压 , 然 后 进 行 简 单 设 置 。 在 我 的 vimrc 中 , 对 ShowMarks 进 行 了 如<br />

下 配 置 :<br />

""""""""""""""""""""""""""""""<br />

" showmarks setting<br />

""""""""""""""""""""""""""""""<br />

" Enable ShowMarks<br />

let showmarks_enable = 1<br />

" Show which marks<br />

let showmarks_include = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"<br />

" Ignore help, quickfix, non-modifiable buffers<br />

let showmarks_ignore_type = "hqm"<br />

" Hilight lower & upper marks<br />

let showmarks_hlline_lower = 1<br />

let showmarks_hlline_upper = 1<br />

首 先 , 使 能 showmarks 插 件 , 然 后 定 义 showmarks 只 显 示 全 部 的 大 写 标 记 和 小 写 , 并 高 亮 这 两 种 标<br />

记 ; 对 文 件 类 型 为 help、quickfix 和 不 可 修 改 的 缓 冲 区 , 则 不 显 示 标 记 的 位 置 。<br />

你 可 以 定 义 自 己 的 颜 色 来 高 亮 标 记 所 在 的 行 , 下 面 是 我 的 定 义 , 我 把 它 放 在 我 自 己 的<br />

colorscheme 文 件 中 :<br />

" For showmarks plugin<br />

hi ShowMarksHLl ctermbg=Yellow ctermfg=Black guibg=#FFDB72 guifg=Black<br />

hi ShowMarksHLu ctermbg=Magenta ctermfg=Black guibg=#FFB3FF guifg=Black<br />

ShowMarks 插 件 中 已 经 定 义 了 一 些 快 捷 键 :<br />

mt - 打 开 / 关 闭 ShowMarks 插 件<br />

mo - 强 制 打 开 ShowMarks 插 件<br />

mh - 清 除 当 前 行 的 标 记<br />

ma - 清 除 当 前 缓 冲 区 中 所 有 的 标 记<br />

mm - 在 当 前 行 打 一 个 标 记 , 使 用 下 一 个 可 用 的 标 记 名<br />

我 最 常 使 用 的 是 "mm" 和 "mh", 用 起 来 非 常 方 便 。 在 我 的 vimrc 中 , 把 Leader 定<br />

义 为 ",", 所 以 每 次 都 使 用 ",mm" 和 ",mh" 来 设 置 和 删 除 mark。<br />

64


指 随 意 动 , 移 动 如 飞 ( 二 )<br />

在 vim 7.0 中 , 如 果 大 写 的 标 记 被 定 义 了 , 那 么 函 数 line() 无 论 在 哪 个 缓 冲 区 里 都 会 返 回 该 标 记<br />

的 行 号 , 导 致 showmarks 在 每 个 缓 冲 区 里 都 会 把 这 个 大 写 标 记 显 示 出 来 。 因 此 我 为 这 个 插 件 打 了<br />

个 补 丁 来 修 正 此 问 题 。<br />

vim 7.0 中 也 可 以 真 正 的 删 除 一 个 mark 标 记 , 所 以 也 改 了 showmarks 插 件 的 删 除 标 记 功 能 。 原 来 的<br />

功 能 在 删 除 标 记 时 , 并 未 真 正 删 除 它 , 只 是 把 这 个 标 记 指 向 缓 冲 区 的 第 一 行 ; 现 在 则 是 真 正 删 除<br />

此 标 记 。<br />

如 果 想 使 用 我 为 showmarks 打 的 补 丁 , 请 点 击 这 里 下 载 showmarks 补 丁 。<br />

用 法 :<br />

1. 保 存 该 patch 到 某 一 目 录 , 例 如 :/tmp/showmarks.vim.patch<br />

2.cd 到 你 的 .vim 目 录 :cd ~/.vim<br />

3. 运 行 命 令 :cat /tmp/showmarks.vim.patch | patch -p0<br />

Marks Browser 插 件 可 以 显 示 出 当 前 缓 冲 区 中 定 义 的 小 写 标 记 的 位 置 , 在 你 无 法 对 应 上 标 记 的 名<br />

字 和 其 位 置 时 , 非 常 有 用 。<br />

下 载 后 把 它 放 到 你 的 $HOME/.vim/plugin 目 录 即 可 , 我 为 其 定 义 了 一 个 快 捷 键 :<br />

""""""""""""""""""""""""""""""<br />

" markbrowser setting<br />

""""""""""""""""""""""""""""""<br />

nmap mk :MarksBrowser<br />

这 样 , 直 接 使 用 ",mk" 就 可 以 打 开 Mark Browser 窗 口 了 。<br />

下 图 显 示 这 两 个 插 件 工 作 时 的 效 果 。 我 在 文 件 中 定 义 了 三 个 标 记 , 一 个 大 写 标 记 A, 两 个 小 写 标<br />

记 a 和 t。 最 上 面 的 窗 口 是 Mark Browser 窗 口 , 主 编 辑 窗 口 中 的 高 亮 行 及 sign 标 记 是 ShowMarks 插<br />

件 放 置 的 。<br />

[ 折 行 ]<br />

点 击 查 看 大 图<br />

65


指 随 意 动 , 移 动 如 飞 ( 二 )<br />

在 文 件 比 较 大 时 , 在 文 件 中 移 动 也 许 会 比 较 费 力 。 这 个 时 候 , 你 可 以 根 据 自 己 的 需 要 把 暂 时 不 会<br />

访 问 的 文 本 折 叠 起 来 , 既 减 少 了 对 空 间 的 占 用 , 移 动 速 度 也 会 快 很 多 。<br />

vim 提 供 了 多 种 方 法 来 进 行 折 叠 , 既 可 以 手 动 折 叠 , 也 可 以 根 据 缩 进 、 语 法 , 或 使 用 表 达 式 来 进<br />

行 折 叠 。<br />

程 序 文 件 一 般 都 具 有 良 好 的 结 构 , 所 以 根 据 语 法 进 行 折 叠 是 一 个 不 错 的 选 择 。<br />

要 启 用 折 叠 , 首 先 要 使 能 'foldenable' 选 项 , 这 个 选 项 是 局 部 于 窗 口 的 选 项 , 因 此 可 以 为 每 个 窗<br />

口 定 义 不 同 的 折 叠 。<br />

接 下 来 , 设 置 'foldmethod' 选 项 , 对 于 程 序 , 我 们 可 以 选 择 根 据 语 法 高 亮 进 行 折 叠 。 需 注 意 的 ,<br />

要 根 据 语 法 高 亮 进 行 折 叠 , 必 须 打 开 文 件 类 型 检 测 和 语 法 高 亮 功 能 , 请 参 见 我 前 面 的 文 章 。<br />

下 面 是 我 的 vimrc 中 的 设 置 , 它 使 用 了 自 动 命 令 , 如 果 发 现 文 件 类 型 为 c 或 cpp, 就 启 用 折 叠 功<br />

能 , 并 按 语 法 进 行 折 叠 :<br />

autocmd FileType c,cpp setl fdm=syntax | setl fen<br />

注 意 ,vim 的 很 多 命 令 、 选 项 名 都 有 简 写 形 式 , 在 帮 助 手 册 中 可 以 看 到 简 写 形 式 , 也 可 以 按 简 写<br />

形 式 来 help, 例 如 , 要 查 看 'foldmethod' 选 项 的 帮 助 , 可 以 只 输 入 ":help 'fdm'"。<br />

折 叠 后 的 效 果 见 下 图 :<br />

点 击 查 看 大 图<br />

图 中 以 黑 色 背 景 显 示 的 行 就 是 被 折 叠 起 来 的 行 ,vim 会 显 示 这 个 fold 中 被 折 叠 了 多 少 行 , 以 及 起<br />

始 行 的 内 容 。 留 意 一 下 左 下 方 的 "__Tag_List__" 窗 口 , 在 这 个 窗 口 中 也 存 在 着 折 叠 , 我 把 macro,<br />

typedef, variable 几 项 折 叠 起 来 了 , 而 把 function 的 折 叠 打 开 。 从 该 窗 口 最 左 边 的 折 叠 栏<br />

(:help fold-foldcolumn) 也 可 以 看 出 不 同 : 被 折 叠 的 文 本 前 显 示 了 "+", 打 开 的 折 叠 前 显 示 的<br />

是 "|"。<br />

折 叠 的 背 景 色 及 显 示 文 字 等 都 可 以 修 改 , 参 阅 帮 助 手 册 (:help folding)。<br />

下 面 的 命 令 用 来 打 开 和 关 闭 折 叠 :<br />

66


指 随 意 动 , 移 动 如 飞 ( 二 )<br />

zo – 打 开 光 标 下 的 折 叠<br />

zO – 循 环 打 开 光 标 下 的 折 叠 , 也 就 是 说 , 如 果 存 在 多 级 折 叠 , 每 一 级 都 会 被 打 开<br />

zc – 关 闭 光 标 下 的 折 叠<br />

zC – 循 环 关 闭 光 标 下 的 折 叠<br />

更 多 的 命 令 , 请 参 阅 手 册 (:help folding)。<br />

vim 提 供 了 一 些 命 令 在 折 叠 间 快 速 移 动 :<br />

[z – 到 当 前 打 开 折 叠 的 开 始<br />

]z – 到 当 前 打 开 折 叠 的 结 束<br />

zj – 向 下 移 动 到 下 一 个 折 叠 的 开 始 处<br />

zk – 向 上 移 动 到 上 一 个 折 叠 的 结 束 处<br />

我 通 常 不 喜 欢 把 文 本 折 叠 起 来 , 因 为 我 更 喜 欢 一 目 了 然 的 看 到 全 部 文 本 。 你 可 以 根 据 自 己 的 喜 好<br />

来 决 定 是 否 启 用 折 叠 。<br />

多 说 一 点 , 手 动 创 建 的 折 叠 是 可 以 保 存 在 session 文 件 中 的 , 这 样 下 次 进 入 vim 时 可 以 载 入 之 前 创<br />

建 的 折 叠 , 参 见 :help 'sessionoptions'。<br />

[ 在 程 序 中 移 动 ]<br />

vim 的 作 者 是 一 个 程 序 员 , 这 就 不 难 理 解 为 什 么 vim 提 供 了 众 多 在 程 序 中 移 动 的 命 令 。 这 里 面 既 包<br />

括 我 们 前 面 的 文 章 中 介 绍 过 的 利 用 tag 文 件 及 cscope 在 标 签 间 跳 转 , 也 包 括 众 多 在 函 数 、 注 释 、<br />

预 处 理 指 令 、 程 序 段 , 及 其 它 程 序 元 素 中 移 动 的 命 令 。<br />

本 文 不 再 详 细 介 绍 这 些 命 令 , 作 为 程 序 员 , 一 定 要 熟 读 usr_29.txt! 这 些 命 令 , 可 以 帮 助 你 在 程<br />

序 中 得 心 应 手 的 移 动 。<br />

在 这 里 介 绍 两 个 插 件 , 增 强 了 在 程 序 中 移 动 的 功 能 , 一 个 是 a.vim, 另 外 一 个 是 matchit。<br />

a.vim 的 功 能 非 常 简 单 , 它 帮 助 你 在 源 文 件 和 头 文 件 间 进 行 切 换 , 这 个 简 单 的 功 能 , 却 非 常 实<br />

用 , 至 少 它 为 我 节 省 了 很 多 时 间 。<br />

下 载 a.vim 后 , 把 它 放 到 你 的 .vim/plugin 目 录 就 可 以 了 。<br />

假 设 你 正 在 浏 览 C 语 言 的 源 文 件 , 这 时 想 修 改 它 对 应 的 头 文 件 , 只 需 要 输 入 ":A" 命 令 , 就 切 换 到<br />

头 文 件 了 ( 需 要 源 文 件 和 头 文 件 在 同 一 目 录 中 )。a.vim 插 件 还 定 义 了 其 它 一 些 命 令 和 快 捷 键 ,<br />

参 见 它 的 帮 助 手 册 。<br />

在 vim 中 ,"%" 命 令 跳 转 到 与 当 前 项 目 相 匹 配 的 项 目 。 例 如 , 当 光 标 位 置 在 "{" 时 , 按 下 %, 光 标 就<br />

跳 转 到 对 应 的 "}"( :help %)。<br />

但 vim 提 供 的 % 命 令 , 只 能 在 括 号 , 或 者 C 注 释 的 开 始 和 结 束 ( /* */), 或 者 C 编 译 预 处 理 指 令 间 进<br />

行 跳 转 。 对 于 其 它 程 序 结 构 , 例 如 HTML,% 命 令 不 能 从 标 记 , 跳 转 到 对 应 的 标 记 。<br />

Matchit 插 件 则 扩 展 了 % 命 令 的 功 能 , 使 % 命 令 可 以 对 其 它 程 序 语 言 的 开 始 和 结 束 标 记 间 进 行 跳<br />

转 。<br />

下 载 后 , 把 这 个 插 件 放 到 你 的 .vim/plugin 目 录 , 你 就 可 以 用 % 在 各 种 开 始 / 结 束 标 记 间 跳 转 了 ,<br />

目 前 , 它 可 以 支 持 Ada, ASP with VBS, Csh, DTD, Essbase, Fortran, HTML, JSP (same as<br />

HTML), LaTeX, Lua, Pascal, SGML, Shell, Tcsh, Vim, XML 等 语 言 。<br />

[ 插 入 模 式 下 的 移 动 ]<br />

上 面 介 绍 的 移 动 命 令 , 都 是 在 normal 模 式 下 使 用 的 , 如 果 想 在 insert 模 式 下 移 动 , 阅 读 :help<br />

ins-special-special。<br />

67


指 随 意 动 , 移 动 如 飞 ( 二 )<br />

你 真 的 需 要 在 插 入 模 式 下 移 动 吗 ? 我 几 乎 不 会 ! 通 常 我 会 先 按 ESC 返 回 Normal 模 式 , 然 后 再 移<br />

动 , 当 你 习 惯 了 以 后 , 你 会 发 现 效 率 会 更 高 。<br />

[ 小 结 ]<br />

你 会 发 现 , 本 文 的 内 容 , 和 usr_03.txt 帮 助 文 档 很 相 似 。 是 的 , 只 要 你 学 会 了 usr_03.txt 中 列 出<br />

的 命 令 , 你 就 掌 握 了 最 常 用 最 实 用 的 vim 移 动 命 令 (:help usr_03.txt)。<br />

如 果 你 想 了 解 更 多 的 移 动 命 令 , 请 通 篇 阅 读 motion.txt, 记 住 你 最 有 可 能 用 到 的 那 些 键 。 当 你 的<br />

手 指 能 够 不 假 思 索 的 使 用 这 些 命 令 后 , 你 在 vim 中 就 能 做 到 指 随 意 动 、 移 动 如 飞 了 。<br />

[ 参 考 文 档 ]<br />

• vim 手 册<br />

• vim 中 文 手 册<br />


第 18 章 在 vim 中 使 用 gdb 调 试<br />


在 vim 中 使 用 gdb 调 试<br />

[ 定 制 vim 的 功 能 ]<br />

缺 省 的 vim 配 置 已 经 适 合 大 多 数 人 , 但 有 些 时 候 你 可 能 需 要 一 些 额 外 的 功 能 , 这 时 就 需 要 自 己 定<br />

制 一 下 vim。 定 制 vim 很 简 单 , 进 入 ~/install/vim71/src 文 件 , 编 辑 Makefile 文 件 。 这 是 一 个 注<br />

释 很 好 的 文 档 , 根 据 注 释 来 选 择 :<br />

• 如 果 你 不 想 编 译 gvim, 可 以 打 开 --disable-gui 选 项 ;<br />

• 如 果 你 想 把 perl, python, tcl, ruby 等 接 口 编 译 进 来 的 话 , 打 开 相 应 的 选 项 , 例 如 , 我 打 开<br />

了 --enable-tclinterp 选 项 ;<br />

• 如 果 你 想 在 vim 中 使 用 cscope 的 话 , 打 开 --enable-cscope 选 项 ;<br />

• 我 们 刚 才 打 的 vimgdb 补 丁 , 自 动 在 Makefile 中 加 入 了 --enable-gdb 选 项 ;<br />

• 如 果 你 希 望 在 vim 使 用 中 文 , 使 能 --enable-multibyte 和 --enable-xim 选 项 ;<br />

• 可 以 通 过 --with-features=XXX 选 项 来 选 择 所 编 译 的 vim 特 性 集 , 缺 省 是 --withfeatures=normal;<br />

• 如 果 你 没 有 root 权 限 , 可 以 把 vim 装 在 自 己 的 home 目 录 , 这 时 需 要 打 开 prefix = $(HOME) 选<br />

项 ;<br />

编 辑 好 此 文 件 后 , 就 可 以 编 辑 安 装 vim 了 。 如 果 你 需 要 更 细 致 的 定 制 vim, 可 以 修 改 config.h 文<br />

件 , 打 开 / 关 闭 你 想 要 的 特 性 。<br />

[ 编 译 安 装 ]<br />

编 译 和 安 装 vim 非 常 简 单 , 使 用 下 面 两 个 命 令 :<br />

make<br />

make install<br />

你 不 需 要 手 动 运 行 ./configure 命 令 ,make 命 令 会 自 动 调 用 configure 命 令 。<br />

上 面 的 命 令 执 行 完 后 ,vim 就 安 装 成 功 了 。<br />

我 在 编 译 时 打 开 了 "prefix = $(HOME)" 选 项 , 因 此 我 的 vim 被 安 装 在 ~/bin 目 录 。 这 时 需 要 修 改 一<br />

下 PATH 变 量 , 以 使 其 找 到 我 编 辑 好 的 vim。 在 ~/.bashrc 文 件 中 加 入 下 面 这 两 句 话 :<br />

PATH=$HOME/bin:$PATH<br />

export PATH<br />

退 出 再 重 新 登 录 , 现 在 再 敲 入 vim 命 令 , 发 现 已 经 运 行 我 们 编 译 的 vim 了 。<br />

[ 安 装 vimgdb 的 runtime 文 件 ]<br />

运 行 下 面 的 命 令 , 解 压 vimgdb 的 runtime 文 件 到 你 的 ~/.vim/ 目 录 :<br />

cd ~/install/vimgdb/<br />

tar zxf vimgdb_runtime.tgz –C~/.vim/<br />

现 在 启 动 vim, 在 vim 中 运 行 下 面 的 命 令 以 生 成 帮 助 文 件 索 引 :<br />

:helptags ~/.vim/doc<br />

现 在 , 你 可 以 使 用 ":help vimgdb" 命 令 查 看 vimgdb 的 帮 助 了 。<br />

70


在 vim 中 使 用 gdb 调 试<br />

至 此 , 我 们 重 新 编 译 了 vim, 并 为 之 打 上 了 vimgdb 补 丁 。 下 面 我 以 一 个 例 子 来 说 明 如 何 在 vim 中 完<br />

成 " 编 码 — 编 译 — 调 试 " 一 条 龙 服 务 。<br />

[ 在 vim 中 调 试 ]<br />

首 先 确 保 你 的 计 算 机 上 安 装 了 gdb ,vimgdb 支 持 5.3 以 上 的 gdb 版 本 , 不 过 最 好 使 用 gdb 6.0 以 上<br />

的 版 本 。<br />

我 使 用 下 面 这 个 简 单 的 例 子 , 来 示 例 一 下 如 何 在 vim 中 使 用 gdb 调 试 。 先 来 看 示 例 代 码 :<br />

文 件 ~/tmp/sample.c 内 容 如 下 , 这 是 主 程 序 , 调 用 函 数 计 算 某 数 的 阶 乘 并 打 印 :<br />

/* ~/tmp/sample.c */<br />

#include <br />

extern int factor(int n, int *rt);<br />

int main(int argc, char **argv)<br />

{<br />

int i;<br />

int result = 1;<br />

for (i = 1; i < 6; i++)<br />

{<br />

factor(i, &result);<br />

printf("%d! = %d\n", i, result);<br />

}<br />

}<br />

return 0;<br />

文 件 ~/tmp/factor/factor.c 内 容 如 下 , 定 义 了 子 函 数 factor()。 之 所 以 把 它 放 到 子 目 录<br />

factor/, 是 为 了 演 示 vimgdb 可 以 根 据 调 试 位 置 自 动 打 开 文 件 , 不 管 该 文 件 在 哪 个 目 录 下 :<br />

/* ~/tmp/factor/factor.c */<br />

int factor(int n, int *r)<br />

{<br />

if (n


在 vim 中 使 用 gdb 调 试<br />

sample: sample.c factor/factor.c<br />

gcc -g -Wall -o sample sample.c factor/factor.c<br />

假 设 vim 的 当 前 工 作 目 录 是 ~/tmp( 使 用 ":cd ~/tmp" 命 令 切 换 到 此 目 录 )。 我 们 编 辑 完 上 面 几 个 文<br />

件 后 , 输 入 命 令 ":make",vim 就 会 根 据 Makefile 文 件 进 行 编 译 。 如 果 编 译 出 错 ,vim 会 跳 到 第 一<br />

个 出 错 的 位 置 , 改 完 后 , 用 ":cnext" 命 令 跳 到 下 一 个 错 误 , 以 此 类 推 。 这 种 开 发 方 式 被 称 为<br />

quickfix, 我 们 已 经 在 剑 不 离 手 - quickfix 一 文 中 讲 过 , 不 再 赘 述 。<br />

现 在 , 假 设 已 经 完 成 链 接 , 生 成 了 最 终 的 sample 文 件 , 我 们 就 可 以 进 行 调 试 了 。<br />

vimgdb 补 丁 已 经 定 义 了 一 些 键 绑 定 , 我 们 先 加 载 这 些 绑 定 :<br />

:run macros/gdb_mappings.vim<br />

加 载 后 , 一 些 按 键 就 被 定 义 为 调 试 命 令 (vimgdb 定 义 的 键 绑 定 见 ":help<br />

按 可 以 在 按 键 的 缺 省 定 义 和 调 试 命 令 间 切 换 。<br />

gdb-mappings")。<br />

好 了 , 我 们 现 在 按 空 格 键 , 在 当 前 窗 口 下 方 会 打 开 一 个 小 窗 口 (command-line 窗 口 ), 这 就 是<br />

vimgdb 的 命 令 窗 口 , 可 以 在 这 个 窗 口 中 输 入 任 何 合 法 的 gdb 命 令 , 输 入 的 命 令 将 被 送 到 gdb 执 行 。<br />

现 在 , 我 们 在 这 个 窗 口 中 输 入 "gdb", 按 回 车 后 ,command-line 窗 口 自 动 关 闭 , 而 在 当 前 窗 口 上<br />

方 又 打 开 一 个 窗 口 , 这 个 窗 口 是 gdb 输 出 窗 口 。 现 在 vim 的 窗 口 布 局 如 下 ( 我 又 按 空 格 打 开 了<br />

command-line 窗 口 ):<br />

点 击 查 看 大 图<br />

小 技 巧 : command-line 窗 口 是 一 个 特 殊 的 窗 口 , 在 这 种 窗 口 中 , 你 可 以 像 编 辑 文 本 一 样 编 辑<br />

命 令 , 完 成 编 辑 后 , 按 回 车 , 就 会 执 行 此 命 令 。 你 要 重 复 执 行 某 条 命 令 , 可 以 把 光 标 移 到 该 命 令<br />

所 在 的 行 , 然 后 按 回 车 即 可 ; 你 也 可 以 对 历 史 命 令 进 行 修 改 后 再 执 行 。 详 见 ":help cmdlinewindow"。<br />

接 下 来 , 在 command-line 窗 口 中 输 入 以 下 命 令 :<br />

cd ~/tmp<br />

file sample<br />

这 两 条 命 令 切 换 gdb 的 当 前 工 作 目 录 , 并 加 载 我 们 编 译 的 sample 程 序 准 备 调 试 。<br />

72


在 vim 中 使 用 gdb 调 试<br />

现 在 使 用 vim 的 移 动 命 令 , 把 光 标 移 动 到 sample.c 的 第 7 行 和 14 行 , 按 "CTRL-B" 在 这 两 处 设 置 断<br />

点 , 然 后 按 "R", 使 gdb 运 行 到 我 们 设 置 的 第 一 个 断 点 处 ("CTRL-B" 和 "R" 都 是 gdb_mappings.vim 定<br />

义 的 键 绑 定 , 下 面 介 绍 的 其 它 调 试 命 令 相 同 )。 现 在 vim 看 起 来 是 这 样 :<br />

点 击 查 看 大 图<br />

断 点 所 在 的 行 被 置 以 蓝 色 , 并 在 行 前 显 示 标 记 1 和 2 表 明 是 第 几 个 断 点 ; 程 序 当 前 运 行 到 的 行 被 置<br />

以 黄 色 , 行 前 以 "=>" 指 示 , 表 明 这 是 程 序 执 行 的 位 置 ( 显 示 的 颜 色 用 户 可 以 调 整 )。<br />

接 下 来 , 我 们 再 按 "C", 运 行 到 第 2 个 断 点 处 , 现 在 , 我 们 输 入 下 面 的 vim 命 令 , 在 右 下 方 分 隔 出<br />

一 个 名 为 gdb-variables 的 窗 口 :<br />

:bel 20vsplit gdb-variables<br />

然 后 用 "v" 命 令 选 中 变 量 i, 按 "CTRL-P" 命 令 , 把 变 量 i 加 入 到 监 视 窗 口 , 用 同 样 的 方 式 把 变 量<br />

result 也 加 入 到 监 视 窗 口 , 这 里 可 以 从 监 视 窗 口 中 看 到 变 量 i 和 result 的 值 。<br />

73


在 vim 中 使 用 gdb 调 试<br />

点 击 查 看 大 图<br />

现 在 我 们 按 "S" 步 进 到 factor 函 数 ,vim 会 自 动 打 开 factor/factor.c 文 件 并 标 明 程 序 执 行 的 位<br />

置 。 我 们 再 把 factor() 函 数 中 的 变 量 n 加 入 到 监 视 窗 口 ; 然 后 按 空 格 打 开 command-line 窗 口 , 输<br />

入 下 面 的 命 令 , 把 变 量 *r 输 入 到 变 量 窗 口 :<br />

createvar *r<br />

现 在 ,vim 看 起 来 是 这 样 的 :<br />

点 击 查 看 大 图<br />

现 在 , 你 可 以 用 "S"、"CTRL-N" 或 "C" 来 继 续 执 行 , 直 至 程 序 运 行 结 束 。<br />

如 果 你 是 单 步 执 行 到 程 序 结 束 , 那 么 vim 最 后 可 能 会 打 开 一 个 汇 编 窗 口 。 是 的 ,vimgdb 支 持 汇 编<br />

级 的 调 试 。 这 里 我 们 不 用 进 行 汇 编 级 调 试 , 忽 略 即 可 。<br />

如 果 你 发 现 程 序 有 错 误 , 那 么 可 以 按 "Q" 退 出 调 试 (gdb 会 提 示 是 否 退 出 , 回 答 y 即 可 ), 然 后 修 改<br />

代 码 、 编 译 、 调 试 , 直 到 最 终 完 成 。 在 修 改 代 码 时 , 你 可 能 并 不 喜 欢 vimgdb 的 键 映 射 ( 例 如 , 它<br />

把 CTRL-B 映 射 为 设 置 断 点 , 而 这 个 键 又 是 常 用 的 翻 页 功 能 ), 你 可 以 按 取 消 vimgdb 的 键 映<br />

射 , 或 者 你 直 接 修 改 gdb_mappings.vim 文 件 中 定 义 的 映 射 。<br />

看 ,vim + gdb 调 试 是 不 是 很 简 单 ?!<br />

我 们 可 以 再 定 制 一 下 , 使 调 试 更 加 方 便 。<br />

打 开 ~/.vim/macros/ gdb_mappings.vim 文 件 , 在 "let s:gdb_k = 0" 这 一 行 下 面 加 上 这 段 内 容 :<br />

" easwy add<br />

if ! exists("g:vimgdb_debug_file")<br />

let g:vimgdb_debug_file = ""<br />

elseif g:vimgdb_debug_file == ""<br />

call inputsave()<br />

let g:vimgdb_debug_file = input("File: ", "", "file")<br />

call inputrestore()<br />

endif<br />

74


在 vim 中 使 用 gdb 调 试<br />

call gdb("file " . g:vimgdb_debug_file)<br />

" easwy end<br />

在 "let s:gdb_k = 1" 这 一 行 下 面 加 上 这 段 内 容 :<br />

" easwy add<br />

call gdb("quit")<br />

" end easwy<br />

注 释 掉 最 后 一 行 的 "call s:Toggle()"。<br />

然 后 在 你 的 vimrc 中 增 加 这 段 内 容 :<br />

""""""""""""""""""""""""""""""<br />

" vimgdb setting<br />

""""""""""""""""""""""""""""""<br />

let g:vimgdb_debug_file = ""<br />

run macros/gdb_mappings.vim<br />

现 在 , 在 启 动 vim 后 , 按 , 就 进 入 调 试 模 式 以 及 设 定 调 试 的 键 映 射 。 在 第 一 次 进 入 调 试 模 式<br />

时 , 会 提 示 你 输 入 要 调 试 的 文 件 名 , 以 后 就 不 必 再 输 入 了 。 再 按 一 次 , 就 退 出 调 试 模 式 , 取<br />

消 调 试 的 键 映 射 。<br />

利 用 vim 的 键 映 射 (map) 机 制 , 你 可 以 把 你 喜 欢 的 gdb 命 令 映 射 为 vim 的 按 键 , 方 便 多 了 。 映 射 的 例<br />

子 可 以 参 照 ~/.vim/macros/ gdb_mappings.vim。<br />

再 附 上 一 张 抓 图 , 这 是 使 用 putty 远 程 登 录 到 linux 上 , 在 终 端 vim 中 进 行 调 试 。 这 也 是 我 为 什 么<br />

喜 欢 vimgdb 的 原 因 , 因 为 它 可 以 在 终 端 vim 中 调 试 , 而 clewn 只 支 持 gvim:<br />

点 击 查 看 大 图<br />

因 为 我 不 常 使 用 gdb 调 试 , 所 以 本 文 仅 举 了 个 简 单 的 例 子 , 以 抛 砖 引 玉 。 欢 迎 大 家 共 享 自 己 的 经<br />

验 和 心 得 。<br />

最 后 , 让 我 们 感 谢 vimgdb 作 者 xdegaye 的 辛 勤 劳 动 , 我 们 后 续 文 章 会 介 绍 clewn, 这 是 vim 与 gdb 结<br />

合 的 另 外 一 种 形 式 , 它 和 vimgdb 同 属 一 个 项 目 。<br />

75


在 vim 中 使 用 gdb 调 试<br />

[ 参 考 文 档 ]<br />

• vim 帮 助 文 件<br />

• vim 中 文 手 册<br />

• http://clewn.sourceforge.net/index.html<br />


第 19 章 vim 编 译 中 遇 到 的 问 题 及 解 决 方<br />

法<br />

&5<br />

3. conftest.c:16:27: error: X11/Intrinsic.h: No such file or directory<br />

4. configure:7634: $? = 1<br />

5. configure: failed program was:<br />

6. | /* confdefs.h. */<br />

7. | #define PACKAGE_NAME “”<br />

8. | #define PACKAGE_TARNAME “”<br />

9. | #define PACKAGE_VERSION “”<br />

10. | #define PACKAGE_STRING “”<br />

11. | #define PACKAGE_BUGREPORT “”<br />

12. | #define UNIX 1<br />

13. | #define STDC_HEADERS 1<br />

14. | #define HAVE_SYS_WAIT_H 1<br />

15. | #define FEAT_NORMAL 1<br />

77


vim 编 译 中 遇 到 的 问 题 及 解 决 方 法<br />

16. | #define USE_XSMP_INTERACT 1<br />

17. | #define HAVE_LIBNSL 1<br />

18. | #define FEAT_NETBEANS_INTG 1<br />

19. | /* end confdefs.h. */<br />

20. | #include <br />

21. | #include <br />

22. | int<br />

23. | main ()<br />

24. | {<br />

25. |<br />

26. | ;<br />

27. | return 0;<br />

28. | }<br />

29. configure:7645: result: no<br />

30. configure:7978: checking –enable-gui argument<br />

31. configure:8038: result: no GUI support<br />

我 们 可 以 看 到 在 第 30 行 和 31 行 显 示 没 有 GUI 支 持 , 而 原 因 则 在 第 3 行 :"conftest.c:16:27:<br />

error: X11/Intrinsic.h: No such file or directory", 也 就 是 说 找 不 到 文 件 X11/<br />

Intrinsic.h。<br />

在 网 上 搜 索 后 得 知 , 这 个 库 在 debian 的 libdevel/libxt-dev 包 中 , 安 装 此 包 后 ,gvim 就 编 译 成 功<br />

了 。<br />

另 外 还 有 一 个 朋 友 问 , 如 何 使 vim 支 持 +signs 功 能 ,signs 功 能 是 在 big 版 本 中 才 被 包 含 进 来 的 功<br />

能 , 如 果 想 在 normal 版 本 的 vim 中 包 含 此 功 能 , 就 需 要 修 改 vim72/src/feature.h 文 件 , 在 此 文 件<br />

中 把 :<br />

# define FEAT_SIGNS<br />

打 开 , 然 后 再 编 译 就 可 以 了 。<br />

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!