2

作为一款历史悠久的编辑器,Vim 不仅支持用别具一格的 Vimscript 编写插件,还提供了 Python、Ruby、Lua 和 Perl 等语言对应的接口,甚至包括了对 Tcl 的支持,注意我说的是名为 Tcl 的编程语言,不是某家电品牌。通过这些语言,开发者可以摆脱 Vimscript 的限制,挑选自己最擅长的工具来拓展自己的编辑器。几年前,我曾经心血来潮,学了一段时间 Vimscript,帮忙翻译了《笨方法学Vimscript》一书。然而学到的知识如沙滩上的城堡,早已被时光之潮拍得支离破碎。所以现在要想写点小效果,都会用 Vimscript 搭个脚手架,用其他语言实现具体的逻辑。考虑到 NeoVim 当前并不支持 Lua 和 Perl 等小众语言,出于适用的目标,通常只会选择用 Python 或者 Ruby 来实现。鉴于如何用 Ruby 拓展 Vim 的资料相对缺乏,我决定写下本文,以供后来者参考。

前提

你所用的 Vim 可能不支持 Ruby 拓展。通过键入 :echo has('ruby'),你可以了解 Ruby 拓展功能是否已启用。幸运的是,从 Linux 包管理器上安装的 Vim 默认是支持 Ruby 的。如果不支持,就只能自己重新编译一份了。值得注意的是,NeoVim 还需要运行 gem install neovim 来下载对应的 Ruby Client。

Hello World

一切先从 Hello World 开始::ruby p 'hello world'。你会看到一条 “hello world” 打印在编辑器下方。通常的做法是用 Vimscript 写一个函数,在这个函数里面调用 ruby 命令去执行 ruby 代码。像这样:

function! Test()
ruby <<EOS
    p "hello world"
EOS
endfunction

command! Test :call Test()

这里用到了 Vimscript 的 heredoc 语法,让 ruby 命令执行一个多行的 Ruby 代码字符串。最后一行把这个函数映射到 Test 命令上,这样就能通过 :Test 的方式调用它。

如果要写的 Ruby 代码比较多,推荐放到一个独立的文件里面,然后再从 ruby 命令里面 require 进来。记得处理下 ruby 文件加载的路径。

Vim 跟 Ruby 相关的 API 文档可以通过 vert help ruby 看到,整篇说明也不过一两百行。功能是少了点,不过日常写点小玩意,代替成段 Vimscript 还是能做到的。

IO

要想写出超越 Hello World 的代码,不能不了解 Vim 提供的输入输出 API。
Vim 暴露在 Ruby 代码里的 API,都在 Vim 这个模块下面。

有两种方式可以获取当前 Vim 状态(输入 API):

  1. 通过 Vim::evaluate(expr) 的方式执行任意 Vimscript 表达式并获得其结果。这种方法用于获取 Vim 变量,比如 :ruby p Vim::evaluate(g:maplocalleader)
  2. 通过 Vim::BufferVim::Window 两个子模块,获取 Buffer 或 Window 的各种状态。比如 :ruby p Vim::Buffer.current[1] 会返回第一行的内容。可惜的是,没有 Tab 模块。

对应有两种方法可以修改当前 Vim 状态(输出 API):

  1. 通过 Vim::command(cmd) 的方式执行任意命令。其效果等同于 :cmd。比如 :ruby Vim::command('set paste') 其实就是 :set paste 的意思。
  2. 通过 Vim::BufferVim::Window 去设置 Buffer 或 Window 的状态。比如 :ruby Vim::Buffer.current[1] = 'ruby evaluation' 会把第一行变成 ruby evaluation

More

如果你对用 Ruby 拓展 Vim 感兴趣,而又恰好使用 NeoVim,可以看下这个项目:https://github.com/alexgenco/...
这个项目提供了我们前面安装的 neovim gem。除了 Vim 模块,这个 gem 还在 NeoVim 模块下面放了更多的 API。如果你在写的 Ruby 拓展需要更多的 API,可以考虑给这个 gem 贡献代码。当然,额外引入的新功能就不会兼容原生 Vim 了。


spacewander
5.6k 声望1.5k 粉丝

make building blocks that people can understand and use easily, and people will work together to solve the very largest problems.


引用和评论

0 条评论