第一节 - 通用信息
1.1. 什么是 Vim?
Vim 的意思是 Vi IMproved (Vi 改进版)。以前它是 Vi IMitation (Vi 模仿版) 的缩
写,但是由于做了许多改进,改一下名字还是合适的。Vim 文本编辑器包含了 unix "Vi"
编辑器的几乎所有的命令并且还加入了许多新的命令。所有的命令都可以通过键盘来输
入。这样的优点在于: 你可以通过把手放在键盘上,把眼睛放在屏幕上,集中精力在编辑
的任务上。如果你需要,Vim 提供对鼠标的支持,并且还有带有滚动条和菜单的图形界面
版本。
Vim 是编辑器,不是文字处理器。文字处理器主要用于文本的排版,意思是定位文本,改
变输出显示的方式。常常,最终文档用于打印或排字或其它方式,以让他人愉悦的方式展
现出来。文字处理器的例子有 Microsoft Word、FrameMaker 和 OpenOffice Writer。
编辑器简单来说就是用来输入文本。文档的排字或排版是次要考虑。通过使用编辑器,人
们花大部分精力输入文本,不是让文本好看。编辑器的例子除了 Vim 和 Vi 以外,还有
Emacs、TextMate、Ultraedit 和 gedit。还有 Notepad。
更多详情请阅读:
intro
1.2. 谁编写了 Vim?
Vim 大部分是基于 Stvie 的工作并由 Bram Moolenaar 编写,还有来自多不胜数的人士
的贡献。
更多详情请阅读:
author
credits
1.3. Vim 是否和 Vi 兼容?
是的。Vim 和 Vi 非常兼容。"-C" 命令行标志位可用来以 Vi 兼容方式启动 Vim:
$ vim -C
也可以用:
$ vim -u NONE
也可以置位 'compatible' 选项来打开 Vi 兼容模式:
:set compatible
如果你要确信以和原始的 Vi 不兼容 ('nocompatible') 模式启动 Vim,可提供 -N 命令
行参数:
$ vim -N
更多详情请阅读:
-C
-N
'compatible'
compatible-default
1.4. Vim 在 Vi 之上有什么改进?
下面给出 Vim 在 Vi 之上改进的一个简短总结。此列表显示了 Vi 是完全现代和功能丰
富的编辑器。它实现了现代编辑器的标准功能,对广泛的超级用户功能和面向程序员的功
能也有同样的重视。
现代化 Vi 的功能:
多层撤销
可以设置文件缓冲区里改动的撤销次数。撤销的改动可以重做。
另外,从 7.3 版本开始,Vim 可以永久保存撤销信息,这样可以撤销之前编辑会话
中的改动。
标签页、多重窗口和缓冲区
每个文件可以在自己的窗口中显示。可以方便地在窗口间移动。Vim 会话中打开的
每个文件也会有相关联的缓冲区,可以方便地在缓冲区间跳转。和任何现代 GUI 一
样,Vim 支持在标签页中打开多个文件。可以为标签页、缓冲区、窗口和参数列表
进行批处理。
灵活的插入模式
Vim 可以在插入模式中使用光标键在文件中到处移动。不再需要按 <Esc>
,到处移
动,再按 'i' 或 'a' 了。
宏
Vim 有一个记录键入字符序列,并任意多次重复此序列的机制。
可视模式
可以高亮一段文本并只在此段文本上执行操作。
列块操作符
可以选择和高亮文本的矩形列块,用于在其上执行特定的操作。
在线帮助系统
可以方便地寻找 Vim 使用的方方面面的帮助。帮助在自身的窗口上显示。
命令行编辑和历史
通过历史,可用光标键来重复或搜索曾经键入过的命令。可用一个命令的开始部分
来匹配历史缓冲区中另一个相似命令的开始部分。还可以通过编辑命令来改正打字
错误或修正若干值。
命令行补全。
使用 <Tab>
键可以按照需要补全命令、选项、文件名等等。
水平滚动。
长行可以横向滚动 (无论有无 GUI)。
Unicode 和国际化的改进。
Vim 可以编辑 unicode 编码的文件且内部使用 utf-8 编码。另外,Vim 可以显示
从右到左的文本。
高级用户功能:
文本排版
使用两个键击,可以对大段文本进行排版而不需使用外部程序。
插入模式补全
Vim 提供若干补全文本的不同可能性。例如在键入时,Vim 可以通过用当前单词来
匹配文件中的类似单词来补全单词。
标签跳转
就像互联网浏览器那样,可以跳回到编辑过文本的之前部分,然后跳回来。你的大
脑可以解放出来专心编辑而非浏览。
自动命令
读写文件、跳转到其它缓冲区等等场合下自动执行命令。
Viminfo
可以在特定文件中保存命令行历史、位置标记和寄存器,以便启动时读入。你因而
可以在新的 Vim 会话中回放旧的搜索模式、宏等等。
鼠标支持
xterm 和 MS-DOS 中支持鼠标。可用于定位光标、选择可视区域、粘贴寄存器等
等。
图形用户界面 (GUI)
有若干不同的图形用户界面可用。另外,加入自选的菜单很方便。当然,控制台
vim 还是得到支持且非常广泛地使用着。
脚本语言
Vim 有强大的脚本语言来创建新命令。也可用 Perl、Python、TCL、Lua 和 Ruby
来做同样的事!
插件
通过启动时自动载入的 vim 命令 (常规命令或脚本语言) 实现的附加功能。例如:
文件探索器、网络编辑、增强的自动补全、语法检查。更多插件在不停地开发中和
通过 VimOnline 共享。
众多编程语言的语法高亮
支持数以百计的编程语言语法高亮 (包括隐藏项目)。还可以加入其它语言的支持。
扩展的正规表达式
Vim 支持扩展的正规表达式,和 Perl 正规表达式的扩展提供的功能类似。
集成拼写检查
拼写检查已和 Vim 集成。
比较模式
Vim 可以高亮两个、三个或四个文件的差异。相同的行可以被折叠并隐藏。
使用 blowfish 算法加密
可以使用对称块加密算法 blowfish 加密文件和交换文件。
充分可定制
Vim 可以通过设置选项来调整和定制,以达到你理想的工作环境。可以定义自己的
命令、宏,甚至还有插件来延伸其能力
软件包
加入软件包使日益增长的插件的安装可以有效管理。这是获取一或多个插件的方便
途径,把它们放在一个目录上并保持更新。Vim 就会自动载入,也可以按照个人喜
好来载入。
编程性能功能:
编辑-编译-编辑 加速
可以在 Vim 内编译并自动跳转到源码中的错误位置。
为众多程序语言提供缩进
C、C++、Java、Perl、XML 和许多其它的语言在输入时 Vim 可以自动缩进。还可以
加入其它语言的支持。
在头文件中查找单词
可在当前文件和头文件中查找光标所在的单词的匹配。
高级文本对象
即时应用选择、删除、复制、缩进、排版、改变大小写等等操作于 ( 和 )、{ 和
}、< 和 >、[ 和 ] 之间的文本、或单词、或句子、或段落。功能很强大。
折叠
文本的特定部分可以被 "折叠" 掉。最好的例子是函数的函数体部分。可以先看代
码的总览,然后在要关心的函数上打开折叠以细读其实现。
ctags 和 cscope 集成
使用这两个强大的程序,可以从函数的调用跳转到函数的定义,并使用其它技巧来
浏览源码。
和若干程序语言的集成
如果你觉得内部脚本语言不够强大,可以用 Lua、Ruby、Tcl、Perl 和 Python 2
和 3 来扩展 Vim。
异步 I/O 支持
Vim 使用作业和通道和其它的程序异步对话。这样可以让编译器在后台运行,一但
完成,打开快速修复列表以修正警告
和错误。
定时器
定时器是异步的,可单次或重复触发,以调用函数来完成任意操作。
更多详情请阅读:
vi-differences
1.5. Vim 是免费的吗?
Vim 是慈善软件。使用或复制 Vim 没有限制,但作者鼓励你给慈善事业捐献。发布中有
关于如何捐款的文档。
更多详情请阅读:
copyright
第二节 - 资源
2.1. 我去哪里可以学到更多关于 Vim 的知识?
你可以在 vim@vim.org 邮件列表发帖问 Vim 相关的问题。可以在 vim-dev@vim.org 邮
件列表发帖问关于 Vim 开发相关的问题。Vim 没有自己的新闻组,最合适发帖的新闻组
是 comp.editors。
"VimOnline" 网站是 vim 事实上的主页,不过其主要用途是收集来自各处的小窍门和脚
本。参与进来吧!URL 是 https://www.vim.org
还可以阅读 Vi 的常见问题解答:
http://www.faqs.org/faqs/editor-faq/vi/part1/index.html
最后,还有若干社团,可以讨论功能或问问题:
https://vi.stackexchange.com
https://vim.reddit.com
更多详情请阅读:
mail-list
internet
2.2. 有没有可用的邮件列表?
有好几个:
名字 描述
---------------- ---------------------------------------------
vim-announce 新发布通告
vim 通用讨论
vim-dev 补丁、漏洞报告、开发讨论
vim-mac Macintosh 讨论
vim-fr 法语的通用讨论
这里,一般人只有对 vim 和 vim-dev 感兴趣。vim-announce 对多数人是只读的,相关
消息也会发送到其它列表。其余四个流量都很小。
动 作 邮 件 发 送 到
---------------- --------------------------
要订阅: <NAME>
-subscribe@vim.org
要退阅: <NAME>
-unsubscribe@vim.org
要获得帮助: <NAME>
-help@vim.org
这里也提到可用的邮件列表:
https://www.vim.org/maillist.php
2.3. Vim 邮件列表有没有可用的归档?
有。访问 https://groups.yahoo.com/,其中组名是下列之一: vimannounce、vim、
vimdev、vim-fr、vim-mac、vim-vms。
或者,访问 www.gmane.org 了解一下 GNANE,可以像新闻组一样访问邮件列表。为浏览
历史或偶尔察看当前信息链提供了一些便利。
2.4. 哪里可以找到 HTML/PDF/PS 格式的 Vim 用户手册?
可以在这里下载 HTML/PDF/PS 格式的 Vim 用户手册:
https://vimdoc.sourceforge.net/
备注
,此页的用户手册目前相当过时。最好使用 vim 自带的文档或使用在线版本
https://vimhelp.appspot.com
可以在这里找到完整英语帮助的 pdf 版本,包含本常见问题解答 (有 letter、A4 和
Ipad 格式):
https://nathangrigg.com/vimhelp/
此文本有交叉引用,所以可用超链功能。
2.5. 我有 Vim 上的 "xyz" (一些) 问题。如何判别是我个人设置的问题还是 Vim 的问
题?/ 我是发现了 Vim 的漏洞吗?
首先你要确定错误来自实际运行时文件、随 Vim 发布的插件,或仅仅是你自己的 .vimrc
或 .gvimrc 配置选项产生的副作用。所以首先,请这样启动 vim:
vim -u NONE -U NONE -N -i NONE
这会以非兼容方式 (-N)、跳过自己的 viminfo 文件 (-i NONE)、跳过任何配置文件 (-u
NONE 不读 .vimrc 文件,而 -U NONE 不读 .gvimrc 文件) 或插件来启动 Vim。
用此种调用方式来试图重现你的问题。如果错误还在,很有可能你确实发现了 Vim 的漏
洞 (另见问题 2.6. faq-2.6 )
如果此种方式启动 Vim 后错误不再出现,问题或者和某些你的插件有关,或者和你本地
设置文件某些设置有关。需要找到是什么触发的错误,可以尝试这样启动 Vim:
vim -u NONE -U NONE -N
如果问题持续,问题就在 .viminfo 文件。简单删除 viminfo 文件就可以了。如果问题
不再发生,试试:
vim -u ~/.vimrc --noplugin -N -i NONE
这会简单地使用你的 .vimrc 作为配置文件,但不载入插件。如果问题这次出现了,错误
可能来自你的 .vimrc 文件的某些配置选项。取决于你 vimrc 文件的长度,发现文件中
问题的源头未必容易。
最好的方式是在 .vimrc 半中间加入 :finish 命令。用同样的命令行重启。如果错误
还是发生了,问题应是 .vimrc 前半部的某个设定。如是不是,问题设置必在 .vimrc 后
半部。所以移动 :finish 命令到已知触发问题那半部的中间位置,如此重复,直到你
找到问题选项为止。如果 .vimrc 有 350 行长,最多需要 9 次尝试就可以找到出问题的
行 (实际上,常常会少很多,因为行与行往往互相依赖)。
如果只载入 .vimrc 文件时问题不再出现,错误必来自某插件或另一个运行时文件 (缩进
自动命令或语法脚本)。检查 :scriptnames 命令的输出,查看载入了什么文件,然后
一个一个关闭看看哪个会触发此漏洞。Vim 载入的文件常常有简单的配置变量可关闭之,
但需要你一个个分别查看文件内部以找到这些变量。
也可用 -V 命令行参数来取得更多调试信息来分析问题:
$ vim -V2logfile
可以增加传递给 -V 参数的值以得到更多调试信息。同时提供 logfile 文件名以确保调
试信息不出现在屏幕上,不干扰你试图重现问题的努力。
更多详情请阅读:
-u
-U
-N
-V
'verbose'
:verbose
:set-verbose
2.6. 我去哪里汇报漏洞?
首先用下面的命令收集所需的信息:
:source $VIMRUNTIME/bugreport.vim
现在把上述命令的结果文本发送给 bugs@vim.org e-mail 地址。还有一个公共漏洞跟踪
器: https://github.com/vim/vim/issues。那里每个消息会转发给 Vim 开发列表。
Vim 开发邮件列表 (见问题 2.2 faq-2.2 ) 是个讨论一般漏洞的好去处。如果你发现的
漏洞和语法高亮、运行时文件、或其它一些 "附加特性" (也就是,不直接编进 vim 程序
的) 有关,试试通知该特性的维护者。相应的运行时文件的顶部会提及他们的 e-mail 地
址。
更多详情请阅读:
bug-reports
2.7. 哪里能找到本 FAQ?
本 FAQ 可在这里找到 https://vimhelp.appspot.com/vim_faq.txt.html。它从
https://www.github.com/chrisbra/vim_faq github 库管理的源码自动生成 (欢迎补
丁)。
此库也包含 faq 的多种格式,如 manpage、pdf 文件、html 文件、平凡文本和 vim 帮
助格式的版本。
VimOnline (https://www.vim.org/) 还可以找到一个稍老的版本 (看来不再有更新)。
2.8. 在本 FAQ 找不到答案怎么办?
本 FAQ 主要覆盖 Vim 特定的问题。阅读 Vi FAQ 可以找到和大多数 Vi 克隆相关的更多
信息。在 comp.editors 上常有帖子。也可以在这里找到备份
http://www.faqs.org/faqs/editor-faq/vi/part1/index.html
另外,既然 Vim 在过去几年收集如此众多的功能,要在这里成功地记录常见的问题是几
乎不可能的任务。要使之可能,如果你有好问题的话,请邮寄维护者。好问题是那些你试
图自己回答 (记住,Vim 有很好的文档) 但有困难的。
2.9. 我有实现 Vim 某功能的补丁。如何发送补丁?
可以把您的补丁发送到 Vim 开发者邮件列表 vim-dev@vim.org。
更多详情请阅读:
vim-dev
2.10. 我有 Vim 的小窍门或开发了新的 Vim 语法/缩进/文件类型/编译器插件或开发了
新脚本或色彩方案。有没有公共网站可以上传这些?
是的。可以在 Vim Online 网站上传你的插件/脚本,色彩方案等等。站址在
https://www.vim.org
现时人们也在 github 上分享他们的插件/运行时文件。
也可在 Wiki 上分享小窍门,地址在
http://vim.wikia.com
第四节 - 帮助
4.1. 如何使用帮助文件?
Vim 所有的功能都能找到帮助。要得到帮助,可用 :help 命令。这会把你带到主帮助
页面。在该首页上,可以找到如何到处移动的说明。基本上,帮助页相当于在只读文档上
的移动。可以使用标签跳转到指定主题上。有两种方法:
* 在命令或选项名之上用 CTRL-]
命令。只有标签为关键字时才可以用。
<Ctrl-LeftMouse>
和 g<LeftMouse>
相当于 CTRL-]
。
* 使用 `:tag <subject>
` 命令。可用于所有字符。
CTRL-T
跳回帮助文件中的原来的地方。 :q 关闭帮助窗口。
如果你要跳转到帮助页上的特定主题,可用 `:help {subject}
`。如果不知道找什么,试
试 `:help index` 来得到所有可用主题的列表。标准的搜索键可用于定位要找的信息。
:help 命令可简化为 :h 。
要搜索帮助,见下个问题 4.2。 faq-4.2
更多详情请阅读:
online-help
4.2. 如何在 Vim 帮助文件中搜索某关键字?
a) 在输入 help 关键字后按 CTRL-D
键可以得到包含指定模式的所有帮助关键字的列
表。可用元字符如 *、\+ 等来指定帮助搜索模式:
:help init<C-D>
:help str*()<C-D>
:help '*indent<C-D>
b) 在输入部分的帮助关键字后按 <Tab>
键可扩展匹配的关键字。继续按 <Tab>
键可以
得到其它的关键字匹配。
c) 从帮助窗口,用 :tag 命令可以搜索关键字。例如,
:tselect /window
此命令会列出所有包含文本 "window" 的帮助关键字。从列表中可以选择一个并跳转
过去。
d) 可用 :helpgrep 命令在所有帮助文件中搜索给定文本。打开快速修复窗口显示所
有匹配行。
更多详情请阅读:
help-summary
c_CTRL-D
c_<Tab>
:tselect
:help
:helpgrep
4.3. 我得到了错误信息 E123,我做错什么了?
可以用下面的帮助链接了解错误的相关情况和错误信息:
E123
更多详情请阅读:
error-messages
4.4. 在哪里可以了解 Vim 的各种模式?
通过阅读下面的帮助链接可以了解 Vim 中不同模式的信息
vim-modes
4.5. 加入新 Vim 帮助文件后,如何生成 Vim 帮助标签文件呢?
可在 Vim 内部用 :helptags 命令来重新生成 Vim 帮助标签文件。例如:
:cd $VIMRUNTIME/doc
:helptags .
要刷新所有 'runtimepath' 下的 "doc" 目录,可用
:helptags ALL
更多详情请阅读:
:helptags
add-local-help
4.6. 可以用帮助文件的压缩版本吗?
可以。可以压缩帮助文件,然后在 Vim 中还可以阅读。帮助文件的访问会稍慢一些,也
需要 "gzip" 工具。以下步骤可以压缩并使用 Vim 帮助文件:
- 用 "gzip doc/*.txt" 压缩所有帮助文件。
- 编辑 "doc/tags" 文件,这样来把 ".txt" 改成 ".txt.gz"
:%s=\(\t.*\.txt\)\t=\1.gz\t=
- 在 vimrc 中加入下行:
set helpfile={dirname}/help.txt.gz
其中 {dirname}
是帮助文件所在的目录。Vim 标准发布自带的 gzip.vim 插件会负责解
压这些文件。如果其它 Vim 文件和存放压缩帮助的 "doc" 目录所在的位置不一致,要确
保 $VIMRUNTIME 设为存放那些 Vim 文件的目录。
注意
, :helpgrep 命令不支持压缩帮助页。
更多详情请阅读:
gzip-helpfile
'helpfile'
gzip
$VIMRUNTIME
第六节 - 编辑多个文件
6.1. 在 Vim 里如何一次打开多个文件?
先区别一下参数、缓冲区、标签页和窗口。Vim 里这些是不同的概念。
参数是命令行参数的列表。缓冲区是编辑文本的地方,几乎总是和文件捆绑在一起,但也
不一定。窗口是缓冲区放置的地方而标签页是一组窗口,"布局" 可能是更好的名字。
有几个方法可以在 Vim 里一次打开多个文件。可用 :next 命令来指定一组文件:
:next f1.txt f2.txt
:next *.c
可用 :args 命令来指定一组文件作为参数:
:args f1.txt f2.txt
:args *.c
载入文件后,可用 :next 和 :prev 命令在文件间切换。
要为参数列表中的所有文件执行命令,可用 :argdo
更多详情请阅读:
07.2
:next
:args_f
argument-list
6.2. 在 Vim 里如何在多个文件/缓冲区间切换?
用 :ls 列出所有的缓冲区,用 :ls!
列出没有关联文件的缓冲区 (亦: 列表外缓冲
区,如草稿缓冲区和帮助窗口)。
有几种方法可以在多个文件中切换。用 :buffer 命令来在多个文件间切换。也可简写
为 :b 并只用部分文件名。例如
:buffer file1
:buffer file2
:b e2
也可在 :b 后用 <TAB>
自动补全。也试试 :b 后跟 CTRL-D
也看到所有可用的缓冲
区。这也适用于 :e 。
也可用 CTRL-^
键在缓冲区间切换。按此键前如指定计数,可编辑带此号码的缓冲区。如
果没有计数,CTRL-^
可用来编辑轮换缓冲区。
也可用 `:e #` 命令来编辑特定缓冲区:
:e #5
用 :bd 命令来关闭缓冲区。
可用 :bufdo 来为缓冲区列表中的所有文件执行命令。
更多详情请阅读:
edit-files
:buffer
CTRL-^
alternate-file
22.4
07.3
6.3. 在 Vim 里如何在单独的窗口/标签页中分别打开多个文件?
可用 -o 和 -O 命令行参数来在水平或垂直分割的 Vim 窗口中分别打开多个文件。例
如:
$ vim -o3 f1.txt f2.txt f3.txt
上述命令会在三个水平分割的 Vim 窗口中分别打开文件 f1.txt、f2.txt 和 f3.txt。
$ vim -O3 f1.txt f2.txt f3.txt
上述命令会在三个垂直分割的 Vim 窗口中分别打开文件 f1.txt、f2.txt 和 f3.txt。
$ vim -p f1.txt f2.txt f3.txt
上述命令会在三个标签页中分别打开文件 f1.txt、f2.txt 和 f3.txt。'tabpagemax' 选
项定义一次最多能打开多少个标签页,缺省是 10 个。
更多详情请阅读:
-o
-O
-p
startup-options
'tabpagemax'
6.4. 如何配置 Vim 可以一次自动载入若干文件,类似于 "工作集" 或 "项目"?
可用 :mksession 和 :mkview 命令在 Vim 里自动载入若干文件。
:mksession 命令创建 Vim 脚本用来恢复当前编辑的会话。可用 :source 命令来执
行 mksession 命令生成的文件。
:mkview 命令创建 Vim 脚本用来恢复当前窗口的内容。可用 :loadview 命令来载入
当前文件的视图。
更多详情请阅读:
21.4
21.5
views-sessions
'sessionoptions'
:mksession
:source
v:this_session
:mkview
:loadview
'viewdir'
buffers
6.5. 可以在单个 Vim 实例中打开多个顶层窗口,就像 Nedit 或 emacs 那样吗?
不行。目前不可能在单个 Vim 实例中打开多个顶层窗口。此功能还在待开发列表中。
6.6. 如何在 Vim 内浏览/探索目录?
在 Vim 内,可用标准 Vim 安装提供的 netrw.vim 插件来浏览/探索目录。可用以下命令
之一来启动文件探索器:
:e <directory>
:Explore
:Sexplore
:Vexplore
:Texplore
从文件探索器出发,可以浏览目录,换名、删除和编辑文件。
更多详情请阅读:
netrw.vim
22.1
6.7. 如何用 ftp/scp/rcp/http 通过网络编辑文件?
可用标准 Vim 软件包提供的 netrw.vim 插件,用 ftp/scp/rcp/http 通过网络编辑文
件。通过此插件,Vim 会自己用 ftp/scp/rcp/http 透明地载入和保存文件。例如,要通
过 ftp 编辑文件,可用以下命令:
$ vim ftp://machine/path
更多详情请阅读:
netrw.vim
第八节 - 缓冲区
8.1. 我在缓冲区上做了修改。如何才能编辑另一个缓冲区而无需保存修改过的缓冲区也
不会丢失我的改动?
可置位 'hidden' 选项来编辑文件而不会丢失当前文件上的修改:
:set hidden
通过置位 'hidden' 选项,你也继续保存缓冲区的修改历史 (撤销历史)。否则,文件间
切换时会丢失撤销历史 (除非使用了持续撤销文件)。
更多详情请阅读:
'hidden'
hidden-quit
:hide
8.2. 如何配置 Vim 在切换到其它缓冲区时自动保存修改过的缓冲区?
可置位 'autowrite' 选项,在切换到其它缓冲区时自动保存修改过的缓冲区:
:set autowrite
更多详情请阅读:
'autowrite'
'autowriteall'
'hidden'
8.3. 如何用空缓冲区来替换当前窗口的缓冲区?
可用 :enew 命令来载入空缓冲区以替换当前窗口的缓冲区。
更多详情请阅读:
:enew
8.4. 有没有用缓冲区号载入缓冲区的快捷键?
可用 CTRL-^
命令来通过指定缓冲区号载入缓冲区。例如,要载入 5 号缓冲区,须用
5 CTRL-^
命令。
更多详情请阅读:
CTRL-^
8.5. 如何在不同的窗口分别打开当前所有的缓冲区?
可用 :ball 或 :sball 命令来打开缓冲区列表中的所有缓冲区:
:ball
如果想所有的缓冲区在新标签页中分别打开,简单加上 :tab 命令前缀:
:tab :sball
更多详情请阅读:
:ball
8.6. 如何关闭 (删除) 缓冲区而不退出 Vim?
可用 :bdelete 、 :bwipeout 或 :bunload 命令中的一个来删除缓冲区而不退出
Vim。例如:
:bdelete file1
更多详情请阅读:
:bdelete
:bwipeout
:bunload
8.7. 用命令 :%bd
删除所有缓冲区时,不是所有的缓冲区都删除了。为什么?
用 :%bd
命令时,"%" 范围会被当前缓冲区的起末行号代替。不要用 "%" 作为范围,
而应该指定数值作为范围。例如,要删除所有的缓冲区,可用命令 :1,9999bd
。
更多详情请阅读:
:bd
(7.4.530 补丁修正了此行为)
8.8. 如何显示当前缓冲区/文件的缓冲区号?
可用 2<CTRL-G
> 命令来显示当前文件/缓冲区的缓冲区号。注意
CTRL-G
命令计数的使
用。如果计数大于 1,Vim 会显示缓冲区号。
也可用下列命令来显示当前缓冲区号:
:echo bufnr("%")
也可在 'statusline' 选项中加入 "%n" 域来在状态行上显示当前缓冲区号。
更多详情请阅读:
CTRL-G
bufnr()
:echo
'statusline'
8.9. 如何删除缓冲区而不关闭显示该缓冲区的窗口?
可用下列命令来打开下个缓冲区并删除当前缓冲区。
:bnext | bdelete #
更多详情请阅读:
:bnext
:bdelete
:buffers
8.10. 如何映射 <Tab>
键来循环并打开所有缓冲区?
可用下列两个映射命令来映射 <Ctrl-Tab>
键来打开后一个缓冲区,<Ctrl-Shift-Tab>
键来打开前一个缓冲区:
:nnoremap <C-Tab> :bnext<CR>
:nnoremap <S-C-Tab> :bprevious<CR>
注意
,这不能用于 Vim 终端版本。
更多详情请阅读:
:bnext
:bprevious
第十节 - 动作
10.1. 如何跳到文件的开头 (首行) 或尾部 (末行)?
可用 "G" 命令来跳转到文件的末行,而用 "gg" 命令来跳转到文件的首行。
更多详情请阅读:
G
gg
10.2. 插入模式下,按 <Esc>
键回到命令模式时,光标向左移了一个字符 (除了光标在
行首以外)。可以改变此行为来保持光标在同一列上吗?
不行。不能改变此行为。光标总是留在合法的字符上 (除非打开了虚拟编辑模式)。所
以,如果在行尾附加文本,返回命令模式时光标 必须
退回到输入的末字符上。为统一起
见,光标不管在哪里,即使你在行的中间,都会退回。
插入模式下,可用 CTRL-O
或 CTRL-\
CTRL-O
命令执行单个 ex 命令并返回到插入模式
而不移动光标列。
更多详情请阅读:
'virtualedit'
i_CTRL-O
i_CTRL-\_CTRL-O
10.3. 如何配置 Vim 在用 <Page Up>、<Page Down> 等键滚动时保持水平光标位置?
可复位 'startofline' 选项来使文本滚动时保持光标水平位置不变:
:set nostartofline
更多详情请阅读:
'startofline'
10.4. 文件中的有些行超过屏幕宽度而被回绕。用 j、k 键从一行移到下一行时光标移动
到文件的下一行而不是屏幕的下一行。如何才能移动到下一屏幕行?
可用 gj 和 gk 命令来从一屏幕行移到后/前一个屏幕行。j 和 k 命令则移动光标从一文
件行到后/前一个文件行。复位 'wrap' 选项可避免行回绕:
:set nowrap
更多详情请阅读:
gj
gk
'wrap'
可用以下映射:
:map <Up> gk
:imap <Up> <C-o>gk
:map <Down> gj
:imap <Down> <C-o>gj
:noremap j gj
:noremap k gk
10.5. 句子、段落和小节的定义是什么?
一个句子以 '.'、'!' 或者 '?' 结尾并紧随着一个换行符、一个空格 (或两个) 或者制
表符。哪个字符和几个空格算作句尾由 'joinspaces' 和 'cpoptions' 选项决定。
一个段落以每个空行或段落宏命令开始,段落宏由 'paragraphs' 选项里成对出现的字符
所定义。
一个小节以每个首列出现的换页符 (<C-L>
) 或小节宏命令开始。小节宏由 'sections'
选项里成对出现的字符所定义。
更多详情请阅读:
sentence
'joinspaces'
'cpoptions'
paragraph
section
word
10.6. 如何跳转到句子、段落或小节的头部或尾部?
用下列动作命令跳转到句子、段落或小节的头部或尾部:
动作 位置 哪里
------ --------- -----------------
( 头部 当前句子
) 尾部 当前句子
{ 头部 当前段落
} 尾部 当然段落
[] 尾部 前一小节
[[ 头部 当前小节
][ 尾部 当前小节
]] 头部 后一小节
每个动作可以前导一个数值,会延展往前或往后的跳转次数。
更多详情请阅读:
object-motions
10.7. 我有延伸到屏幕右端之外的文件行。如何往右移动 Vim 视图来看到原来不在屏幕
上的文本?
可用下列命令之一来横向往左或右滚动屏幕:
命令 滚动到
--- --------------------------
zl 往左滚动
zh 往右滚动
zL 往左半个屏幕宽度
zH 往右半个屏幕宽度
zs 滚动使光标位于屏幕开始的开始位置
ze 滚动使光标位于屏幕开始的结束位置
可用 g0 命令移动光标到屏幕行的首个字符,而 g$ 命令移动光标到屏幕行的末个字符。
两者都不滚动屏幕。
更多详情请阅读:
scroll-horizontal
10.8. 如何同时滚动两或多个缓冲区?
可为每个缓冲区置位 'scrollbind' 选项来同时滚动这些缓冲区。
更多详情请阅读:
'scrollbind'
scroll-binding
'scrollopt'
'cursorbind'
10.9. 用光标键时,Vim 改变了模式,在文档中插入奇怪的字符,但不正确地移动光标。
怎么啦?
有几个可能性: 或者你在慢速连接上使用 Vim,或者 Vim 不识别你键盘生成的键序列。
如果你用的是慢速连接 (如 2400 bps modem),可以试试置位 'timeout' 或 'ttimeout'
选项。这些选项加上 'timeoutlen' 和 'ttimeoutlen' 选项也许可以解决问题。
如果 Vim 不识别你的终端发送的键代码,以上步骤可能无效。为此,最好的选择是把你
的正确键序列映射到对应的光标移动命令上,并把这些映射保存进某个文件。每次使用该
终端时 :source 该文件。
更多详情请阅读:
'timeout'
'ttimeout'
'timeoutlen'
'ttimeoutlen'
:map
vt100-cursor-keys
10.10. 如何配置 Vim 当光标在行首而按左键时,移动光标到前行的行尾?
可为 'whichwrap' 选项加上 "<" 标志位,来配置 Vim 当光标在行首而按左键时,移动
光标到前行的行尾:
:set whichwrap+=<
类似地,当光标在行尾而按右键时,要移动光标到后行的行首,可为 'whichwrap' 选项
加上 ">" 标志位:
:set whichwrap+=>
上述设定只可用于普通和可视模式。要在插入和替换模式下也如此,分别加入 "[" 和
"]" 标志位。
更多详情请阅读:
'whichwrap'
05.7
10.11. 如何配置 Vim 只留在插入模式 (无模式编辑)?
可置位 'insertmode' 选项来配置 Vim 只留在插入模式:
:set insertmode
置位该选项可把 Vim 作为无模式的编辑器来使用。如果按了 <Esc>
键,Vim 不会转入普
通模式。要执行单个普通模式命令,可按 CTRL-O
后跟普通模式命令。可执行多于一个普
通模式命令,可用 CTRL-L
后跟那些命令。然后用 <Esc>
键返回插入模式。要关闭此选
项,复位 'insertmode' 选项:
:set noinsertmode
也可用 "evim" 命令或 "vim -y" 来作为无模式编辑器启动 Vim。
也可用 :startinsert ex 命令来以插入模式启动 Vim。
更多详情请阅读:
'insertmode'
:startinsert
:stopinsert
i_CTRL-O
i_CTRL-L
evim
evim-keys
10.12. 滚动文本时如何显示若干上下文?
可设置 'scrolloff' 选项来控制在光标上方和下方显示的最少的屏幕行数 (上下文)。
:set scrolloff=10
更多详情请阅读:
'scrolloff'
'sidescrolloff'
10.13. 如何回到之前的光标位置?
可用 '' 或 `` 命令回到上次跳转之前的光标位置。可用 CTRL-O
命令回到跳转列表中更
老的光标位置,而可用 CTRL-I
命令跳到跳转列表中更新的光标位置。
更多详情请阅读:
03.10
mark-motions
jump-motions
第十一节 - 搜索文本
11.1. 用模式搜索文本后,所有匹配的文本保持高亮。如何临时/永久关闭高亮?
'hlsearch' 选项控制是否高亮前次搜索模式所有的匹配。缺省不打开此选项。如果系统
范围的 vimrc 文件置位了此选项,可用以下命令关闭搜索高亮:
:set nohlsearch
要临时关闭搜索高亮,可用
:nohlsearch
也可用搜索当前文件不存在的模式来清除搜索高亮 (例如,搜索模式 "asdf")。
用下面的映射在 CTRL-L
重画窗口时同时会清除搜索高亮
:nnoremap <silent> <C-L> <C-L>:nohls<CR>
更多详情请阅读:
'hlsearch'
:nohlsearch
11.2. 如何在搜索模式中输入回车字符?
可用 "\r" 或 <CTRL-V
><CTRL-M
> 来在模式中输入回车。Vim 脚本里,用 "\r" 代表回车
字符更好。
更多详情请阅读:
sub-replace-special
11.3. 如何搜索字符 "^M"?
在搜索命令中可先按 CTRL-V
键再按 CTRL-M
键来输入 ^M 字符。
/^V^M
也可用 "\r" 字符。在 Vim 脚本里,建议使用 "\r"。
更多详情请阅读:
c_CTRL-V
using_CTRL-V
/\r
11.4. 如何搜索/替代显示为 "~R"、"~S" 等的字符?
可用 "ga" 命令来显示特殊字符的 ASCII 值/代码。例如,假定 ASCII 值是 142。可用
下列命令来搜索此特殊字符:
/^V142
这里,^V 用 CTRL-V
输入。
更多详情请阅读:
ga
using_CTRL-V
24.8
11.5. 如何高亮文件中所有的不可显示字符?
可用下列命令和搜索模式来高亮文件中所有的不可显示字符:
:set hlsearch
/\(\p\|$\)\@!.
更多详情请阅读:
/\p
/bar
/$
/\(
/\@!
'hlsearch'
11.6. 如何在文件中搜索整词?
在文件中可用 \< 和 \> 匹配原来搜索整词。例如:
/\<myword\>
\< 匹配原用来匹配单词的起始,而 \> 匹配原用来匹配单词的结尾。
更多详情请阅读:
/\<
/\>
11.7. 如何搜索光标下的当前单词?
按 * 键可正向搜索光标下的当前单词。# 键进行反向搜索。注意
这些命令只搜索完整的
关键字。
更多详情请阅读:
star
#
gstar
g#
03.8
search-commands
11.8. 如何在搜索单词时忽略大小写?
要在搜索模式时忽略大小写,置位 'ignorecase' 选项:
:set ignorecase
要仅在搜索特定模式时忽略大小写,使用特殊的 \c 指令:
/\c<pattern>
更多详情请阅读:
'ignorecase'
/ignorecase
/\c
11.9. 如何搜索连续两次出现的单词?
可用下面的搜索命令来定位连续两次出现的单词:
/\(\<\w\+\)\_s\+\1\>
/\(\<\k\+\)\_s\+\1\>
"\w" 和 "\k" 的主要区别是后者基于 'iskeyword' 选项,此选项可包含重音和其它语言
特定的字符。
更多详情请阅读:
/\1
/\(
/\)
/\<
/\>
/\w
/\k
/\+
/\_x
'iskeyword'
11.10. 如何统计缓冲区中特定单词出现的次数?
可用下面一组命令来统计缓冲区中特定单词出现的次数:
:let cnt=0
:g/\<your_word\>/let cnt=cnt+1
:echo cnt
这只统计单词出现的行数。也可用下面的命令:
:%s/\<word\>/&/gn
要统计文件中字母单词的个数,可用
:%s/\a\+/&/gn
要统计非空白字符构成的单词的个数,可用
:%s/\S\+/&/gn
更多详情请阅读:
count-items
word-count
v_g_CTRL-G
12.5
:s_flags
11.11. 如何在搜索模式时把光标放置在匹配单词的尾部?
可用搜索命令的 "e" 偏移来把光标放置在匹配单词的尾部。例如
/mypattern/e
关于搜索位移的更多详情请阅读:
search-offset
/
11.12. 如何搜索空行?
可如此搜索空行:
/^$
或
/^\s*$
后者也匹配只由空白构成的行,而前者只匹配真正的空行。更多详情请阅读:
/^
/$
/\s
/star
search-commands
11.13. 如何搜索只有一个字符的行?
可如此搜索只有一个字符的行:
/^\s*\a\s*$
更多详情请阅读:
/^
/\a
/\s
/star
/$
11.14. 如何搜索和替代多个文件中的字符串?
可用 :argdo 、 :bufdo 、 :windo 或 :tabdo 命令来在多个文件中执行 ex 命令。
例如:
:argdo %s/foo/bar/g|upd
更多详情请阅读:
:argdo
:bufdo
:windo
:tabdo
11.15. 我在映射中使用了 :s 替代命令。如果模式的搜索失败,映射被终止。我想要
即使替代命令失败时,映射还继续处理下个命令。该如何做呢?
可用替代命令的 "e" 标志位,即使模式没找到,也让映射继续处理其它命令。
更多详情请阅读:
:s_flags
11.16. 如何搜索一行中某字符的第 n 次出现?
要搜索一行中某字符的第 n 次出现,可为 "f" 命令加上数值前缀。例如,要搜索一行中
@ 字符的第 5 次出现,可用命令 5f@。这假定光标在行首 - 而且首字符不是你要寻找的
那个字符。
更多详情请阅读:
f
F
t
T
;
,
11.17. 如何把制表符 (或任何字符) 换成硬回车 (换行) 字符?
可用下列命令把制表符 (或任何字符) 换成硬回车 (换行) 字符:
:s/\t/\r/
注意
上述命令中,如果用 \n 代替\r,制表符并不会被换行符所代替。
更多详情请阅读:
sub-replace-special
NL-used-for-Nul
CR-used-for-NL
11.18. 如何用字符的 ASCII 值来搜索字符?
在搜索 "/" 命令中,可用 CTRL-V
后跟字符的十进制或十六进制或八进制值来用 ASCII
值搜索字符。要确定字符的 ASCII 值,可用 :ascii 或 "ga" 命令。
例如,要搜索 ASCII 字符值 188 (¼),可用以下搜索命令之一:
/<CTRL-V>188
/<CTRL-V>o274
/<CTRL-V>xBC
/<CTRL-V>u00bc
也可用排序规则元素 [] 来用十进/八进/十六进数值搜索字符:
/[\d188]
/[\o274]
/[\xbc]
/[\u00bc]
此外,也可用特定匹配原 \%d \%o \%x \%u:
/\%d188
/\%o274
/\%xbc
/\%u00bc
也可用二合字母来输入字符。例如输入:
/CTRL-K14
来搜索上述字符。
更多详情请阅读:
i_CTRL-V_digit
:ascii
ga
/\]
/\%d
digraphs
11.19. 如何搜索长行?
可用搜索命令中的 Vim 正规表达式来搜索长行或超过一定数目字符的行。例如,要搜索
所有超过 80 个字符的行,可用以下之一的命令:
/^.\{80}.\+$
/^.*\%>80c.*$
/^.*\%>80v.*$
更多详情请阅读:
/\{
/\%c
/\%v
11.20. 如何在当前缓冲区中显示包含特定模式的所有行?
可用以下命令来在当前缓冲区中显示包含特定模式的所有行:
:g/<pattern>/p
例如,下列命令会在当前缓冲区中显示包含 "vim" 的所有行:
:g/vim/p
因为 :p 是 ex 命令 :g 执行的缺省命令,也可用:
:g/vim
如果也想要对应的行号,可用以下的命令:
:g/<pattern>/#
更多详情请阅读:
:global
:print
:number
11.21. 如何搜索跨越多行的文本字符串?
可用 \_x 正规表达式匹配原去搜索跨越多行的文本字符串。例如,要搜索文本字符串
"Hello
World",可用下列搜索命令:
/Hello\_sWorld
这会匹配单词 "Hello" 后跟换行符然后跟着从下一行开始的单词 "World"。它也会匹配
单词 "Hello" 后跟空格符然后跟着单词 "World"。要搜索 "Hello World" 字符串并包括
行尾和行首的任意个空白字符,可用以下的搜索命令:
/Hello\_s\+World
更多详情请阅读:
27.8
pattern-atoms
/\_
pattern-searches
11.22. 如何只在缓冲区中给定行范围内搜索模式?
可以用 \%>l 和 \%<l 正规表达式匹配原来在给定行范围内搜索模式。例如,要在缓冲
区第 10 到 30 行间搜索单词 "white",可用下列命令:
/white\%>9l\%<31l
更多详情请阅读:
/\%l
11.23. 如何清除前次搜索模式?
前次搜索模式存在 "/" 寄存器里。可用下列命令清除此寄存器:
:let @/=""
要在缓冲区卸载时清除前次搜索模式,可用下列命令:
:autocmd BufUnload * let @/ = ""
更多详情请阅读:
@/
:let-@
autocmd-searchpat
last-pattern
11.24. 为什么模式 "a.\{-}
p\@!" 不能匹配?
"\{-}
" 不意味着 "越少越好",它的含义是 "越少越好使整个模式匹配"。如果它不匹配
"p",整个模式会失败 (因为有 "p\@!"),所以它必须匹配 "p"。这确实是一个更长的匹
配,但它是最短的能使整个模式成功的匹配。
如果你想要 "无论如何也越少越好",可用 "\@>",它基本上把一个模式分成两部分,每
部分相互独立。如果模式是 "a.\{-}
\@>p\@!",那么 ".\{-}
" 总是匹配空串,因为在没
有其它限制的情况下这是最短能成功的匹配。整个模式此时相当于 "ap\@!",也就是匹配
任何后面不跟 "p" 的 "a"。
这意味着,它会匹配尽量少的 "a" 而不会继续试下去,直到 Vim 找到最长的匹配为止。
这也意味着,它还是会匹配 "ap"。
11.25. 如何在模式中使用 "/" 时不用对它转义?
用 / 搜索模式时,需要转义模式中所有的 "/",不然它们会终止模式。因此,你不能直
接搜索 /usr/share/doc/,而必须搜索 \/usr\/share\/doc\/
最简单的解决方法是用 "?" 来进行反向搜索,然后用 /<CR>
来使用前次搜索模式进行正
向搜索。
如果有内建 eval 特性的 Vim (至少要 normal 版本或更高),也可直接粘贴模式到搜索
寄存器:
:let @/ = '/usr/share/doc/'
然后用 "n" 跳转到下个它的出现。
另见以下相关帮助
@/
/<CR>
11.26. 如何操作搜索的匹配?
"gn" 命令可用来很容易地在匹配当前搜索模式的文本区域上操作。缺省,正向搜索前次
搜索模式并可视选择匹配。如果光标已经在匹配上,就对它可视选择。如果在操作符后使
用 "gn" 命令 (如用 "c" 来修改文本),就在匹配上应用此操作符。
如果使用 gn 之前激活了可视模式,延伸可视选择区到下个匹配的结尾。
"gN" 命令类似,但用于反向搜索。
此命令可用于为每个匹配重复一些简单操作。例如,要把所有的 apple 换成 peach。先
用 "/apple" 开始搜索,然后用 "cgnpeach<Esc>
" 把当前匹配替代成 peach。现在用句
号 "." 命令就可为缓冲区其余部分重做此替代操作。
另见以下相关帮助
gn
gN
第十二节 - 修改文本
12.1. 如何删除文件中所有行的拖尾空白字符 (空格和制表)?
可用 :substitute 命令在整个文件上搜索和删除所有的拖尾空白字符:
:%s/\s\+$//
更多详情请阅读:
:%
:s
/\s
/\+
/$
12.2. 如何把所有的多个连续出现的空格字符换成单个空格?
可用以下命令来把所有的多个连续出现的空格字符换成单个空格:
:%s/ \{2,}/ /g
也可用:
:%s/ \+/ /g
更多详情请阅读:
:%
:s
/\{
:s_flags
12.3. 如何把一串空行缩减成一行?
可用下列命令来把一串空行缩减成一行:
:v/./.,/./-1join
此命令的解释如下:
部分 描述
----- --------------------------
:v/./ 为所有不包含一个字符的行 (也就是空行) 执行下列命令。
., 使用当前行作为行范围的开始行。
/./ 使用包含一个字符的行作为结束行。
-1 调整行范围,使结束行变成原来结束行的前一行。
j 连接范围中的所有行。
备注
文件末有空行时会报错。要改正这个问题,在文件末加一行临时行,执行本命
令,然后再删除临时行。
更多详情请阅读:
:v
:join
cmdline-ranges
collapse
12.4. 如何删除文件中的全部空行?如何删除全部只有空白字符的行?
要删除全部空行,使用下列命令:
:g/^$/d
要删除全部只有空白字符 (空格或制表) 的行,使用下列命令:
:g/^\s\+$/d
要删除全部要么没有,如果有的话只有空白字符的行,使用下列命令:
:g/^\s*$/d
12.5. 如何复制/抽出当前单词?
可用 "yiw" (抽出内含单词,不带空白) 命令或 "yaw" (抽出一个单词,带空白) 命令来
复制/抽出当前单词。
更多详情请阅读:
04.6
04.8
iw
yank
text-objects
objects
12.6. 如何从一行中抽出一个位置到另一个位置的文本而不是抽出整行?
可用动作命令带抽出操作符 (y) 来从一行中抽出一个位置到另一个位置的文本。例如,
要抽出当前光标位置到下个 x 字符的文本,用 yfx 或 Fx 和 tx 或 Tx。要抽出直到第
n 列的文本,用 n|。要抽出直到下个 "word" 的出现的文本,用 /word。要抽出直到另
一行第 n 列的文本,先用 "ma" 命令标记该位置,再转到抽出开始的位置,然后用 y`a
来抽出直到标记所在的文本 (注意
引号的方向)
更多详情请阅读:
yank
motion.txt
04.6
12.7. 抽出文本到寄存器时,如何附加文本到当前寄存器的内容上?
指定一些操作的寄存器时,如果使用了寄存器名的大写形式,则新的文本会附加到已有的
内容上。例如,假定寄存器 "a" 有些文本,如果想附加新文本于其后,可用 "A" 寄存器
名。如果用寄存器名的小写形式,则寄存器内容会给新文本覆盖。
更多详情请阅读:
quote
quote_alpha
10.1
12.8. 如何抽出跨越多行的完整句子?
要抽出跨越多行的完整句子,须用带动作命令的抽出操作符。如:
y)
从句子内部可用 "yi)" 来抽出句子 (译者注
: 原文如此,似应为 "yis")。
更多详情请阅读:
yank
{motion}
object-motions
04.6
12.9. 如何抽出所有包含一个模式的行到一个缓冲区?
可用 :global 命令来把所有包含一个模式的行抽出到寄存器里,然后把寄存器的内容
粘贴到缓冲区上:
:let @a=''
:g/mypattern/y A
第一个命令,清除寄存器 "a" 的内容。第二个命令复制所有包含 "mypattern" 的行到寄
存器 "a" 里。注意
使用了大写字母 "A",把匹配的行附加进来。现在可用 "ap 命令来
粘贴突破口 "a" 的内容到缓冲区里。
如果你只想收集所有的匹配,还有一个不同的方法。为此,用 :s 命令带上标志位
"gn",这样不实际修改缓冲区 ("n" 标志位) 但选择所有匹配 ("g" 标志位)。把此命令
和替代部分的 "\=" 部分组合起来,可把每个匹配复制到比如一个列表上。 加总起来,
可用下面的形式:
:let list=[]
:%s/pattern/\=add(list, submatch(0))/gn
现在所有的匹配都在列表里,然后按需可对它们进行后期处理。
更多详情请阅读:
:g
:y
:let-register
quote_alpha
put
registers
:registers
sub-replace-\=
12.10. 如何删除文件中所有不包含特定模式的行?
可用 :v 来删除文件中所有不包含特定模式的行:
:v/pattern/d
或
:g!/pattern/d
更多详情请阅读:
:v
:g
12.11. 如何在每个带 "pattern" 的行之前加上一行?
可用下列命令来在每个带 "pattern" 的行之前加上一行:
:g/pattern/normal! Oi<把文本行放在这里>
此外,还可用 Y 命令抽出行,然后用下列命令插入该行:
:g/pattern/put!
更多详情请阅读:
:g
:put
insert
0
12.12. 有没有办法在前行包含指定模式的行上操作?
可用 :global 命令在前行包含指定模式的行上操作:
:g/<pattern>/+{cmd}
更多详情请阅读:
:g
:range
12.13. 如何在所有包含指定模式的行上执行命令?
可用 :global (:g) 命令在所有包含指定模式的行上执行命令。
:g/my pattern/d
如要想用非 Ex 的命令,可用 :normal 命令:
:g/my pattern/normal {command}
除非你希望普通模式命令被重映射,考虑用 :normal!
命令来代替 (注意
这里的
"!")。
更多详情请阅读:
:global
:v
:normal
12.14. 可以复制光标上方的字符到当前光标位置吗?
在插入模式下,可用 CTRL-Y
来复制光标上方的字符到当前光标位置。也可用 CTRL-E
对
光标下方的字符同样办理。
更多详情请阅读:
i_CTRL-Y
i_CTRL-E
12.15. 如何在当前行上方/下方插入空行而无需进入插入模式?
可用 :put ex 命令来插入空行。例如,试试
:put =''
:put! =''
更多详情请阅读:
:put
12.16. 如何插入当前文件名到当前缓冲区?
有几种办法插入当前文件名到当前缓冲区。插入模式下,可用 <C-R>
% 或
<C-R>
=expand("%") 命令。普通模式下,可用 `:put =@%` 命令。
更多详情请阅读:
i_CTRL-R
expand()
!!
12.17. 如何插入 Vim 寄存器的内容到当前缓冲区?
插入模式下,可用 <CTRL-R
><register>
命令来插入 <register>
的内容。例如,
<CTRL-R
>a 插入寄存器 "a" 的内容到当前缓冲区。
普通模式下,可用 `:put <register>
` 命令来插入 <register>
的内容。例如,
`:put d` 命令插入寄存器 "d" 的内容到当前缓冲区。
更多详情请阅读:
i_CTRL-R
i_CTRL-R_CTRL-R
i_CTRL-R_CTRL-O
i_CTRL-R_CTRL-P
:put
12.18. 如何移动光标跨过行尾并在行尾之后的列插入字符?
可设置 'virtualedit' 选项,这样就可以移动光标跨过行尾并在行尾之后的列插入字
符。要启动虚拟模式,用
:set virtualedit=all
更多详情请阅读:
'virtualedit'
12.19. Vim 如何把光标所在的单词 (比如说: junk) 替代为 "foojunkbar"?
有几种方法。如果单词是本行首个这样的词,可用以下的命令:
:exe "s/".expand("<cword>")."/foo&bar/"
要只匹配整个单词,可以这样用一个更复杂的替代:
:exe 's/\<'.expand("<cword>").'\%>'.(col(".")-1).'c\>/foo&bar/'
也可用命令: ciwfoo<C-R>
"bar<Esc>
更多详情请阅读:
:substitute
expand()
col()
/\%c
12.20. 如何对一个目录中的所有文件里的特定文本进行替代?
可用 :argdo 命令在参数指定的所有文件上执行替代命令:
:args *
:argdo %s/<your_text>/<replacement_text>/ge | update
更多详情请阅读:
:args_f
:argdo
:s_flags
12.21. 文件中有若干数值。如何为文件中的数值增量或减量?
可用 CTRL-A
键来增量数值,而用 CTRL-X
键来减量数值。也可通过指定键的计数来指定
增减的量。可用十进制、八进制和十六进制数值。修改 'nrformats' 选项可改变此操作
Vim 使用的基底。
更多详情请阅读:
26.2
CTRL-A
CTRL-X
'nrformats'
12.22. 如何在 :substitute 命令中重用前次搜索模式?
要在 :substitute 命令中重用前次搜索模式,不要指定新的搜索模式:
:s/pattern/newtext/
:s//sometext/
第二个 :s 命令里没有指定搜索模式,所以使用第一个 :s 命令的模式 "pattern"。
如果你想改变搜索模式但重复替代模式,可用特殊的右手边形式,波浪符:
:s/newpattern/~/
更多详情请阅读:
:s
:&
:~
&
sub-replace-special
可用 :substitute 命令的替代字符串中的特殊字符来改变匹配字符串的大小写。例
如,要把字符串 "MyString" 改成全部大写,可用以下命令:
:%s/MyString/\U&/g
要改成小写,可用以下命令:
:%s/MyString/\L&/g
要把当前行的所有单词的首字符改为大写,可用以下命令:
:s/\<\(.\)\(\k*\)\>/\u\1\L\2/g
更多详情请阅读:
sub-replace-special
:substitute
/\U
/\L
/\u
12.24. 如何键入键盘上没有的字符?
可用二合字母来键入键盘上没有的字符。可用 :digraphs 命令来显示所有当前定义的
二合字母。可用 :digraphs 命令在该列表中加入新的二合字母。
更多详情请阅读:
digraphs
'digraph'
24.9
12.25. 有没有命令删除任何或所有的二合字母?
没有。二合字母表是编译时定义的。只可以加入新二合字母。将来会考虑增加新命令来删
除二合字母。
12.26. 插入模式下,按退格键时,只删除这次在插入模式中键入的字符。如何能用退格
键删除在之前的插入模式中键入的字符?
这是 vi 的传统行为。可用 'backspace' 选项来删除之前插入模式中键入的字符:
:set backspace=indent,eol,start
更多详情请阅读:
'backspace'
i_backspacing
12.27. 文件有长于 72 字符的行,以 "+" 终止并回绕到下一行。如何快速连接这些行?
可用 :global 命令来搜索和连接这些行:
:g/+$/j
不过,这只会对每两行进行连接。一个更复杂的例子,可以连接所有连续以 "+" 结尾的
行:
:g/+$/,/\(^\|[^+]\)$/j
:g/+$/mark a | .,/\(^\|[^+]\)$/s/+$// | 'a,.j
更多详情请阅读:
:g
:j
:mark
12.28. 如何把抽出的面向字符的文本粘贴到单独的行上?
可用 :put 命令来把抽出的面向字符的文本粘贴到单独的行上:
:put =@"
更多详情请阅读:
:put
quote_=
12.29. 如何改变单词或字符或文本块的大小写?
可用 "~" 命令切换字符的大小写。
可用 "gUiw" 或 "viwU" 命令把光标所在的单词改为大写,而用 "guiw" 或 "viwu" 命令
改为小写。
可用 "viw~" 或 "g~iw" 命令切换光标所在的单词的大小写 (大写到小写,小写到大
写)。
可用 "gUgU" 命令把当前行改为大写,而用 "gugu" 命令把当前行改为小写。
可用 "g~g~" 命令切换当前行的大小写。可用 "g~{motion}
" 或 "{Visual}
~" 命令来切
换文本块的大小写。
如果置位了 'tildeop',"~" 命令类似操作符,会期待后跟应用的动作命令。如果设了
:set tildeop
而现在要切换当前光标位置到行尾的大小写,只要简单地用 "~$"。
更多详情请阅读:
case
'tildeop'
12.30. 如何键入键盘上没有的 ASCII 字符?
可用 CTRL-V
后跟 ASCII 字符值来键入键盘上没有的 ASCII 字符。也可用二合字母来键
入特殊的 ASCII 字符。
更多详情请阅读:
i_CTRL-V_digit
digraphs
45.5
12.31. 如何替代文件中的不可显示字符?
要替代不可显示字符,需要先决定字符的 ASCII 值。可用 :ascii ex 命令或 "ga" 普
通模式命令来显示光标所在字符的 ASCII 值。
可用 CTRL-V
后跟十进制数 1-255 (不能有前导的零)、或用 x 加上十六进数 00-FF,或
用八进制数 0-0377 (要有前导的零),或用 u 和十六进制数 0-FFFF,或用 U 和十六进
制数 0-7FFFFFFF
另一个办法是用 :digraphs ex 命令来显示所有字符的二合字母以及它们的十进制值和
字母值。可用 CTRL-K
后跟两个字母数字字符 (二合字母) 来输入不可显示字符。
更多详情请阅读:
:ascii
i_CTRL-V
i_CTRL-V_digit
:digraphs
12.32. 如何删除缓冲区中的重复行?
可用以下用户定义的命令来删除缓冲区中的重复行:
:command -range=% Uniq <line1>
,<line2>
g/^\%<<line2>
l\(.*\)\n\1$/d
把上述命令加入 .vimrc 文件,并调用 :Uniq
来删除所有的重复行。
12.33. 如何给文件中的所有行加上对应行号前缀?
有几个方法给文件中的所有行加上对应行号前缀。下面列出一些:
:%s/^/\=line('.'). ' '
:%s/^/\=printf('%5d ', line('.'))/
:%s/^/\=strpart(line('.').'. ', 0, 5)
:%s/^/\=strpart(' ', strlen(line('.'))).line('.').'. '
最后两个命令会用空格填充行号。最后那个命令会右对齐行号,而之前那个命令则左对齐
行号。
如果不想为连续行编号,而要为一些非连续的区域编号,可用以下的套路:
:let i = 1
:g/TODO/s/^/\=printf('%2d.',i)|let i+=1
首先,变量 i 初始化为 1。下一行中 :g 命令用于只在匹配 "TODO" 的行上执行替代
命令。变量 i 在每次替代命令发生后增加 1。
更多详情请阅读:
sub-replace-special
line()
expr6
strpart()
printf()
:execute
:global
12.34. 如何交换两个字符或单词或行?
可用 "xp" 命令序列来交换两个字符。"x" 会删除光标所在的字符而 "p" 会把刚刚删
除的字符粘贴到光标所在字符之后。最终结果就是交换了两个字符。
可用 "deep" 命令序列来交换两个单词 (先移动光标到首个单词之前的空白上)。
可用 "ddp" 命令序列来交换两行。"dd" 删除当前行,而 "p" 把刚刚删除的行粘贴到当
前行后。最终结果就是交换了两行。
所有以上的操作都会改变 " 无名寄存器。
可用 ":m +" ex 命令来交换两行而不改变无名寄存器。
更多详情请阅读:
x
p
dd
d
e
linewise-register
quotequote
:move
12.35. 如何改变用作单词定界的字符?
Vim 使用 'iskeyword' 选项指定的字符用作单词定界符。此选项的缺省值是
"@,48-57,_,192-255"。
例如,要加上 ":" 作为单词定界符,可用
:set iskeyword+=:
要让 "_" 不再用作单词定界符,可用
:set iskeyword-=_
更多详情请阅读:
'iskeyword'
word
第十三节 - 插入模式补全
13.1. 插入模式下如何补全单词或行?
插入模式下,可用 CTRL-P
和 CTRL-N
键补全单词。
CTRL-N
命令正向搜索下个匹配关键字。
CTRL-P
命令反向搜索下个匹配关键字。
插入模式下,可用 CTRL-X
CTRL-L
命令序列来补全开头和当前行光标前字符序列相同的
行。要得到下个匹配行,按 CTRL-P
或 CTRL-N
键。插入模式下还有其它很多的键/方法
可用。
Vim 支持以下项目的补全:
CTRL-X CTRL-L 整行
CTRL-X CTRL-N 当前文件中的关键字
CTRL-X CTRL-K 字典里的单词
CTRL-X CTRL-T 同义词字典里的单词
CTRL-X CTRL-I 当前文件和头文件
CTRL-X CTRL-] 标签
CTRL-X CTRL-F 文件名
CTRL-X CTRL-D 宏定义 (也包含头文件里的)
CTRL-X CTRL-V Vim 命令行
CTRL-X CTRL-U 用户定义补全
CTRL-X CTRL-O 全能补全
用户定义补全和全能补全常由文件类型插件设置。
更多详情请阅读:
24.3
ins-completion
13.2. 插入模式下如何补全文件名?
插入模式下,可用 CTRL-X
CTRL-F
命令序列来补全开头和当前行光标前字符序列相同的
文件名。
更多详情请阅读:
compl-filename
13.3. 插入模式下用了 CTRL-P
/CTRL-N
补全单词。如何补全刚补全的单词之后的单词?
可用 CTRL-X
CTRL-N
和 CTRL-X
CTRL-P
键来补全刚补全的单词之后的单词。
更多详情请阅读:
i_CTRL-X_CTRL-P
i_CTRL-X_CTRL-N
ins-completion
第十四节 - 文本排版
14.1. 如何排版文本段落以在每个回绕行尾插入换行符?
可用 "gq" 命令来排版段落。它会按照当前的 'textwidth' 设置来排版文本。另一方案
是用 "gw" 命令,和 "gq" 一样排版,但不移动光标。
注意
gq 操作符可和动作命令联用,在指定文本范围上操作。例如:
gqgq - 排版当前行
gqap - 排版当前段落
gwap - 排版当前段落 (且不移动光标)
gq3j - 排版当前行和后 3 行
更多详情请阅读:
gq
gw
formatting
usr_25.txt
motion.txt
14.2. 如何排版文件中的长行使得每行少于 "n" 个字符?
可设置 'textwidth' 选项来控制一行可拥有的字符数。例如,要设置行的最大宽度为 70
个字符,可用以下命令:
set textwidth=70
现在要在文件里断开长行到 'textwidth' 选项定义的长度,可用
:g/./normal gqq
更多详情请阅读:
'textwidth'
gq
14.3. 如何连接短行以形成段落?
首先,确保 'textwidth' 选项设为大值:
:set textwidth=99999
然后,用以下命令来连接短行以形成段落:
1GgqG
上述命令会在整个文件上操作。要在指定行范围上段落排版,可用:
:'a,'bg/\S/normal gq}
更多详情请阅读:
gq
G
gqq
14.4. 如何排版项目符号和编号列表?
可用 'formatoptions' 选项来配置 Vim 为项目符号和编号列表排版。例如,可以排版下
列格式的列表:
- this is a test. this is a test. this is a test. this is a test.
this is a test.
为如下格式:
- this is a test. this is a test. this is a test. this is a test.
this is a test.
可用 'formatoptions' 里的 "n" 标志位来对齐文本。
:set fo+=n
有此选项时,Vim 在文本排版时会识别编号列表。要此选项可用,必须置位
'autoindent' 选项。
更多详情请阅读:
'formatoptions'
fo-table
format-comments
14.5. 插入模式下如何缩进行?
插入模式下,可用 CTRL-T
键来在当前行的行首插入一个 shiftwidth 的缩进。插入模式
下,可用 CTRL-D
键来删除当前行行首的一个 shiftwidth 的缩进。插入模式下也可用
CTRL-O
>> 和 CTRL-O
<< 命令来缩进当前行。
更多详情请阅读:
i_CTRL-T
i_CTRL-D
i_0_CTRL-D
i_CTRL-O
>>
<<
14.6. 如何排版/缩进整个文件?
可以用 gg=G 命令来排版/缩进整个文件,其中
gg - 转到文件头
= - 应用缩进
G - 直到文件尾
更多详情请阅读:
gg
=
G
'formatprg'
C-indenting
14.7. 如何增加或减少当前行的缩进?
可用 ">>" 和 "<<" 命令来增加或减少当前行的缩进。
更多详情请阅读:
shift-left-right
>>
<<
'shiftwidth'
14.8. 如何对一组/块行进行缩进?
可以先可视选择一组行,然后按 > 或 < 键来对行缩进/反向缩进。也可用下列 ex 命令
来对行缩进
:10,20>
更多详情请阅读:
shift-left-right
v_>
v_<
:<
:>
14.9.用 > 或 < 键缩进行时,使用标准的 8-制表位而不是当前 'tabstop' 设置。为什
么?
">" 操作符缩进行时使用的空格数由 'shiftwidth' 选项控制。仅当 'shiftwidth' 选项
为零时才使用 'tabstop' 设置。
:set shiftwidth=4
更多详情请阅读:
'shiftwidth'
>>
'softtabstop'
14.10. 如何关闭文本的自动缩进?
缺省,不打开文本的自动缩进。检查配置文件 (.vimrc、.gvimrc) 关于缩进的设置。确
保没有 `:filetype indent on` 命令。如果有,把它删掉。另外,取决于你的选择,也
可以检查一下 'autoindent'、'smartindent'、'cindent' 和 'indentexpr' 选项的值,
有必要时关闭它们。
更多详情请阅读:
:filetype-indent-off
'autoindent'
'smartindent'
'cindent'
'indentexpr'
14.11. 如何配置 Vim 在编辑邮件时自动设置 'textwidth' 选项为指定值?
可用 "FileType" 自动命令来设置 'textwidth' 选项:
autocmd FileType mail set tw=<your_value>
更多详情请阅读:
:autocmd
FileType
usr_43.txt
14.12. 有没有办法使得 Vim 自动神奇地断行?
有。设置 'textwidth' 选项为推荐的行长度。Vim 会自动神奇在新输入的行上断开。例
如:
:set textwidth=75
更多详情请阅读:
'textwidth'
ins-textwidth
'formatoptions'
fo-table
formatting
14.13. 我在文件中看到很多的 ^M 符号。我试过设置 'fileformat' 选项为 "dos",又
试过 "unix" 然后 "mac"。都不行。我怎么才能隐藏这些符号呢?
文件载入到 Vim 时,文件的格式由以下步骤决定:
- 如果所有行都以换行符 (<NL>
) 结尾,则 fileformat 为 "unix"。
- 如果所有行都以回车符 (<CR>
) 后跟换行符 (<NL>
) 结尾,则 fileformat 为 "dos"。
- 如果所有行都以回车符 (<CR>
) 结尾,则 fileformat 为 "mac"。
如果文件有些行以 <CR>
结尾,有些行以 <CR>
后跟 <NL>
结尾,则 fileformat 设为
"unix"。
可以通过显式设置来改变当前文件的格式,例如改成 dos 格式:
:w ++ff=dos
要显示当前文件的格式,可用
:set fileformat?
上述行为也由 'fileformats' 选项控制。可用以下命令:
:set fileformats+=unix
:e <your_file>
:set fileformat=unix
:w
要删除当前文件所有行尾的回车符 (<CR>
),可用以下命令:
:%s/\r$//
要强制 Vim 在编辑文件时使用指定的文件格式,可用以下命令:
:e ++ff=dos filename
更多详情请阅读:
'fileformats'
'fileformat'
file-formats
DOS-format-write
Unix-format-write
Mac-format-write
dos-file-formats
23.1
++ff
14.14. 我从另一个应用粘贴文本到 Vim 缓冲区时,新文本的对齐 (缩进) 不对。如何修
正?
用鼠标粘贴文本到 GUI Vim 时,Vim 可以检测到你在粘贴文本。此时,忽略缩进有关的
设置 (如 autoindent、smartindent、cindent 等等),按本义粘贴文本。
用鼠标粘贴文本到终端 (如 xterm) 上运行的 Vim 时,Vim 可能检测不到你在粘贴文
本。这取决于几种事: 终端给 Vim 传递鼠标事件的能力、编译 Vim 时关于鼠标事件处理
和剪贴板访问的支持,DISPLAY 变量的正确设置,Vim 'mouse' 选项的正确设置。
如果 Vim 能检测到你在用鼠标粘贴文本,粘贴的文本会按本义插入。
如果 Vim 检测不到你在用鼠标粘贴文本,它会把文本的粘贴当作你在按文本直接输入文
本。插入粘贴文本的第一行后,Vim 看到了换行符,因为有缩进设置,下行会以缩进开
始,粘贴文本第二行开头的空白会导致额外的缩进。这会在之后的行上重复进行,所以最
后会以阶梯形式的缩进插入粘贴文本。
对终端 Vim 有几种方法可以修正此问题:
1. 编译 Vim 时带上 +mouse 和 +xterm_clipboard 编译时选项。Vim 的 normal 或 big
或 huge 版本包含了这些选项。设置 'mouse' 选项为 "a" 或至少包含 "i"。用鼠标
粘贴文本时,不要按 Shift 键。仅当 Vim 可访问 X 显示时可用。更多详情请阅读以
下 Vim 帮助主题:
+feature-list
'mouse'
<MiddleMouse>
x11-selection
xterm-clipboard
1.1 有些 Linux 发布编译它们的终端 vim 包时没有 X 支持。这不合理,给很多用户留
下了终端模式下的 Vim 不支持某些操作,比如用鼠标正确地粘贴文本的印象。
如果你的发布包含了如今几乎肯定有的 gvim,解决方案包含以下选项之一。
a) 用下列方式启动 Vim
gvim -v
b) 把下列 alias 放进外壳配置文件,如 ~/.bashrc 里:
alias vim='gvim -v'
c) 把下列命令存到名为 "vim" 的文件中,并把此文件放到你的 ~/bin 目录里:
gvim -v "$@"
d) 用下列命令把发布的 gvim 链接到 ~/bin/vim。只需要执行一次。
ln -s $(which gvim) ~/bin/vim
对 c) 和 d) 而言,确保你的 PATH 里 ~/bin 在 /usr/bin 之前。
2. 用 CTRL-R
CTRL-O
* 命令粘贴文本。这会按本义粘贴文本,不应用自动缩进。如果你
希望先粘贴文本然后修正缩进,可用 CTRL-R
CTRL-P
*。仅当 Vim 能访问 X 显示时
才能使用这些命令。更多详情请阅读以下 Vim 帮助主题:
i_CTRL-R_CTRL-O
i_CTRL-R_CTRL-P
quotestar
3. 在粘贴文本前置位 'paste' 选项。此选项会关闭所有缩进相关设置的效果。粘贴完文
本后务必用 `:set nopaste` 关闭此选项。否则 Vim 的缩进特性会停止工作。不要在
.vimrc 文件里永久置位 'paste' 选项。如果你经常重复以上步骤,可设置
'pastetoggle' 选项为某个键。按此键时,切换 'paste' 选项的值。粘贴文本前按此
键一次,粘贴文本后再按此键一次。注意
置位 'paste' 选项时,关闭所有的映射和
缩写。更多详情请阅读以下 Vim 帮助主题:
'paste'
'pastetoggle'
也可参考用户手册中的以下主题:
04.7
09.3
14.15. 有很长回绕行 (回绕处于 "on" 状态) 时,如有一行不能完全放进屏幕,它会完
全不显示。出现的是 "@" 符号开始的空行而不是回绕行。如果滚动屏幕后行能完
全放进,"@" 符号消失而该行会再次显示。什么 Vim 设置控制此行为?
可设置 'display' 选项为 "lastline" 来显示窗口末行尽量多的内容,而不是显示 "@"
符号。
:set display=lastline
更多详情请阅读:
'display'
14.16. 如何把文件中的所有的制表符转化为空格符?
可用 :retab 命令来用 'expandtab' 和 'tabstop' 的当前设置来更新当前文件中所有
的制表符。例如,把所有的制表符转化为空格符,可用
:set expandtab
:retab
更多详情请阅读:
:retab
'expandtab'
'tabstop'
25.3
14.17. 什么 Vim 选项可用来编辑之后会用文字处理器处理的文本?
可用以下选项来编辑之后会用文字处理器处理的文本:
:set wrap
:set linebreak
:set textwidth=0
:set showbreak=>>>
可用 "gk" 和 "gj" 命令来向上和向下移动一行屏幕行。更多详情请阅读:
'wrap'
'linebreak'
'textwidth'
'showbreak'
gk
gj
14.18. 如何才能连接行而不加减空格字符?
缺省用 "J" 或 :join 命令连接行时,Vim 会把换行符、引导和拖尾的空白替代为单个
空格符。如果行尾已经有空格或一行以 ")" 字符开头,Vim 不会加入空格符。
要连接行而不加减空格字符,可用 gJ 或 :join!
命令。
更多详情请阅读:
gJ
:join
J
10.5
'joinspaces'
'cpoptions'
'formatoptions'
第十五节 - 可视模式
15.1. 如何进行矩形列块复制?
Vim 中可用面向列块的可视模式来进行矩形列块复制。要启动面向列块的可视模式,用
CTRL-V
键。用任何动作命令来移动光标,然后用 y 操作符来抽出可视选中的文本。
如果 CTRL-V
没有效果,可能是被 mswin.vim 脚本重映射到了 CTRL-Q
,在 Windows 机
器上 vimrc 常执行此脚本以模拟一些其它程序常用的快捷方式。
更多详情请阅读:
04.4
blockwise-visual
visual-mode
Q_vi
15.2. 如何删除或修改文件中的一列文本?
可用 Vim 面向列块的可视方式来选择文本列并在其上应用操作符 (删除、修改、复制等
等)。
更多详情请阅读:
visual-block
visual-operators
15.3. 如何在一组可视选中的行上应用 ex 命令?
在可视模式下选中了行范围时,< 寄存器设为可视区域的开始处而 > 寄存器设为可视区
域的结束处。可用这些寄存器来指定 ex 命令的范围。可视地选择了行后,按 ":" 转到
命令行模式。Vim 会自动插入可视范围 '<,'>。在可视范围上可以运行任何 ex 命令。
更多详情请阅读:
v_:
'<
'>
15.4. 如何在可视列块模式选中的文本列上执行 ex 命令?
所有的 ex 命令仅在整行上操作。如果试图在可视列块模式选中的文本列执行 ex 命令,
Vim 会在所有选中的行 (而不是选中的列) 上操作。可用 https://www.vim.org 脚本归
档里的 vis.vim 或 NrrwRgn 插件脚本来完成。
更多详情请阅读:
cmdline-ranges
10.3
cmdline-lines
15.5. 如何用可视模式选择整个文件?
可用 ggVG 在可视模式下选择整个文件。
gg - 转到文件头。
V - 启动面向行的可视模式
G - 转到文件尾。
更多详情请阅读:
gg
linewise-visual
G
15.6. 可视选择一组行并按 > 键缩进选中的行时,可视模式结束。如何才能重新选择区
域用于将来的操作?(或) 如何才能重新选择最近选中的可视区域?
可用 "gv" 命令来重重新选择最近选中的可视区域。也可用位置标记 '< 和 '> 来跳转到
最近选中可视区域的开始和结束处。
更多详情请阅读:
gv
'<
'>
15.7. 如何跳转到可视选择区域的开始/结束处?
可用 "o" 命令来跳转到可视选择区域的开始/结束处。
更多详情请阅读:
v_o
15.8. 用鼠标选择文本并按 : 来输入 ex 命令时,选中的文本被 : 字符替代。如何才能
用鼠标在选中的文本上执行 ex 命令,就像在可视模式选中的文本那样?
如果配置 Vim 通过 'selectmode' 选项来使用选择模式而不是可视模式时,这会发生。
检查此选项的值:
:set selectmode?
此模式被称为选择模式,它和可视模式类似。用 "behave mswin" 命令时自动置位此选
项。选择模式类似于可视模式,但和 MS-Windows 的选择模式更类似。
更多详情请阅读:
Select-mode
'selectmode'
09.4
:behave
15.9. 用鼠标选择文本块时,Vim 进入了选择模式而不是可视模式。为什么?
'selectmode' 选项控制用鼠标选择文本块时是否启动可视模式。要在用鼠标选择文本时
启动可视模式,从 'selectmode' 选项中删除 "mouse" 值:
:set selectmode-=mouse
注意
缺省情况下,'selectmode' 选项设为空,因而总是使用可视模式。
更多详情请阅读:
'selectmode'
Select-mode
:behave
15.10. 如何可视地选择最近的复制/粘贴文本?
可用 '[ 和 '] 位置标记来可视地选择最近的复制/粘贴文本。'[ 位置标记设为最近修改
/抽出文本的开始处而 '] 位置标记设为最近修改/抽出文本的结束处。要可视地选择此文
本块,用命令 '[v']
更多详情请阅读:
'[
']
`a
v
第十六节 - 命令行模式
16.1. 如何在命令模式或 ex 命令行上使用当前文件名?
命令行上 "%" 字符代表当前文件名。有些命令需要你用 expand("%")
来取得文件
名:
:!perl %
另一例是载入从你正在编辑的文件用 latex 生成的 pdf 文件:
:!xpdf %<.pdf
更多详情请阅读:
:_%
cmdline-special
expand()
16.2. 如何有效地在 Vim 命令行上编辑文本?
可用命令行窗口来编辑 Vim 的命令行文本。要打开 Vim 命令行窗口,可在普通模式下用
"q:" 命令。在命令行模式下,用 CTRL-F
键。在此窗口中,会显示命令行历史。可用普
通的 Vim 键/命令来编辑任何之前/新的命令行。要执行某命令行,按 enter/return
键。
类似地,可用 "q/" 和 "q?" 命令编辑搜索历史。
更多详情请阅读:
cmdline-window
16.3. 如何从 Vi 模式切换到 Ex 模式?
可用 Q 命令来从 Vi 模式切换到 Ex 模式。要从 Ex 模式切换回 Vi 模式,可用 :vi
命令。
更多详情请阅读:
Q
gQ
Ex-mode
:vi
16.4. 如何把 ex 命令的输出复制进缓冲区?
要把 ex 命令的输出复制到缓冲区里,先要把命令输出放进一个寄存器。这可用
:redir 命令来完成。例如,
:redir @a
:g/HelloWord/p
:redir END
现在寄存器 'a' 会包含 ex 命令 :g/HelloWord/p
的输出,然后你可以把寄存器 'a'
的内容粘贴进缓冲区。也可用 :redir 命令把 ex 命令的输出发送或附加到文件。
可给 :global 命令加上 :silent 前缀,以避免把行显示在屏幕上。
要重定向 ex 命令的输出到文件,可用下列的命令组合:
:redir > myfile
:g/HelloWord/p
:redir END
更多详情请阅读:
:redir
:silent
16.5. 在命令模式下按了 <Tab>
键补全文件名时,如果有多于一个匹配的文件名,Vim
会用第一个匹配文件名补全并显示所有匹配文件名的列表。如何配置 Vim 只显示
匹配文件名的列表而不用第一个补全?
可修改 'wildmode' 选项来配置 Vim 在命令模式下补全文件名的方式。在这个情况下,
可设置 'wildmode' 选项为 "list":
:set wildmode=list
更多详情请阅读:
'wildmode'
16.6. 如何从缓冲区复制文本到命令行,又如何从命令行到缓冲区?
要从缓冲区复制文本到命令行,在从缓冲区抽出文本后,命令行上用 "<CTRL-R
>0" 来粘
贴文本。也可抽出文本到指定寄存器并用 CTRL-R
<register>
来粘贴文本到命令行。可
用 CTRL-R
CTRL-W
来粘贴光标所在的单词到命令行。
要从命令行复制文本到缓冲区,可用 ":p 命令粘贴 : 寄存器的内容。最近执行的命令行
存在 : 寄存器里。
另一个从或到命令行的复制和粘贴文本的办法是用普通模式下的 q: 或命令行模式的
CTRL-F
来打开命令行窗口。命令行窗口里可用所有的 Vim 命令来编辑命令行。
更多详情请阅读:
c_CTRL-R
quote_:
cmdline-window
16.7. 如何把命令放进命令历史而不执行它?
要把命令放进命令历史而不执行它,按 <Esc>
取消该命令。
一个替代方法是用 histadd() 函数,就像这样:
:call histadd(':', 'echo strftime("%c")')
更多详情请阅读:
c_<Esc>
histadd()
16.8. 如何增加命令行的高度?
可修改 'cmdheight' 选项来增加命令行的高度:
:set cmdheight=2
更多详情请阅读:
'cmdheight'
hit-enter
05.7
第十七节 - VIMINFO
17.1. 启动 Vim 时,给出关于 viminfo 里非法字符的错误信息。如何才能去掉这些信
息?
可以删除 $HOME/.viminfo 或 $HOME/_viminfo 文件来去掉这些错误信息。
更多详情请阅读:
viminfo-errors
viminfo-file-name
viminfo
21.3
17.2. 如何关闭 viminfo 特性?
缺省 viminfo 特性是关闭的。如果有系统范围的 vimrc 文件打开了 viminfo 特性,可
在局部的 .vimcrc 文件中设置 'viminfo' 选项为空串来关闭 viminfo 特性:
:set viminfo=""
更多详情请阅读:
'viminfo'
17.3. 如何保存和跨 Vim 会话使用 Vim 的位置标记/命令?
可用 viminfo 文件来保存和跨 Vim 会话使用 Vim 的位置标记。要使用 viminfo 文件,
确保 'viminfo' 选项非空。要保存和恢复 Vim 位置标记,'viminfo' 选项不应包含 "f"
标志位或 "f" 选项的值应大于零。
也可用 viminfo 文件来在不同会话间同步命令行历史。为此,使用 :wviminfo 和
:rviminfo 加上 FocusGained 或 FocusLost 自动命令:
augroup viminfo
au!
au FocusLost * wviminfo
au FocusGained * rviminfo
augroup end
备注
: 要使这段代码可靠地工作,Vim 应能正确检测 FocusLost 和 FocusGained 自动命
令。这就是说 GVim 没问题,而控制台 vim 取决于你的终端。
更多详情请阅读:
21.3
viminfo
'viminfo'
:wviminfo
:rviminfo
FocusLost
FocusGained
第十八节 - 远程编辑
18.1. 如何使用已有的 gvim 实例打开文件?Vim 5.x 的 OpenWithVim.exe 和
SendToVim.exe 文件去哪里啦?
从 Vim6 开始,OLE 版本的 OpenWithVim.exe 和 SendToVim.exe Vim 工具被新的客户-
服务器特性代替了。要用已有的 Gvim 实例 (MyVim) 打开文件 j.txt,可用:
$ gvim --servername MyVim --remote-silent j.txt
要列出当前运行的 Vim 实例的服务器名,可用
$ vim --serverlist
要了解客户-服务器特性的详情,请阅读
client-server
18.2. 如何发送命令到 Vim 服务器去把所有缓冲区写回到盘上?
可用 Vim 远程服务器功能来完成:
$ gvim --servername myVIM --remote-send "<C-\><C-N>:wall<CR>"
更多详情请阅读:
client-server
CTRL-\_CTRL-N
:wall
18.3. 哪里有 Vim 远程服务器功能的文档?
关于 Vim 远程服务器功能的文档的详情,请阅读
client-server
第十九节 - 选项
19.1. 如何可以简便地配置 Vim?
可用 :options 命令来打开 Vim 选项窗口:
:options
此窗口可用于察看和设置所有选项。
更多详情请阅读:
:options
19.2. 如何切换选项值?
可用选项加上 "inv" 前缀来切换选项值:
:set invignorecase
:set invhlsearch
也可用选项加上 "!" 后缀来切换选项值:
:set ignorecase!
:set hlsearch!
更多详情请阅读:
set-option
19.3. 如何设置只影响当前缓冲区/窗口的选项?
有些 Vim 选项有局部和全局值。局部值只应用于指定的缓冲区和窗口。全局值应用于所
有缓冲区或窗口。
用 :set 命令修改选项时,同时改变选项的全局和局部值。用 :setlocal 命令可只
修改选项的局部值,而 :setglobal 命令只修改选项的全局值。
可用 :setlocal 命令来设置只影响当前文件/缓冲区的选项:
:setlocal textwidth=70
注意
不是所有选项都有局部值。仅当选项支持局部值时,才能用 :setlocal 命令来设
置局部于缓冲区/窗口的选项。
也可用下列命令设置局部选项:
:let &l:{option-name} = <value>
更多详情请阅读:
:setlocal
local-options
19.4. Vim 选项值里如何使用空格符?
要在 Vim 选项值里使用空格符,需要给空格符转义。例如:
:set tags=tags\ /usr/tags
更多详情请阅读:
option-backslash
19.5. 如何把 Vim 选项设定加入 (嵌入) 文件内容里?
可用模式行把 Vim 选项设定加进文件内容。例如,在 C 文件里,可在文件的顶部或底部
加入下行:
/* vim:sw=4: */
编辑此 C 文件时,'shiftwidth' 选项就会设置为 4。为此必须置位 'modeline' 选项。
缺省是置位的。另一个例子在本文档的首行给出。
'modelines' 设置指定用于检查 Vim set 命令的行数。
更多详情请阅读:
21.6
modeline
auto-setting
'modeline'
'modelines'
19.6. 如何显示文件中所有行的行号?
可设置 'number' 选项来显示所有行的行号。
:set number
更多详情请阅读:
'number'
19.7. 如何改变 'number' 选项显示的行号的宽度?
可用 'numberwidth' 选项来设置用于行号的最少列数:
:set numberwidth=3
这会设置行号的宽度为 3 个数位,如果缓冲区少于 999 行,这应该足够了。不过如果当
前缓冲区多于 999 行,'numberwidth' 会相应调整,使得最大行号可以放进屏幕。
19.8. 如何显示 (查看) 文件中所有的不可见字符,如空格、制表和换行?
可置位 'list' 选项来看到文件中所有的不可见字符。
:set list
置位此选项后,可以查看空格符、制表、换行、拖尾的空格符和回绕行。
要不显示不可见字符 (这是缺省),需要复位 'list' 选项:
:set nolist
(或)
:set list!
`:set list!` 命令会切换布尔 'list' 选项的当前值。
可修改 'listchars' 选项来配置如何显示和显示什么不可见字符。例如,下列命令会显
示所有的拖尾空格符为 "." 字符。
:set listchars=trail:.
更多详情请阅读:
'listchars'
'list'
19.9. 如何配置 Vim 来总是显示当前行号和列号?
可置位 'ruler' 选项来在状态行上显示当前列号和行号:
:set ruler
更多详情请阅读:
'ruler'
19.10. 如何显示当前 Vim 模式?
可置位 'showmode' 选项来显示当前 Vim 模式。在插入、替换和可视模式下,Vim 会在
末行显示当前模式。
:set showmode
更多详情请阅读:
'showmode'
19.11. 如何配置 Vim 在状态行上显示待定/部分命令?
可置位 'showcmd' 选项在状态行上显示待定/部分命令:
:set showcmd
更多详情请阅读:
'showcmd'
19.12. 如何配置 Vim 状态行以显示不同的设置/值?
可设置 'statusline' 选项来在 Vim 状态行上显示不同的值/设置。
更多详情请阅读:
'statusline'
'laststatus'
'rulerformat'
'ruler'
19.13. 如何配置 Vim 总是显示状态行?
可设置 'laststatus' 选项为 2 来总是显示状态行。
:set laststatus=2
更多详情请阅读:
'laststatus'
19.14. 如何在不同的 Vim 调用/实例/会话间存留 Vim 设置?
要在不同的 Vim 实例间存留 Vim 选项设置,把你的设置放在 .vimrc 或 .gvimrc 文
件里。也可用 :mkvimrc 命令来用当前设置生成 vimrc 文件。
更多详情请阅读:
save-settings
vimrc
gvimrc
vimrc-intro
:mkvimrc
initialization
19.15. 为什么在按 Escape 键后会听到响铃 (窗口会闪烁) 大约 1 秒钟?
这是正常行为。如果窗口闪烁,你打开了可视响铃。不然,你会听到鸣叫。
Vim 需要超时来区别简单的 Escape 和,比如说,光标键盘序列。在普通模式按键 (即使
插入模式也是如此) 而该键是映射开始的一部分时,Vim 会等待一段时间来观察映射序列
的其余部分是否出现。如果映射序列在规定超时期限之前完成,应用该键盘序列的映射。
但如果映射被中断,执行和键关联的正常动作。
例如,如果你有映射定义 `:imap vvv Vim is great!!`,然后快速地按了 "vvv",那么
就会插入文本 "Vim is great!!"。但如果你按了 "vv v" 那么就按原样放置进文本。这
也适用于键入 "vvv" 过慢的情形,这里 "过慢" 是超过超时选项值的时间。设置超时选
项为更大值可有助于减轻在慢速线路上使用函数键出现的问题。
更多详情请阅读:
'ttimeout'
19.16. 如何使 "c" 和 "s" 命令显示 "$" 而不是删除正在修改的字符?
要使 "c" 和 "s" 命令显示 "$" 而不是删除正在修改的字符,给 'cpoptions' 选项加入
$ 标志位:
:set cpoptions+=$
更多详情请阅读:
'cpoptions'
19.17. 如何用单个 :set 命令删除一个 Vim 选项的多个标志位?
要用单个 :set 命令删除一个 Vim 选项的多个标志位,可指定和选项中出现顺序完全
相同的标志位序列。例如,如果用下列命令来从 'formatoptions' 选项中删除 "t" 和
"n" 标志位:
:set formatoptions-=tn
仅当 'formatoptions' 选项以顺序 "tn" 包含这些标志位时,才从 'formatoptions' 选
项里删除 "t" 和 "n" 标志位。否则,标志位不会被删除。要避免此问题,可以一个一个
删除标志位:
:set formatoptions-=t formatoptions-=n
更多详情请阅读:
:set-=
第二十节 - 键映射
20.1. 如何知道键被映射了?
要看到什么键被映射了,可用以下命令:
:map <key>
:map! <key>
也可用 :cmap 、 :nmap 、 :vmap 、 :imap 、 :omap 等命令之一来检查特定模式下
的映射。
要知道键映射是在哪里发生的,加上 :verbose 命令前缀:
:verbose :map <key>
更多详情请阅读:
map-listing
map-overview
20.2. 如何列出用户定义的所有键映射?
可以这样列出用户定义的所有键映射:
:map
更多详情请阅读:
map-listing
20.3. 如何删除键映射?
可用 :unmap 命令来删除之前的键映射:
:unmap <key>
:unmap! <key>
对模式特定的映射,可用以下命令之一:
:nunmap
:vunmap
:ounmap
:iunmap
:lunmap
:cunmap
以下命令会在删除局部于缓冲区的键映射时失败:
:unmap <key>
要删除局部于缓冲区的键映射,须在 unmap 命令里用 <buffer>
关键字:
:unmap <buffer> <key>
:unmap! <buffer> <key>
更多详情请阅读:
:unmap
map-modes
:map-local
mapleader
20.4. 不能建立 <xxx>
键的映射。哪里做错了?
1) 首先要确定,此键正确地传给了 Vim。要确定这一点,进入插入模式,然后按 CTRL-V
(或 CTRL-Q
,如果 CTRL-V
被重映射到粘贴操作,例如在 Windows 上而用了
mswin.vim 脚本文件的时候) 后跟你的键。
如果缓冲区里什么都没有 (假定你打开了 'showcmd',^V 会在 Vim 屏幕右下角继续
显示),那么 Vim 没有正确地接收到该键,此时你什么都做不了,除了选一个不同的
键用于映射以外。也可考虑用 GVim,后者应能正确地识别这些键。
2) 有可能,Vim 收到了该键,但不觉得它和另一个键有何不同。例如你要映射
<Ctrl-Right>
,在插入模式下在 CTRL-V
之后按了 Ctrl-Right。如果 Vim 显示
<C-Right>
,应是正确看见了键击,而你应该就可以对它映射 (把 <C-Right>
作为
{lhs}
)。如果显示的是 <Right>
,也就是看见了键击但就像没按下 Ctrl 一样: 这意
味着终端把 Ctrl-Right 当作 <Right>
一样传送。任何其它值都意味着键被错认了。
3) 如果看到了键,但既不是它自身也不是其它能识别的键,可能是当前终端的终端库
(termcap 或 terminfo 数据库) 里有误。这种情形下
:set term?
会告诉你 Vim 用的是哪个 termcap 或 terminfo。可以在 vimrc 里加入下列命令来
试图告知 vim 该终端应使用什么键码:
if &term == <termname>
set <C-Right>=<keycode>
endif
其中上面的 <termname>
应被 'term' 的值替换 (加上引号) 而 <keycode>
被你在插
入模式下按 CTRL-V
后跟 <Ctrl-Right>
得到的键值所替换 (不加引号)。<C-Right>
照字面输入 (9 个字符)。不要忘记 :set 命令不允许等号和值之间有空白,而作为
值一部分的空格、双引号、垂直线或反斜杠必须用反斜杠转义。
现在你应能看到对应键的键码,然后就可以用下列命令创建该键的映射:
:map <C-Right> <要映射的命令>
更多详情请阅读:
map-keys-fails
:map-special-keys
key-codes
20.5. 为什么 <C-...> 键的映射不可用?
Vim 能可靠识别的 <Ctrl>
-<printable-key>
组合 (因为由 ASCII 标准定义) 只有以下
这些:
CTRL-@ 0x00 NUL
CTRL-A 到 CTRL-Z 0x01 到 0x1A
CTRL-a 到 CTRL-z 0x01 到 0x1A
CTRL-[ 0x1B ESC
CTRL-\ 0x1C
CTRL-] 0x1D
CTRL-^ 0x1E
CTRL-_ 0x1F
CTRL-? 0x7F DEL
不过,这里多数键在 Vim 里已有对应功能 (有些是其它键的别名: CTRL-H
对应 <BS>
、
CTRL-I
对应 <Tab>
、CTRL-M
对应 <Enter>
、CTRL-[
对应 <Esc>
、CTRL-?
对应
<Del>
)。
Vim 可用的 "最安全的" 用于映射 {lhs}
的键是带或不带 Shift 的 F 系列键: <F2>
到
<F12>
和 <S-F1>
到 <S-F12>
。(有些操作系统,包括我的,截获 <Ctrl-Fn>
和
<Alt-Fn>
,使它们永远到不了 vim 或 gvim 这样的应用程序)。
可以试试其它 <Ctrl>
+ 任何键的组合,不过未必在所有地方都可用 (例如终端可能不把
该键传给 Vim),或有意想不到的副作用 (例如 <C-I>
的映射也会用于 <Tab>
的映射)。
这是个已知的问题,讨论过,将来可能会允许 Vim 即使在控制台模式也能区别若干键的
实现。(例如 https://groups.google.com/d/msg/vim_dev/2bp9UdfZ63M/sajb9KM0pNYJ)
20.6. 如何映射数字小键盘上的键?
首先确保数字小键盘的键能传递给 Vim。然后用下列命令来映射数字小键盘上的键:
:map <kSomething> <your_command>
其中,<kSomething>
可以是 kHome、kEnd、kPageUp、kPageDown、kPlus、kMinus、
kDivide、kMultiply、kEnter 等等。
更多详情请阅读:
key-codes
terminal-options
20.7. 如何创建只在可视模式下可用的映射?
可创建只用于指定模式的映射 (普通、命令、插入、可视等)。要创建只能用于可视模式
的映射,可用 :vmap 命令:
:vmap <F3> <你的映射>
此映射只用于可视和选择模式。如果只想此映射用于可视模式 (排除选择模式),用:
:xmap <F3> <你的映射>
要使此映射只用于选择模式 (而不是可视模式),用:
:smap <F3> <你的映射>
更多详情请阅读:
:vmap
:xmap
:smap
map-modes
40.1
20.8. 如何创建只在普通和操作符等待模式 (而不是可视模式) 下可用的映射?
:map 创建可用于普通、可视+选择和操作符等待模式的映射。可用 :nmap 定义只用
于普通模式的映射,用 :vmap 定义只用于可视和选择模式的映射,而用 :omap 定义
只用于操作符等待模式的映射。
不过如果你要定义可用于操作符等待和普通模式而不用于可视和选择模式的映射,需要先
用 :map 定义映射,然后删除可视和选择模式下的该映射:
:map <f3>
<your mapping here>
:vunmap <f3>
20.9. Vim 脚本中,如何知道用哪个键来映射而不会和已有的键相冲突?
Vim 用了键盘上的大多数键。映射中可用 <leader>
前缀来定义不会和 Vim 键起冲突的
键。例如:
:map <leader>S <C-W>s
:map <leader>j <C-W>j
:map <leader>k <C-W>k
这里,缺省 <leader>
被反斜杠 (\) 替代,这样用户会输入
\s
\j
\k
来调用以上的映射命令。用户可修改 mapleader 变量为任何他们想要的键:
:let mapleader = ","
编写插件或其它脚本时,多数情况建议使用 :noremap 而不是 :map 以避免用户定义
映射的副作用。
更多详情请阅读:
<Leader>
<LocalLeader>
write-plugin
20.10. 如何映射 escape 键?
可用 :map 命令把 escape 键映射成其它键。例如,下列命令把 escape 键映射成
CTRL-O
。
:map <Esc> <C-O>
20.11. 如何把键映射为空操作?
可把键映射为 <Nop>
,按下此键时不执行任何操作。例如,以下映射使 <F7>
键在按下时
什么都不做。
:map <F7> <Nop>
:map! <F7> <Nop>
更多详情请阅读:
<Nop>
:map
:map!
map-modes
20.12. 想用 <Tab>
键来缩进一块文本而 <Shit-Tab>
键来反向缩进一块文本。如何才能
通过映射键完成?此行为和 textpad、visual studio 等类似。
使用以下映射:
:inoremap <S-Tab> <C-O><lt><lt>
:nnoremap <Tab> >>
:nnoremap <S-Tab> <lt><lt>
:vnoremap <Tab> >
:vnoremap <S-Tab> <lt>
注意
,<S-Tab>
映射仅当 Vim 能正确接收它的键序列时才可用。GUI Vim 上多半可以。
更多详情请阅读:
:inoremap
:nnoremap
:vnoremap
<S-Tab>
i_CTRL-O
>>
<<
<lt>
20.13. 我的映射里不识别 <CR>
这样的特殊字符。如何配置 Vim 才能识别特殊字符?
检查 'cpoptions' 选项值:
:set cpoptions?
此选项包含 "<" 标志位时,映射里不识别特殊字符。从 'cpoptions' 选项里删除 "<"
标志位:
:set cpo-=<
另外,检查 'compatible' 选项值:
:set compatible?
'compatible' 选项必须复位:
:set nocompatible
更多详情请阅读:
'cpoptions'
'compatible'
20.14. 如何在映射里使用 "|" 来分隔多个命令?
映射里可以用反斜杠转义 "|" 字符。
:map _l :!ls \| more<CR>
也可试试以下命令:
:map _l :!ls <bar> more<CR>
还有其它办法可以做到。
更多详情请阅读:
map_bar
20.15. 如果一个映射/缩写的结束是另一个映射/缩写的开始,如何不让第一个映射扩展
第二个映射?
不用 `:map lhs rhs` 命令,而用 `:noremap lhs rhs` 命令代替。缩写可用
"noreabbrev lhs rhs"。"nore" 前缀防止映射或缩写被再次扩展。
更多详情请阅读:
:noremap
:noreabbrev
20.16. 为什么有时我按一个键时,Vim 需要花一秒或更长时间来处理这个键?
用下列命令来确认你没有定义此键的映射:
:map <key>
如果此键有定义映射且映射用键多于一个字符,Vim 会等待下个字符按下来决定是否有映
射用键。例如,如果你映射了 "ab" 然后按 "a",Vim 会等待下个键按下。如果下个键是
"b",Vim 会执行映射序列。否则,Vim 会用正常方式处理 "a" 和下一个键。如果置位了
'timeout' 选项 (这是缺省),Vim 会等待 'timeoutlen' 选项 (缺省为 1 秒) 指定的超
时。
更多详情请阅读:
map-typing
'timeoutlen'
'ttimeoutlen'
'timeout'
'ttimeout'
vt100-cursor-keys
slow-fast-terminal
20.17. 如何映射键来在可视选择文本上运行外部命令?
可用 :vmap 命令来为可视模式映射键。在命令序列中,要先抽出文本。抽出的文本在
'"' 寄存器里。然后用此寄存器的内容来运行外部命令。例如,要在可视选择文本上运行
命令 "perldoc",可用以下映射:
:vmap <F7> y:!exec "!perldoc '" . @" . "'"<CR>
如果想要映射在可视模式下可用但不使用高亮文本,可用以下命令:
:vmap <F7> :<C-U>!perldoc <cword><CR>
以上映射使用光标所在的单词而不是高亮文本。注意
在调用 "perldoc" 外部命令之前的
<C-U>
的使用。<C-U>
用于删除在命令行上显示的可视模式选择的文本范围。如果不用
<C-U>
删除可视范围,外部命令的输出会替换可视选择文本。
更多详情请阅读:
:vmap
quote_quote
:let-register
c_CTRL-U
:!cmd
20.18. 如何映射 CTRL-I
键,同时保留 <Tab>
键的功能?
CTRL-I
键和 <Tab>
键产生相同的键码,所以 Vim 无法区分 CTRL-I
和 <Tab>
键。映射
CTRL-I
键时,同时映射了 <Tab>
键 (反之亦然)。同样的限制也适用于 CTRL-[
键和
<Esc>
键。
更多详情请阅读:
keycodes
20.19. 如何定义接受计数的映射?
用 @= 命令来使用表达式。例如,
nnoremap = @='3l'
现在就可为 "=" 命令给出计数了。
complex-repeat
20.20. 如何使普通模式映射用于插入模式?
插入模式下,在 CTRL-O
之后也可执行普通模式的映射,但映射 {rhs}
如果包含更多命
令,只执行普通模式下的第一个命令,而其余的 {rhs}
会在插入模式下按本义显示。此
问题的一个临时解决方案是使通过函数封装使 {rhs}
成为一个命令。例如:
function GetFontNameOfFirstChar()
normal! 0
echo getfontname()
endfunction
:nmap <F9>
:call GetFontNameOfFirstChar()<CR>
此问题更技术性及具体的解决方法如下,也可在以下位置找到
https://groups.google.com/group/vim_dev/msg/75f1f2dfc00908bb
不是每个普通模式映射都自动地适合用于插入模式下的 CTRL-O
执行;需要为此显式设计
你的映射。
CTRL-O
命令允许插入模式下执行一个普通模式命令,然后返回插入模式。如果普通模式
映射连接了多个普通模式命令,在临时普通模式中会被分解,命令的第二部分会按本义插
进缓冲区。要支持插入模式下普通模式映射的执行,可用以下策略:
1) 使用一个 :normal 映射而不是连接多个普通模式命令:
:nnoremap <silent> zC :<C-U>normal! zCVzC<CR>
2) 在右手边用 <Bar>
连接多个 Ex 命令:
:nnoremap zC :<C-U>call MyMap1()<Bar>call MyMap2()<CR>
3) 定义插入模式映射来重新进入普通模式并执行真正的普通模式映射:
:nnoremap <silent> <SID>MyMap2 :<C-U>call MyMap2()<CR>
:inoremap <silent> <script> <SID>MyMap2 <C-\><C-O><SID>MyMap2
:nnoremap <silent> <script> zC <SID>MyMap1<SID>MyMap2
4) 包含多个 Ex 命令行 (且 Ex 命令不能用 <Bar>
连接) 的普通模式映射把 :<C-U>
换成 <SID>
NM;<SID>
NM 映射会在普通模式下执行一个 ex 命令行:
:nnoremap <silent> <SID>NM :<C-U>
:inoremap <silent> <SID>NM <C-\><C-O>:
:nnoremap <silent> <script> zC <SID>MyMap1<SID>NMcall MyMap2()<CR>
5) 如果以上都不可行,至少为后续命令用 CTRL-\
CTRL-N
来强制普通模式以避免意外插
入映射的余下部分。
:nnoremap zC zC<C-\><C-N>VzCzz
更多详情请阅读:
i_CTRL-O
map_bar
i_CTRL-\_CTRL-O
CTRL-\_CTRL-N
第二十一节 - 缩写
21.1. 如何自动修正单词的错误拼写?
可用缩写来自动修正单词的错误拼写。例如,下列缩写可用于修正 "teh" 为 "the":
:abbreviate teh the
Vim 支持插入模式、替换模式和命令行模式下的缩写。
更多详情请阅读:
24.7
abbreviations
Q_ab
21.2. 如何创建多行缩写?
可在文本中嵌入 <CR>
键盘代码来创建多行缩写:
iabbrev #c --------------<CR>-- Date:<CR>--<CR>---------
使用以上缩写,输入 #c 后,会扩展为下列文本:
更多详情请阅读:
abbreviations
21.3. 扩展缩写时,在扩展文本尾部加了额外的一个空格。如何才能避免这个空格?
要避免扩展文本尾部的额外空格,可用 CTRL-]
键来扩展缩写。此时缩写扩展后不会在尾
部加上空格。
另一个方案是使用下列函数和命令:
function! Eatchar(pat)
let c = nr2char(getchar())
return (c =~ a:pat) ? '' : c
endfunction
command! -nargs=+ Iabbr execute "iabbr" <q-args> . "<C-R>=Eatchar('\\s')<CR>"
现在,用新的 "Iabbr" 命令而不是内建的 :iabbrev 命令来定义缩写。用此命令,扩
展缩写文本后,忽略下个输入的空格。
更多详情请阅读:
abbreviations
21.4. 如何在文件中插入当前日期/时间戳?
可用 strftime() 函数在文件中插入当前日期/时间戳。例如,可用:
iabbrev dts <C-R>=strftime("%y/%m/%d %H:%M")<CR>
用此缩写,插入模式下输入的 dts 会扩展为日期/时间戳。
以下列出上述缩写的其它形式:
iabbrev mdyl <C-R>=strftime("%a %d %b %Y")<CR>
iabbrev mdys <C-R>=strftime("%y%m%d")<CR>
iabbrev mdyc <C-R>=strftime("%c")<CR>
iabbrev hml <C-R>=strftime("%d/%m/%y %H:%M:%S")<CR>
iabbrev hms <C-R>=strftime("%H:%M:%S")<CR>
更多详情请阅读:
strftime()
i_CTRL-R
21.5. 插入模式下如何防止缩写被扩展?
插入模式下,缩写单词前按 CTRL-V
可防止缩写被扩展。
更多详情请阅读:
abbreviations
第二十二节 - 记录和回放
22.1. 如何重复编辑操作 (插入、删除、粘贴等等)?
可用 "." 命令重复前次的编辑操作。这会重复前次的简单改动,如插入、删除、修改、
粘贴等等。
更多详情请阅读:
04.3
single-repeat
Q_re
22.2. 如何记录和重复一组键序列?
在普通模式下可用 "q" 命令来记录一组键序列并存入一个寄存器。例如,普通模式下可
按 q 后跟寄存器名 {0-9a-bA-Z"} 来开始记录。要结束/中止记录,再次按 q。然后可以
按 @ 后跟寄存器名来回放/重复记录的键序列,如 @a。
另一个方法是用 "-w" 命令行参数启动 Vim。
$ vim -w <file_name>
Vim 会把会话中输入的所有字符记录到指定的文件 "file_name" 里。然后可用 "-s" 命
令行参数来回放此记录文件:
$ vim -s <file_name>
更多详情请阅读:
10.1
recording
-w
-s
22.3. 如何编辑/修改记录好的键序列组?
记录好的键序列会存入一个寄存器。可把此寄存器内容粘贴到 Vim 缓冲区里,编辑粘贴
的文本,然后抽出文本回该寄存器。也可用 :let 命令来修改寄存器。例如:
:let @a = "iHello World\<Esc>"
更多详情请阅读:
recording
10.1
:let-register
<>
'cpoptions'
22.4. 如何把记录好的键序列存入文件?
记录好的键序列会存入一个寄存器。可把寄存器内容粘贴到 Vim 缓冲区里。然后保存缓
冲区到文件。也可修改粘贴的文本,然后抽出文本回该寄存器以修改键序列的记录。例
如,如果用 qa ..... q 来记录一组键序列,记录好的键序列存入寄存器 'a'。用 "ap
可以粘贴寄存器 'a' 的内容。
更多详情请阅读:
recording
10.1
22.5. 用寄存器 0 来记录键序列时 (即 q0 .... q),记录的键序列中有抽出文本的操
作。记录的键序列在第一次回放后,就不能再次回放了。
寄存器 0 包含了最近抽出操作的文本。在完成记录键序列中的抽出时,寄存器 0 被抽出
的文本覆盖。这样你存在寄存器 0 的记录就丢失了。请使用其它寄存器。
更多详情请阅读:
registers
第二十三节-自动命令
23.1. 如何在试图修改只读文件时执行命令?
可用 FileChangedRO 自动命令事件在试图修改只读文件时执行命令。例如,利用此事件
来检出只读文件:
:autocmd FileChangedRO * call MyCheckoutFunction()
更多详情请阅读:
FileChangedRO
23.2. 如何在每次进入缓冲区时执行命令?
可用 BufEnter 自动命令事件在每次进入缓冲区时执行命令。例如:
:autocmd BufEnter *.c set formatoptions=croqt
更多详情请阅读:
BufEnter
23.3. 如何在每次进入窗口时执行命令?
可用 WinEnter 自动命令事件在每次进入窗口时执行命令。例如:
:autocmd WinEnter *.c call MyFunction()
更多详情请阅读:
WinEnter
23.4. 自动命令里,如何确定激活自动命令的文件名或缓冲区号?
可在自动命令里用特殊单词 <afile>
和 <abuf>
取得激活自动命令的文件名或缓冲区
号。
更多详情请阅读:
:<afile>
:<abuf>
:<amatch>
23.5. 如何在 Vim 丢失焦点时自动保存所有已修改的缓冲区?
可定义 FocusLost 自动命令事件在 Vim 丢失焦点时自动保存所有已修改的缓冲区:
:autocmd FocusLost * wall
更多详情请阅读:
FocusLost
:wall
23.6. 如何在 Vim 退出时执行/运行函数进行清理?
可用 VimLeave 自动命令事件在 Vim 即将退出之前执行函数。例如,
:autocmd VimLeave * call MyCleanupFunction()
更多详情请阅读:
VimLeave
第二十四节 - 语法高亮
24.1. 如何关闭/打开语法高亮?
缺省关闭 Vim 语法高亮。要打开语法高亮,可用以下命令之一:
:syntax enable
或
:syntax on
要关闭语法高亮,可用以下命令:
:syntax off
更多详情请阅读:
06.1
06.4
:syntax-enable
:syntax-on
:syn-clear
24.2. 如何改变 Vim 使用的背景和前景色?
"Normal" 高亮组用于背景和前景色。要改变前景/背景色,可修改 "Normal" 高亮组。例
如,要设置背景为蓝色及前景为白色,可用
:highlight Normal ctermbg=blue ctermfg=white guibg=blue guifg=white
如果使用 GUI Vim 的 Motif 或 Athena 版本,可修改 .Xdefaults 文件里的前景和背景
资源名来修改颜色:
Vim.foreground: Black
Vim.background: Wheat
也可用 "-foreground" 和 "-background" 命令行参数指定前景和背景色。只有 Motif
和 Athena 版本支持这些参数:
$ gvim -foreground Black -background Wheat
更多详情请阅读:
:highlight
.Xdefaults
-gui
24.3. 如何改变高亮色彩来匹配深色/浅色背景?
可设置 'background' 选项为 "dark" 或 "light" 来改变高亮色彩以匹配深色/浅色背
景:
:set background=dark
更多详情请阅读:
'background'
06.2
24.4. 如何改变使用 `:set number` 时显示行号的颜色?
显示的行号使用 LineNr 高亮组。要看到当前使用的颜色,用
:hi LineNr
要改变颜色,修改 LineNr 高亮组。例如:
:hi linenr guifg=red guibg=black
GVIM 里,这会显示黑色背景上的红色数字。
更多详情请阅读:
:highlight
24.5. 如何改变用于可视选择列块的背景色?
可修改 "Visual" 高亮组来改变用于可视选择列块的背景色:
:highlight Visual guibg=red
更多详情请阅读:
:highlight
hl-Visual
24.6. 如何高亮 'list' 选项显示的特殊字符 (制表、拖尾空格、行尾等)?
可修改 "NonText" 和 "SpecialKey" 高亮组来高亮 'list' 选项显示的特殊字符:
:highlight NonText guibg=red
:highlight SpecialKey guibg=green
"NonText" 高亮组用于 'listchars' 选项中的 "eol"、"extends" 和 "precedes" 设
置。"SpecialKey" 高亮组用于 "tab" 和 "trail" 设置。
更多详情请阅读:
'listchars'
hl-NonText
hl-SpecialKey
24.7. 如何在 .vimrc/.gvimrc 文件里设置色彩方案,让 Vim 每次都使用我指定的色彩
方案?
可在 .vimrc 或 .gvimrc 文件里用 :colorscheme 命令指定色彩方案:
colorscheme evening
更多详情请阅读:
:colorscheme
24.8. Vim 语法高亮不能用了。编辑文件时,文件的一部分没有语法高亮或语法高亮不正
确。
Vim 进行语法高亮时不读入整个文件来解析文本。它在任何你阅读文件的地方开始解析。
这节约了很多时间,但因此有时颜色不正确。简单的修正是用 CTRL-L
键刷新屏幕。或回
滚一小段再滚动回来。也可用命令:
:syntax sync fromstart
注意
这会显著地减慢屏幕刷新。
更多详情请阅读:
:syn-sync
:syn-sync-first
24.9. 有没有内建功能来语法高亮对应的匹配括号?
有的。Vim 包含了 matchparen 插件,作为标准插件缺省打开。无论何时光标移动过
'matchpairs' 选项定义的项目时,Vim 会用 MatchParen 高亮组高亮对应的括号。
不过,如果对应的括号在当前窗口不可见,光标不会跳过去。
matchit 插件提供了类似的功能,会让光标跳转到相关项目 (如 "if"、"else"、
"endif" 项目) 且并跳过注释里的匹配。它用 % 命令来完成对应项目的跳转。尽管两个
插件提供了相似的功能,两者没有关系,工作方式也不同。
更多详情请阅读:
matchparen
'matchpairs'
matchit-install
matchit-intro
24.10. 如何关闭 C 注释语法高亮?
可用以下命令来关闭 C 注释语法高亮:
:highlight clear comment
更多详情请阅读:
ft-c-syntax
24.11. 如何加入我自己的 Vim 提供的标准语法文件的语法扩展?
不应修改 Vim 提供的语法文件来加入你的扩展。安装 Vim 的下个版本时,会丢失你自己
的改变。相反,应该在 ~/.vim/after/syntax 目录下建立和原始语法文件同名的文件,
在该文件里加入你自己的扩展。
更多详情请阅读:
mysyntaxfile-add
'runtimepath'
24.12. 如何用我自己的语法文件来替换 Vim 发布自带的标准语法文件?
可建立和原始语法文件同名的文件并放在 vim 运行时语法目录 ~/.vim/syntax 下来替换
Vim 发布自带的标准语法文件。例如,要替换 Unix 系统上的 c.vim 语法文件,把新的
c.vim 放在 ~/.vim/syntax 目录下。在 MS-Windows 系统上,把新的语法文件放在
$HOME/vimfiles/syntax 或 $VIM/vimfiles/syntax 目录下。
更多详情请阅读:
mysyntaxfile-replace
44.11
mysyntaxfile
24.13. 如何高亮特定列后的所有字符?
可用 :match 命令来高亮特殊列后的所有字符:
:match Todo '\%>75v.\+'
这会高亮所有第 75 列之后的字符。
也可设置 'colorcolumn' 选项来高亮特定列:
:set colorcolumn=+2
会高亮当前 'textwidth' 设置后面第二列 (也可用绝对列号)。
更多详情请阅读:
:match
/\%v
/\+
/.
'colorcolumn'
24.14. 如何把源文件 (.c、.h 等) 带 Vim 语法高亮转换为 HTML 文件?
可用 2html.vim 脚本把源文件带 Vim 语法高亮转换为 HTML 文件。用以下命令:
:TOhtml
更多详情请阅读:
convert-to-HTML
:TOhtml
24.15. 如何列出所有当前高亮组的定义?
可用 :highlight (不带参数) ex 命令来列出所有当前高亮组的定义。
更多详情请阅读:
:highlight
24.16. 如何在一个语言的语法高亮中嵌入另一个语言的高亮?
可在一个语言的语法高亮中嵌入另一个语言的高亮,不过目前发布的多数语法高亮脚本不
是为给其它语法脚本包含准备的。
不过你可以建立自己的定制脚本来定义自己的区域,使用另一个语言的高亮。
全面的方案请参见此 wiki:
http://vim.wikia.com/wiki/Different_syntax_highlighting_within_regions_of_a_file
更多详情请阅读:
:syn-include
sh-awk
第二十五节 - VIM 脚本编写
25.1. 如何列出 Vim 执行过的所有脚本名?
可用 :scriptnames 命令来列出 Vim 执行过的所有脚本名:
:scriptnames
更多详情请阅读:
:scriptnames
25.2. 如何调试 Vim 脚本?
Vim 有内建的基本调试器支持,用于调试 Vim 插件和脚本。使用此调试器可设置断点和
在插件函数上步进。
更多详情请阅读:
debug-scripts
-D
25.3. 如何定位设置某个 Vim 选项的脚本/插件?
可用 :verbose 命令来定位最后修改某个 Vim 选项的插件/脚本。例如:
:verbose set textwidth?
更多详情请阅读:
:set-verbose
:verbose
25.4. Vim 给出一些错误/提示信息 (可能在运行脚本时),信息被立即清除。如何才能再
次显示这些信息?
可用 :messages 命令来显示之前的消息。
:messages
更多详情请阅读:
:messages
:echoerr
:echomsg
message-history
25.5. 如何跨 Vim 调用保存和恢复插件特定的信息?
Vim 会保存和恢复以大写字母开始且不包含小写字母的全局变量。为此,'viminfo' 选项
必须包含 "!" 标志位。Vim 会在 viminfo 文件里保存这些变量。
更多详情请阅读:
'viminfo'
viminfo-file
variables
25.6. 如何在 Vim 函数中启动插入模式?
可用 :startinsert 命令来从 Vim 函数中启动插入模式。
更多详情请阅读:
:startinsert
25.7. 如何在 Vim 函数中改变光标位置?
可用 cursor() 函数来定位光标。
call cursor(lnum, col)
也可用 setpos() 函数:
call setpos('.', [bufnum, lnum, col, off])
这会定位缓冲区 bufnum 里的光标在行 lnum,列 col 以及带 'virtualedit' 所用的偏
移。可用 getpos() 函数取回这些值的列表,之后可在 setpos() 函数里用到这些值。
要想保存和恢复窗口的视点,可用 winsaveview() 和 winrestview() 函数调用。
也可用下列命令来改变光标位置:
exe "normal! " . lnum . "G" . col . "|"
更多详情请阅读:
cursor()
bar
getpos()
setpos()
winsaveview()
winrestview()
25.8. 如何在 .vimrc 文件中检查环境变量值?
在 Vim 脚本函数中可在环境变量名前加上前缀 "$" 字符来访问之。使用 $env_var 语法
可以引用环境变量的值:
if $EDITOR == 'vi'
endif
更多详情请阅读:
expr-env
25.9. 如何在 Vim 函数中检查环境变量设置与否?
可用 exists() 函数来检查环境变量是否存在。
if exists("$MY_ENV_VAR")
endif
更多详情请阅读:
exists()
expr-env
25.10. 如何调用/使用 Vim 内建函数?
可用 :call 命令来调用 Vim 内建函数:
:call cursor(10,20)
可用 :echo 命令来回显函数返回值:
:echo char2nr('a')
可用 :let 命令把函数返回值赋给变量:
:let a = getline('.')
可用以下命令把函数返回值存入 Vim 寄存器:
:let @a = system('ls')
上述命令会把 "ls" 命令的输出存入寄存器 'a'。
更多详情请阅读:
:call
:echo
:let
:let-register
user-functions
usr_41.txt
25.11. 在 Vim 脚本里使用普通模式命令时,如何避免这些普通模式命令应用用户定义的
映射,而使用这些普通模式命令标准的 Vim 功能?
脚本中可用 :normal!
命令来调用普通模式命令。它会使用普通模式命令的标准功能而
不应用用户定义的映射。
更多详情请阅读:
:normal
25.12. 如何把可视选择文本存入 Vim 变量或寄存器?
要把可视选择文本存入 Vim 变量,可先把文本抽出到 Vim 寄存器里,然后把寄存器的内
容存入变量:
:normal! gvy
:let myvar = @"
上述命令把可视选择文本复制入变量 "myvar"。
也可用以下命令:
:normal! gv"*y
上述命令里,gv 重新选择了最近可视选择文本,其余命令复制选中的文本进 * (剪贴板)
寄存器。此外,也可在 'guioptions' 选项里设置 "a" 标志位以自动复制可视选择文本
进 * 寄存器。作为可视映射的一部分,可用下面所示的命令来完成:
:vmap <F3> "*y:call ...
更多详情请阅读:
gv
:normal
:let-@
quotestar
clipboard
registers
25.13. Vim 变量 "myvar" 存了一些文本。想在 :s 替代命令里用此变量来替代文本
"mytext"。应该怎么做?
可用 :execute 命令来计算变量:
:execute '%s/mytext/' . myvar . '/'
更多详情请阅读:
:execute
也可用替代命令中的 "\=" 来计算变量:
:%s/mytext/\=myvar/
更多详情请阅读:
sub-replace-special
25.14. Vim 变量 (bno) 包含了缓冲区号。如何用此变量来打开对应的缓冲区?
:buffer 命令不接受变量名。它只接受缓冲区号或缓冲区名。须用 :execute 命令来
计算变量对应的值。例如:
:execute "buffer " . bno
更多详情请阅读:
:execute
25.15. 如何保存 Vim 选项值到 Vim 变量里?
可用选项名加上前缀 "&" 字符并把 :let 命令来把选项值赋给 Vim 变量。例如,要保
存 'textwidth' 选项值到 Vim 变量 "old_tw",可用以下命令:
:let old_tw = &tw
要显式保存缓冲区局部选项,可用前缀 "l:"
:let old_tw = &l:tw
要显式保存全局选项,可用选项名加上前缀 "g:"。
相反地,要把 "old_tw" 变量保存的值赋给 'textwidth' 选项,可用以下命令:
:let &tw = old_tw
更多详情请阅读:
expr-option
:let-option
25.16. 从 Vim 函数复制并插入了一些文本到缓冲区。如何在 Vim 函数里缩进插入的文
本?
可用以下命令来排版刚刚插入的文本:
:normal '[=']
更多详情请阅读:
'[
']
=
:normal
25.17. Vim 脚本里如何取得光标所在的字符?
可用 getline() 函数并用字符串索引 [] 来取得字符:
:echo getline(".")[col(".") - 1]
上述命令中,getline(".") 返回当前行上的文本,字符串的索引从零开始,用
"string[index]" 记法可以取得该字符串对应索引的单个字符。col(".)" 返回光标所在
的列;做的调整是为了获取字符串中正确的字符。不过,此命令 不能
用于多字节字符,
因为它只返回字节索引。
此外,也可用下列命令序列来取得光标所在的字符:
normal! vy
let ch=@"
注意
,上述命令会改变 '< 或 '> 位置标记。
更多详情请阅读:
getline()
col()
expr-[]
25.18. 如何取得不带扩展名的当前文件名?
可以这样取得不带扩展名的当前文件名:
:echo expand("%:r")
有些命令里可以直接用文件名修饰符:
:cd %:p:h
:!gcc -o %:r.o %
:!xpdf %<.pdf
更多详情请阅读:
filename-modifiers
expand()
cmdline-special
fnamemodify()
25.19. 如何取得当前文件名的基名?
可用 ":t" 文件名修饰符来取得当前文件名的基名:
:echo expand("%:t")
更多详情请阅读:
filename-modifiers
25.20. 如何把 Vim 函数的输出写入当前缓冲区?
插入模式下,可以用以下命令插入函数的返回值:
<C-R>=MyFunc()
注意
,这只能插入函数的返回值。
更多详情请阅读:
i_CTRL-R
i_CTRL-R_CTRL-R
i_CTRL-R_CTRL-O
expression
25.21. Vim 函数里如何调用外部程序?
Vim 函数里有几种方式可以调用外部程序。可用内建的 system() 函数来调用外部程序并
返回结果:
:let output = system("ls")
也可用 "!" ex 命令来运行外部程序。
更多详情请阅读:
system()
:!
10.9
25.22. 如何得到用 :! 命令执行的程序的返回状态?
可用预定义的 Vim v:shell_error 变量来取得最近运行的外壳命令的返回状态。
更多详情请阅读:
v:shell_error
25.23. 如何确定当前缓冲区是否修改过?
可以检查 'modified' 选项值来确定当前缓冲区是否修改过:
:set modified?
Vim 脚本里,可以这样检查 'modified' 选项值:
if &modified
echo "此文件已修改"
endif
更多详情请阅读:
'modified'
25.24. Vim 脚本里 normal 命令想用回车字符。如何指定回车字符?
可用 :execute 命令来指定普通模式命令使用的特殊 (控制) 字符:
:execute "normal \<CR>"
:execute "normal ixxx\<Esc>"
更多详情请阅读:
:execute
expr-quote
25.25. Vim 脚本里如何分割长行?
Vim 脚本里可以在下一行的行首插入反斜杠 ("\") 字符来分隔长行。例如,
set comments=sr:/*,mb:*,el:*/,
\://,
\b:#,
\:%,
\n:>,
\fb:-
更多详情请阅读:
line-continuation
25.26. 用 `:execute Myfunc()` 命令试图 "execute" 我的函数时,光标移到了当前缓
冲区的顶部。为什么?
:execute 命令运行参数指定的 ex 命令。在下列命令的情形下:
:execute Myfunc()
Myfunc() 的调用会返回 0。 :execute 命令会运行 ex 命令 :0
,移动光标到文件顶
部。所以,要调用 Vim 函数,应该用 :call 命令而不是 :execute 命令:
:call Myfunc()
更多详情请阅读:
:call
:execute
:echo
user-functions
41.5
41.6
cmdline-lines
25.27. 如何执行寄存器的内容?
如果抽出了一组 Vim 命令到 Vim 寄存器里 (如寄存器 'a'),就可以用以下命令之一来
执行寄存器的内容:
:@a
或
:exe @a
更多详情请阅读:
:@
25.28. 调用了 Vim 函数或映射后,按 "u" 键撤销最近的修改时,Vim 撤销了该映射/函
数所做的所有改动。为什么?
调用了 Vim 函数或映射后,该函数/映射所做的所有操作会被当成一个单一操作。按 "u"
撤销最近操作时,此函数/映射所做的所有改动都被逆转。
更多详情请阅读:
undo-redo
:map-undo
25.29. 如何从另一个脚本/插件调用定义时带 s: 的函数 (脚本局部函数)?
Vim 函数名的 s: 前缀用于创建脚本局部函数。脚本局部函数只可在该脚本内部调用,不
能被其它脚本执行。要在脚本中定义其它插件/脚本可调用的函数,函数定义时不能带 s:
前缀。
更多详情请阅读:
script-variable
script-local
:scriptnames
25.30. 可以撤销已执行的脚本吗?换句话说,反转一个脚本执行的所有命令的效果。
不可以。没有办法反转或撤销一个脚本执行的所有命令的效果。
更多详情请阅读:
:source
第二十六节 - 插件
26.1. 如何为不同类型的文件设置不同的选项?
可创建文件类型插件来为不同类型的文件设置不同的选项。首先要用此命令打开文件类型
插件:
:filetype plugin on
文件类型插件是 Vim 打开或创建该类型文件时都会载入的 vim 脚本。例如,要确保编辑
C 程序 (文件类型是 "c") 时 'textwidth' 选项设为 80,建立下列文件之一:
~/.vim/ftplugin/c.vim (Unix)
%HOME%\vimfiles\ftplugin\c.vim (Windows)
放入以下文本:
setlocal textwidth=80
也可用自动命令在编辑指定文件类型时设置特定选项。例如,要只为 *.txt 文件设置
'textwidth' 选项为 75,可用以下自动命令:
autocmd BufRead *.txt setlocal textwidth=80
更多详情请阅读:
filetype-plugin
add-filetype-plugin
:autocmd
40.3
26.2. 从网上下载了 Vim 插件、语法文件、缩进文件、色彩方案或文件类型插件。应该
怎么复制这些文件才能让 Vim 找到它们?
可把 Vim 运行时文件 (插件、语法文件、缩进文件、色彩方案、文件类型插件等等) 放
在 'runtimepath' 选项指定的一个目录下。要知道 'runtimepath' 选项的当前值,可用
以下命令:
:set runtimepath
Unix 系统上,这通常是 "$HOME/.vim" 目录。MS-Windows 系统上,这通常是
$VIM\vimfiles 或 $HOME\vimfiles 目录。运行时文件须放在该运行时目录下由文件类型
决定的目录里。下面列出这些目录名:
目录名 描述
---------- ------------------
colors/ 色彩方案文件
compiler/ 编译器文件
doc/ 文档
ftplugin/ 文件类型插件
indent/ 缩进脚本
keymap/ 键盘映射文件
lang/ 菜单翻译
plugin/ 插入脚本
syntax/ 语法文件
tutor/ vimtutor 教程文件
更多详情请阅读:
your-runtime-dir
'runtimepath'
:runtime
26.3. 如何扩展已有的文件类型插件?
可在任何 'runtimepath' 目录下的 after/ 目录里创建文件来扩展已有的文件类型插
件。
- 对在 Vim 安装的 ftplugin 已经完成部分之上的小改动 (或新增),使用 after 目录
如下 (把 foobar 换成关心的 'filetype'):
- 只用于个别用户的私人修改:
- Windows 上:
$HOME/vimfiles/after/ftplugin/foobar.vim
- Unix 系列的操作系统上:
$HOME/.vim/after/ftplugin/foobar.vim
- 影响系统上所有用户的修改:
$VIM/vimfiles/after/ftplugin/foobar.vim
- 用不同的版本替换整个文件类型插件,或安装 Vim 原装还不支持的文件类型的新文件
类型插件时: 使用相同的路径,但不带 after/ 部分。这种情况下应该在插件头部放上
"if... finish... endif... let" 块,就像随 Vim 发布的插件那样。
上述路径使用 Vim 的术语 (和 Unix 术语类似,但即使 Windows 上的 Vim 也能理解);
缺省这些目录不存在,第一次需要的时候你要自己用 mkdir (任何 OS 包括 DOS/Windows
上都有) 或 md (只用于 DOS/Windows) 创建这些目录。在 Vim 之外,$VIM 和
DOS/Windows 上的 $HOME 未必存在。如果 $HOME 在 Vim 里没有值 (或没有合法值),可
用 $VIM 代替;不过除了很老的 Windows 系统外,$HOMEDRIVE 和 $HOMEPATH 都由系统
定义,如果 Vim 启动时 $HOME 无定义,Vim 会在执行你的 vimrc 之前先通过扩展
$HOMEDRIVE$HOMEPATH 来设置之。要知道 Vim 使用的是什么值,可以 (在运行中的 Vim
里) 输入:
:echo $VIM
:echo $HOME
如果把文件放在 after/ftplugin 运行时目录里,Vim 会先执行已有的文件类型插件文件
然后执行新文件。如果把文件放在 $VIMRUNTIME/ftplugin 运行时目录里,Vim 会先执行
新文件然后再执行已有的文件类型插件文件。
更多详情请阅读:
ftplugin-overrule
filetype-plugin
add-filetype-plugin
'runtimepath'
26.4. 如何关闭 Vim 插件的载入?
可以复位 'loadplugins' 选项来关闭插件的载入:
:set noloadplugins
也可指定 "--noplugin" 命令行参数来停止插件的载入:
$ vim --noplugin
更多详情请阅读:
'loadplugins'
--noplugin
load-plugins
26.5. 如何打开/关闭文件类型插件的载入?
缺省 Vim 不载入文件类型插件。可以用此命令配置 Vim 来载入文件类型插件:
filetype plugin on
可以这样关闭文件类型的载入:
filetype plugin off
更多详情请阅读:
:filetype-plugin-on
:filetype-plugin-off
:filetype
26.6. 如何为所有文件类型覆盖全局 ftplugin 目录下的文件类型插件的设定?
可用 FileType 事件触发的自动命令:
au Filetype * set formatoptions=xyz
这至少应在 vimrc 中的 "filetype on" 之后出现。最好放在你自己的
"myfiletypefile" 文件里,以保证在最后执行。
如果你要覆盖特定文件类型的设定,在 ~/.vim/after/ftplugin 目录下创建和原来的文
件类型插件同名的文件。例如,要覆盖 c.vim 文件类型插件的设置,在
~/.vim/after/ftplugin 目录下创建 c.vim 文件,并在此文件中加入你的偏好设置。
更多详情请阅读:
ftplugin-overrule
ftplugins
myfiletypefile
26.7. 如何关闭 Vim 目录浏览器插件?
要关闭目录浏览 Vim 插件,在 .vimrc 文件中加入下行:
let g:loaded_netrw = 1
更多详情请阅读:
netrw
26.8. 如何为名字匹配特定模式或文件扩展名的文件设置 filetype 选项?
可用自动命令为名字匹配特定模式的文件设置 'filetype' 选项。例如,要为所有带扩展
名 ".x" 的文件设置 'filetype' 选项为 "c",可用以下自动命令:
autocmd! BufRead,BufNewFile *.x setfiletype c
比上述方法更好的办法是在 ~/.vim 目录 (或 'runtimepath' 选项指定的目录之一) 下
创建 filetype.vim 文件,并加入下行:
" 我的 filetype 文件
if exists("did_load_filetypes")
finish
endif
augroup filetypedetect
au! BufRead,BufNewFile *.x setfiletype c
augroup END
更多详情请阅读:
new-filetype
43.2
:setfiletype
第三十节 - VIM 和外部应用
30.1. 如何在 Vim 窗口里运行外壳?
从 8.1 版本开始,Vim 提供了终端窗口。支持在普通 Vim 窗口 (例如通过分割) 中异步
运行外壳,使用普通的 Vim 命令和外壳交互。
焦点在终端窗口时,输入的键发送到作业,这称为终端模式。可以在终端窗口之外点击来
把键盘焦点移到别处,也可用 CTRL-W
来浏览不同的 Vim 窗口。要给终端发送 CTRL-W
,
须用 CTRL-W
.
要专门为终端模式映射键,可用新的 :tmap 命令。在终端窗口中按 CTRL-W
N 后会切
换到终端普通模式 (可用于移动光标,滚动窗口等等,就像普通模式一样)。
要在终端和 Vim 间交互,Vim 用 term_sendkeys()、终端 API 和客户-服务器机制实现
了几种接口。
更多详情请阅读:
terminal
mapmode-t
Terminal-Normal
terminal-communication
30.2. 如何传递光标所在的单词给外部命令?
可用特殊关键字 <cword>
来传递光标所在的单词给外部命令。例如:
:!dict <cword>
更多详情请阅读:
:<cword>
30.3. 如何把外壳命令的输出放进 Vim 缓冲区?
可用 `:r !` 命令来把外壳命令的输出放进 Vim 缓冲区。例如,要插入 "ls" 外壳命令
的输出,可用以下命令:
:r !ls
要插入外壳命令的输出到首行的上方,可用以下命令:
:0r !ls
更多详情请阅读:
:r!
30.4. 如何把当前缓冲区的内容用管道发给外部命令,并用命令的输出替换缓冲区的内
容?
用 :! 命令可把当前缓冲区的内容用管道发给外部命令,并用命令的输出替换缓冲区的内
容。例如,要用 Unix sort 命令给当前缓冲区的内容排序,可用以下命令:
:%!sort
要只给 10-20 行排序,可用以下命令
:10,20!sort
另外,如果要把缓冲区用管道发给外部命令但不需要把结果传回缓冲区,可用
:w !sort
上述命令会把整个缓冲区用管道发给 sort 命令。注意
,"w" 和 "!" 间的空格是至关重
要的。要只发给管道一段行范围,可用
:10,20w !sort
上述命令会把 10-20 行用管道发给 sort 命令。
更多详情请阅读:
:range!
10.9
:w_c
30.5. 如何给文件的一部分排序?
可这样用 :sort 命令:
:5,100sort
:sort 命令提供了许多选项,可这样按第一个找到的十进制数值排序:
:%sort n
也可指定从虚拟第 8 列开始给文件排序:
:%sort /.*\%8v/
也可把文件的一部分用管道传给 Unix "sort" 工具来给文件排序。例如:
:5,100!sort
也可用可视列块,在选中的列块上使用 "!sort" 命令。
另见:
:sort
filter
30.6. 如何把 Vim 用作分页程序?
可用标准 Vim 发布提供的 $VIMRUNTIME/macros/less.sh 外壳脚本来把 Vim 用作分页程
序。此外壳脚本使用 $VIMRUNTIME/macros/less.vim Vim 脚本来提供类似 less 的键盘
绑定。
更多详情请阅读:
less
30.7. 如何在 Vim 内部查阅 Unix man 页面?
可用标准 Vim 发布提供的 man.vim 插件在 Vim 内部查阅 Unix man 页面。要使用此插
件,在启动 vimrc 文件中加入下行:
runtime ftplugin/man.vim
也可按 K 键来运行 'keywordprg' 选项指定的程序,带上光标所在的关键字。缺省的
'keywordprg' 设置会在光标所在的关键字上运行 man。
更多详情请阅读:
ft-man-plugin
K
'keywordprg'
30.8. 如何更换 Vim 比较支持所需的 diff 命令?
缺省,Vim 的比较支持使用 'diff' 命令。可通过修改 'diffexpr' 选项来更改之。
更多详情请阅读:
diff-diffexpr
'diffexpr'
30.9. 如何在使用 Vim 比较模式时不带折叠?
可用以下命令行来启动 Vim 带两个文件名,并使用不带折叠的比较模式:
$ vim -o file1 file2 "+windo set diff scrollbind scrollopt+=hor nowrap"
如果你喜欢垂直分割的窗口,把 "-o" 换成 "-O"。
更多详情请阅读:
vimdiff
第三十一节 - GUI VIM
31.1. 如何创建缓冲区特定的菜单?
加入缓冲区特定的菜单在 Vim 待开发列表中。与此同时,可以试试 Michael Geddes 的
buffermenu.vim 插件:
https://www.vim.org/scripts/script.php?script_id=246
31.2. 如何改变 GUI Vim 使用的字体?
可以修改 'guifont' 选项来改变 GUI Vim 使用的字体。要显示此选项的当前值,可用
:set guifont?
可把显示的字体名加入 .vimrc 文件,这样跨 Vim 会话可以继续使用该字体。例如,加
入下列行到 .vimrc 文件以使用 Andale Mono 字体。
set guifont=Andale_Mono:h10:cANSI
Win32、GTK 和 Photon 的 Vim 版本可用以下命令来打开一个对话框,帮助你修改
guifont:
:set guifont=*
也可用 -font Vim 命令行选项来指定普通文本使用的字体。
更多详情请阅读:
'guifont'
'guifontset'
'guifontwide'
font-sizes
-font
-boldfont
-italicfont
-menufont
-menufontset
31.3. 启动 GUI Vim 时,如何指定 GVIM 窗口的位置?
可用 "-geometry" 命令行参数来指定 GUI Vim 窗口的位置。例如:
$ gvim -geometry 80x25+100+300
更多详情请阅读:
31.4
-geom
31.4. 如何给 GVim 加上水平滚动条?
可修改 'guioptions' 选项来加上水平滚动条:
:set guioptions+=b
更多详情请阅读:
'guioptions'
gui-horiz-scroll
31.5. 如何使滚动条缺省出现在左侧?
可给 'guioptions' 选项加上 "l" 标志位,使滚动条出现在左侧。
:set guioptions+=l
:set guioptions-=r
更多详情请阅读:
'guioptions'
gui-scrollbars
31.6. 如何删除 Vim 菜单条?
可从 'guioptions' 选项里删除 "m" 标志位来删除 Vim 菜单条:
:set guioptions-=m
更多详情请阅读:
'guioptions'
31.7. 用 GUI Vim 时,按 <Alt>
键和字母时选择以该字母开始的菜单。我不想这样,因
为我想映射 <Alt>
-<key>
组合。如何才可以?
可用 'winaltkeys' 选项来关闭 <Alt>
键选择菜单项目的用法:
:set winaltkeys=no
更多详情请阅读:
'winaltkeys'
:simalt
31.8. 可以拖动滚动条来滚动文本而光标保持原来的位置吗?
Vim 的设计方法是普通、可视、选择和插入模式下,光标位置必须在可见的地点。不修改
Vim 不可能改变这一点。使用滚动条时,会移动光标使它可见。另一个解决此问题的方法
是使用 Vim 位置标记。可以用 ma 标记当前光标位置。然后滚动到文本的不同部分,然
后用 `a 跳回原来的位置。也可试试以下来自 Vim Online 网站的建议:
http://vim.wikia.com/wiki/VimTip320
更多详情请阅读:
mark-motions
31.9. 如何使 gvim 用 :browse 命令时从指定目录开始浏览文件?
用 'browsedir' 选项可以设置 :browse 命令使用的缺省目录。
:set browsedir='<你的目录>'
更多详情请阅读:
'browsedir'
31.10. 有些问题,比如文件在 Vim 外面修改后,会显示 GUI 对话框。如何把 GUI 对话
框换成控制台对话框?
你可以设置 'guioptions' 选项里的 "c" 标志位以配置 Vim 来使用控制台对话框而不是
GUI 对话框:
:set guioptions+=c
更多详情请阅读:
'guioptions'
31.11. 我试图用 GUI Vim 作为 xxx 应用的编辑器。当 xxx 应用启动 GUI Vim 编辑文
件时,控制立即返回 xxx 应用。如何启动 GUI Vim 使得 Vim 退出时才会把控制
返回 xxx 应用?
启动 GUI Vim 时须用 "-f" (foreground) 命令行选项:
$ gvim -f
缺省,GUI Vim 会和启动 Vim 的程序断开。用了 "-f" 选项后,GUI Vim 就不会和启动
它的程序断开。
更多详情请阅读:
gui-fork
-f
31.12. 为什么 "Select Font" 对话框不显示我系统上安装的所有字体?
Vim 只支持固定宽度 (等宽) 字体。不支持比例字体。在 "Select Font" 对话框中,只
显示固定宽度字体。
更多详情请阅读:
font-sizes
'guifont'
31.13. 在 Vim 命令行模式中如何使用鼠标?
可设置 'mouse' 选项的 "c" 标志位以在 Vim 命令行模式中使用鼠标:
:set mouse+=c
更多详情请阅读:
mouse-using
gui-mouse
09.2
31.14. 用鼠标中键来滚动文本时,它却粘贴了前次复制的文本。如何停止此行为?
可把鼠标中键映射为 <Nop>
以关闭鼠标中键:
:map <MiddleMouse> <Nop>
:map! <MiddleMouse> <Nop>
更多详情请阅读:
gui-mouse-mapping
<Nop>
31.15. 如何改变 GUI Vim 窗口的位置和大小?
可用 :winpos 命令来改变 Vim 窗口位置。要改变窗口大小,可修改 'lines' 和
'columns' 选项。
例如,下列命令会把 GUI Vim 窗口放在 X,Y 坐标 50,50 并设置行数为 50 及列数为
80。
:winpos 50 50
:set lines=50
:set columns=80
:winpos 命令的参数指定 Vim 窗口的像素坐标。'lines' 和 'columns' 选项指定行数
和字符数,分别用于窗口的高度和宽度。
更多详情请阅读:
31.4
:winpos
'lines'
'columns'
GUIEnter
31.16. Vim 窗口垂直分割时,Vim 改变了位置。
这是个已知问题。当你分割 Vim 窗口时,Vim 会试图画出滚动条。因为这改变了 gui 窗
口,Vim 会试图调整其主窗口的大小以保持相同的位置,而这会使 Vim 移动它的位置。
这发生在带多窗口布局或有一个 "钉" 在固定位置的 Windows 系统上。
一个此问题的临时解决方案是删除 gui 滚动条,例如
:set guioptions-=L
第三十二节 - Unix 上的 VIM
32.1. 我在 xterm 里运行 Vim。当按了 CTRL-S
键时,Vim 死机了。我现在应该做什
么?
许多终端模拟器和实际终端驱动程序用 CTRL-S
键来停止数据的接收,以便停止快速滚动
的显示以看清楚内容 (也允许旧式的终端减慢电脑速度,不致产生缓冲区溢出)。可以按
CTRL-Q
键重新输出。
按 CTRL-S
键时,终端驱动会停止发送输出数据。后果就是看起来 Vim 挂起了。如果你
按 CTRL-Q
键,一切都会恢复正常。
用 "stty" 命令可以关闭终端驱动的流控制:
$ stty -ixon -ixoff
或者用下列命令来改变终端流控制的用键:
$ stty stop <char>
$ stty start <char>
32.2. Vim 上看到奇怪的屏幕刷新问题。如何才能解决屏幕/显示刷新问题?
你需要使用像 xterm 那样合适的终端模拟器,并带有正确的 TERM 设置 (TERM=xterm)
还有正确的 terminfo/termcap 文件。
更多详情请阅读:
'term'
32.3. 使用 Vim 的终端/控制台版本时,插入模式下,按了退格键没有删除光标前的字
符。如何配置 Vim 来做到这一点?
要确保 Vim 收到退格键的正确键盘码。可用以下命令:
:fixdel
确保 TERM 环境变量设为正确的终端名。可试用 "stty" 命令:
$ stty erase ^H
这里,你要用 CTRL-V
键后跟 CTRL-H
键来输入 ^H 字符。也要检查 'backspace' 设置
的值。
更多详情请阅读:
:fixdel
Linux-backspace
NetBSD-backspace
'backspace'
32.4. 我在 xterm 下使用 Vim。退出 Vim 时,屏幕内容恢复为原先的内容。如何关闭此
行为?
xterm 有名为 "alternate screen" 的能力。如果此能力存在,vim 在启动时切换到轮换
屏幕,退出时再切换回来,从而会恢复原先的屏幕内容。要关闭此功能,在 .vimrc 文件
中加入下行:
:set t_ti= t_te=
更多详情请阅读:
'restorescreen'
xterm-screens
32.5. 启动 Vim 时,花了好几秒才启动。如何才能最少化启动时间?
这可能和 Vim 打开 X 显示来设置 xterm 标题和使用 X 剪贴板有关。确信 DISPLAY 变
量设为正确的主机名。试试以下命令:
$ vim -X
这会防止 Vim 打开 X 显示。用此命令行选项,不使用 X 剪贴板而 Vim 也不会修改
xterm 标题。
也可设置 'clipboard' 选项为
:set clipboard=exclude:.*
这和使用 -X 命令行参数有相同的效果。
更多详情请阅读:
-X
'clipboard'
如果剪贴板不是启动慢的原因,可能是某个插件导致的减慢。在此情形下,可用
--startuptime 参数进一步调试。可用:
$ vim --startuptime vim_startup.log
计时信息会写入文件 vim_startup.log。要更高级的剖视,可用 Vim 的 huge 版本带有
的剖视特性。为此,这样调用 Vim:
$ vim --cmd 'profile start profile.log' \
--cmd 'profile func *' \
--cmd 'profile file *' \
-c 'profdel func *' \
-c 'profdel file *' \
-c 'qa!'
运行后,会在当前目录生成文件 profile.log。要进一步分析,打开 profile.log 文件
并运行:
" 先在 vim 里打开 profile.log 文件
:let timings=[]
:g/^SCRIPT/call add(timings, [getline('.')[len('SCRIPT '):], matchstr(getline(line('.')+1), '^Sourced \zs\d\+')]+map(getline(line('.')+2, line('.')+3), 'matchstr(v:val, ''\d\+\.\d\+$'')'))
:enew
:call setline('.', ['count total (s) self (s) script']+map(copy(timings), 'printf("%5u %9s %8s %s", v:val[1], v:val[2], v:val[3], v:val[0])'))
更多详情请阅读:
--startuptime
profiling
32.6. 如何使 unix 上 gvim 里的光标停止闪烁?
可修改 'guicursor' 选项以停止光标闪烁。例如:
:set guicursor=a:blinkon0
更多详情请阅读:
'guicursor'
32.7. 如何改变 GTK Vim 的菜单字体?
可修改 ~/.gtkrc 文件以改变 GTK Vim 的菜单字体。例如:
style "default"
{ font ="smooth09" }
class "*" style "default"
末行会改变所有小部件的字体。
更多详情请阅读:
gui-gtk
32.8. 如何不让 CTRL-Z
暂停 Vim?
可映射 CTRL-Z
来不让它暂停。这里是一些建议:
- 使 CTRL-Z
什么也不做:
:map <C-Z> <Nop>
- 使 CTRL-Z
启动外壳:
:map <C-Z> :shell<CR>
- 使 CTRL-Z
报错:
:map <C-Z> :"suspending disabled<CR>
最后一个例子里双引号是必要的,它会使消息停留在状态行上。
32.9. 杀掉运行 Vim 的 xterm 时,Vim 进程继续运行并占用大量的 CPU (99%) 时间。
为什么会这样?
Vim 编译时如果带 Python 接口支持,可能会有这个问题。这是一个和 python 线程库和
Vim 相关的已知问题。要解决这个问题,使用不带 Python 接口的 Vim 可执行程序。
更多详情请阅读:
+python
python
32.10. 如何使 Vim 语法高亮在 Unix 终端上工作?
最容易和最简单得到 Vim 语法高亮的方法是使用 Vim 的 GUI 版本 (GVIM)。要使语法高
亮可在 Vim 的控制台/终端版本上工作,需要运行支持色彩的终端模拟器 (比如 Xfree86
xterm 或 rxvt 或 dtterm)。注意
即使终端模拟器支持改变背景和前景色,也未必意味
它同时支持改变色彩的 ANSI 转义序列。可从
https://invisible-island.net/xterm/xterm.html 下载 Xfree86 xterm 的最新版本。
可从 https://rxvt.org 下载 rxvt 的最新版本。还要安装用于终端模拟器的支持色彩的
terminfo/termcap 文件。另外,设置 TERM 环境变量为正确的支持色彩的终端名。
可用 Vim 运行时包提供的 colortest.vim 来测试色彩设置。以下步骤可运行此脚本:
:e $VIMRUNTIME/syntax/colortest.vim
:source %
更多详情请阅读:
06.2
terminal-colors
termcap-colors
startup-terminal
xterm-color
colortest.vim
第三十三节 - MS-WINDOWS 上的 VIM
33.1. MS-Windows 上,CTRL-V
不启动面向列块可视模式。怎么啦?
mswin.vim 脚本提供了使 Vim 行为类似于 MS-Windows 应用的键盘映射和选项。其中一
个映射的键是 CTRL-V
,在 MS-Windows 应用中它用于粘贴文本。这就关闭了 CTRL-V
启
动面向列块可视模式的功能。mswin.vim 脚本 把 CTRL-Q
映射为启动面向列块可视模
式。所以,可用 CTRL-Q
代替 CTRL-V
。
更多详情请阅读:
CTRL-V
CTRL-V-alternative
CTRL-Q
10.5
33.2. 按 CTRL-Y
键时,就像 CTRL-R
键一样。如何配置 Vim 把 CTRL-Y
当作 CTRL-Y
?
把 CTRL-Y
键映射成 CTRL-R
键是 mswin.vim 脚本完成的。mswin.script 对 CTRL-Y
的
映射使 Vim 的行为类似于标准的 MS-Windows 应用。`:help CTRL-Y
` 里有解释。可以注
释掉 mswin.vim 映射 CTRL-Y
键的那一行,或者从 .vimrc 文件里删除执行 mswin.vim
脚本的那行。
33.3. 如何总是最大化窗口启动 GUI?
用 :simalt 命令可最大化 Vim 窗口。所以,可以这样用 GUIEnter 自动命令在启动时
最大化 Vim 窗口:
autocmd GUIEnter * simalt ~x
更多详情请阅读:
:simalt
GUIEnter
gui-win32-maximized
33.4. 做完一些编辑操作后,Vim 死机了。光标成了空的长方形。不能输入任何字符。怎
么啦?
最有可能是你在 Vim 中用了鼠标滚轮来滚动文本。Vim 使用智能鼠 (intellimouse) 鼠
标滚动有已知的问题。要避免这个问题,请关闭 Vim 的 Universal scrolling 支持。
更多详情请阅读:
intellimouse-wheel-problems
33.5. 使用 Windows XP 时,最大化 GVim 的显示速度很慢。如何才能加速显示更新?
这可能是因为你打开了显示属性的 "平滑屏幕字符边缘"。试试关闭字体平滑或改变平滑
方法为 "标准"。
33.6. 使用 cygwin 时,什么是 Vim 的建议设定?
可以考虑以下外壳相关的 Vim 设置:
:set shellcmdflag=-c
:set shellquote=
:set shellslash " 使用正斜杠用于扩展。
:set shellxquote=\"
:set shell=d:\cygwin\bin\bash.exe " 使用 bash 外壳
:set shellpipe=2>&1| tee
:set shellredir=>%s 2>&1
33.7. 为 Vim 比较模式我试图用 GNU diff。在命令行上运行 diff 没问题。但在 Vim
上试着用 diff 却不行。我应该怎么办?
GNU diff 用于 Vim 有问题。可用以下链接来试用 Ron Aaron 编译的 GNU diff.exe:
http://www.mossbayeng.com/~ron/vim/builds.html
(此页面不再存在。)
33.8. 可以用 Vim 作为 MS-Windows Outlook 邮件客户端的外部编辑器吗?
可用 "cubiclevim" COM Add-In 来使用 Vim 作为 MS-Windows Outlook 邮件客户端的外
部编辑器。详情可访问下列 URL:
https://sourceforge.net/projects/cubiclevim/
注意
,目前只能用于 MS-Office 2000 和 XP。
另外,OutlookVim 插件也值得考虑:
https://www.vim.org/scripts/script.php?script_id=3087
33.9. 我用 Vim 来编辑 HTML 文件。如何启动 internet explorer 来预览当前 HTML 文
件?
可用以下命令:
:!start c:\progra~1\intern~1\iexplore.exe file://%:p<CR>
33.10. 我想在 Microsoft Visual Studio 上用 Vim。要怎么做?
需要下载 Vim 的 OLE 版本 (如: gvim61ole.zip)。此文件也有关于如何把 Vim 用于
Visual Studio 的说明。
更多详情请阅读:
MSVisualStudio
33.11. 在哪里放 _vimrc 和 _gvimrc 文件?
可以把 _vimrc 和 _gvimrc 文件放在 VIM 环境变量指向的目录下。如果你和其它用户分
享此系统,可把文件放在一个目录下,并把 HOME 环境变量设为此目录。
更多详情请阅读:
$HOME-use
_vimrc
33.12. 每次我保存文件时,Vim 警告
我文件在 Vim 外面被修改了。为什么?
如果你每次保存文件时都会得到以下警告
信息:
WARNING: The file has been changed since reading it!!!
Do you really want to write to it (y/n)?
那么问题可能和 MS-Windows 一个夏令时开始日期的漏洞有关。Vim 写入文件后,记住文
件的时间戳。在下次写入之前,再次读取时间戳以检查文件是否在 Vim 外部被修改。这
是正确的,但夏令时开始的那天会出问题。
此问题在夏令时开始日的下一天就会消失。
更多详情请阅读:
W11
第三十五节 - 从源码开始编译 VIM
35.1. Unix 系统上如何从源码开始编译 Vim?
Unix 系统上,采取以下步骤来从源码开始编译 Vim:
- 从 ftp://ftp.vim.org/pub/vim/unix 目录下载源码和运行时文件归档
(vim-##.tar.bz2)。
- 用 bzip2 和 tar 工具解压归档,命令如下:
$ bunzip2 -c <filename> | tar -xf -
- 或者,从 git 库下载源码:
https://github.com/vim/vim/releases/
- 或者,从 mercurial 库下载源码:
https://bitbucket.org/vim-mirror/vim/downloads/
- 运行 "make" 命令,用缺省的配置设定来配置和编译 Vim。
- 运行 "make install" 命令在缺省目录上安装 Vim。
要打开/关闭若干 Vim 特性,在运行 "make" 命令前可运行 "configure" 命令带不同标
志位来包含/排除对应的 Vim 特性。可以这样列出 "configure" 所有可用的选项:
$ configure --help
更多详情请阅读:
install
35.2. 如何在主目录或不同于缺省安装目录的位置安装 Vim?
要在不同于缺少安装目录的位置安装 Vim,可在运行 configure 脚本时用 --prefix 选
项指定该目录。
$ ./configure --prefix=/users/xyz
给 configure 脚本不同的参数可以打开/关闭若干的 Vim 特性。关于这些选项的更多详
情,可运行:
$ ./configure --help
更多详情请阅读:
install-home
install
35.3. MS-Windows 系统上如何如何从源码开始编译 Vim?
MS-Windows 系统上,可用 Visual C++ 编译器或 Borland C++ 编译器或 Ming GCC 编译
器或 cygwin gcc 编译器来编译 Vim。采取以下步骤来从源码开始编译 Vim:
- 从 ftp://ftp.vim.org/pub/vim/pc 目录下载源码 (vim##src.zip)、运行时文件
(vim##rt.zip) 和额外文件 (vim-##-extra.tar.gz) 归档。
- 在某个目录 (例如,c:\vimsrc) 解压归档
- 或者,从 git 库下载源码:
https://github.com/vim/vim/releases/
- 或者,从 mercurial 库下载源码:
https://bitbucket.org/vim-mirror/vim/downloads/
- 取决于安装的编译器,可用对应的 makefile 来编译 Vim 源码。Visual C++ 用
Make_mvc.mak makefile,borland C++ 用 Make_bc5.mak makefile,
ming GCC 用 Make_ming.mak makefile,cygwin gcc 用 Make_cyg.mak
makefile。
取决于你想编译的是 GUI 版本的 Vim 还是控制台版本的 Vim,需要给 makefile 传递不
同的参数。成功编译源码后,可以复制 vim.exe 或 gvim.exe 文件以及运行时文件归档
到目的目录。
更多详情请阅读:
install
35.4. 我的 Vim 安装找不到 Vim 帮助、语法、缩进文件。如何安装这些文件?
Vim 帮助、语法、缩进和其它运行时文件是 Vim 运行时包的一部分。可以下载和安装
Vim 运行时包。例如,MS-Windows 上的 Vim 6.1 运行时包的名字是 vim61rt.zip。
更多详情请阅读:
install
35.5. 从源码编译 Vim 并用 "make install" 安装了 Vim 包。我还需要留着 Vim 源码
目录吗?
不需要。一但编译并安装 Vim 到原先源码目录以外的目录 (例如 /usr/bin 和
/usr/local/bin) 后,就可以删除源码目录。
35.6. 如何确定编译时打开的 Vim 特性?
可用 :version 命令确定编译时打开的 Vim 特性。打开的特性会加上前缀 "+"。未打
开的特性会加上前缀 "-"。
如果你要在脚本中测试某特性是否存在,可用 has() 函数:
if has("menu")
" 设置一些菜单
endif
更多详情请阅读:
:version
+feature-list
has()
35.7. 编译 Vim 时可以不带 GUI 支持吗?
是的,你在编译 Vim 时可以打开/关闭许多可选特性,包含 GUI。
更多详情请阅读:
install
35.8. Unix 系统上编译 Vim 时,得到了 "undefined reference to term_set_winsize"
错误。如何解决这个错误?
如果编译过程中没找到 termlib、termcap 或 ncurses 库,就会得到这个错误。需要安
装 ncurses-dev 库来解决这个错误。
35.9. Vim configure 试图用 GTK 2.03 时不停抱怨找不到 gtk-config。这是对的,因
为 GTK 2 里转而改用了通用的 pkg-config。我可以拿到 pkg-config 来列出若干
gtk 的头文件和库,但不知为什么 configure 脚本还是找它不到。
可用以下外壳脚本,命名为 gtk-config:
#!/bin/sh
pkg-config gtk+-2.0 $1 $2
35.10. 我成功地下载了源码并在 Unix 上编译了 Vim。但某某特性还是不能用。哪里做
错了,如何才能纠正问题?
要首先检查一下你实际运行的是自己编译的 Vim 而不是系统提供的版本。所以首先检查
一下 $PATH 设置。
取决于编译选项,你编译的 Vim 可能没有些某些特性。可用 :version 命令确定编译
时带了哪些 Vim 特性。打开的特性会加上前缀 "+"。未打开的特性会加上前缀 "-"。
最简单的包含所有特性的方法是编译 huge 版本。为此,运行 configure 脚本时须指定
--with-features 选项:
$ ./configure --with-features=huge
不过,编译时如果 configure 脚本找不到某些特性需要的库,仍然可以关闭这些特性
(例如,剪贴板集成需要链接 X11 开发库)。
有几种方法可以安装所需的库:
1) 在基于 Debian 的发布上,可用软件库管理工具 "apt" 来安装所有所需的依赖。作为
超级用户,运行命令:
$ apt-get build-dep vim-gtk
这会确保所有编译 vim-gtk 包所需要的库被安装。(这需要你的源列表包含了
deb-src 项目。如果上述命令不可用,参见你的发布手册了解如何加上这些项目。)
2) openSUSE 上可用软件库管理工具 "zypper" 来安装所有所需的库。这需要有可从配置
好的仓库里安装的库的源版本 (缺省并非如此)。用:
$ zypper search -t srcpackage vim
来确定在仓库里里是否有源版本。如果没有,需要加上源仓库。对 openSUSE 11.2 可
用比如说
$ zypper ar
http://download.opensuse.org/source/distribution/11.2/repo/oss/src-11.2
(一行)
一旦在仓库里有了可用的源版本,用以下命令来安装所有所需的部件:
$ zypper source-install --build-deps-only vim
3) 在基于 Fedora/RedHat 的系统上,可用
$ yum-builddep vim-enhanced
4) 运行 configure 并带上你的选项,然后观察缺失的库:
$ ./configure --with-features=huge 2>&1 |tee logfile
这会运行 configure 并记录输出到文件 "logfile"。需要检查 logfile 来寻找缺失
依赖。考虑以下输出:
checking --disable-gtktest argument... gtk test enabled
checking for pkg-config... /usr/bin/pkg-config
checking for GTK - version >= 2.2.0... no
这里你看到,缺失了 gtk 库,因而不能编译 GTK gui 版本。所以,你需要在你的系
统上安装 GTK 库,用你的软件库管理工具或自己编译。然后再次运行 configure 脚
本,并检查这次是否找到了库。
理论上,你的发布提供的这些依赖仍可能缺少某些特性需要的库,也可能仅仅因为没有被
你的发布打开,所以不能被 1-3 的命令安装。但至少,这里的说明提供了一个发动点,
用上述的方法 4 你可以继续追踪所需的缺失库。不过对大多数人而言,这里的步骤通常
已经够用,而不需要麻烦第四个方法了。
更多详情请阅读:
:version
+feature-list
第三十六节 - 杂项
36.1. 用 Vim 如何编辑二进制文件?
可用以下选项来用 Vim 编辑二进制文件:
:set binary
:set display=uhex
也可用 "-b" 命令行选项来编辑二进制文件:
$ vim -b <binary_file_name>
也可用 xxd 工具 (Vim 发布的一部分) 来编辑二进制文件。
更多详情请阅读:
23.4
edit-binary
hex-editing
-b
'binary'
'endofline'
'display'
36.2. 如何关闭可视错误闪烁和错误响铃?
可用以下命令关闭可视错误闪烁和错误响铃:
:set visualbell t_vb=
更多详情请阅读:
'visualbell'
'errorbells'
t_vb
36.3. 如何查看在缓冲区中显示的字符的 ascii 值?
可用 "ga" 命令来查看在缓冲区中显示的字符的 ascii 值。
更多详情请阅读:
ga
:ascii
36.4. Vim 命令如何使用零计数?
Vim 命令不能使用零计数。因为 "0" 自身是个命令,移动到行的首列。
更多详情请阅读:
0
count
36.5. 如何关闭 Vim 欢迎屏幕?
在 'shortmess' 选项中加入 "I" 标志位可以关闭 Vim 欢迎屏幕:
:set shortmess+=I
更多详情请阅读:
:intro
'shortmess'
36.6. 如何避免 "hit enter to continue" 提示?
如果有消息在屏幕上等待你阅读并且屏幕即将要重画时,Vim 会提示 "hit enter to
continue"。在 'shortmess' 选项中加入 "T" 标志位可截短所有的信息。这有助于避免
hit-enter 的提示:
:set shortmess+=T
也可设置 'cmdheight' 选项来增加命令高度:
:set cmdheight=2
更多详情请阅读:
hit-enter
avoid-hit-enter
'shortmess'
'cmdheight'
36.7. 如何从命令行调用 Vim 来为一组文件运行一组命令?
有几种方法来从命令行调用 Vim 来为一组文件运行一组命令。可用一组 "-c" 命令行选
项来指定一组命令:
$ vim -c "<ex_command_1>" -c "<ex_command_2>" *.txt
每个 "-c" 命令行选项指定的 ex 命令会依次顺序执行。也可用单个 "-c" 命令行选项,
然后用 "|" 字符分隔 ex 命令:
$ vim -c "<ex_command_1> | <ex_command_2>" *.txt
上面的命令里,如果一个 ex 命令失败,其余的 ex 命令都不会执行。
例如,要从命令行把一个文件里的 "ABC" 换为 "DEF",可用以下命令:
$ vim -c "%s/ABC/DEF/ge | update" myfile.txt
要从命令行把多个文件里的 "ABC" 换为 "DEF",可用以下命令:
$ vim -c "argdo %s/ABC/DEF/ge | update" *.txt
可把一组命令存到一个文件里,然后在一组文件上用 "-s" 命令行选项来执行这些命令。
例如,如果这组命令存入文件 mycmds.txt,可用下列命令:
$ vim -s mycmds.txt *.pl
更多详情请阅读:
-c
-s
36.8. 如何在插入模式里使用普通模式命令,而不用退出插入模式?
可按 CTRL-O
键后跟单个普通模式命令来在插入模式里使用普通模式命令,而不用退出插
入模式。
要执行多于一个普通模式命令,按 CTRL-L
键后跟任意数量的普通模式命令,然后按
<Esc>
回到插入模式。(只适用于 'insertmode' 选项置位的情形)。
更多详情请阅读:
i_CTRL-O
i_CTRL-L
36.9. 如何在启动 Vim 时就进行插入模式?
可用 :startinsert ex 命令在启动 Vim 时就进行插入模式:
$ vim +startinsert myfile.txt
上述命令会打开文件 "myfile.txt" 并进行插入模式,光标在首行的首个字符上。要打开
文件并立即在末行的末字符之后开始添加,可用以下命令:
$ vim + +startinsert! myfile.txt
更多详情请阅读:
:startinsert
36.10. Vim 里如何使用复制和粘贴?
首先检查 :version 命令的输出,确定有 +xterm-clipboard。
在 xterm 里运行 Vim 时,或者让 Vim 控制鼠标,或者让 xterm 控制鼠标。这是由
'mouse' 选项配置的。
如果不设置 'mouse' 选项 (或设为缺省值),Vim 不控制鼠标。你不能用鼠标移动 Vim
的文本光标。用鼠标选择文本时,xterm 会把它复制到 X11 剪切缓冲区。如果同时按下
两个鼠标键,xterm 会从剪切缓冲区里粘贴文本。
如果 'mouse' 选项设为 "a" 或其它值,Vim 控制鼠标。'mouse' 选项配置 Vim 在何种
模式 (普通或插入或可视等等) 下控制鼠标。可用鼠标移动 Vim 文本光标。选择一些文
本时,'clipboard' 选项设置用于决定是否传送选中的文本到剪贴板。缺省设置是把选中
的文本传送到剪贴板。如果在此模式下想用 xterm 的选择机制,可按 <Shift>
键。用鼠
标选择文本时如果按住了 <Shift>
键,Vim 不控制鼠标而让 xterm 控制鼠标。
在 GUI 模式下,取决于 'mouse' 设定,复制和粘贴应该总是可用。更多详情请阅读:
'clipboard'
x11-selection
clipboard
'go-a'
'mouse'
xterm-copy-paste
09.3
36.11. 为什么不应修改系统运行时目录里的文件?
修改 $VIMRUNTIME 里的文件要小心。它们通常在 /usr/share/vim/vimXX (Unix) 或
C:\Program Files\vim\vimXX (Windows),这里 XX 是适用的版本号,如 Vim 7.3
对应 73。
通常应避免修改这些文件,因为它们在 Vim 安装升级时会被替换,而你的改动会丢失。
另外,如果你更新 Vim 的主要或次要版本 (如从 7.3 升到 7.4),新版本的 Vim 会使用
不同的 $VIMRUNTIME 目录,你的改动尽管不会丢失,也不会被采用。
所以,看一看
filetypes
其中解释了几种更改 Vim 对不同文件类型应对的方法,同时也解释了应在哪里放置那些
修改,才会使修改不被覆盖。