*if_pyth.txt*   For Vim version 7.3.  最近更新：2010年8月


		  VIM REFERENCE MANUAL    by Paul Moore
		  译者: lang2，Willis http://vimcdoc.sf.net


Vim 的 Python 编程接口					*python* *Python*

1. 命令				|python-commands|
2. vim 模块			|python-vim|
3. 缓冲区对象			|python-buffer|
4. 范围对象			|python-range|
5. 窗口对象			|python-window|
6. 动态调入			|python-dynamic|
7. Python 3			|python3|

{Vi 无此功能}

Vim 的 Python 2.x 接口仅当 |+python| 特性被编译进 Vim 时才有效。
Vim 的 Python 3 接口仅当 |+python3| 特性被编译进 Vim 时才有效。

==============================================================================
1. 命令							*python-commands*

					*:python* *:py* *E205* *E263* *E264*
:[range]py[thon] {stmt}
			执行 Python 语句 {stmt}。

:[range]py[thon] << {endmarker}
{script}
{endmarker}
			执行 Python 脚本 {script}。
			备注: 此命令在没有编译进 Python 特性时无效。为了避免这
			样的错误，参阅 |script-here|。

{endmarker} 前面_不能_有任何空白字符。如果在 "<<" 之后省略了 {endmarker}，在
{script} 之后一定要有一个点 '.'。这和 |:append| 及 |:insert| 命令的道理是一样
的。这种形式的 |:python| 命令主要用于在 Vim 脚本中嵌入 Python 代码。

例子: >
	function! IcecreamInitialize()
	python << EOF
	class StrawberryIcecream:
		def __call__(self):
			print 'EAT ME'
	EOF
	endfunction
<
备注: Python 对于缩进是非常敏感的。要确保 "class" 所在行及 "EOF" 没有任何缩
进。

							*:pyfile* *:pyf*
:[range]pyf[ile] {file}	
			执行 {file} 文件中包含的 Python 脚本。整个参数被用作一
			个文件名。 {Vi 无此功能}

这些命令根本上都差不多 － 它们都将当前范围 |python-range| 设定为指定的行范围，
并对其执行 Python 代码。

:python 的情况所执行的代码来自命令行。
:pyfile 的情况所执行的代码来自一个指定的文件。

Python 命令不能在 |sandbox| 里使用。

需要传递参数的话，你得使用 sys.argv[]。例如： >

	:python import sys
	: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 的解释
程序是一样的。)

==============================================================================
2. vim 模块						*python-vim*

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 字典，那么返回一个字典
	字典和列表被递归扩展。
	例: >
	    :py text_width = vim.eval("&tw")
	    :py str = vim.eval("12+12")		# 注意：结果是个字符串！
						# 使用 string.atoi()
						# 把它转换成数字

	    :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" 模块中的异常对象

	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.current						*python-current*
	一个用来提供对各种各样当前 "current" 对象进行操作的对象。它包括一些特
	定的属性:
		vim.current.line	当前行 (读写)			字符串
		vim.current.buffer	当前缓冲区 (只读)		缓冲区
		vim.current.window	当前窗口 (只读)			窗口
		vim.current.range	当前行范围 (只读)		范围

	最后一种情况需要一些额外的解释。当用 :python 或 :pyfile 命令指定一个范
	围之后，该范围将成为 "当前范围"。一个范围就如同一个缓冲区，只不过所操
	作的对象界限于所有行的一个子集。请参阅 |python-range|。


Python 的输出						*python-output*
	Vim 将所有 Python 代码的输出都显示在信息区。普通的输出会以一般信息出
	现，错误会以出错信息出现。

	用具体实现的术语来讲，这表示所有 sys.stdout (包括 print 语句的输出) 以
	一般信息形式出现，而所有 sys.stderr (包括 error tracebacks) 都会被显示
	成出错信息。

							*python-input*
	Vim 并不支持用 Python 来输入 (通过 sys.stdin，包括 input() 和
	raw_input())。这些调用可能会导致崩溃。这个问题可能以后会修正。

==============================================================================
3. 缓冲区对象						*python-buffer*

缓冲区对象代表 vim 缓冲区。你可以用以下这几种办法来获取缓冲区的列表:
	- 通过 vim.current.buffer (|python-current|)
	- 通过 vim.buffers 的索引访问 (|python-buffers|)
	- 通过一个窗口的 "buffer" 属性 (|python-window|)

缓冲区对象只有一个只读属性 - name - 缓冲区的文件全名。该对象还包括三个方法
(append，mark 及 range；见下)。

你也可以将缓冲区对象视为序列对象。这样的话，它们就可以被看作字符串的列表进行存
取 (它们是可变的)。每一个元素是缓冲区中的一行。所有通常的序列存取操作，包括索
引，索引赋值，切片 (slice) 及切片赋值，等等，都可以被使用。注意 索引 (切片) 操
作的结果是一个字符串 (字符串列表)。这产生了一个意想不到的结果 - b[:] 和 b 是不
同的。确切一些，"b[:] = None" 会清空整个缓冲区，而 "b = None" 仅仅更新变量 b 
的值，完全不会影响到缓冲区。

缓冲区索引从 0 开始算起，这与通常的 Python 语法一致。但这和 Vim 的行号从 1 算
起有分歧。这一点在处理标记 (见下) 是要特别留意，因为标记是以行号区分的。

缓冲区对象的方法有:
	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())

例如 (假定 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)		# 缓冲区内的一个范围

==============================================================================
4. 范围对象						*python-range*

范围对象代表一个 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" 行之后

例如 (假设 r 是当前范围):
	# 发送范围内的所有行给缺省打印机
	vim.command("%d,%dhardcopy!" % (r.start+1,r.end+1))

==============================================================================
5. 窗口对象						*python-window*

窗口对象代表一个 vim 窗口。你可以用以下几种方法来获取一个窗口对象:
	- 通过 vim.current.window (|python-current|)
	- 通过对 vim.windows 的索引操作 (|python-windows|)

你只能通过窗口对象的属性来控制它。这些对象没有方法，也没有序列等其它接口。

窗口的属性包括:
	buffer (只读)		窗口中显示的缓冲区
	cursor (读写)		窗口中的当前光标位置
				这是一个 tuple (行，列)。
	height (读写)		行数表示的窗口高度
	width (读写)		列数表示的窗口宽度
height 属性只有当屏幕被水平分割时才可写。
width  属性只有当屏幕被垂直分割时才可写。

==============================================================================
6. 动态调入						*python-dynamic*

MS-Windows 上，可以动态调入 Python 库。|:version| 输出这时应包括
|+python/dyn|。

这意味着 Vim 只有在必要时才寻找 Python DLL 文件。如果不使用 Python 接口，你就
不需要它。这样，即使没有该 DLL 文件，你也可使用 Vim。

要使用 Python 接口，Python DLL 必须在搜索路径上。控制台窗口里输入 "path" 可以
看到 (搜索路径) 当前使用的目录。

DLL 的名字必须匹配 Vim 编译时所使用的 Python 版本。目前，该名字为
"python24.dll"，也就是 Python 2.4。要确信这一点，编辑 "gvim.exe" 文件并查找
"python\d*.dll\c"。

==============================================================================
7. Python 3						*python3*

							*:py3* *:python3*
|:py3| 和 |:python3| 命令和 |:python| 类似。
							*:py3file*
|:py3file| 命令和 |:pyfile| 类似。

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 和 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 崩
   溃。


==============================================================================
 vim:tw=78:ts=8:ft=help:norl:
