Python在输入原始输入时为光标移动添加钩子/回调?

2024-04-29 09:43:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试编写一个交互式解释器的版本,它具有语法高亮显示功能。在

以下是我目前为止运行得相当好的部分(使用祝福pygments模块)。。。在

import code
import readline
import threading
import blessings
from pygments import highlight
from pygments.formatters import TerminalFormatter
from pygments.lexers import PythonLexer

def check_line():
    global current_line
    try:
        while True:
            line = readline.get_line_buffer()
            if line != current_line:
                current_line = line
                do_colour()
    except:
        pass

def do_colour():
    global terminal

    raw_line = readline.get_line_buffer()
    line = highlight(raw_line, lexer, formatter)[:-1]

    with terminal.location(x = 4):
        print line,

    readline.redisplay()

current_line = ''
terminal = blessings.Terminal()
lexer = PythonLexer()
formatter = TerminalFormatter()
console = code.InteractiveConsole()

colour_thread = threading.Thread(target=check_line)
colour_thread.setDaemon(True)
colour_thread.start()

console.interact('')

当你打字的时候,它会给线条着色。。。在

Syntax highlighting in interactive prompt

问题是:

  1. 这使用一个单独的线程来忙着检查行中的更改(认为这可能使用了整个内核)
  2. 如果您将光标移回一行,然后将其移回右侧,终端将重新绘制刚刚未选定的字符,并以白色重新绘制

我真正想要的是当光标移动或行缓冲区改变时的回调/钩子-这两种情况都有可能吗?我是否可以将stdin置于逐字节模式,然后以某种方式将字节传递给原始输入的内部缓冲版本,同时触发回调吗?在

另外,它目前还不处理多行字符串("""like this"""),但这不是一个非常困难的修复。在


编辑:

好吧,我已经到了,这是最新的代码。。。在

^{pr2}$

我要找的是PyOS_InputHook,它叫做

  1. 每次按键时
  2. 每0.1秒

所以这意味着我可以抛弃繁忙的监视线程,也就是说我不用(几乎)任何CPU。在

最后一个问题是,在输入从stdin读取之前(对于可打印字符),在输入被附加到行缓冲区之前,输入钩子被立即调用。结果是给最近的字符着色有0.1秒的延迟。在

我用一种有点老套的方法解决了这个问题,在0.001秒的延迟下在一个线程中绘制。在


Tags: fromimport版本readlinepygmentsline绘制code