如何用python写vim插件 (http://python.42qu.com/11165602)

23 篇文章 0 订阅
10 篇文章 0 订阅
如何用python写vim插件
  
  
HOW TO WRITE VIM PLUGINS WITH PYTHON

如何用python写vim插件

I'm not going to dive into how good or extendible Vim is. If you are reading this article, you probably know that. 我不会深入讲解vim是如何的优秀或者易于扩展。 如果你正在阅读本文,你应该已经知道那些了。 The thing that makes Vim so good, is the scripting environment behind it called VimL. Using this scripting language, you can write any functionality/plugin you need for Vim. 让vim如此优秀的是它背后的叫 VimL的脚本环境。你可以使用这个脚本语言为vim编写任何功能/插件。 Each plugin you use is written in this language. Here's the best part. You only need very little knowledge of VimL to be able to write plugins, if you know Python (or Ruby). 你使用的每个插件都是使用这个语言编写的。 最爽的是如果你懂python(或者ruby),你只要知道非常少的关于VimL的知识就可以编写插件。 WHAT'S A VIM PLUGIN ANYWAY

到底什么是VIM 插件

A Vim plugin is a .vim script that defines functions, mappings, syntax rules, commands that may, or may not, manipulate the windows, buffers, lines. It is a complete piece of code with some specific functionality. Vim 插件是一个 定义了可能会操作窗口、缓冲区、文本行的函数、映射、语法规则和命令 的.vim脚本。它是包涵了特定功能的完整代码片段。 Usually, a plugin consists of several functions mappings command definitions and event hooks. When writing vim plugins with Python, often, everything outside the functions is written in VimL. But those are vim commands and they can be learned fast. 一个插件通常由几个函数映射 命令定义甚至是 hook 组成。当用python写vim插件的时候通常函数之外的东西都是使用VimL编写。但是那都是可以很快学会的Vim命令。 In fact, VimL can be learned fast, but using python gives so much flexibility. Think about using urllib/httplib/simplejson for accessing some web service that helps editing in Vim. This is why most of the plugins that work with web services are usually done in VimL+Python. 实际上,VimL可以很快被学会,但是python使之如此灵活。想想用 urllib/httplib/simplejson 访问网络服务来辅助vim编辑。 这就是为什么大部分使用网络服务的插件是用 VimL 和 python 完成的。 ANY PREREQUISITES?

需要准备些什么?

You must have vim compiled with +python support. You can check that using the command: 你必须安装有编译时带有对python支持的vim, 你可以用下面的命令检查。
vim --version | grep +python
Vim package in Ubuntu and it's derivatives comes with +python support.ubuntu 和 ubuntu的衍生版本 下的vim包默认就有 对python的支持 To Work - VIMMIT.VIM

一个能使用的脚本 - VIMMIT.VIM

What's better than starting with a simple example? This is a plugin that, when called, will retrieve the homepage of Reddit and will display it in the current buffer.还有什么比从一个简单样例开始更好的。 这是一个被调用时会获取 Reddit 主页并把它展现在当前缓冲区的插件。Start by opening "vimmit.vim" file (in vim). Since we are writing python code, its good to check if Vim supports Python:从打开“vimmit.vim”开始(这里是在VIm中打开)。 因为我们是写 python代码, 最好检查一下vim是否支持python:
if !has('python')
    echo "Error: Required vim compiled with +python"
    finish
endif
This piece is writen in VimL. It's best if we stick to VimL for things like this, mappings and event hooks. This function will check if Vim has python support or it will end the script with an error message.这个代码片段是使用VimL编写的。如果我们要实现这种功能、映射甚至是hook最好使用VimL。 这个函数会检查vim是否支持python 否则提示错误信息结束脚本。We continue with the main function Reddit(). This is where we use Python and do the main functionality:我们继续写主要的函数 Reddit()。 这里是我们使用python完成主要功能的地方:
" Vim comments start with a double quote.
" 双引号开头表示Vim的注释
" Function definition is VimL. We can mix VimL and Python in
" function definition.
" 函数使用VimL定义的, 我们可以在函数定义中混用 VimL和 Python
function! Reddit()

" We start the python code like the next line.
" 我像下面这行这样开始写 python 代码

python << EOF
# the vim module contains everything we need to interface with vim from
# python. We need urllib2 for the web service consumer.
# Vim 模块包含了所有从python访问vim的接口。 我们需要用urllib2写访问网络服务的部分。
import vim, urllib2
# we need json for parsing the response
# 我们需要用json来解析 response
import json

# we define a timeout that we'll use in the API call. We don't want
# users to wait much.
# 我们定义了一个最长时间来调用 api 。我们不希望用户久等。
TIMEOUT = 20
URL = "http://reddit.com/.json"

try:
    # Get the posts and parse the json response
    # 得到帖子 并分析json
    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.
    # vim.current.buffer 就是当前缓冲区。它是一个类似于列表的对象
    # 每行是一个list的一项。 我们可以对它们循环遍历、删除、修改等等。
    # 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.
" Python代码在这里结束。 我们可以再继续写 VimL 或者 python代码。
endfunction
Save the file, source it in vim (:source vimmit.vim) and:保存文件, 用source命令加载它(:source vimmit.vim) 然后
:call Reddit()
Now, the way we call the function is not so elegant. So we define a command:我们现在调用函数的方式不是很优雅, 所以我们定义了一个命令:
command! -nargs=0 Reddit call Reddit()
We define the command :Reddit to call the function. After adding this, open a new bufer and do :Reddit . Home page will be loaded in the buffer. The -nargs argument states how many arguments the command will take.我们定义了命令 :Reddit 来调用这个函数。 加了这些之后, 打开一个新缓冲然后运行 :Reddit. 主页会被加载到缓冲区里。 -nargs 参数表示这个命令有多少参数 。 FUNCTION ARGUMENTS, EVAL AND COMMAND

函数参数传入,取值 和 命令

Q: How does one access functional arguments?问:怎么去访问函数参数?
function! SomeName(arg1, arg2, arg3)
    " Get the first argument by name in VimL
    " 在VimL中使用变量名获得第一个参数
    let firstarg=a:arg1

    " Get the second argument by position in Viml
    " 在VimL中使用位置获得第一个参数
    let secondarg=a:1

    " Get the arguments in python
    " 在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")
