有些的Python的直译器版本有支援目前所在行的编辑,以及过去输入内容的代换,这跟在Korn Shell以及GNU Bash shell里面的一些功能有点像。这个功能是用 GNU Readline 的程式库做出来的,提供了类似Emacs以及类似vi的编辑功能。这个程式库本身有自己的参考文件,所以我在此不再重复,我只是简单的介绍基本的功能。这里所介绍的互动模式输入编辑及代换过去内容的功能通常在Unix以及CygWin的直译器版本都可以见得到。
本章 没有 包含在Mark Hammond的PythonWin package里的编辑功能,也没有包含在标准Python distribution里面的Tk之类的环境,或是IDLE的编辑功能。在DOS以及NT及其他类似的环境下,也有命令列过去内容记忆的功能,但是也不在本文的内容之中。
如果有支援整行编辑的话,当直译器印出primary prompt或是secondary prompt的时候,整行编辑的功能就会被启动起来。你可以用一般的Emacs控制字元来编辑目前所在的行。其中常见的有这些: C-A (Control-A)会移动cursor到目前行的最开头的地方, C-E 会移动到最尾端, C-B 会往左移动一个位置, C-F 会往右边一个位置。Backspace键会消去目前cursor所在处左边的一个字元, C-D 会消去右边的一个字元, C-K 会杀掉 (消去)本行在游标之后的所有字元, C-Y 会把刚刚所杀掉的字串再次贴回来, C-underscore 会取消刚才所做的最后一个动作,这个功能也可以重复多次的使用。
要取代过去的内容其方法如下:所有的非空白行都会被储存在一个储存过去内容的缓冲区(history buffer)里面,当prompt出现的时候,你所在的位置就是在这个buffer的最底下,使用 C-P 会使得在buffer里面往上移动一行, C-N 会往下移动一行。任何在buffer里面的行都可以被编辑,若是在prompt之前出现星号的话就代表这个行已经被修改过了。当你按下 Return 键的时候就是把目前这一行送给直译器了。 C-R 会开始一个逐渐往上的搜寻,按下 C-S 会开始往前的搜寻。
键盘的连结以及一些其他有关Readline library的参数都可以被修改,其方法是在一个叫做 ~/.inputrc 的初始化档案中打入一些指令。键盘的连结有以下的几种形式:
key-name: function-name
或是
"string": function-name
你也可以设定一些选项:
set option-name value
请看下面的例子:
# I prefer vi-style editing:
set editing-mode vi
# Edit using a single line:
set horizontal-scroll-mode On
# Rebind some keys:
Meta-h: backward-kill-word
"\C-u": universal-argument
"\C-x\C-r": re-read-init-file
注意的是在Python里面预设的 Tab 键所连结的是输入一个 Tab 字元,而非Readline 程式库里面预设的档名自动完成的功能。如果你坚持的话,你也可以这样子设定来盖过Python的预设:
Tab: complete
这应该在你的 ~/.inputrc 里面。(当然如果你这样做的话,你在缩排连续行的时候就费力一些了。)
自动完成变数及module的名称的功能是可以自由选择要或不要的。如果你要在互动模式下启动这一个功能的话,可以在启动档里面加入底下的指令: A.1
import rlcompleter, readline
readline.parse_and_bind('tab: complete')
这样做的话会使TAB 键连结到完成的功能,所以按下TAB键两次就会建议一些完整的名称。其所搜寻的是Python的叙述名称,目前的local变数,以及可用的module名称。对于像
string.a
这样带有点的expression,这项功能会先是着先evaluate到最后一个点的意思,然后再从所得的物件中建议可用的变数名称。注意的是,如果这个物件含有的
__getattr__() 这个method是这个expression的一部份的话,就会执行一些特定的程式码。
这个功能跟其他之前的直译器版本比起来是很大的一个进步,但是我们还有很多希望有的功能。如果在连续行的时候可以建议适当的缩排距离(分析器(parser)应该知道何时需要缩排)。自动完成的功能应该也能够使用直译器的symbol table。应该也要有一个指令可以检查(甚至是建议)何时应该要有结束的括弧,括号等等。