You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
200 lines
9.7 KiB
200 lines
9.7 KiB
2 years ago
|
# 第一章 VimL 语言主要特点
|
||
|
|
||
|
## 1.1 Hello World 的四种写法
|
||
|
|
||
|
按惯例,我们讨论一门语言,首先看下如何写最简单的 “Hello World” (程序)。
|
||
|
由于 Vim 是高度自由的,VimL 也有多种不同的方式玩转 “Hello World”。
|
||
|
|
||
|
### 速观派:直接操起命令行
|
||
|
|
||
|
最快速的办法是在 Vim 命令行下用 `:echo` 命令输出 “Hello World”:
|
||
|
```vim
|
||
|
: echo 'Hello World!'
|
||
|
```
|
||
|
唯一需要注意的是,得把 “Hello World” 用引号括起来,单引号或双引号都可以。
|
||
|
这样再按下回车就能在 Vim 的消息区显示出 “Hello World” 这行字符串了。
|
||
|
|
||
|
由于这条消息字符串很简短,一行就能显示完整,Vim 将其直接显示在命令行的位置,并
|
||
|
且运行完直接返回 Vim 普通模式。如果字符串很长或多行字符串,则消息区将向上滚动
|
||
|
,以显示完整的消息,用户需要额外按个回车才回普通模式。
|
||
|
|
||
|
试试在命令行输入这条命令,看看有啥不同反应:
|
||
|
```vim
|
||
|
: echo "Hello World! \n Hello World! \n Hello World!"
|
||
|
```
|
||
|
|
||
|
好了,你已经学会了如何用 VimL 输出 “Hello World” 了。这也算编程吗?别逗了!其
|
||
|
实,别把编程想得那么严肃,那这就算编程!
|
||
|
|
||
|
### 正规派:建立脚本文件
|
||
|
|
||
|
把刚才在命令行输入的那条命令保存在一个 `.vim` 后缀的文本文件中,那就是一个
|
||
|
`vim script` 了,这是用 VimL 编程比较正常的用法。
|
||
|
|
||
|
为了方便,建议在本地建个目录,用于保存本教程的示例代码。比如:
|
||
|
```bash
|
||
|
$ cd ~/.vim
|
||
|
$ mkdir vimllearn
|
||
|
$ vim vimllearn/hello1.vim
|
||
|
```
|
||
|
|
||
|
这将在 `~/.vim` 目录下新建一个 `vimllearn` 目录,并用 vim 开始编辑一个名为
|
||
|
`hello1.vim` 的文件。vim 会为该文件新建一个缓冲区 `buffer`,在该 `buffer` 中输
|
||
|
入以下文本,然后输入命令 `:w` 保存:
|
||
|
```vim
|
||
|
" 文件:hello1.vim
|
||
|
" 用途:VimL hello world 示例
|
||
|
" 作者:lymslive
|
||
|
" 时间:2017-08
|
||
|
|
||
|
echo 'Hello World!'
|
||
|
|
||
|
finish
|
||
|
|
||
|
脚本结束了,可以随便浪~~
|
||
|
不管写些什么乱七八糟的都木有关系。
|
||
|
```
|
||
|
|
||
|
你其实可以只在该文件中写入 `echo 'Hello World!'` 这一行就够了。几点说明:
|
||
|
1. 前面以一个双引号 `"` 开始的行是注释,注释也可以写在行尾。
|
||
|
2. 在脚本文件中,`echo` 命令前不必加冒号 `:`,但是加上冒号也是允许的。
|
||
|
3. `finish` 表示直接结束脚本,在之后的语句都不再被 vim 解析;这是可选的,没有
|
||
|
遇到 `finish` 就会执行到文件最后一行。
|
||
|
|
||
|
当有了 `*.vim` 脚本文件,就可以在 vim 环境中用 `:source` 命令加载运行了:
|
||
|
```vim
|
||
|
: source ~/.vim/vimllearn/hello1.vim
|
||
|
```
|
||
|
需要将脚本文件的路径写在 `source` 命令之后作为参数。如果当前 vim 正常编辑
|
||
|
`hello1.vim` 这个文件,则可用 `%` 表示当前文件的路径:
|
||
|
```vim
|
||
|
: source %
|
||
|
```
|
||
|
|
||
|
折腾并解释了这许久,终于可以通过 `source` 一个 vim 脚本打印输出 “Hello World”
|
||
|
了,与此前的效果是一样一样的。当然了,用 VimL 写脚本肯定不能只满足于写 “Hello
|
||
|
World” 吧,所以这才是标准用法。
|
||
|
|
||
|
此外 Vim 的命令是可以简写的,`source` 可简写为 `so`。当你在写一个 vim 脚本时想
|
||
|
快速验证执行该脚本时,可以只输入:
|
||
|
```vim
|
||
|
: so %
|
||
|
```
|
||
|
|
||
|
如果还想更省键,就定义一个快捷键映射吧,比如:
|
||
|
```vim
|
||
|
: nnoremap <F5> :update<CR>:source %<CR>
|
||
|
```
|
||
|
可以将这行定义加入你的 `vimrc` 中,不过最好是放在 `~/.vim/ftplugin/vim.vim` 中
|
||
|
,并加上局部参数,让它只影响 `*.vim` 文件:
|
||
|
```vim
|
||
|
: nnoremap <buffer> <F5> :update<CR>:source %<CR>
|
||
|
```
|
||
|
|
||
|
### 测试派:进入 Ex 模式
|
||
|
|
||
|
直接在命令行用 `:echo` 查看一些东西其实很有用的,可以快速验证一些记不清楚的细
|
||
|
节。比如你想确认下在 VimL 中字符 `'0'` 是不是与数字 `0` 相等,可以这样:
|
||
|
```vim
|
||
|
: echo '0' == 0
|
||
|
```
|
||
|
|
||
|
但如果要连续输入多条命令并查看结果,每次都要(从普通模式)先输入个冒号,不免有
|
||
|
些麻烦。这时,`Ex` 模式就有用了。默认情况下(若未在 vimrc 被改键映射),在普通
|
||
|
模式下用 `Q` 键进入 `Ex` 模式。例如,在 `Ex` 模式下尝试各种输出 “Hell World”
|
||
|
的写法,看看不同引号对结果的影响:
|
||
|
```vim
|
||
|
Entering Ex mode. Type "visual" to go to Normal mode.
|
||
|
: echo 'Hello World!'
|
||
|
: echo "Hello World!"
|
||
|
: echo 'Hello \t World! \n Hello \t World!'
|
||
|
: echo "Hello \t World! \n Hello \t World!"
|
||
|
: vi
|
||
|
```
|
||
|
|
||
|
最后,按提示用 `visual` 或简写 `vi` 命令回到普通模式。
|
||
|
|
||
|
Vim 的 `Ex` 模式有点像 VimL 的交互式的解释器,不过语法完全一样(有些脚本语言的
|
||
|
交互式解释器与执行脚本有些不同的优化),仍然要用 `echo` 显示变量的值。
|
||
|
|
||
|
### \*索隐派:从 shell 直接运行
|
||
|
|
||
|
如果只为了运行一个 vim script 脚本,也不一定要先启动 vim 再 `source`,直接在启
|
||
|
动 vim 时指定特定参数也能办到。`-e` 参数表示以 `Ex` 模式启动 vim,`-S` 参数启
|
||
|
动后立即 source 一个脚本。因此,也可以用如下的命令来输出 “Hello World”:
|
||
|
```vim
|
||
|
$ cd ~/.vim/vimllearn
|
||
|
$ vim -eS hello1.vim
|
||
|
```
|
||
|
|
||
|
这就相当于使用 `vim` 解释器来运行 `hello.vim` 这个脚本,并且停留在交互式界面
|
||
|
上。此时可以用 `:q` 命令退出,或 `:vi` 以正常方式继续使用 Vim。
|
||
|
|
||
|
vim 本身的命令行启动参数其实还支持很多功能,请查阅 `:help starting`。其中还有
|
||
|
个特殊的参数是 `-s`,如果与 `-e` 联用,就启动静默的批处理模式,试试这个:
|
||
|
```vim
|
||
|
$ vim -eS hello1.vim -s
|
||
|
```
|
||
|
没有任何反应输出?因为 `-s` 使普通的 `echo` 提示无效,看不到任何提示!赶紧输入
|
||
|
`q` 回车退出 vim 回到 shell。因为如果不小心按了其他键,vim 可能就将其当作命令
|
||
|
来处理了,而且不会有任何错误提示,这就会让大部分人陷入不知如何退出 vim 的恐慌
|
||
|
。
|
||
|
|
||
|
虽然 `vim -e -s` 不适合来输出 “Hello World”,但如果你的脚本不是用来做这种无聊
|
||
|
的任务,这种模式还是有用的。比如批处理,在完全不必启动 vim 可视编辑的情况下,
|
||
|
批量地对一个文件或多个文件执行编辑任务。可达到类似 `sed` 的效果。而且,在 vim
|
||
|
脚本写好的情况下,不仅可以按批处理模式执行,也可以在正常 Vim 可视编辑某个文件
|
||
|
时,遇到类似需求时,也可以再手动 `:source` 脚本处理。
|
||
|
|
||
|
### 小结
|
||
|
|
||
|
运行 vim 脚本的常规方法用 `:source` 命令,而且有很多情况下并不需要手动输入
|
||
|
`:source` 命令,在满足一定条件下,vim 会自动帮你 source 一些脚本。vim 的启动参
|
||
|
数 `-S` 其实也是执行 `:source`。
|
||
|
|
||
|
Vim 的命令行可以随时手动输入一些简短命令以验证某些语法功能,进入 `Ex` 模式则可
|
||
|
以连续手动输入命令并执行。`Ex` 模式虽然比较少用,但不该反感排斥,这对学用 VimL
|
||
|
还是大有裨益的,以后会讲到,VimL 的 debug 功能也是在 `Ex` 模式中的。
|
||
|
|
||
|
静默批处理 `vim -e -s` 本质上也是 `Ex` 模式,不过禁用或避免了交互的中断。属于
|
||
|
黑科技,一般的 vim 用户可先不必深究。
|
||
|
|
||
|
### \*拓展阅读:Vim 与可视化
|
||
|
|
||
|
“可视化”是个相对的概念。现在说到可视化,似乎是指功能丰富的 IDE 那种,有很多辅
|
||
|
助窗口展示各方面的信息,甚至有图形化来表示类层次关系与函数调用关系。还有传说中
|
||
|
的唯一的中文编程语言“易语言”还支持图文框拖拖拽拽就能编写代码的东东……而 vim 这
|
||
|
种古董,只有编辑纯文本,似乎就该归属于“不可视”。
|
||
|
|
||
|
然而,让我们回顾洪荒时代,体验一下什么叫真正的“不可视”编辑。
|
||
|
|
||
|
在 Vi 都还没诞生的时代,有一个叫 `ed` 的行编辑器,它只能通过命令以行为单位去操
|
||
|
作或编辑文本文件。它完全没有界面,无从知道当前编辑的是哪个文件,在哪行,当前行
|
||
|
是什么内容,用户只能“记住”,或用命令查询。比如用 `p` 命令打印显示当前行(不过
|
||
|
也可以在前面带上行地址打印多行,至今 `vim` 的大部分命令都可以带地址参数)。要
|
||
|
编辑当前行,请用 `a` `i` 或 `c` 命令(vimer 有点眼熟吧),不过编辑完后也无从知
|
||
|
晓结果是否正确,可能还需要再用 `p` 命令打印查看确证。
|
||
|
|
||
|
之后,有个 `ex` 编辑器,不过是对 `ed` 的命令进行了扩展,本质上仍是行编辑器。直
|
||
|
到 `vi` 横空出世,那才叫“屏幕编辑器”。意思是可以全屏显示文件的许多行,移动光标
|
||
|
实时修改某一可见行,修改结果即时显示……这才像我们现在可认知的编辑器了。
|
||
|
|
||
|
然后是 `vim` 对 `vi` 的扩展增强。事实上,`vim` 还不如 `vi` 的划时代意义,它的
|
||
|
增强与此前 `ex` 对 `ed` 的增强是差不多的程度,基本上是平行扩展。
|
||
|
|
||
|
可视化程度不是越高越好。 `vim` 与 `vi` 都保留与继承了 `ex` 的命令,因为 `ex`
|
||
|
命令确实高效,当你能确知一个命令的运行结果,就没必要关注中间过程了。比如最平凡
|
||
|
无奇但常用的 `ex` 命令就是 `:s` 全局替换命令。
|
||
|
|
||
|
VimL 语言就是基于 `ex` 命令的,再加上一些流程控制,就成了一种完整的脚本语言。
|
||
|
如果说 `vim` 对 `vi` 有什么压倒性的里程碑意义,我觉得应是丰富完善了 VimL 语言
|
||
|
,使得 `vim` 有了无穷的扩展与定制。利用 VimL 写的插件,既可以走增加可视化的方
|
||
|
向,也可以不增加可视化而偏向自动化。依每人的性格习惯不同,可能会在 Vim 的可视
|
||
|
化与自动化之间找到适合自己的不同的平衡点。
|
||
|
|
||
|
<!--
|
||
|
—— 楼上的天花乱坠地在说些什么呀
|
||
|
|
||
|
—— 不知道耶,再看看吧
|
||
|
-->
|