使用Python编写vim插件的简单示例


Posted in Python onApril 17, 2015

 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网站找到一些有用的资料。

Python 相关文章推荐
python进阶教程之函数参数的多种传递方法
Aug 30 Python
python+opencv实现动态物体追踪
Jan 09 Python
Python编程flask使用页面模版的方法
Dec 28 Python
Python读取csv文件分隔符设置方法
Jan 14 Python
解决使用PyCharm时无法启动控制台的问题
Jan 19 Python
浅谈Scrapy网络爬虫框架的工作原理和数据采集
Feb 07 Python
python pexpect ssh 远程登录服务器的方法
Feb 14 Python
Python虚拟环境的原理及使用详解
Jul 02 Python
python KNN算法实现鸢尾花数据集分类
Oct 24 Python
python3 BeautifulSoup模块使用字典的方法抓取a标签内的数据示例
Nov 28 Python
Python爬虫实现自动登录、签到功能的代码
Aug 20 Python
Python页面加载的等待方式总结
Feb 28 Python
用Python登录Gmail并发送Gmail邮件的教程
Apr 17 #Python
基于Python实现的百度贴吧网络爬虫实例
Apr 17 #Python
python中dir函数用法分析
Apr 17 #Python
python传递参数方式小结
Apr 17 #Python
使用70行Python代码实现一个递归下降解析器的教程
Apr 17 #Python
python类继承与子类实例初始化用法分析
Apr 17 #Python
python中split方法用法分析
Apr 17 #Python
You might like
基于PHP CURL获取邮箱地址的详解
2013/06/03 PHP
phpmyadmin config.inc.php配置示例
2013/08/27 PHP
php计算税后工资的方法
2015/07/28 PHP
Symfony2实现在doctrine中内置数据的方法
2016/02/05 PHP
HR vs ForZe BO3 第一场 2.13
2021/03/10 DOTA
Mootools 1.2教程 选项卡效果(Tabs)
2009/09/15 Javascript
PHP配置文件php.ini中打开错误报告的设置方法
2015/01/09 PHP
JS仿Windows开机启动Loading进度条的方法
2015/02/26 Javascript
javascript实现在网页任意处点左键弹出隐藏菜单的方法
2015/05/13 Javascript
微信小程序上滑加载下拉刷新(onscrollLower)分批加载数据(二)
2017/05/11 Javascript
Angular 4依赖注入学习教程之组件服务注入(二)
2017/06/04 Javascript
switchery按钮的使用方法
2017/12/18 Javascript
JS+WCF实现进度条实时监测数据加载量的方法详解
2017/12/19 Javascript
node作为中间服务层如何发送请求(发送请求的实现方法详解)
2018/01/02 Javascript
详解Angular5/Angular6项目如何添加热更新(HMR)功能
2018/10/10 Javascript
详解Angular Forms中自定义ngModel绑定值的方式
2018/12/10 Javascript
Vue批量图片显示时遇到的路径被解析问题
2019/03/28 Javascript
微信小程序云开发之模拟后台增删改查
2019/05/16 Javascript
react+redux仿微信聊天界面
2019/06/21 Javascript
解决layui table表单提示数据接口请求异常的问题
2019/09/24 Javascript
解决vue项目 build之后资源文件找不到的问题
2020/09/12 Javascript
基于VUE实现简单的学生信息管理系统
2021/01/13 Vue.js
Python实现扫描局域网活动ip(扫描在线电脑)
2015/04/28 Python
Python实现简单HTML表格解析的方法
2015/06/15 Python
详解使用Python处理文件目录的相关方法
2015/10/16 Python
利用Python实现图书超期提醒
2016/08/02 Python
python基于ID3思想的决策树
2018/01/03 Python
django的ORM模型的实现原理
2019/03/04 Python
python使用celery实现异步任务执行的例子
2019/08/28 Python
pycharm配置python 设置pip安装源为豆瓣源
2021/02/05 Python
丝芙兰波兰:Sephora.pl
2018/03/25 全球购物
在对linux系统分区进行格式化时需要对磁盘簇(或i节点密度)的大小进行选择,请说明选择的原则
2012/11/24 面试题
购房意向书范本
2014/04/01 职场文书
2015年社区服务活动总结
2015/03/25 职场文书
百家讲坛观后感
2015/06/12 职场文书
python实现学员管理系统(面向对象版)
2022/06/05 Python