diff --git a/README.md b/README.md index 9c71c94..c13e59e 100644 --- a/README.md +++ b/README.md @@ -25,122 +25,117 @@ > Vim from zero to hero - Vim 从入门到精通 -- 原文地址:https://github.com/mhinz/vim-galore +- 原文地址: - 原文作者:Marco Hinz -- 本文地址:https://github.com/wsdjeg/vim-galore-zh_cn +- 本文地址: -### [简介](#简介-1) + -- [什么是 Vim](#什么是-vim) -- [Vim 的哲学](#vim-的哲学) -- [入门步骤](#入门步骤) -- [精简的 vimrc](#精简的-vimrc) -- [我正在使用的是什么样的 Vim](#我正在使用什么样的-vim) -- [备忘录](#备忘录) + - [简介](#简介) + - [什么是 Vim?](#什么是-vim) + - [Vim 哲学](#vim-哲学) + - [入门](#入门) + - [精简的 vimrc](#精简的-vimrc) + - [我正在使用什么样的 Vim](#我正在使用什么样的-vim) + - [备忘录](#备忘录) +- [基础](#基础) + - [缓冲区,窗口,标签](#缓冲区窗口标签) + - [已激活、已载入、已列出、已命名的缓冲区](#已激活已载入已列出已命名的缓冲区) + - [参数列表](#参数列表) + - [按键映射](#按键映射) + - [映射前置键](#映射前置键) + - [寄存器](#寄存器) + - [范围](#范围) + - [标注](#标注) + - [补全](#补全) + - [动作,操作符,文本对象](#动作操作符文本对象) + - [自动命令](#自动命令) + - [变更历史,跳转历史](#变更历史跳转历史) + - [内容变更历史记录](#内容变更历史记录) + - [全局位置信息表,局部位置信息表](#全局位置信息表局部位置信息表) + - [宏](#宏) + - [颜色主题](#颜色主题) + - [折叠](#折叠) + - [会话](#会话) + - [局部化](#局部化) + - [用法](#用法) + - [获取离线帮助](#获取离线帮助) + - [获取离线帮助(补充)](#获取离线帮助补充) + - [获取在线帮助](#获取在线帮助) + - [执行自动命令](#执行自动命令) + - [用户自定义事件](#用户自定义事件) + - [内部自带事件](#内部自带事件) + - [剪切板](#剪切板) + - [剪贴板的使用(Windows, OSX)](#剪贴板的使用windows-osx) + - [剪贴板的使用(Linux, BSD, ...)](#剪贴板的使用linux-bsd-) + - [打开文件时恢复光标位置](#打开文件时恢复光标位置) + - [备份文件,交换文件,撤销文件以及 viminfo 文件的处理](#备份文件交换文件撤销文件以及-viminfo-文件的处理) + - [编辑远程文件](#编辑远程文件) + - [插件管理](#插件管理) + - [多行编辑](#多行编辑) + - [使用外部程序和过滤器](#使用外部程序和过滤器) + - [Cscope](#cscope) + - [1. 构建数据库](#1-构建数据库) + - [2. 添加数据库](#2-添加数据库) + - [3. 查询数据库](#3-查询数据库) + - [MatchIt](#matchit) + - [在 Vim 8 中安装](#在-vim-8-中安装) + - [在 Vim 7 或者更早的版本中安装](#在-vim-7-或者更早的版本中安装) + - [简短的介绍](#简短的介绍) +- [技巧](#技巧) + - [聪明地使用 n 和 N](#聪明地使用-n-和-n) + - [聪明地使用命令行历史](#聪明地使用命令行历史) + - [智能 Ctrl-l](#智能-ctrl-l) + - [禁用错误报警声音和图标](#禁用错误报警声音和图标) + - [快速移动当前行](#快速移动当前行) + - [快速添加空行](#快速添加空行) + - [快速编辑自定义宏](#快速编辑自定义宏) + - [快速跳转到源(头)文件](#快速跳转到源头文件) + - [在 GUI 中快速改变字体大小](#在-gui-中快速改变字体大小) + - [根据模式改变光标类型](#根据模式改变光标类型) + - [防止水平滑动的时候失去选择](#防止水平滑动的时候失去选择) + - [重新载入保存文件](#重新载入保存文件) + - [更加智能的当前行高亮](#更加智能的当前行高亮) + - [更快的关键字补全](#更快的关键字补全) + - [改变颜色主题的默认外观](#改变颜色主题的默认外观) + - [命令](#命令) + - [:global 和 :vglobal - 在所有匹配行执行命令](#global-和-vglobal---在所有匹配行执行命令) + - [:normal 和 :execute - 脚本梦之队](#normal-和-execute---脚本梦之队) + - [:redir - 重定向消息](#redir---重定向消息) +- [调试](#调试) + - [常规建议](#常规建议) + - [查看启动日志](#查看启动日志) + - [查看运行时日志](#查看运行时日志) + - [调整日志等级](#调整日志等级) + - [vim 脚本调试](#vim-脚本调试) + - [语法文件调试](#语法文件调试) +- [杂项](#杂项) + - [附加资源](#附加资源) + - [Vim 配置集合](#vim-配置集合) + - [内置插件](#内置插件) + - [将 Control 映射到 CapsLock](#将-control-映射到-capslock) + - [复活节彩蛋](#复活节彩蛋) + - [为何使用 hjkl](#为何使用-hjkl) + - [常见问题](#常见问题) + - [编辑小文件时很慢](#编辑小文件时很慢) + - [编辑大文件的时候很慢](#编辑大文件的时候很慢) + - [持续粘贴(为什么我每次都要设置 'paste' 模式)](#持续粘贴为什么我每次都要设置-paste-模式) + - [在终端中按 ESC 后有延时](#在终端中按-esc-后有延时) + - [无法重复函数中执行的搜索](#无法重复函数中执行的搜索) + - [主题列表](#主题列表) +- [插件列表](#插件列表) +- [Neovim](#neovim) + - [加入我们](#加入我们) + - [致谢:](#致谢) -### [基础](#基础-1) + -- [缓冲区,窗口,标签](#缓冲区窗口标签) -- [当前缓冲区,加载缓冲区,缓冲区列表,命名缓冲区](#已激活已载入已列出已命名缓冲区) -- [参数列表](#参数列表) -- [按键映射](#按键映射) -- [映射占位符](#映射占位符) -- [寄存器](#寄存器) -- [范围](#范围) -- [标注](#标注) -- [补全](#补全) -- [动作,操作符,文本对象](#动作操作符文本对象) -- [自动命令](#自动命令) -- [变更历史,跳转历史](#变更历史跳转历史) -- [内容变更历史记录](#内容变更历史记录) -- [全局位置信息表,局部位置信息表](#全局位置信息表局部位置信息表) -- [宏](#宏) -- [颜色主题](#颜色主题) -- [折叠](#折叠) -- [会话](#会话) -- [局部化](#局部化) - -### [用法](#用法-1) - -- [获取离线帮助](#获取离线帮助) -- [获取离线帮助(补充)](#获取离线帮助补充) -- [获取在线帮助](#获取在线帮助) -- [执行自动命令](#执行自动命令) - - [用户自定义事件](#用户自定义事件) - - [内部自带事件](#内部自带事件) -- [剪切板](#剪切板) - - [剪贴板的使用 (Windows, OSX)](#剪贴板的使用windows-osx) - - [剪贴板的使用 (Linux, BSD, ...)](#剪贴板的使用linux-bsd-) -- [打开文件时恢复光标位置](#打开文件时恢复光标位置) -- [备份文件,交换文件,撤销文件以及 viminfo 文件的处理](#备份文件交换文件撤销文件以及-viminfo-文件的处理) -- [编辑远程文件](#编辑远程文件) -- [插件管理](#插件管理) -- [多行编辑](#多行编辑) -- [使用外部程序和过滤器](#使用外部程序和过滤器) -- [MatchIt](#matchit) - -### [技巧](#技巧-1) - -- [聪明地使用 n 和 N](#聪明地使用-n-和-n) -- [聪明地使用命令行历史](#聪明地使用命令行历史) -- [智能 Ctrl-l](#智能-ctrl-l) -- [禁用错误报警声音和图标](#禁用错误报警声音和图标) -- [快速移动当前行](#快速移动当前行) -- [快速添加空行](#快速添加空行) -- [快速编辑自定义宏](#快速编辑自定义宏) -- [快速跳转到源(头)文件](#快速跳转到源头文件) -- [在 GUI 中快速改变字体大小](#在-gui-中快速改变字体大小) -- [根据模式改变光标类型](#根据模式改变光标类型) -- [防止水平滑动的时候失去选择](#防止水平滑动的时候失去选择) -- [重新载入保存文件](#重新载入保存文件) -- [更加智能的当前行高亮](#更加智能的当前行高亮) -- [更快的关键字补全](#更快的关键字补全) -- [改变颜色主题的默认外观](#改变颜色主题的默认外观) - -### [命令](#命令-1) - -- [:global](#global---在所有匹配行执行命令) - 在所有匹配行执行命令 -- [:normal and :execute](#normal-and-execute---脚本梦之队) - 脚本梦之队 -- [:redir](#redir---重定向消息) - 重定向消息 - -### [调试](#调试-1) - -- [常规建议](#常规建议) -- [查看启动日志](#查看启动日志) -- [查看运行时日志](#查看运行时日志) -- [调整日志等级](#调整日志等级) -- [Vim 脚本调试](#vim-脚本调试) -- [语法文件调试](#语法文件调试) - -### [杂项](#杂项-1) - -- [附加资源](#附加资源) -- [Vim 配置集合](#vim-配置集合) -- [内置插件](#内置插件) -- [将 Control 映射到 CapsLock](#将-control-映射到-capslock) -- [复活节彩蛋](#复活节彩蛋) -- [为何使用 hjkl](#为何使用-hjkl) - -### [怪癖](#怪癖-1) - -- [编辑小文件很慢](#编辑小文件很慢) -- [编辑大文件很慢](#编辑大文件很慢) -- [新行用于 NUL](#新行用于-nul) -- [相同部分粘贴 (要不为什么我总要设置‘粘贴’?)](#相同部分粘贴-要不为什么我总要设置粘贴) -- [在终端使用 Esc 延时](#在终端使用-esc-延时) -- [无法重复函数中执行的搜索](#无法重复函数中执行的搜索) - -### [主题列表](#主题列表-1) - -### [插件列表](content/plugins.md) - -### [Neovim](content/neovim.md) - ---- +* * * ## 简介 ### 什么是 Vim? + [Vim](http://www.vim.org) 是一个历史悠久的文本编辑器,可以追溯到 [qed](https://en.wikipedia.org/wiki/QED_(text_editor))。[Bram Moolenaar](https://en.wikipedia.org/wiki/Bram_Moolenaar) 于 1991 年发布初始版本。 @@ -148,6 +143,8 @@ Moolenaar](https://en.wikipedia.org/wiki/Bram_Moolenaar) 于 1991 年发布初 获取 Vim:用包管理器安装或者直接到 vim.org [下载](http://www.vim.org/download.php)。 +对于 Windows 用户,可以从 [我的网盘](https://share.weiyun.com/da2be5937ac0e2bd3abc26355fad1204) 下载。该版本可轻易添加 `python` 、`python3` 、`lua` 等支持,只需要安装 python、lua 即可。 + 讨论使用相关问题最好使用 [vim_use](https://groups.google.com/forum/#!forum/vim_use) 邮件列表或者使用 IRC([Freenode](https://freenode.net)) 的 `#vim` 频道。 欢迎加入我们的中文讨论群:[![QQ](https://img.shields.io/badge/QQ%e7%be%a4-121056965-blue.svg)](https://jq.qq.com/?_wv=1027&k=43DB6SG) @@ -173,9 +170,7 @@ around paragraph_)。 Vim 自带一个交互式的教程,内含你需要了解的最基础的信息,你可以通过终端运行以下命令打开教程: -``` -$ vimtutor -``` + $ vimtutor 不要因为这个看上去很无聊而跳过,按照此教程多练习。你以前用的 IDE 或者其他编辑器很少是有“模式”概念的,因此一开始你会很难适应模式切换。但是你 Vim 使用的越多,[肌肉记忆](https://en.wikipedia.org/wiki/Muscle_memory) 将越容易形成。 @@ -234,11 +229,10 @@ endif 相关帮助: -``` -:h :version -:h feature-list -:h +feature-list -``` + :h :version + :h feature-list + :h +feature-list + :h has-patch 返回主目录 [:arrow_heading_up:](#简介) @@ -246,11 +240,11 @@ endif 为了避免版权问题,我只贴出链接: -- http://people.csail.mit.edu/vgod/vim/vim-cheat-sheet-en.png -- https://cdn.shopify.com/s/files/1/0165/4168/files/preview.png -- http://www.nathael.org/Data/vi-vim-cheat-sheet.svg -- http://michael.peopleofhonoronly.com/vim/vim_cheat_sheet_for_programmers_screen.png -- http://www.rosipov.com/images/posts/vim-movement-commands-cheatsheet.png +- +- +- +- +- 或者在 Vim 中快速打开备忘录:[vim-cheat40](https://github.com/lifepillar/vim-cheat40)。 @@ -278,7 +272,7 @@ Vim 是一个文本编辑器。每次文本都是作为**缓冲区**的一部分 返回主目录 [:arrow_heading_up:](#基础) -## 已激活,已载入,已列出,已命名,缓冲区 +## 已激活、已载入、已列出、已命名的缓冲区 用类似 `vim file1` 的命令启动 Vim 。这个文件的内容将会被加载到缓冲区中,你现在有一个**已载入的缓冲区**。如果你在 Vim 中保存这个文件,缓冲区内容将会被同步到磁盘上(写回文件中)。 @@ -318,14 +312,14 @@ Vim 是一个文本编辑器。每次文本都是作为**缓冲区**的一部分 使用 `:map` 命令家族你可以定义属于你自己的快捷键。该家族的每一个命令都限定在特定的模式下。从技术上来说 Vim 自带高达 12 中模式,其中 6 种可以被映射。另外一些命令作用于多种模式: -|   递归   |   非递归     | 模式                           | -|-----------|---------------|----------------------------------| -| `:map` | `:noremap` | normal, visual, operator-pending | -| `:nmap` | `:nnoremap` | normal | -| `:xmap` | `:xnoremap` | visual | -| `:cmap` | `:cnoremap` | command-line | -| `:omap` | `:onoremap` | operator-pending | -| `:imap` | `:inoremap` | insert | +|   递归   |   非递归     | 模式                           | +| --------- | ------------ | -------------------------------- | +| `:map` | `:noremap` | normal, visual, operator-pending | +| `:nmap` | `:nnoremap` | normal | +| `:xmap` | `:xnoremap` | visual | +| `:cmap` | `:cnoremap` | command-line | +| `:omap` | `:onoremap` | operator-pending | +| `:imap` | `:inoremap` | insert | 例如:这个自定义的快捷键只在普通模式下工作。 @@ -372,12 +366,12 @@ Vim 是一个文本编辑器。每次文本都是作为**缓冲区**的一部分 :h mapping :h 05.3 ``` - + 返回主目录 [:arrow_heading_up:](#基础) -## 映射占位符 +## 映射前置键 -映射占位符(Leader 键)本身就是一个按键映射,默认为 \\。我们可以通过在 `map` 中调用 `` 来为把它添加到其他按键映射中。 +映射前置键(Leader 键)本身就是一个按键映射,默认为 \\。我们可以通过在 `map` 中调用 `` 来为把它添加到其他按键映射中。 ```vim nnoremap h :helpgrep @@ -404,19 +398,19 @@ nnoremap h :helpgrep Vim 为我们提供了如下的寄存器: -| 类型 | 标识 | 读写者 | 是否为只读 | 包含的字符来源 | -| ---- | ---- | ------ | ---------- | -------------- | -| Unnamed | `"` | vim | 否 | 最近一次的复制或删除操作 (`d`, `c`, `s`, `x`, `y`) | -| Numbered | `0`至`9` | vim | 否 | 寄存器 `0`: 最近一次复制。寄存器 `1`: 最近一次删除。寄存器 `2`: 倒数第二次删除,以此类推。对于寄存器 `1` 至 `9`,他们其实是只读的最多包含 9 个元素的队列。这里的队列即为数据类型 [queue](https://en.wikipedia.org/wiki/Queue_(abstract_data_type)) | -| Small delete | `-` | vim | 否 | 最近一次行内删除 | -| Named | `a`至`z`, `A`至`Z` | 用户 | 否 | 如果你通过复制操作存储文本至寄存器 `a`,那么 `a` 中的文本就会被完全覆盖。如果你存储至 `A`,那么会将文本添加给寄存器 `a`,不会覆盖之前已有的文本 | -| Read-only | `:`与`.`和`%` | vim | 是 | `:`: 最近一次使用的命令,`.`: 最近一次添加的文本,`%`: 当前的文件名 | -| Alternate buffer | `#` | vim | 否 | 大部分情况下,这个寄存器是当前窗口中,上一次访问的缓冲区。请参阅 `:h alternate-file` 来获取更多帮助 | -| Expression | `=` | 用户 | 否 | 复制 VimL 代码时,这个寄存器用于存储代码片段的执行结果。比如,在插入模式下复制 `=5+5`,那么这个寄存器就会存入 10 | -| Selection | `+`和`*` | vim | 否 | `*` 和 `+` 是 [剪贴板](#剪贴板) 寄存器 | -| Drop | `~` | vim | 是 | 最后一次拖拽添加至 Vim 的文本(需要 "+dnd" 支持,暂时只支持 GTK GUI。请参阅 `:help dnd` 及 `:help quote~`) | -| Black hole | `_` | vim | 否 | 一般称为黑洞寄存器。对于当前操作,如果你不希望在其他寄存器中保留文本,那就在命令前加上 `_`。比如,`"_dd` 命令不会将文本放到寄存器 `"`、`1`、`+` 或 `*` 中 | -| Last search pattern | `/` | vim | 否 | 最近一次通过 `/`、`?` 或 `:global` 等命令调用的匹配条件 | +| 类型 | 标识 | 读写者 | 是否为只读 | 包含的字符来源 | +| ------------------- | ------------------ | ------ | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Unnamed | `"` | vim | 否 | 最近一次的复制或删除操作 (`d`, `c`, `s`, `x`, `y`) | +| Numbered | `0`至`9` | vim | 否 | 寄存器 `0`: 最近一次复制。寄存器 `1`: 最近一次删除。寄存器 `2`: 倒数第二次删除,以此类推。对于寄存器 `1` 至 `9`,他们其实是只读的最多包含 9 个元素的队列。这里的队列即为数据类型 [queue](https://en.wikipedia.org/wiki/Queue_(abstract_data_type)) | +| Small delete | `-` | vim | 否 | 最近一次行内删除 | +| Named | `a`至`z`, `A`至`Z` | 用户 | 否 | 如果你通过复制操作存储文本至寄存器 `a`,那么 `a` 中的文本就会被完全覆盖。如果你存储至 `A`,那么会将文本添加给寄存器 `a`,不会覆盖之前已有的文本 | +| Read-only | `:`与`.`和`%` | vim | 是 | `:`: 最近一次使用的命令,`.`: 最近一次添加的文本,`%`: 当前的文件名 | +| Alternate buffer | `#` | vim | 否 | 大部分情况下,这个寄存器是当前窗口中,上一次访问的缓冲区。请参阅 `:h alternate-file` 来获取更多帮助 | +| Expression | `=` | 用户 | 否 | 复制 VimL 代码时,这个寄存器用于存储代码片段的执行结果。比如,在插入模式下复制 `=5+5`,那么这个寄存器就会存入 10 | +| Selection | `+`和`*` | vim | 否 | `*` 和 `+` 是 [剪贴板](#剪贴板) 寄存器 | +| Drop | `~` | vim | 是 | 最后一次拖拽添加至 Vim 的文本(需要 "+dnd" 支持,暂时只支持 GTK GUI。请参阅 `:help dnd` 及 `:help quote~`) | +| Black hole | `_` | vim | 否 | 一般称为黑洞寄存器。对于当前操作,如果你不希望在其他寄存器中保留文本,那就在命令前加上 `_`。比如,`"_dd` 命令不会将文本放到寄存器 `"`、`1`、`+` 或 `*` 中 | +| Last search pattern | `/` | vim | 否 | 最近一次通过 `/`、`?` 或 `:global` 等命令调用的匹配条件 | 只要不是只读的寄存器,用户都有权限修改它的内容,比如: @@ -458,22 +452,22 @@ Vim 为我们提供了如下的寄存器: 范围的使用是十分直观的。以下为一些例子(其中,`:d` 为 `:delete` 的缩写): -| 命令 | 操作的行 | -| ---- | -------- | -| `:d` | 当前行 | -| `:.d` | 当前行 | -| `:1d` | 第一行 | -| `:$d` | 最后一行 | -| `:1,$d` | 所有行 | -| `:%d` | 所有行(这是 `1,$` 的语法糖) | -| `:.,5d` | 当前行至第 5 行 | -| `:,5d` | 同样是当前行至第 5 行 | -| `:,+3d` | 当前行及接下来的 3 行 | -| `:1,+3d` | 第一行至当前行再加 3 行 | -| `:,-3d` | 当前行及向上的 3 行(Vim 会弹出提示信息,因为这是一个保留的范围) | -| `:3,'xdelete` | 第三行至[标注](#标注) 为 x 的那一行 | -| `:/^foo/,$delete` | 当前行以下,以字符 "foo" 开头的那一行至结尾 | -| `:/^foo/+1,$delete` | 当前行以下,以字符 "foo" 开头的那一行的下一行至结尾 | +| 命令 | 操作的行 | +| ------------------- | ----------------------------------------------------------------- | +| `:d` | 当前行 | +| `:.d` | 当前行 | +| `:1d` | 第一行 | +| `:$d` | 最后一行 | +| `:1,$d` | 所有行 | +| `:%d` | 所有行(这是 `1,$` 的语法糖) | +| `:.,5d` | 当前行至第 5 行 | +| `:,5d` | 同样是当前行至第 5 行 | +| `:,+3d` | 当前行及接下来的 3 行 | +| `:1,+3d` | 第一行至当前行再加 3 行 | +| `:,-3d` | 当前行及向上的 3 行(Vim 会弹出提示信息,因为这是一个保留的范围) | +| `:3,'xdelete` | 第三行至[标注](#标注) 为 x 的那一行 | +| `:/^foo/,$delete` | 当前行以下,以字符 "foo" 开头的那一行至结尾 | +| `:/^foo/+1,$delete` | 当前行以下,以字符 "foo" 开头的那一行的下一行至结尾 | 需要注意的是,`;` 也可以用于表示范围。区别在于,`a,b` 的 `b` 是以当前行作为参考的。而 `a;b` 的 `b` 是以 `a` 行作为参考的。举个例子,现在你的光标在第 5 行。这时 `:1,+1d` 会删除第 1 行至第 6 行,而 `:1;+1d` 会删除第 1 行和第 2 行。 @@ -502,34 +496,34 @@ Vim 为我们提供了如下的寄存器: 你可以使用标注功能来标记一个位置,也就是记录文件某行的某个位置。 -| 标注 | 设置者 | 使用 | -| ---- | ------ | ---- | -| `a`-`z` | 用户 | 仅对当前的一个文件生效,也就意味着只可以在当前文件中跳转 | -| `A`-`Z` | 用户 | 全局标注,可以作用于不同文件。大写标注也称为「文件标注」。跳转时有可能会切换到另一个缓冲区 | +| 标注 | 设置者 | 使用 | +| ------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `a`-`z` | 用户 | 仅对当前的一个文件生效,也就意味着只可以在当前文件中跳转 | +| `A`-`Z` | 用户 | 全局标注,可以作用于不同文件。大写标注也称为「文件标注」。跳转时有可能会切换到另一个缓冲区 | | `0`-`9` | viminfo | `0` 代表 viminfo 最后一次被写入的位置。实际使用中,就代表 Vim 进程最后一次结束的位置。`1` 代表 Vim 进程倒数第二次结束的位置,以此类推 | -如果想跳转到指定的标注,你可以先按下 `'`、`g'`、`\`` 或 `g\`` 然后按下标注名。 +如果想跳转到指定的标注,你可以先按下 `'` / `g'` 或者 `` ` `` / `` g` `` 然后按下标注名。 -如果你想定义当前文件中的标注,可以先按下 `m` 再按下标注名。比如,按下 `mm` 就可以把当前位置标注为 `m`。在这之后,如果你的光标切换到了文件的其他位置,只需要通过 `'m` 或者 `\`m` 即可回到刚才标注的行。区别在于,`'m` 会跳转回被标记行的第一个非空字符,而 `\`m` 会跳转回被标记行的被标记列。根据 viminfo 的设置,你可以在退出 Vim 的时候保留小写字符标注。请参阅 `:h viminfo-'` 来获取更多帮助。 +如果你想定义当前文件中的标注,可以先按下 `m` 再按下标注名。比如,按下 `mm` 就可以把当前位置标注为 `m`。在这之后,如果你的光标切换到了文件的其他位置,只需要通过 `'m` 或者 `\`m`即可回到刚才标注的行。区别在于,`'m`会跳转回被标记行的第一个非空字符,而`\`m`会跳转回被标记行的被标记列。根据 viminfo 的设置,你可以在退出 Vim 的时候保留小写字符标注。请参阅`:h viminfo-'\` 来获取更多帮助。 -如果你想定义全局的标注,可以先按下 `m` 再按下大写英文字符。比如,按下 `mM` 就可以把当前文件的当前位置标注为 `M`。在这之后,就算你切换到其他的缓冲区,依然可以通过 `'M` 或 `\`M` 跳转回来。 +如果你想定义全局的标注,可以先按下 `m` 再按下大写英文字符。比如,按下 `mM` 就可以把当前文件的当前位置标注为 `M`。在这之后,就算你切换到其他的缓冲区,依然可以通过 `'M` 或 `\`M\` 跳转回来。 关于跳转,还有以下的方式: -| 按键 | 跳转至 | -| ---- | ------ | -| `'[` 与 `` `[ `` | 上一次修改或复制的第一行或第一个字符 | -| `']` 与 `` `] `` | 上一次修改或复制的最后一行或最后一个字符 | -| `'<` 与 `` `< `` | 上一次在可视模式下选取的第一行或第一个字符 | -| `'>` 与 `` `> `` | 上一次在可视模式下选取的最后一行或最后一个字符 | -| `''` 与 `` `' `` | 上一次跳转之前的光标位置 | -| `'"` 与 `` `" `` | 上一次关闭当前缓冲区时的光标位置 | -| `'^` 与 `` `^ `` | 上一次插入字符后的光标位置 | -| `'.` 与 `` `. `` | 上一次修改文本后的光标位置 | -| `'(` 与 `` `( `` | 当前句子的开头 | -| `')` 与 `` `) `` | 当前句子的结尾 | -| `'{` 与 `` `{ `` | 当前段落的开头 | -| `'}` 与 `` `} `` | 当前段落的结尾 | +| 按键 | 跳转至 | +| --------------- | ---------------------------------------------- | +| `'[` 与 `` `[`` | 上一次修改或复制的第一行或第一个字符 | +| `']` 与 `` `]`` | 上一次修改或复制的最后一行或最后一个字符 | +| `'<` 与 `` `<`` | 上一次在可视模式下选取的第一行或第一个字符 | +| `'>` 与 `` `>`` | 上一次在可视模式下选取的最后一行或最后一个字符 | +| `''` 与 `` `'`` | 上一次跳转之前的光标位置 | +| `'"` 与 `` `"`` | 上一次关闭当前缓冲区时的光标位置 | +| `'^` 与 `` `^`` | 上一次插入字符后的光标位置 | +| `'.` 与 `` `.`` | 上一次修改文本后的光标位置 | +| `'(` 与 `` `(`` | 当前句子的开头 | +| `')` 与 `` `)`` | 当前句子的结尾 | +| `'{` 与 `` `{`` | 当前段落的开头 | +| `'}` 与 `` `}`` | 当前段落的结尾 | 标注也可以搭配 [范围](#范围) 一起使用。前面提到过,如果你在可视模式下选取一些文本,然后按下 `:`,这时候你会发现命令行已经被填充了 `:'<,'>`。对照上面的表格,现在你应该明白了,这段代表的就是可视模式下选取的范围。 @@ -545,20 +539,20 @@ Vim 在插入模式中为我们提供了多种补全方案。如果有多个补 针对不同的补全方案,Vim 为我们提供了不同的按键映射。这些映射都是在**插入模式中**通过 Ctrl + x 来触发: -| 映射 | 类型 | 帮助文档 | -| ---- | ---- | -------- | -| `` | 整行 | `:h i^x^l` | -| `` | 当前缓冲区中的关键字 | `:h i^x^n` | -| `` | 字典(请参阅 `:h 'dictionary'`)中的关键字 | `:h i^x^k` | +| 映射 | 类型 | 帮助文档 | +| ------------ | ----------------------------------------------- | ---------- | +| `` | 整行 | `:h i^x^l` | +| `` | 当前缓冲区中的关键字 | `:h i^x^n` | +| `` | 字典(请参阅 `:h 'dictionary'`)中的关键字 | `:h i^x^k` | | `` | 同义词字典(请参阅 `:h 'thesaurus'`)中的关键字 | `:h i^x^t` | -| `` | 当前文件以及包含的文件中的关键字 | `:h i^x^i` | -| `` | 标签 | `:h i^x^]` | -| `` | 文件名 | `:h i^x^f` | -| `` | 定义或宏定义 | `:h i^x^d` | -| `` | Vim 命令 | `:h i^x^v` | -| `` | 用户自定义补全(通过 `'completefunc'` 定义) | `:h i^x^u` | -| `` | Omni Completion(通过 `'omnifunc'` 定义) | `:h i^x^o` | -| `s` | 拼写建议 | `:h i^Xs` | +| `` | 当前文件以及包含的文件中的关键字 | `:h i^x^i` | +| `` | 标签 | `:h i^x^]` | +| `` | 文件名 | `:h i^x^f` | +| `` | 定义或宏定义 | `:h i^x^d` | +| `` | Vim 命令 | `:h i^x^v` | +| `` | 用户自定义补全(通过 `'completefunc'` 定义) | `:h i^x^u` | +| `` | Omni Completion(通过 `'omnifunc'` 定义) | `:h i^x^o` | +| `s` | 拼写建议 | `:h i^Xs` | 尽管用户自定义补全与 Omni Completion 是不同的,但他们做的事情基本一致。共同点在于,他们都是一个监听当前光标位置的函数,返回值为一系列的补全建议。用户自定义补全是由用户定义的,基于用户的个人用途,因此你可以根据自己的喜好和需求随意定制。而 Omni Completion 是针对文件类型的补全,比如在 C 语言中补全一个结构体(struct)的成员(members),或者补全一个类的方法,因而它通常都是由文件类型插件设置和调用的。 @@ -567,6 +561,7 @@ Vim 在插入模式中为我们提供了多种补全方案。如果有多个补 如果你想配置弹出菜单的行为,请一定要看一看 `:h 'completeopt'` 这篇帮助文档。默认的配置已经不错了,但我个人(原作者)更倾向于把 "noselect" 加上。 请参阅以下文档获取更多帮助: + ```vim :h ins-completion :h popupmenu-keys @@ -641,10 +636,10 @@ au BufNewFile,BufRead *.rb,*.rbw setf ruby Vim 中的跳转命令,包括 `'`、`` ` ``、`G`、`/`、`?`、`n`、`N`、`%`、`(`、`)`、`[[`、`]]`、`{`、`}`、`:s`、`:tag`、`L`、`M`、`H` 以及开始编辑一个新文件的命令。 -| 列表 | 显示所有条目 | 跳转到上一个位置 | 跳转到下一个位置 | -| ---- | ------------ | ---------------- | ---------------- | -| 跳转历史 | `:jumps` | `[count]` | `[count]` | -| 变更历史 | `:changes` | `[count]g;` | `[count]g,` | +| 列表 | 显示所有条目 | 跳转到上一个位置 | 跳转到下一个位置 | +| -------- | ------------ | ---------------- | ---------------- | +| 跳转历史 | `:jumps` | `[count]` | `[count]` | +| 变更历史 | `:changes` | `[count]g;` | `[count]g,` | 如果你执行第二列的命令显示所有条目,这时 Vim 会用 `>` 标记来为你指示当前位置。通常这个标记位于 1 的下方,也就代表最后一次的位置。 @@ -679,13 +674,11 @@ oquux 那么现在,Vim 中会显示三行文本,分别是 "foo"、"bar" 和 "quux"。这时候,存储的树形结构如下: -``` - foo(1) - / - bar(2) - / \ -baz(3) quux(4) -``` + foo(1) + / + bar(2) + / \ + baz(3) quux(4) 这个树形结构共包含四次改动,括号中的数字就代表时间顺序。 @@ -695,13 +688,13 @@ baz(3) quux(4) 与之对应的是按时间遍历,对应的按键是 `g-` 和 `g+`。对于上面的例子,按下 `g-` 会首先回退到 "baz" 节点。再次按下 `g-` 会回退到 "bar" 节点。 -| 命令/按键 | 执行效果 | -| --------- | -------- | -| `[count]u` 或 `:undo [count]` | 回退到 `[count]` 次改动之前 | -| `[count]` 或 `:redo [count]` | 重做 `[count]` 次改动 | -| `U` | 回退至最新的改动 | +| 命令/按键 | 执行效果 | +| ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `[count]u` 或 `:undo [count]` | 回退到 `[count]` 次改动之前 | +| `[count]` 或 `:redo [count]` | 重做 `[count]` 次改动 | +| `U` | 回退至最新的改动 | | `[count]g-` 或 `:earlier [count]?` | 根据时间回退到 `[count]` 次改动之前。"?" 为 "s"、"m"、"h"、"d" 或 "f"之一。例如,`:earlier 2d` 会回退到两天之前。`:earlier 1f` 则会回退到最近一次文件保存时的内容 | -| `[count]g+` 或 `:later [count]?` | 类似 `g-`,但方向相反 | +| `[count]g+` 或 `:later [count]?` | 类似 `g-`,但方向相反 | 内容变更记录会储存在内存中,当 Vim 退出时就会清空。如果需要持久化存储内容变更记录,请参阅[备份文件,交换文件,撤销文件以及viminfo文件的处理](#备份文件交换文件撤销文件以及viminfo文件的处理)章节的内容。 @@ -728,14 +721,14 @@ Vim 中,全局位置信息表只能有一个,但每一个窗口都可以有 以下为两者的操作比较: -| 动作 | 全局位置信息表 | 局部位置信息表 | -| ---- | -------------- | -------------- | -| 打开窗口 | `:copen` | `:lopen` | -| 关闭窗口 | `:cclose` | `:lclose` | -| 下一个条目 | `:cnext` | `:lnext` | -| 上一个条目 | `:cprevious` | `:lprevious` | -| 第一个条目 | `:cfirst` | `:lfirst` | -| 最后一个条目 | `:clast` | `:llast` | +| 动作 | 全局位置信息表 | 局部位置信息表 | +| ------------ | -------------- | -------------- | +| 打开窗口 | `:copen` | `:lopen` | +| 关闭窗口 | `:cclose` | `:lclose` | +| 下一个条目 | `:cnext` | `:lnext` | +| 上一个条目 | `:cprevious` | `:lprevious` | +| 第一个条目 | `:cfirst` | `:lfirst` | +| 最后一个条目 | `:clast` | `:llast` | 请参阅 `:h :cc` 以及底下的内容,来获取更多命令的帮助。 @@ -840,14 +833,14 @@ q 在 Vim 中,有以下 6 中折叠类型: -| 折叠方式 | 概述 | -| -------- | ---- | -| diff | 在「比较窗口」中折叠未改变的文本 | -| expr | 使用 `'foldexpr'` 来创建新的折叠逻辑 | -| indent | 基于缩进折叠 | -| manual | 使用 `zf`、`zF` 或 `:fold` 来自定义折叠 | -| marker | 根据特定的文本标记折叠(通常用于代码注释) | -| syntax | 根据语法折叠,比如折叠 `if` 代码块 | +| 折叠方式 | 概述 | +| -------- | ------------------------------------------ | +| diff | 在「比较窗口」中折叠未改变的文本 | +| expr | 使用 `'foldexpr'` 来创建新的折叠逻辑 | +| indent | 基于缩进折叠 | +| manual | 使用 `zf`、`zF` 或 `:fold` 来自定义折叠 | +| marker | 根据特定的文本标记折叠(通常用于代码注释) | +| syntax | 根据语法折叠,比如折叠 `if` 代码块 | **注意**:折叠功能可能会显著地影响性能。如果你在使用折叠功能的时候出现了打字卡顿之类的问题,请考虑使用 [FastFold 插件](https://github.com/Konfekt/FastFold)。这个插件可以让 Vim 按需更新折叠内容,而不是一直调用。 @@ -886,13 +879,13 @@ q 以上提到的很多概念,都有一个局部化(非全局)的版本: -| 全局 | 局部 | 作用域 | 帮助文档 | -| ---- | ---- | ------ | -------- | -| `:set` | `:setlocal` | 缓冲区或窗口 | `:h local-options` | -| `:map` | `:map ` | 缓冲区 | `:h :map-local` | -| `:autocmd` | `:autocmd * ` | 缓冲区 | `:h autocmd-buflocal` | -| `:cd` | `:lcd` | 窗口 | `:h :lcd` | -| `:` | `:` | 缓冲区 | `:h maploacalleader` | +| 全局 | 局部 | 作用域 | 帮助文档 | +| ----------- | --------------------- | ------------ | --------------------- | +| `:set` | `:setlocal` | 缓冲区或窗口 | `:h local-options` | +| `:map` | `:map ` | 缓冲区 | `:h :map-local` | +| `:autocmd` | `:autocmd * ` | 缓冲区 | `:h autocmd-buflocal` | +| `:cd` | `:lcd` | 窗口 | `:h :lcd` | +| `:` | `:` | 缓冲区 | `:h maploacalleader` | 变量也有不同的作用域,详细内容请参考 [Vim scripting 的文档](http://vimdoc.sourceforge.net/htmldoc/usr_41.html)。 @@ -906,9 +899,9 @@ Vim 自带了一套很完善的帮助文档,它们是一个个有固定排版 一些关于帮助主题的简单规则: -* 用单引号把文本包起来表示选项,如:`:h 'textwidth'` -* 以小括号结尾表示 VimL 函数,如:`:h reverse()` -* 以英文冒号开头表示命令,如:`:h :echo` +- 用单引号把文本包起来表示选项,如:`:h 'textwidth'` +- 以小括号结尾表示 VimL 函数,如:`:h reverse()` +- 以英文冒号开头表示命令,如:`:h :echo` 使用快捷键 `` (这是 ctrl+d)来列出所有包含你当前输入的内容的帮助主题。如:`:h tab` 会列出所有包含 `tab` 主题,从 `softtabstop` 到 `setting-guitablabel` (译者注:根据安装的插件不同列出的选项也会不同)。 @@ -922,14 +915,13 @@ Vim 自带了一套很完善的帮助文档,它们是一个个有固定排版 上面的命令会在所有的帮助文件中搜索“backwards”,然后跳转到第一个匹配的位置。所有的匹配位置都会被添加到全局位置信息表,用 `:cp / :cn` 可以在匹配位置之间进行切换。或者用 `:copen` 命令来打开全局位置信息表,将光标定位到你想要的位置,再按 回车就可以跳转到该匹配项。详细说明请参考 `:h quickfix`。 - ### 获取离线帮助(补充) 这个列表最初发表在 [vim_dev](https://groups.google.com/forum/#!forum/vim_dev),由 @chrisbra 编辑的,他是 Vim 开发人员中最活跃的一个。 经过一些微小的改动后,重新发布到了这里。 ---- +* * * 如果你知道你想要找什么,使用帮助系统的搜索会更简单一些,因为搜索出的主题都带有固定的格式。 @@ -955,7 +947,7 @@ Vim 自带了一套很完善的帮助文档,它们是一个个有固定排版 8. 命令定义用 "command-" 开头,如用 `:h command-bar` 来查看自定义命令中'!'的作用。 -9. 窗口管理类的命令是以 "CTRL-W" 开头的,所以你可以用 `:h CTRL-W_*` 来查找相应的帮助(译者注:'*'同样为占位符)(如:`:h CTRL-W_p` 查看切换到之前访问的窗口命令的解释)。如果你想找窗口处理的命令,还可以通过访问 `:h windows.txt` 并逐行向下浏览,所有窗口管理的命令都在这里了。 +9. 窗口管理类的命令是以 "CTRL-W" 开头的,所以你可以用 `:h CTRL-W_*` 来查找相应的帮助(译者注:'\*'同样为占位符)(如:`:h CTRL-W_p` 查看切换到之前访问的窗口命令的解释)。如果你想找窗口处理的命令,还可以通过访问 `:h windows.txt` 并逐行向下浏览,所有窗口管理的命令都在这里了。 10. 执行类的命令以":"开头,即:`:h :s` 讲的是 ":s" 命令。 @@ -983,22 +975,18 @@ Vim 自带了一套很完善的帮助文档,它们是一个个有固定排版 22. 关于包含的语法文件的文档的帮助话题格式是 `:h ft-*-syntax`。如:`:h ft-c-syntax` 说的就是C语言语法文件以及它所提供的选项。有的语法文件还会带有自动完成(`:h ft-php-omni`)或文件类型插件(`:h ft-tex-plugin`)相关的章节可以查看。 - 另外在每个帮助页的顶端通常会包含一个用户文档链接(更多的从从用户的角度出发来主角命令的功能和用法,不涉及那么多细节)。如:`:h pattern.txt` 里包含了 `:h 03.9` 和 `:h usr_27` 两个章节的链接。 - ### 获取在线帮助 如果你遇到了无法解决的问题,或者需要指引的话,可以参考 [Vim 使用](https://groups.google.com/forum/#!forum/vim_use)邮件列表。 [IRC](https://de.wikipedia.org/wiki/Internet_Relay_Chat) 也是一个很不错的资源。 [Freenode](https://freenode.net/) 上的 `#vim` 频道很庞大,并且里面有许多乐于助人的人。 如果你想给 Vim 提交 Bug 的话,可以使用 [vim_dev](https://groups.google.com/forum/#!forum/vim_dev) 邮件列表。 - ### 执行自动命令 你可以触发任何事件,如:`:doautocmd BufRead`。 - #### 用户自定义事件 对于插件而言,创建你自己的自定义事件有时非常有用。 @@ -1029,7 +1017,6 @@ endif 帮助文档:`:h User` - #### 内部自带事件 默认情况下,自动命令不能嵌套!如果某个自动命令执行了一个命令,这个命令再依次触发其它的事件,这是不可能的。 @@ -1050,7 +1037,6 @@ autocmd VimEnter * nested edit $MYVIMRC 帮助文档:`:h autocmd-nested` - ### 剪切板 如果你想在没有GUI支持的Unix系统中使用 Vim 的 `'clipboard'` 选项,则需要 `+clipboard` 以及可选的 `+xterm_clipboard` 两个[特性](#what-kind-of-vim-am-i-running)支持。 @@ -1110,20 +1096,18 @@ set guioptions+=a 选择的工作工模大致是这样的: -``` -Program A: -Program A:声称对 CLIPBOARD 的所有权 -Program B: -Program B:发现CLIPBOARD的所有权被Program A持有 -Program B:从Program A请求数据 -Program A:响应这个请求并发送数据给Program B -Program B:从Program A接收数据并插入到窗口中 -``` + Program A: + Program A:声称对 CLIPBOARD 的所有权 + Program B: + Program B:发现CLIPBOARD的所有权被Program A持有 + Program B:从Program A请求数据 + Program A:响应这个请求并发送数据给Program B + Program B:从Program A接收数据并插入到窗口中 -| 选择 | 何时使用 | 如何粘贴 | 如何在 Vim 中访问 | -|--------|-------------------|-------------------|--------------------| -| PRIMARY | 选择文本 | 鼠标中键, shift+insert | `*` 寄存器 | -| CLIPBOARD | 选择文本并按 `ctrl+c` | `ctrl+v` | `+`寄存器 | +| 选择 | 何时使用 | 如何粘贴 | 如何在 Vim 中访问 | +| --------- | --------------------- | ---------------------- | ----------------- | +| PRIMARY | 选择文本 | 鼠标中键, shift+insert | `*` 寄存器 | +| CLIPBOARD | 选择文本并按 `ctrl+c` | `ctrl+v` | `+`寄存器 | **注意**:X 服务器并不会保存选择(不仅仅是 CLIPBOARD 选择)!因此在关闭了相应的程序后,你用 `ctrl+c` 复制的内容将丢失。 @@ -1183,7 +1167,6 @@ $ diff ~/.vim/vimrc ~/.vim/files/backup/vimrc-vimbackup 帮助文档:`:h backup` - **交换文件**: 假设你有一个非常棒的科幻小说的构思。在按照故事情节已经写了好几个小时几十万字的时候..忽然停电了!而那时你才想起来你上次保存 `~/来自外太空的邪恶入侵者.txt` 是在.. 好吧,你从来没有保存过。 @@ -1196,14 +1179,12 @@ $ diff ~/.vim/vimrc ~/.vim/files/backup/vimrc-vimbackup 帮助文档:`:h swap-file` 和 `:h usr_11` - **撤销文件**: [内容变更历史记录](#%E5%86%85%E5%AE%B9%E5%8F%98%E6%9B%B4%E5%8E%86%E5%8F%B2%E8%AE%B0%E5%BD%95)是保存在内存中的,并且会在 Vim 退出时清空。如果你想让它持久化到磁盘中,可以设置 `:set undofile`。这会把文件 `~/foo.c` 的撤销文件保存在 `~/foo.c.un~`。 帮助文档:`:h 'undofile'` 和 `:h undo-persistence` - **viminfo 文件**: 备份文件、交换文件和撤销文件都是与文本状态相关的,而 viminfo 文件是用来保存在 Vim 退出时可能会丢失的其它的信息的。包括历史记录(命令历史、搜索历史、输入历史)、寄存器内容、标注、缓冲区列表、全局变量等等。 @@ -1212,7 +1193,7 @@ $ diff ~/.vim/vimrc ~/.vim/files/backup/vimrc-vimbackup 帮助文档:`:h viminfo` 和 `:h 'viminfo'` ---- +* * * 如果你跟我一样,也喜欢把这些文件放到一个位置(如:`~/.vim/files`)的话,可以使用下面的配置: @@ -1238,7 +1219,6 @@ endif 注意:如果你在一个多用户系统中编辑某个文件时, Vim 提示你交换文件已经存在的话,可能是因为有其他的用户此时正在编辑这个文件。而如果将交换文件放到自己的home目录的话,这个功能就失效了。 - ### 编辑远程文件 Vim 自带的 netrw 插件支持对远程文件的编辑。实际上它将远程的文件通过 scp 复制到本地的临时文件中,再用那个文件打开一个缓冲区,然后在保存时把文件再复制回远程位置。 @@ -1251,12 +1231,10 @@ Vim 自带的 netrw 插件支持对远程文件的编辑。实际上它将远程 如果你已经设置了 `~/.ssh/config`,SSH 会自动读取这里的配置: -``` -Host awesome - HostName awesome.site.com - Port 1234 - User bram -``` + Host awesome + HostName awesome.site.com + Port 1234 + User bram 如果你的 `~/.ssh/config` 中有以上的内容,那么下面的命令就可以正常执行了: @@ -1268,22 +1246,20 @@ Host awesome 确保你已经看过了 `:h netrw-ssh-hack` 和 `:h g:netrw_ssh_cmd`。 ---- +* * * 另外一种编辑远程文件的方法是使用 [sshfs](https://wiki.archlinux.org/index.php/Sshfs),它会用 [FUSE](https://en.wikipedia.org/wiki/Filesystem_in_Userspace) 来挂载远程的文件系统到你本地的系统当中。 - ### 插件管理 [Pathogen](https://github.com/tpope/vim-pathogen)是第一个比较流行的插件管理工具。实际上它只是修改了 _runtimepath_ (`:h 'rtp'`) 来引入所有放到该目录下的文件。你需要自己克隆插件的代码仓库到那个目录。 真正的插件管理工具会在 Vim 中提供帮助你安装或更新插件的命令。以下是一些常用的插件管理工具: -* [dein](https://github.com/Shougo/dein.vim) -* [plug](https://github.com/junegunn/vim-plug) -* [vim-addon-manager](https://github.com/MarcWeber/vim-addon-manager) -* [vundle](https://github.com/VundleVim/Vundle.vim) - +- [dein](https://github.com/Shougo/dein.vim) +- [plug](https://github.com/junegunn/vim-plug) +- [vim-addon-manager](https://github.com/MarcWeber/vim-addon-manager) +- [vundle](https://github.com/VundleVim/Vundle.vim) ### 多行编辑 @@ -1342,17 +1318,16 @@ set virtualedit=all 鉴于Tag文件只是知道某个符号是在哪里定义的,cscope的数据库里的数据信息就多的多了: -* 符号是在哪里定义的? -* 符号是在哪里被使用的? -* 这个全局符号定义了什么? -* 这个变量是在哪里被赋值的? -* 这个函数在源文件的哪个位置? -* 哪些函数调用了这个函数? -* 这个函数调用了哪些函数? -* "out of space"消息是从哪来的? -* 在目录结构中当前的源文件在哪个位置? -* 哪些文件引用了这个头文件? - +- 符号是在哪里定义的? +- 符号是在哪里被使用的? +- 这个全局符号定义了什么? +- 这个变量是在哪里被赋值的? +- 这个函数在源文件的哪个位置? +- 哪些函数调用了这个函数? +- 这个函数调用了哪些函数? +- "out of space"消息是从哪来的? +- 在目录结构中当前的源文件在哪个位置? +- 哪些文件引用了这个头文件? #### 1. 构建数据库 @@ -1387,7 +1362,6 @@ $ cscope -bq (当然你可以添加多个连接。) - #### 3. 查询数据库 ```vim @@ -1396,20 +1370,19 @@ $ cscope -bq 如:`:cs find d foo` 会列出 `foo(...)` 调用的所有函数。 -| Kind | 说明 | -|------|-------------| -| s | **s**ymbol:查找使用该符号的引用 | -| g | **g**lobal:查找该全局符号的定义 | -| c | **c**alls:查找调用当前方法的位置 | -| t | **t**ext:查找出现该文本的位置 | -| e | **e**grep:使用 egrep 搜索当前单词 | -| f | **f**ile:打开文件名 | +| Kind | 说明 | +| ---- | -------------------------------------- | +| s | **s**ymbol:查找使用该符号的引用 | +| g | **g**lobal:查找该全局符号的定义 | +| c | **c**alls:查找调用当前方法的位置 | +| t | **t**ext:查找出现该文本的位置 | +| e | **e**grep:使用 egrep 搜索当前单词 | +| f | **f**ile:打开文件名 | | i | **i**ncludes:查询引入了当前文件的文件 | -| d | **d**epends:查找当前方法调用的方法 | +| d | **d**epends:查找当前方法调用的方法 | 推荐一些比较方便的映射,如: - ```vim nnoremap cs :cscope find s =expand('') nnoremap cg :cscope find g =expand('') @@ -1425,14 +1398,12 @@ nnoremap cd :cscope find d =expand('') 帮助文档:`:h cscope` - ### MatchIt 由于 Vim 是用 C 语言编写的,因此许多功能都假设使用类似 C 语言的语法。默认情况下,如果你的光标在 `{` 或 `#endif` , 就可以使用 `%` 跳转到与之匹配的 `}` 或 `#ifdef`。 Vim 自带了一个名为 matchit.vim 的插件,但是默认没有启用。启用后可以用 `%` 在HTML相匹配的标签或 VimL 的 if/else/endif 块之间进行跳转,它还带来了一些新的命令。 - ##### 在 Vim 8 中安装 ```vim @@ -1539,7 +1510,7 @@ nnoremap [ :put! =repeat(nr2char(10), v:count1)'[ nnoremap ] :put =repeat(nr2char(10), v:count1) ``` -设置之后,连续按下 5 [ 空格 在当前行上方插入 5 个空行。 +设置之后,连续按下 5 \[ 空格 在当前行上方插入 5 个空行。 ## 快速编辑自定义宏 @@ -1599,7 +1570,7 @@ endif ## 防止水平滑动的时候失去选择 -如果你选中了一行或多行,那么你可以用 <> 来调整他们的缩进。但在调整之后就不会保持选中状态了。 +如果你选中了一行或多行,那么你可以用 <> 来调整他们的缩进。但在调整之后就不会保持选中状态了。 你可以连续按下 g v 来重新选中他们,请参考 `:h gv`。因此,你可以这样来配置映射: @@ -1636,6 +1607,7 @@ autocmd InsertEnter,WinLeave * set nocursorline set complete-=i " disable scanning included files set complete-=t " disable searching tags ``` + ## 改变颜色主题的默认外观 如果你想让状态栏在颜色主题更改后依然保持灰色,那么只需要这样设置: @@ -1654,12 +1626,11 @@ autocmd ColorScheme lucius highlight StatusLine ctermbg=darkgray cterm=NONE guib 下面的命令都比较有用,最好了解一下。用 `:h :` 来了解更多关于它们的信息,如:`:h :global`。 - ### :global 和 :vglobal - 在所有匹配行执行命令 在所有符合条件的行上执行某个命令。如: `:global /regexp/ print` 会在所有包含 "regexp" 的行上执行 `print` 命令(译者注:regexp 有正则表达式的意思,该命令同样支持正则表达式,在所有符合正则表达式的行上执行指定的命令)。 -趣闻:你们可能都知道老牌的 grep 命令,一个由 Ken Thompson 编写的过滤程序。它是干什么用的呢?它会输出所有匹配指定正则表达式的行!现在猜一下 `:global /regexp/ print` 的简写形式是什么?没错!就是 `:g/re/p` 。 Ken Thompsom 在编写 grep 程序的时候是受了 vi `:global` 的启发。(译者注: https://robots.thoughtbot.com/how-grep-got-its-name) +趣闻:你们可能都知道老牌的 grep 命令,一个由 Ken Thompson 编写的过滤程序。它是干什么用的呢?它会输出所有匹配指定正则表达式的行!现在猜一下 `:global /regexp/ print` 的简写形式是什么?没错!就是 `:g/re/p` 。 Ken Thompsom 在编写 grep 程序的时候是受了 vi `:global` 的启发。(译者注: 既然它的名字是 `:global`,理应仅作用在所有行上,但是它也是可以带范围限制的。假设你想使用 `:delete` 命令删除从当前行到下一个空行(由正则表达式 `^$` 匹配)范围内所有包含 "foo" 的行: @@ -1669,8 +1640,6 @@ autocmd ColorScheme lucius highlight StatusLine ctermbg=darkgray cterm=NONE guib 如果要在所有 _不_ 匹配的行上执行命令的话,可以使用 `:global!` 或是它的别名 `:vglobal` ( V 代表的是 inVerse )。 - - ### :normal 和 :execute - 脚本梦之队 这两个命令经常在 Vim 的脚本里使用。 @@ -1694,7 +1663,6 @@ autocmd ColorScheme lucius highlight StatusLine ctermbg=darkgray cterm=NONE guib :execute 'normal!' n . 'j' ``` - ### :redir - 重定向消息 许多命令都会输出消息,`:redir` 用来重定向这些消息。它可以将消息输出到文件、[寄存器](#寄存器)或是某个变量中。 @@ -1717,19 +1685,31 @@ autocmd ColorScheme lucius highlight StatusLine ctermbg=darkgray cterm=NONE guib 帮助文档:`:h :redir` # 调试 + ## 常规建议 + ## 查看启动日志 + ## 查看运行时日志 + ## 调整日志等级 + ## vim 脚本调试 + ## 语法文件调试 # 杂项 + ## 附加资源 + ## Vim 配置集合 + ## 内置插件 + ## 将 Control 映射到 CapsLock + ## 复活节彩蛋 + ## 为何使用 hjkl ## 常见问题 @@ -1742,19 +1722,17 @@ autocmd ColorScheme lucius highlight StatusLine ctermbg=darkgray cterm=NONE guib 2. **屏幕重绘** 。有一些功能会强制重绘所有行。 -| 典型肇事者 | 原因 | 解决方案 | -|--------|--------|-----------| -| `:set cursorline` | 会导致所有行重绘 | `:set nocursorline` | -| `:set cursorcolumn` | 会导致所有行重绘 | `:set nocursorcolumn` | -| `:set relativenumber` | 会导致所有行重绘 | `:set norelativenumber` | -| `:set foldmethod=syntax` | 如果语法文件已经很慢了,这只会变得更慢 | `:set foldmethod=manual`,`:set foldmethod=marker` 或者使用[快速折叠](https://github.com/Konfekt/FastFold)插件 | -| `:set synmaxcol=3000` | 由于内部表示法,Vim 处理比较长的行时会有问题。让它高亮到 3000 列…… | `:set synmaxcol=200` | -| matchparen.vim | Vim 默认加载的插件,用正则表达式查找配对的括号 | 禁用插件:`:h matchparen` | - +| 典型肇事者 | 原因 | 解决方案 | +| ------------------------ | ------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------- | +| `:set cursorline` | 会导致所有行重绘 | `:set nocursorline` | +| `:set cursorcolumn` | 会导致所有行重绘 | `:set nocursorcolumn` | +| `:set relativenumber` | 会导致所有行重绘 | `:set norelativenumber` | +| `:set foldmethod=syntax` | 如果语法文件已经很慢了,这只会变得更慢 | `:set foldmethod=manual`,`:set foldmethod=marker` 或者使用[快速折叠](https://github.com/Konfekt/FastFold)插件 | +| `:set synmaxcol=3000` | 由于内部表示法,Vim 处理比较长的行时会有问题。让它高亮到 3000 列…… | `:set synmaxcol=200` | +| matchparen.vim | Vim 默认加载的插件,用正则表达式查找配对的括号 | 禁用插件:`:h matchparen` | **注意**:只有在你真正遇到性能问题的时候才需要做上面的调整。在大多数情况下使用上面提到的选项是完全没有问题的。 - ### 编辑大文件的时候很慢 Vim 处理大文件最大的问题就是它会一次性读取整个文件。这么做是由于缓冲区的内部机理导致的(在 [vim_dev](https://groups.google.com/forum/#!topic/vim_dev/oY3i8rqYGD4/discussion) 中讨论)。 @@ -1775,8 +1753,6 @@ $ vim -n -u NONE -i NONE -N 简而言之,尽量避免使用 Vim 写过大的文件。 - - ### 持续粘贴(为什么我每次都要设置 'paste' 模式) 持续粘贴模式让终端模拟器可以区分输入内容与粘贴内容。 @@ -1795,7 +1771,6 @@ $ vim -n -u NONE -i NONE -N Neovim 尝试把这些变得更顺畅,如果终端支持的话,它会自动开启持续粘贴模式,无须再手动进行切换。 - ### 在终端中按 ESC 后有延时 如果你经常使用命令行,那么肯定要接触_终端模拟器_,如 xterm、gnome-terminal、iTerm2 等等(与实际的[终端](https://en.wikipedia.org/wiki/Computer_terminal)不同)。 @@ -1813,9 +1788,9 @@ Neovim 尝试把这些变得更顺畅,如果终端支持的话,它会自动 转义序列会产生同样的问题: -* `` 作为返回普通模式或取消某个动作的按键而被大量使用 -* 光标键使用转义序列进行的编码 -* Vim 期望 Alt (也叫作 _Mate Key_)会发送一个正确的 8-bit 编码的高位,但是许多终端模拟器并不支持这个(也可能默认没有启用),而只是发送一个转义序列作为代替。 +- `` 作为返回普通模式或取消某个动作的按键而被大量使用 +- 光标键使用转义序列进行的编码 +- Vim 期望 Alt (也叫作 _Mate Key_)会发送一个正确的 8-bit 编码的高位,但是许多终端模拟器并不支持这个(也可能默认没有启用),而只是发送一个转义序列作为代替。 你可以这样测试上面所提到的事情: `vim -u NONE -N` 然后输入 `i` ,你会看到一个以 `^[` 开头的字符串,表明这是一个转义序列,`^[` 就是转义字符。 @@ -1834,15 +1809,12 @@ set ttimeoutlen=10 " unnoticeable small value 而如果你在 tmux 中使用 Vim 的话,别忘了把下面的配置加入到你的 `~/.tmux.conf`文件中: -``` -set -sg escape-time 0 -``` - + set -sg escape-time 0 ### 无法重复函数中执行的搜索 -* 在命令中的搜索(`/`、`:substitute` 等)内容会改变“上次使用的搜索内容”。(它保存在`/`寄存器中,用 `:echo @/` 可以输出它里面的内容) -* 简单的文本变化可以通过 `.` 重做。(它保存在 `.` 寄存器,用 `:echo @.` 可以输出它的内容) +- 在命令中的搜索(`/`、`:substitute` 等)内容会改变“上次使用的搜索内容”。(它保存在`/`寄存器中,用 `:echo @/` 可以输出它里面的内容) +- 简单的文本变化可以通过 `.` 重做。(它保存在 `.` 寄存器,用 `:echo @.` 可以输出它的内容) 而在你在函数中进行这些操作的时候,一切就会变得不同。因此你不能用 N/n 查找某个函数刚刚查找的内容,也不能重做函数中对文本的修改。