Vim 是一款功能强大的文本编辑器,它拥有许多强大的功能,其中之一就是自动跳转。Vim 自动跳转可以帮助用户快速定位到文件中的指定位置,而不需要手动搜索。
Vim 自动跳转的基本原理是使用正则表达式来匹配文件中的字符串,然后将光标定位到匹配字符串所在的位置。Vim 中有几个命令可以用来实现这一目标,其中最常用的是 / 和 ? 命令。/ 命令可以向文件尾部搜索匹配字符串,而 ? 命令则可以向文件头部搜索匹配字符串。
/pattern // 向文件尾部搜索 pattern ?pattern // 向文件头部搜索 pattern
此外,Vim 还提供了 n 和 N 命令来快速地在当前文本中循环搜索匹配字符串。n 命令会向当前光标所在位置之后寻找匹配字符串;而 N 则会向当前光标所在位置之前寻找匹配字符串。
n // 查找当前光标之后的匹配字符串 N // 查找当前光标之前的匹配字Vimscript 自动命令
现在我们谈论一个跟映射一样重要的东西:自动命令。
自动命令可以让Vim自动执行某些指定的命令,这些指定的命令会在某些事件发生的时候执行。我们先看一个例子。
使用
:edit foo
打开一个新文件,然后立即使用:quit
关闭。查看你的硬盘,你会发现这个文件并不存在。这是因为在你第一次保存这个文件之前,Vim_实际上_并没有真正创建它。让我们对Vim做一些改变,使得Vim可以在你开始编辑文件的时候就创建它们。执行下面的命令:
:autocmd BufNewFile * :write
这里面有很多需要进一步说明的,不过在此之前我建议你先感受下它是怎么工作的。执行
:edit foo
,使用:quit
关闭,然后查看硬盘。这个时候文件会存在(当然文件内容为空)。你只有关闭Vim才能删除这个自动命令。我们会在后面的章节说明如何避免这种情况。
自动命令结构
让我们来深入分析下我们刚才创建的自动命令:
:autocmd BufNewFile * :write ^ ^ ^ | | | | | 要执行的命令 | | | 用于事件过滤的“模式(pattern)” | 要监听的“事件”
这个命令的第一部分是我们想监听的事件的类型。Vim提供了_很多_可以监听的事件。这些事件包括:
- 开始编辑一个当前并不存在的文件。
- 读取一个文件,不管这个文件是否存在。
- 改变一个缓冲区的
filetype
设置。- 在某段时间内不按下键盘上面的某个按键。
- 进入插入模式。
- 退出插入模式。
上面只举出了可用事件里面的很小一部分。还有很多其他的事件,你可以利用这些事件来做一些有趣的事情。
这个自动命令的下一部分是一个“模式”,这个模式可以进一步限定你要执行的命令的执行范围。新开一个Vim实例,执行下面的命令:
:autocmd BufNewFile *.txt :write
这个跟之前的那个自动命令基本一样,不过这个自动命令只对后缀为
.txt
的文件有效,也就是说当你新建的文件为txt文件的时候,Vim会在文件创建的时候自动执行write命令将文件保存到硬盘上。试试执行
:edit bar
,然后执行:quit
,再执行:edit bar.txt
,然后再执行:quit
。你会发现Vim会自动创建bar.txt
,但不会创建bar
,因为它的后缀名不是txt,不跟模式匹配。这个自动命令的最后一部分是事件发生时我们想执行的命令。这个部分很容易理解,跟我们执行其他命令一样,除了不能在这个命令中使用特殊的字符,例如
<cr>
。我们会在本书后面的章节中谈论如何突破这个限制,现在你只需要遵守它就可以。再来一个示例
我们再定义一个自动命令,这次使用一个不同的事件。执行下面的命令:
:autocmd BufWritePre *.html :normal gg=G
这里用到了
normal
命令,我会在本书的后面的章节里面讲到它,这可能有点超前,不过我觉得这是一个很好的使用自动命令的示例,所以请大家先忍受一下。创建一个名为
foo.html
的新文件。用Vim编辑它,并输入下面的文本,请保证输入的文本完全一致,包括空白符:<html> <body> <p>Hello!</p> </body> </html>
执行
:w
保存这个文件。看看会发生了什么?Vim似乎在文件保存之前重新进行了文本缩进处理。ok,请先相信我文本缩进处理是
:normal gg=G
干的,先别纠结于为什么:normal gg=G
可以干这个。我们_应该_把注意力放在自动命令上。这个自动命令里面用到的事件是
BufWritePre
,这个事件会在你保存_任何_字符到文件之前触发。我们使用了
*.html
这个模式,这个模式会保证命令只会在编辑html文件的时候被执行。这就是自动命令强大的地方,因为它可以专门针对特定类型的文件来执行我们想要执行的命令。ok,让我们继续探索它吧。多个事件
你可以创建一个绑定_多个_事件的自动命令,这些事件使用逗号分隔开。执行下面的命令:
:autocmd BufWritePre,BufRead *.html :normal gg=G
这个跟上面的自动命令基本一样,不同的是它会让Vim不仅在写html文件的时候进行缩进处理,读html文件的时候也会进行缩进处理。如果你有些同事不喜欢把HTML文件格式搞得漂亮点,那么这个命令会很有用。
在Vim脚本编程中有一个不成文的规定,你应该同时使用
BufRead
和BufNewFile
(译注:这里不是BufWritePre)这两个事件来运行命令,这样当你打开某个类型的文件,不论这个文件是否存在命令都会执行。执行下面的命令::autocmd BufNewFile,BufRead *.html setlocal nowrap
上面的命令会使得无论你在什么时候编辑HTML文件自动换行都会被关闭。
FileType事件
最有用的事件是
FileType
事件。这个事件会在Vim设置一个缓冲区的filetype
的时候触发。让我们针对不同文件类型设置一些有用的映射。运行命令:
:autocmd FileType javascript nnoremap <buffer> <localleader>c I//<esc> :autocmd FileType python nnoremap <buffer> <localleader>c I#<esc>
打开一个Javascript文件(后缀为
.js
的文件),将光标移动到某一行,敲击<localleader>c
,光标所在的那一行会被注释掉。现在打开一个Python文件(后缀为
.py
的文件),将光标移动到某一行,敲击<localleader>c
,同样的那一行会被注释掉,不同的是此时所用的是Python的注释字符!在自动命令中包含我们上一章中学到的本地缓冲区映射,我们可以创建一些映射,这些映射会根据我们正在编辑的文件的类型来进行不同的处理。
这可以为我们在编码的时候减轻很多思考的负担。如果要添加一个注释,我们可能想到的是必须将光标移动到行首,然后添加一个注释字符,而使用上面的映射,我们只需要简单的将其理解为“注释掉这一行”。
练习
浏览
:help autocmd-events
查看自动命令可以绑定的所有事件。你不需要现在就记住每一个事件。仅仅只需要了解下你可以使用这些事件做哪些事情。创建一些
FileType
自动命令使用setlocal
对你喜欢的文件类型做一些设置。你可以针对不同的文件类型设置wrap
、list
、spell
和number
这些选项。对一些你会经常处理的文件类型创建一些类似“注释掉这一行”的命令。
把所有这些自动命令写到你的
~/.vimrc
文件里面。记住使用前面章节中提到过的快速编辑和加载~/.vimrc
文件的映射来做这个事情,这是必须的!
接下来我们讲字符串类型。鉴于Vim是用来编辑文本的,你将频繁地跟这一类型打交道。执行下面的代码::echom "Hello"Vim将输出Hell...
我们新鲜出炉的"grep运算符"工作得很好,但是写Vimscript的目的,就是要体贴地改善你的用户的生活。 我们可以额外做两件事,让我...
Group/Order分组与排序Group方法用于查询分组,Order方法用于查询排序。使用示例:// SELECT COUNT(*) total,age FR...
Model对象也可以通过TX事务对象创建,通过事务对象创建的Model对象与通过DB数据库对象创建的Model对象功能...
SVG circle 通过 circle 可以绘制一个圆形,它只有3个属性用来设置圆形。SVG 圆形 - circle circle 标签可用来创建一个圆: 下面...
XSL-FO table-cell 对象XSL-FO 参考手册定义和用法 fo:table-cell 对象是一个包含表格单元格内容的容器。语法fo:table-cell!--Co...
XML Schema element 元素 完整 XML Schema 参考手册定义和用法 element 元素定义一个元素。 元素信息 父元素: schema, choice, ...
XML Schema simpleContent 元素 完整 XML Schema 参考手册定义和用法 simpleContent 元素包含对 complexType 元素(它以字符数据...
XML Schema notation 元素 完整 XML Schema 参考手册 定义和用法 notation 元素描述 XML 文档中非 XML 数据的格式。 元素信息 父...