视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
使用Python编写vim插件的简单示例
2020-11-27 14:32:52 责编:小采
文档

Vim 插件是一个 .vim 的脚本文件,定义了函数、映射、语法规则和命令,可用于操作窗口、缓冲以及行。一般一个插件包含了命令定义和事件钩子。当使用 Python 编写 vim 插件时,函数外面是使用 VimL 编写,尽管 VimL 学起来很快,但 Python 更加灵活,例如可以用 urllib/httplib/simplejson 来访问某些 Web 服务,这也是为什么很多需要访问 Web 服务的插件都是使用 VimL + Python 编写的原因。


在开始编写插件之前,你需要确认 Vim 支持 Python,通过以下命令来判别:

代码如下:

vim --version | grep +python


接下来我们通过一个简单的例子来学习用 Python 编写 Vim 插件,该插件用来获取 Reddit 首页信息并显示在当前缓冲区上。

首先在 Vim 新建 vimmit.vim 文件,我们首先需要判断是否支持 Python,如果不支持给出提示信息:

if !has('python')
 echo "Error: Required vim compiled with +python"
 finish
endif

上面这段代码就是用 VimL 编写的,它将检查 Vim 是否支持 Python。


下面是用 Python 编写的 Reddit() 主函数:


" Vim comments start with a double quote.
" Function definition is VimL. We can mix VimL and Python in
" function definition.
function! Reddit()
 
" We start the python code like the next line.
 
python << EOF
# the vim module contains everything we need to interface with vim from
# python. We need urllib2 for the web service consumer.
import vim, urllib2
# we need json for parsing the response
import json
 
# we define a timeout that we'll use in the API call. We don't want
# users to wait much.
TIMEOUT = 20
URL = "http://reddit.com/.json"
 
try:
 # Get the posts and parse the json response
 response = urllib2.urlopen(URL, None, TIMEOUT).read()
 json_response = json.loads(response)
 
 posts = json_response.get("data", "").get("children", "")
 
 # vim.current.buffer is the current buffer. It's list-like object.
 # each line is an item in the list. We can loop through them delete
 # them, alter them etc.
 # Here we delete all lines in the current buffer
 del vim.current.buffer[:]
 
 # Here we append some lines above. Aesthetics.
 vim.current.buffer[0] = 80*"-"
 
 for post in posts:
 # In the next few lines, we get the post details
 post_data = post.get("data", {})
 up = post_data.get("ups", 0)
 down = post_data.get("downs", 0)
 title = post_data.get("title", "NO TITLE").encode("utf-8")
 score = post_data.get("score", 0)
 permalink = post_data.get("permalink").encode("utf-8")
 url = post_data.get("url").encode("utf-8")
 comments = post_data.get("num_comments")
 
 # And here we append line by line to the buffer.
 # First the upvotes
 vim.current.buffer.append("↑ %s"%up)
 # Then the title and the url
 vim.current.buffer.append(" %s [%s]"%(title, url,))
 # Then the downvotes and number of comments
 vim.current.buffer.append("↓ %s | comments: %s [%s]"%(down, comments, permalink,))
 # And last we append some "-" for visual appeal.
 vim.current.buffer.append(80*"-")
 
except Exception, e:
 print e
 
EOF
" Here the python code is closed. We can continue writing VimL or python again.
endfunction

使用如下命令保存文件

代码如下:

:source vimmit.vim

然后调用该插件:

代码如下:

:call Reddit()

这个命令用起来不那么方便,因此我们再定义一个命令:

代码如下:

command! -nargs=0 Reddit call Reddit()

我们定义了命令:Reddit来调用这个函数。-nargs 参数声明命令行中有多少个参数。


关于函数参数的问题:

问:如何访问函数中的参数?

function! SomeName(arg1, arg2, arg3)
 " Get the first argument by name in VimL
 let firstarg=a:arg1
 
 " Get the second argument by position in Viml
 let secondarg=a:1
 
 " Get the arguments in python
 
 python << EOF
 import vim
 
 first_argument = vim.eval("a:arg1") #or vim.eval("a:0")
 second_argument = vim.eval("a:arg2") #or vim.eval("a:1")

你可以使用 ... 来处理可变个数参数来替换特定的参数名,可通过位置或者命名参数来访问,如:(arg1, arg2, ...)

问:如何在 Python 中调用 Vim 命令?

代码如下:

vim.command("[vim-command-here]")

问:如何定义全局变量,并在 VimL 和 Python 中访问?

全局变量使用形如 g:. 的前缀,定义全局变量前应该检查该变量是否已定义:

if !exists("g:reddit_apicall_timeout")
 let g:reddit_apicall_timeout=40
endif

然后你通过下面代码在 Python 中访问这个变量:

TIMEOUT = vim.eval("g:reddit_apicall_timeout")

可通过下面的方法来对全局变量进行重新赋值:

let g:reddit_apicall_timeout=60

更多关于使用 Python 编写 Vim 插件的说明请看官方文档。


备注:

一旦你用过VimL,就会发现它挺简单的,你用python写的代码也可以用它来实现。详细请参考vim python模块文档,这是一份重要的参考资料。

除了上述文档,你也可以在IBM developerWorks网站找到一些有用的资料。

下载本文
显示全文
专题