Vim

VimScript基础学习(一)

2018-08-04  本文已影响464人  比轩

以下内容为学习VimScript时的记录,如果有兴趣,建议阅读原文。

1. 创建~/.vimrc文件

.vimrc是vim默认的配置文件,一般位于home目录下,在vim启动的时候回默认加载此文件,来初始化vim。

在vim中执行以下命令可获取当前vim实际加载的配置文件的路径:

:echo $MYVIMRC

2. :echo:echom

在vim中执行:echo或者:echom命令可以输出信息到vim底部,类似于c中的printf

执行如下命令,可以在vim底部打印出hello world!

:echo "hello world!"

:echo:echom两个命令的区别在于:后者打印出出来的信息会保存下来,在vim中执行:messages即可查看到打印的历史信息,如果有较为复杂的vim脚本逻辑,使用:echom则方便调试

理解:

到这里应该有一个概念,.vimrc中的配置文件都是基于vimscript脚本的,上述的两个命令其实就是脚本中的两个基础命令。vim底部的:操作则类似于vimscript实时执行的的控制台,

3. 注释

vimscript中的注释使用", 如下:

" 这是一行注释
echo "hello world!"

4. 使用help命令

在vim中,可以使用help命令查看任何其他命令的详细文档,如下:

:help echo
:help echom
:help messages

5. 设置选项

vim中有很bool类型的选项,比如是否显示行号的选项 number,在vim中执行:set number即可开启行号的显示,接着执行:set nonumber即可关闭行号的显示。

凡是表达是否的选项,都是可以使用:set <name>开启,:set no<name>关闭。

尝试依次执行如下命令:

:set number
:set number!
:set number?
:set number!
:set number?

输出如下:

1. 开始行号显示
2. 关闭行号显示
3. vim底部显示nonumber
4. 开启行号显示
5. vim底部显示number

!操作符可以对bool类型的配置选项取反。?操作符则可以获取当前选项的值。因此,上述操作一次为:开启行号->关闭行号->获取nonumber->开启行号->获取number

除了bool类型的开关选项之外,还有很多可以取多个值的选项,比如numberwidth【显示行号的宽度】选项。

执行:set numberwidth=6即可将行号的显示宽度设置为6,当然你可以根据自己的喜好设置为其他的数字。所以,其他类似的配置选项都可以使用如下命令来进行设置。

:set <name>=<value>

?操作符对这些设置选项同样有效,如获取选项matchtime的值:

:set matchtime?

在实际的配置中,一次set可以对多个选项进行设置,如下:

:set number numberwidth=5

6. 基础映射

vim被很多人喜欢的原因就是高度的自定义。vimer可以按照自己的喜欢,对vim进行各种各样的配置,来提高自己的工作效率。这其中,最常用的的功能就是键位映射。

:map - x

执行完上述命令,在vim中选中一个字符,按下-键,选中的字符消失了,如同按了x快捷键。所以,map命令可以实现键位上的映射,以此来达到快捷键的自定义。

所以,如果你想在按下-的时候,删除光标所在的行,就可以执行:map - dd,当按下-的时候,就等同于按下dd,光标所在的行就会被删除。再比如,执行map - viw,这个时候按下-就会高亮选中当前光标所在的整个单词。

这个时候你可能想这么操作:

:map <space> viw " select a word

完事儿,按下空格键可能不会按照原来设想的行为执行。vim会解析为:
viw<space>"<space>select<space>a<space>word

所以注意,不要在map所在行添加注释,此时"及其后面的内容并不会被解析为注释。

7. 模式映射

到这里你可能会发现,map的映射除了normal模式之外,在visual模式也同样起作用。
如果只想让命令在指定的模式下生效,可以使用模式映射命令分别为:nmap,vmap,imap三个命令,对应为normal,visual,insert三种模式。

nmapvmap的行为符合我们直觉上操作,imap则有一点点特殊。

:imap <c-d> dd

执行上述命令,我们的期望是:在insert模式下,按下Ctrl + d ,删除光标所在行。但是实际的情况是:输入了dd。原因是vim此时在insert模式下,dd并不能删除当前行,只是输入了两个d字母。

imap只能确保映射的命令在insert的模式可以被执行,但是具体被映射的命令在insert模式下执行情况是怎样的,需要考虑具体的情景。

所以,想要在insert模式下:按下<C-d>来删除光标所在的行,需要如下的映射:

:imap <c-d> <esc>ddi

很容易理解:<esc>确保回退到normal模式,dd删除当前行,i再进入insert模式。

  1. 精准映射

目前为止掌握的*map如下:

尝试如下映射:

:nmap - dd
:nmap / -

第一行命令将-映射为dd,第二行命令将/映射为-。此时按下/发生什么?答案是删除了当前光标所在的行。因为/被解析为-,但是-又被映射为了dd,所以就执行了删除当前行的操作。因此*map有一个致命的问题就是会导致递归映射。这在实际中是非常麻烦的,因此在实际映射中通常建议使用精准映射:*noremap

在实际的映射中,建议任何时候都使用精准映射:noremap,nnoremap,vnoremap,inoremap

执行如下命令:

:nnoremap x dd
:nnoremap - x

此时按下-会忽略xdd的映射,只会单纯的执行x原来的行为,也就是剪贴当前字符。

至此学到的map命令:

在脑子里回忆下这些map命令之间的区别。

上一篇 下一篇

猜你喜欢

热点阅读