You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Prompt toolkit实现按CTRL+E保存的多行终端文本编辑器

问题原因

你的代码存在三个核心问题:

  1. new_content 是 session.prompt() 执行结束后的返回值,按下CTRL+E触发回调时,prompt 方法还处于阻塞运行状态,new_content 仍为初始的None,写入操作自然无法生效。
  2. 文件操作未做异常处理,也没有正确关闭句柄,首次运行如果目标文件不存在会直接报错,写入后也可能因为缓冲区没刷新导致内容未正确落盘。
  3. 底部工具栏的HTML标签做了多余的转义,实际运行时会显示原始字符而非预期的样式。

修复后完整代码

from prompt_toolkit import PromptSession
from prompt_toolkit.lexers import PygmentsLexer
from pygments.lexers.python import PythonLexer
from prompt_toolkit.formatted_text import HTML
from prompt_toolkit.key_binding import KeyBindings

file_path = 'output.txt'
# 读取文件,不存在则默认内容为空
try:
    with open(file_path, 'r', encoding='utf-8') as f:
        content = f.read()
except FileNotFoundError:
    content = ""

session = PromptSession()
bindings = KeyBindings()    

@bindings.add('c-e')
def _(event):
    # 直接从当前缓冲区获取最新内容,无需等prompt返回
    current_content = event.app.current_buffer.text
    # 用上下文管理器自动处理文件关闭和缓冲刷新
    with open(file_path, 'w', encoding='utf-8') as f:
        f.write(current_content)
    # 退出程序
    event.app.exit()

def show_prompt():
    # 修正HTML转义问题,更新提示文案
    bottom_toolbar = HTML('<b><style background-color="white" color="green">按 CTRL+E 保存并退出</style></b>') 
    lexer = PygmentsLexer(PythonLexer)
    session.prompt('\n', 
                   default=content, 
                   lexer=lexer,
                   multiline=True,
                   bottom_toolbar=bottom_toolbar,
                   key_bindings=bindings)

if __name__ == '__main__':
    show_prompt()

调整说明

  • 快捷键回调中直接从输入缓冲区读取实时内容,解决了原代码拿不到编辑后内容的问题
  • 增加文件不存在的异常兼容,所有文件操作都用with上下文管理器自动处理资源释放,保证内容正确写入磁盘
  • 修正了底部工具栏的HTML转义错误,更新提示文案更符合功能逻辑
  • 移除了无用的全局变量,减少逻辑冗余

内容的提问来源于stack exchange,提问作者SomeName

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 06:21:02