You can define a function with arbitrary number of arguments by putting "..." instead of argument names. You can access these arguments only by position, and you can mix them with named arguments (arg1, arg2, ...)你可以用 "..."来代替命名参数 来定义一个能接收任意数量参数的函数。 你只可能通过位置来访问这些参数, 同时你还可以 把它和 命名参数混用。Q: How can I call Vim commands from Python?问:我怎么才能才 python中调用 vim命令
vim.command("[vim-command-here]")
Q: How to define global variables and access them in VimL and Python?问:怎么在vimL和python中 定义 和 访问全局变量Global vars are prefixed with g:. If you want to define one in your script, best thing to do is check if it exists and if doesn't define it and assign some default value to it:全局变量以 g: 开头。 如果你想在你的脚本中定义全局变量, 最好检查它是否已经存在, 如果不存在就定义一个 并 赋初值。
if !exists("g:reddit_apicall_timeout")
    let g:reddit_apicall_timeout=40
endif
You can access it from python using the vim module:你可以在python中用vim模块这么访问它
TIMEOUT = vim.eval("g:reddit_apicall_timeout")
If you want to override this setting, you can write:如果你要覆写这个设置, 你可以把:
let g:reddit_apicall_timeout=60
in .vimrc .写入 .vimrc ADDITIONAL NOTES

补充:

VimL is pretty easy once you try it. Remember that print works and everything you can do with python, you can do in here. Here you can find the documentation for the vim python module. Vimdoc is the possibly the only resource you will need when writing vim plugins.你试了就会发现VimL相当简单。 记得 你可以 在这里 打印 和 做任何你可以用python做的事情。你可以在 这里找到 viim python 模块的文档. Vimdoc可能是你写 vim 插件时唯一需要用到的资源.You can also check this IBM developerWorks article .你也可以看看这个 IBM developerWorks articleNow, try to extend "vimmit.vim" so the user is able to choose a subreddit (as a first functional argument).现在去试着扩展 "vimmit.vim" 让用户可以选择 reddit 的子栏目吧 (用函数的第一参数传入)本文译自 HOW TO WRITE VIM PLUGINS WITH PYTHON
Young(Genrui·程序员)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值