:python :py E263 E264 E887
:[range]
py[thon] {stmt}
执行 Python 语句 {stmt}
。一个判断 ":python" 命令是否可
用的简单检查:
:python print "Hello"
:[range]
py[thon] << [trim]
[{endmarker}
]
{script}
{endmarker}
执行 Python 脚本 {script}
。
备注
: 此命令在没有编译进 Python 特性时无效。为了避免这
样的错误,参阅 script-here 。
如果在 "<<" 之后省略了 [endmarker]
,就像 :append 及 :insert 命令那样,在
{script}
之后一定要有一个点 '.'。更多详情可见 :let-heredoc 。
这种形式的 :python 命令主要用于在 Vim 脚本中嵌入 Python 代码。
例子:
function! IcecreamInitialize()
python << EOF
class StrawberryIcecream:
def __call__(self):
print 'EAT ME'
EOF
endfunction
要看运行的 Python 版本:
:python print(sys.version)
没必要 import sys,缺省就会。
python-environment
Vim 设置的环境变量不总是在 Python 里可用。取决于 Vim 和 Python 是如何编译的。
另见 https://docs.python.org/3/library/os.html#os.environ
备注
: Python 对于缩进是非常敏感的。要确保 "class" 所在行及 "EOF" 没有任何缩
进。
:pydo
:[range]
pydo {body}
对 [range]
里的每一行执行 Python 函数 "def
_vim_pydo(line, linenr): {body}
",其中的函数参数设为每
行不带尾部 <EOL>
的文本,以及行号。该函数应该返回字符
串或者 None。如果返回字符串,它会用来替代当前执行的
行。缺省 [range]
为整个文件: "1,$"。
示例:
:pydo return "%s\t%d" % (line[::-1], len(line))
:pydo if line: return "%4d: %s" % (linenr, line)
可以和 :py 配合,用 :pydo 来利用 python 过滤行范围。例如:
:py3 << EOF
needle = vim.eval('@a')
replacement = vim.eval('@b')
def py_vim_string_replace(str):
return str.replace(needle, replacement)
EOF
:'<,'>py3do return py_vim_string_replace(line)
:pyfile :pyf
:[range]
pyf[ile] {file}
执行 {file}
文件中包含的 Python 脚本。整个参数被用作一
个文件名。
这些命令根本上都差不多 - 它们都将当前范围 python-range 设定为指定的行范围,
并对其执行 Python 代码。
:python 的情况所执行的代码来自命令行。
:pyfile 的情况所执行的代码来自一个指定的文件。
Python 命令不能在 sandbox 里使用。
需要传递参数的话,你得使用 sys.argv[]。例如:
:python sys.argv = ["foo", "bar"]
:pyfile myscript.py
下面是一些例子 python-examples
:python from vim import *
:python from string import upper
:python current.line = upper(current.line)
:python print "Hello"
:python str = current.buffer[42]
(注意
如同导入 (import) 模块一样,变动对后续命令持续有效。这和 Python 的解释
程序是一样的。)
Python 的代码所有对 Vim 的操作 (只有一个例外 - 看下面的 python-output ) 都是
通过 "vim" 模块来进行的。该模块包括两个方法,三个常量,以及一个异常对象。在使
用它们之前你得先导入 (import) vim 模块。
总览
:py print "Hello" # 显示信息
:py vim.command(cmd) # 执行 Ex 命令
:py w = vim.windows[n] # 获取窗口 "n"
:py cw = vim.current.window # 获取当前窗口
:py b = vim.buffers[n] # 获取缓冲区 "n"
:py cb = vim.current.buffer # 获取当前缓冲区
:py w.height = lines # 设定窗口高度
:py w.cursor = (row, col) # 设定光标位置
:py pos = w.cursor # 获取 tuple (行,列)
:py name = b.name # 获取缓冲区的文件名
:py line = b[n] # 获取缓冲区内的一行
:py lines = b[n:m] # 获取数行
:py num = len(b) # 获取统计的行数
:py b[n] = str # 在缓冲区里写入一行文本
:py b[n:m] = [str1, str2, str3] # 一次性写入多行文本
:py del b[n] # 删除一行
:py del b[n:m] # 删除数行
"vim" 模块中的方法
vim.command(str) python-command
执行 vim (ex-模式) 命令 str。无返回值。
例如:
:py vim.command("set tw=72")
:py vim.command("%s/aaa/bbb/g")
下面的定义可以执行普通模式命令:
def normal(str):
vim.command("normal "+str)
# 注意使用单引号标识出含有双引号的字符串
normal('"a2dd"aP')
E659
":python" 在 Python 2.2 及之前版本上不能嵌套使用。下面命令只对 Python
2.3 之后版本适用:
:py vim.command("python print 'Hello again Python'")
vim.eval(str) python-eval
使用 vim 内部的表达式处理器来对表达式 str 求值。(参阅 expression )。
返回表达式的结果:
-如果 Vim 表达式计算结果是字符串或者数值,那么返回一个字符串。
-如果 Vim 表达式计算结果是 Vim 列表,那么返回一个列表
-如果 Vim 表达式计算结果是 Vim 字典,那么返回一个字典
字典和列表被递归扩展。
例:
:" 'textwidth' 选项值
:py text_width = vim.eval("&tw")
:
:" 'a' 寄存器的内容
:py a_reg = vim.eval("@a")
:
:" 结果是个字符串!使用 string.atoi() 把它转换成数值。
:py str = vim.eval("12+12")
:
:py tagList = vim.eval('taglist("eval_expr")')
后一个将返回一个 python 类型的字典列表,例如:
[{'cmd'
: '/^eval_expr(arg, nextcmd)$/', 'static'
: 0, 'name'
:
'eval_expr', 'kind'
: 'f', 'filename'
: './src/eval.c'}]
vim.bindeval(str) python-bindeval
类似于 python-eval ,但返回 python-bindeval-objects 中描述的特殊对
象。这些 python 对象可用于修改 ( List 或 Dictionary ) 或调用
( Funcref ) vim 对象。
vim.strwidth(str) python-strwidth
类似于 strwidth() : 返回 str 占据的显示单元数,制表符算作一个单元。
vim.foreach_rtp(callable) python-foreach_rtp
对 'runtimepath' 的每个路径调用给定的 callable,直到某次 callable 返回
非 None 值、抛出例外、或者没有更多的路径为止。如果因为 callable 返回
非 None 而停止,vim.foreach_rtp 函数返回 callable 返回的值。
vim.chdir(*args, **kwargs) python-chdir
vim.fchdir(*args, **kwargs) python-fchdir
运行 os.chdir 或 os.fchdir,然后做合适的 vim 的事情。
备注
: 你不应直接使用这些函数,用 os.chdir 或 os.fchdir
代替。如果 os.fchdir 不存在,则 vim.fchdir 的行为未定义。
"vim" 模块中的异常对象
vim.error python-error
当遇到 Vim 的错误时,Python 引起一个 vim.error 类的异常。
例:
try:
vim.command("put a")
except vim.error:
# nothing in register a
"vim" 模块中的常量
注意
这些其实并非真正的常量 - 你还是可以对它们赋值。但这毫无意义,因
为你会丢失该 vim 对象本来代表的值。
vim.buffers python-buffers
一个映射对象,用来提供对 vim 缓冲区的操作。该对象支持以下操作:
:py b = vim.buffers[i] # 索引 (只读)
:py b in vim.buffers # 成员测试
:py n = len(vim.buffers) # 成员个数
:py for b in vim.buffers: # 遍历缓冲区列表
vim.windows python-windows
一个序列对象,用来提供对 vim 窗口的操作。该对象支持以下操作:
:py w = vim.windows[i] # 索引 (只读)
:py w in vim.windows # 成员测试
:py n = len(vim.windows) # 成员个数
:py for w in vim.windows: # 顺序存取
注意
: vim.windows 对象总是访问当前标签页。 python-tabpage .windows 对
象和父 python-tabpage 对象绑定,总是使用该标签页的窗口 (如果该标签页
该删除,抛出 vim.error)。你可以得到两者的引用而无需保存 vim 模块对象或
python-tabpage 的引用。此时它们不会失去自己的属性。
vim.tabpages python-tabpages
一个序列对象,用来提供 vim 标签页的操作。该对象支持以下操作:
:py t = vim.tabpages[i] # 索引 (只读)
:py t in vim.tabpages # 成员测试
:py n = len(vim.tabpages) # 成员个数
:py for t in vim.tabpages: # 顺序存取
vim.current python-current
一个用来提供对各种各样当前 "current" 对象进行操作的对象。它包括一些特
定的属性:
vim.current.line 当前行 (读写) 字符串
vim.current.buffer 当前缓冲区 (读写) 缓冲区
vim.current.window 当前窗口 (读写) 窗口
vim.current.tabpage 当前标签页 (读写) 标签页
vim.current.range 当前行范围 (只读) 范围
最后一种情况需要一些额外的解释。当用 :python 或 :pyfile 命令指定一个范
围之后,该范围将成为 "当前范围"。一个范围就如同一个缓冲区,只不过所操
作的对象界限于所有行的一个子集。请参阅 python-range 。
注意
: 赋值给 vim.current.{buffer,window,tagpage}
时,分别期待合法的
python-buffer 、 python-window 或 python-tabpage 对象。赋值触发
到给定缓冲区、窗口、标签页的正常切换 (带有 autocommand 自动命令)。这
是在 python 里切换 UI 对象的唯一方法: 不能给 python-tabpage .window
属性赋值。要想进行切换但不执行自动命令,可用
py << EOF
saved_eventignore = vim.options['eventignore']
vim.options['eventignore'] = 'all'
try:
vim.current.buffer = vim.buffers[2] # 切换到缓冲区 2
finally:
vim.options['eventignore'] = saved_eventignore
EOF
vim.vars python-vars
vim.vvars python-vvars
类似字典的对象,分别对应全局 ( g: ) 和 vim ( v: ) 变量。等价于
vim.bindeval("g:")
,但更快。
vim.options python-options
部分支持映射协议 (即读写子项目) 的对象,用于对全局选项进行读写访问。
注意
: 和 :set 不同,此对象只能访问全局选项,不能用于读写局部变量的
值或以任何方式去访问只限局部的变量。如果没有指定名字的全局变量,抛出
KeyError (也即,对 global-local 或只限全局的选项,不会抛出此例外,
但对局部于窗口或局部于缓冲区的则会)。 python-buffer 对象可用于访问局
部于缓冲区的选项, python-window 选项则可用于访问局部于窗口的选项。
可通过 vim 模块的 "Options" 属性取得此对象的类型。
Python 的输出 python-output
Vim 将所有 Python 代码的输出都显示在信息区。普通的输出会以一般信息出
现,错误会以出错信息出现。
用具体实现的术语来讲,这表示所有 sys.stdout (包括 print 语句的输出) 以
一般信息形式出现,而所有 sys.stderr (包括 error tracebacks) 都会被显示
成出错信息。
python-input
Vim 并不支持用 Python 来输入 (通过 sys.stdin,包括 input() 和
raw_input())。这些调用可能会导致崩溃。这个问题可能以后会修正。
python2-directory python3-directory pythonx-directory
Python 'runtimepath' 处理 python-special-path
在 python 中,vim.VIM_SPECIAL_PATH 特殊目录用于代表 'runtimepath' 的路径列表:
如果 sys.path 包含此目录而且 sys.path_hooks 包含 vim.path_hooks,python 会试图
载入 'runtimepath' 的每个 {rtp}
对应的 {rtp}
/python2 (或 python3) 和
{rtp}
/pythonx (同时适用于两个 python 版本) 模块。
实现大致如下,但以 C 编写:
from imp import find_module, load_module
import vim
import sys
class VimModuleLoader(object):
def __init__(self, module):
self.module = module
def load_module(self, fullname, path=None):
return self.module
def _find_module(fullname, oldtail, path):
idx = oldtail.find('.')
if idx > 0:
name = oldtail[:idx]
tail = oldtail[idx+1:]
fmr = find_module(name, path)
module = load_module(fullname[:-len(oldtail)] + name, *fmr)
return _find_module(fullname, tail, module.__path__)
else:
fmr = find_module(fullname, path)
return load_module(fullname, *fmr)
# It uses vim module itself in place of VimPathFinder class: it does not
# matter for python which object has find_module function attached to as
# an attribute.
class VimPathFinder(object):
@classmethod
def find_module(cls, fullname, path=None):
try:
return VimModuleLoader(_find_module(fullname, fullname, path or vim._get_paths()))
except ImportError:
return None
@classmethod
def load_module(cls, fullname, path=None):
return _find_module(fullname, fullname, path or vim._get_paths())
def hook(path):
if path == vim.VIM_SPECIAL_PATH:
return VimPathFinder
else:
raise ImportError
sys.path_hooks.append(hook)
vim.VIM_SPECIAL_PATH python-VIM_SPECIAL_PATH
字符串常数,和 vim 路径钩联合使用。如果 vim 安装的路径钩被要求处理任何
非 vim.VIM_SPECIAL_PATH 常数的路径,抛出 ImportError。在唯一可能的另一
种情况下,使用特殊载入程序。
注意
: 不能直接使用该常数的值,必须使用 vim.VIM_SPECIAL_PATH 对象。
vim.find_module(...) python-find_module
vim.path_hook(path) python-path_hook
用于实现上述路径载入的方法或对象。除非你想对 sys.meta_path 进行处理而
可以看看 vim.path_hook,请不要直接使用它们。将来的 vim 版本不一定保证
任何这里描述的对象会继续存在。
vim._get_paths python-_get_paths
用于产生给路径钩搜索的路径列表的方法。可以用于调试,但不要假定将来的
vim 版本中此方法会继续存在。
返回 'runtimepath' 中每个 {rtp}
对应的 {rtp}
/python2 (或
{rtp}
/python3) 和 {rtp}
/pythonx 的目录列表。
缓冲区对象代表 vim 缓冲区。你可以用以下这几种办法来获取缓冲区的列表:
- 通过 vim.current.buffer ( python-current )
- 通过 vim.buffers 的索引访问 ( python-buffers )
- 通过一个窗口的 "buffer" 属性 ( python-window )
缓冲区对象有两个只读属性 - name - 缓冲区的文件全名,还有 number - 缓冲区号。
该对象还包括三个方法 (append,mark 及 range;见下)。
你也可以将缓冲区对象视为序列对象。这样的话,它们就可以被看作字符串的列表进行存
取 (它们是可变的)。每一个元素是缓冲区中的一行。所有通常的序列存取操作,包括索
引,索引赋值,切片 (slice) 及切片赋值,等等,都可以被使用。注意
索引 (切片) 操
作的结果是一个字符串 (字符串列表)。这产生了一个意想不到的结果 - b[:] 和 b 是不
同的。确切一些,"b[:] = None" 会清空整个缓冲区,而 "b = None" 仅仅更新变量 b
的值,完全不会影响到缓冲区。
缓冲区索引从 0 开始算起,这与通常的 Python 语法一致。但这和 Vim 的行号从 1 算
起有分歧。这一点在处理标记 (见下) 是要特别留意,因为标记是以行号区分的。
缓冲区对象的属性有:
b.vars 类似字典的对象,可用于访问 buffer-variable 。
b.options 映射对象 (支持子项目的读写和删除),用于访问局部于缓冲
区的选项和 global-local 选项的缓冲区局部值。如果选项
局部于窗口,请使用 python-window .options,使用此对象
会抛出 KeyError。如果选项是 global-local 而没有局部
的部分,返回 None。
b.name 字符串,可读写。包含缓冲区名 (完整路径)。
备注
: 给 b.name 赋值时激活 BufFilePre 和
BufFilePost 自动事件。
b.number 缓冲区编号。可用作 python-buffers 的键。只读。
b.valid True 或 False。如果对应的缓冲区被删除 (wipe),缓冲区对
象就成为非法。
缓冲区对象的方法有:
b.append(str) 对缓冲区附加一行
b.append(str, nr) 同上,在第 "nr" 行之后
b.append(list) 对缓冲区附加一系列行
备注
: append 方法可以带一个字符串列表作为参数,这和
Python 中内建的列表对象的对应方法是不同的。
b.append(list, nr) 同上,在第 "nr" 行之后
b.mark(name) 返回一个 tuple (行,列) 用来代表该位置上的一个命名标记
(也可以用于 []"<>
等标记)
b.range(s,e) 返回一个范围对象 (参见 python-range ) 用来代表指定缓
冲区中行 s 与 行 e (包含 s 和 e inclusive ) 之间的部
分。
注意
: 当增加一行的时候,这一行里一定不要含有换行符 '\n'。行尾的 '\n' 可以,
但会被忽略,所以下面的操作是可以的:
:py b.append(f.readlines())
可通过 vim 模块的 "Buffer" 属性取得缓冲区对象的类型。
例如 (假定 b 是当前缓冲区)
:py print b.name # 输出缓冲区的名字
:py b[0] = "hello!!!" # 替换最顶上的一行
:py b[:] = None # 删除整个缓冲区
:py del b[:] # 删除整个缓冲区
:py b[0:0] = [ "a line" ] # 在第一行前添加一行
:py del b[2] # 删除一行 (第三行)
:py b.append("bottom") # 在缓冲区结尾添加一行
:py n = len(b) # 总行数
:py (row,col) = b.mark('a') # 命名标记
:py r = b.range(1,5) # 缓冲区内的一个范围
:py b.vars["foo"] = "bar" # 给 b:foo 变量赋值
:py b.options["ff"] = "dos" # 设置 fileformat
:py del b.options["ar"] # 同 :set autoread<
范围对象代表一个 vim 缓冲区内的一个部分。你可以用以下的方法之一来获取一个缓冲
区对象:
- 通过 vim.current.range ( python-current )
- 通过一个缓冲区的 range() 方法 ( python-buffer )
一个范围对象在操作上几乎和一个缓冲区对象完全一样。不过,其操作的目标仅显于范围
指定的行 (当然,这个行范围会随着切片赋值,行删除,或者 range.append() 等等操作
而改变)。
范围对象的属性有:
r.start 首行在缓冲区内的索引
r.end 尾行在缓冲区内的索引
范围对象的方法有:
r.append(str) 给范围附加一行
r.append(str, nr) 同上,在第 "nr" 行之后
r.append(list) 给范围附加一系列行
备注
: append 方法可以带一个字符串列表作为参数,这和
Python 中内建的列表对象的对应方法是不同的。
r.append(list, nr) 同上,在第 "nr" 行之后
可通过 vim 模块的 "Range" 属性取得范围对象的类型。
例如 (假设 r 是当前范围):
# 发送范围内的所有行给缺省打印机
vim.command("%d,%dhardcopy!" % (r.start+1,r.end+1))
窗口对象代表一个 vim 窗口。你可以用以下几种方法来获取一个窗口对象:
- 通过 vim.current.window ( python-current )
- 通过对 vim.windows 的索引操作 ( python-windows )
- 通过对标签页的 "windows" 属性的索引操作 ( python-tabpage )
- 通过标签页的 "window" 属性 ( python-tabpage )
你只能通过窗口对象的属性来控制它。这些对象没有方法,也没有序列等其它接口。
窗口的属性包括:
buffer (只读) 窗口中显示的缓冲区
cursor (读写) 窗口中的当前光标位置
这是一个 tuple (行,列)。
height (读写) 行数表示的窗口高度
width (读写) 列数表示的窗口宽度
vars (只读) 窗口 w: 变量。不能给本属性赋值,但可以用此属
性修改窗口变量
options (只读) 局部于窗口的选项。不能给本属性赋值,但可以用此
属性修改窗口选项。只能用于访问局部于窗口的选
项,对局部于缓冲区的选项要用 python-buffer ,
对全局选项用 python-options 。如果选项是
global-local 的而没有局部值,返回 None。
number (只读) 窗口编号。首个窗口的编号为 1。如果不能决定才
会返回 0 (例如当窗口对象属于其他标签页时)。
row、col (只读) 窗口在屏幕上的位置,以显示单元计。首个位置为
零。
tabpage (只读) 窗口的标签页。
valid (读写) True 或 False。当对应窗口关闭时窗口对象成为非
法。
height 属性只有当屏幕被水平分割时才可写。
width 属性只有当屏幕被垂直分割时才可写。
可通过 vim 模块的 "Window" 属性取得窗口对象的类型。
标签页对象代表一个 vim 标签页。你可以用以下几种方法来获取之:
- 通过 vim.current.tabpage ( python-current )
- 通过对 vim.tabpages 的索引操作 ( python-tabpages )
你可以通过该对象来访问标签页里的窗口。这些对象没有方法,也没有序列等其它接口。
标签页的属性包括:
number 标签页编号,和 tabpagenr() 相同。
windows 类似于 python-windows ,但对应当前标签页
vars 标签页 t: 变量。
valid True 或 False。当对应标签页关闭时标签页对象成为非法。
可通过 vim 模块的 "TabPage" 属性取得标签页对象的类型。
vim.Dictionary 对象 python-Dictionary
类字典对象,用于访问 vim Dictionary 类型。
属性:
属性 描述
locked 以下值之一 python-.locked
值 描述
zero 变量没有上锁
vim.VAR_LOCKED 变量已上锁,但可以解锁
vim.VAR_FIXED 变量已上锁,且不可以解锁
读写。可以通过给本属性赋值 True
或 False
来给变量解锁。
不支持递归上锁。
scope 以下值之一
值 描述
zero 字典无作用域
vim.VAR_DEF_SCOPE g: 或 l: 字典
vim.VAR_SCOPE 其他作用域的字典,
见 internal-variables
方法 (备注
: 方法不支持关键字参数):
方法 描述
keys() 返回字典所有键的列表。
values() 返回字典所有值的列表。
items() 返回字典所有内容的二元组的列表。
update(iterable)、update(dictionary)、update(**kwargs)
把新的键值加入字典。
get(key[, default=None])
从字典读入 key 对应值,如果不存在返回 default。
pop(key[, default])
从字典中删除给定 key 并返回对应值。如果找不到 key 且给出
default 返回 default,不然抛出 KeyErrror。
popitem()
从字典中删除随机键,并返回 (键, 值) 对。
has_key(key)
检查字典中是否包含给定的键 key,类似于 `key in dict`。
__new__(), __new__(iterable), __new__(dictionary), __new__(update)
用 vim.Dictionary()
可以建立新的 vim 字典。
d=vim.Dictionary(arg)
等价于
d=vim.bindeval('{}
');d.update(arg)
。无参数的版本构建空
字典。
示例:
d = vim.Dictionary(food="bar") # 构造函数
d['a'] = 'b' # 子项目赋值
print d['a'] # 读取子项目
d.update({'c': 'd'}) # .update(dictionary)
d.update(e='f') # .update(**kwargs)
d.update((('g', 'h'), ('i', 'j'))) # .update(iterable)
for key in d.keys(): # .keys()
for val in d.values(): # .values()
for key, val in d.items(): # .items()
print isinstance(d, vim.Dictionary) # True
for key in d: # 遍历所有键
class Dict(vim.Dictionary): # 子类
注意
: 遍历键时不应对字典进行修改。
vim.List 对象 python-List
类序列对象,用于访问 vim List 类型。
支持 .locked
属性,见 python-.locked 。还支持以下方法:
方法 描述
extend(item) 给列表加入项目 item。
__new__(), __new__(iterable)
用 vim.List()
可以建立新的 vim 列表。
l=vim.List(iterable)
等价于
l=vim.bindeval('[]');l.extend(iterable)
。无参数的版
本方法构建空列表。
示例:
l = vim.List("abc") # 构造函数,返回: ['a', 'b', 'c']
l.extend(['abc', 'def']) # .extend() 方法
print l[1:] # 分片 (slicing)
l[:0] = ['ghi', 'jkl'] # 分片赋值
print l[0] # 读取项目
l[0] = 'mno' # 赋值
for i in l: # 遍历
print isinstance(l, vim.List) # True
class List(vim.List): # 子类
vim.Function 对象 python-Function
类函数对象,相当于 vim Funcref 对象。接受特殊关键字参数 self ,见
Dictionary-function 。也可用 vim.Function(name)
构造函数,等价于
vim.bindeval('function(%s)'%json.dumps(name))
。
属性 (只读):
属性 描述
name 函数名。
args None 或用作参数的 python-List 对象。注意
这是参数列表
的备份,每次请求参属性时都会重新构建。列表的修改被忽略 (
但不适用于参数列表里的容器: 类似于 copy() 而不是
deepcopy() )。
self None 或用作 self 字典的 python-Dictionary 对象。注意
调用函数对象时显式的 self 参数覆盖此属性。
auto_rebind 布尔值。如果为真,此 Python 对象建立和在 Vim 脚本里存贮的
字典里的的偏函数会在此字典被访问时自动重新绑定此字典。这
体现了 Vim 内部 dict.func
(auto_rebind=True) 和
function(dict.func,dict)
(auto_rebind=False) 的差异。
如果 self 属性为 None ,此属性无意义。
构造函数额外接受 args
、 self 和 auto_rebind
关键字。如果给出 args
和/或 self 参数,构造偏函数,见 function() 。只有给定 self 时才使用
auto_rebind
,否则无论是否给出,总是假定为 True
。如果给出 self ,缺省
为 False
。
示例:
f = vim.Function('tr') # 构造函数
print f('abc', 'a', 'b') # 调用 tr('abc', 'a', 'b')
vim.command('''
function DictFun() dict
return self
endfunction
''')
f = vim.bindeval('function("DictFun")')
print f(self={}) # 相当于
# call('DictFun', [], {})
print isinstance(f, vim.Function) # True
p = vim.Function('DictFun', self={})
print f()
p = vim.Function('tr', args=['abc', 'a'])
print f('b')
MS-Windows 和 Unix 上,可以动态调入 Python 库。 :version 输出这时应包括
+python/dyn 或 +python3/dyn 。
这意味着 Vim 只有在必要时才寻找 Python DLL 文件或共享库。如果不使用 Python 接
口,你就不需要它。这样,即使没有该文件,你也可使用 Vim。
MS-Windows
要使用 Python 接口,Python DLL 必须在搜索路径上。控制台窗口里输入 "path" 可以
看到 (搜索路径) 当前使用的目录。也可用 'pythondll' 或 'pythonthreedll' 选项来
指定 Python DLL。
DLL 的名字应该匹配 Vim 编译时所使用的 Python 版本。目前,用于 Python 2 的名字
为 "python27.dll",也就是 Python 2.7。用于 Python 3 的是 python36.dll (Python
3.6)。要确信这一点,编辑 "gvim.exe" 文件并查找 "python\d*.dll\c"。
Unix
'pythondll' 或 'pythonthreedll' 选项可用来指定 Python 共享库文件,而不用编译时
指定的 DYNAMIC_PYTHON_DLL 或 DYNAMIC_PYTHON3_DLL 文件。共享库的版本必须和 Vim
编译使用的 Python 2.x 或 Python 3 版本保持一致。
:py3 :python3
:[range]
py3 {stmt}
:[range]
py3 << [trim]
[{endmarker}
]
{script}
{endmarker}
:[range]
python3 {stmt}
:[range]
python3 << [trim]
[{endmarker}
]
{script}
{endmarker}
:py3 和 :python3 命令和 :python 类似。判断 :py3 命令是否可用的
一个简单检查:
:py3 print("Hello")
要看运行的 Python 版本:
:py3 import sys
:py3 print(sys.version)
:py3file
:[range]
py3f[ile] {file}
:py3file 命令和 :pyfile 类似。
:py3do
:[range]
py3do {body}
:py3do 命令和 :pydo 类似。
Vim 可以用四种方式编译 (:version 输出结果):
1. 无 Python 支持 (-python、-python3)
2. 只有 Python 2 支持 (+python 或 +python/dyn、-python3)
3. 只有 Python 3 支持 (-python、+python3 或 +python3/dyn)
4. Python 2 和 3 支持 (+python/dyn、+python3/dyn)
关于第四种特殊情况的更多细节: python-2-and-3
要同时支持 Python 2 和 Python 3,两者必须都是动态载入。
在 Linux/Unix 系统上用这种方式并导入全局符号的时候,使用第二个 Python 版本会导
致系统崩溃。所以,要么载入全局符号但只激活一个 Python 版本,要么考虑不载入全局
符号。后者使 Python 导入 ("import") 某些期待 Vim 提供某些符号的库的时候会失
败。
E836 E837
Vim 的配置脚本根据一个特定的 Python 标准库 (termios) 对所有的库进行猜测。如果
对两个 Python 版本导入该库均成功,那么可以在 Vim 中同时使用两者。否则在一个会
话中,只允许使用先用到的版本。使用第二个版本会得到 E836 或 E837 的错误信息。
这里 Vim 的行为取决于配置所在的系统。如果两个 Python 版本都用了
--enable-shared 进行配置,两者会同时激活。但没有链接进 libPython 的第三方库仍
然会有问题。
要回避这些问题,有以下几个方案:
1. 重新编译有问题的库,把它链接进相应的 libpython.so 里。
2. 重新编译 Vim,只用一个 Python 版本。
3. 配置完后,撤销 auto/config.h 中 PY_NO_RTLD_GLOBAL 的定义。这可能会使 Vim 崩
溃。
E880
从 python 抛出 SystemExit 例外不是退出 vim 的好方法,要用:
:py vim.command("qall!")
E1266
Python 3 不能载入必需的模块时出现此错误。这意味着没有正确安装 Python 3,或者设
置有问题。请检查以下项目:
1. 确证正确安装了 Python 3。然后检查 python 版本。
2. 检查 'pythonthreedll' 选项。
3. 检查 'pythonthreehome' 选项。
4. 如果没设置过 'pythonthreedll',检查 PATH 环境变量。
MS-Windows 上,可用 where.exe 来查找载入了哪个 dll。例如
where.exe python310.dll
5. 检查 PYTHONPATH 和 PYTHONHOME 环境变量。
has-python
以下方法可用来测试哪个 Python 版本可用:
if has('python')
echo '有 Python 2.x'
endif
if has('python3')
echo '有 Python 3.x'
endif
注意
不过,当 Python 2 和 3 同时存在且都是动态载入,这些 has() 调用会试图载入
它们。如果两个版本不能同时载入,单单对 Python 2 或 3 是否可用的检查就会导致另
一个版本不能调入。
要避免载入动态库,只需要检查 Vim 编译时是否有 python 支持:
if has('python_compiled')
echo '编译时带 Python 2.x 支持'
if has('python_dynamic')
echo 'Python 2.x 已动态载入'
endif
endif
if has('python3_compiled')
echo '编译时带 Python 3.x 支持'
if has('python3_dynamic')
echo 'Python 3.x 已动态载入'
endif
endif
这段代码也会告诉你 Python 是否已动态载入,如果找不到运行库时会报错。
编译时带 Python 2 或 3 支持的若干提示。
UNIX
关于如何打开 Python 接口的支持,见 src/Makefile。
Ubuntu 上需要为 Python 2 安装以下包:
python
python-dev
Python 3:
python3
python3-dev
Python 3.6:
python3.6
python3.6-dev
如果有多于一个 Python 3 版本,在运行 configure 前链接 python3 到你选择的那
个版本。
vim:tw=78:ts=8:noet:ft=help:norl: