如何在Python脚本中实现类似Git Commit的Vim输入功能(禁用input/stdin)
如何在Python中实现类似Git Commit的Vim弹窗输入功能
当然可以!这种通过终端编辑器弹窗获取输入的方式,其实和Git的实现思路完全一致——借助系统默认编辑器处理输入,完美绕开input()或者标准stdin。下面是具体的实现步骤和完整代码:
核心思路
我们会创建一个临时文件,调用用户指定的终端编辑器(优先用环境变量EDITOR,默认 fallback 到Vim)让用户编辑内容,等用户保存退出后,再读取临时文件的内容作为最终输入。
步骤1:准备依赖模块
只需要用到Python标准库中的tempfile(安全创建临时文件)和subprocess(调用外部编辑器),不需要额外安装第三方包。
步骤2:完整实现代码
import os import tempfile import subprocess def get_editor_input(prompt_message=None): # 优先使用用户环境变量指定的编辑器,默认用vim editor = os.environ.get('EDITOR', 'vim') # 创建临时文件,后缀设为.txt方便编辑器识别格式 with tempfile.NamedTemporaryFile(mode='w+', suffix='.txt', delete=False, encoding='utf-8') as temp_file: # 如果需要引导提示,可以先把内容写入临时文件 if prompt_message: temp_file.write(f"{prompt_message}\n") # 写完后把文件指针移到开头,避免编辑器打开时直接跳到末尾 temp_file.seek(0) temp_filename = temp_file.name try: # 调用编辑器打开临时文件,等待用户编辑完成 subprocess.run([editor, temp_filename], check=True) # 读取用户编辑后的内容,自动去除首尾空白 with open(temp_filename, 'r', encoding='utf-8') as f: user_input = f.read().strip() return user_input finally: # 不管成功失败,最后都删除临时文件,避免残留 os.unlink(temp_filename) # 测试使用 if __name__ == "__main__": commit_msg = get_editor_input(prompt_message="# 请输入提交信息,开头带#的行是注释会被忽略\n") print("\n你输入的提交信息是:") print(commit_msg)
代码细节说明
- 编辑器兼容:和Git逻辑一致,优先读取用户设置的
EDITOR环境变量(比如你习惯用nano或emacs也能直接用),没有的话默认用Vim。 - 临时文件安全:
NamedTemporaryFile创建的文件不会和其他进程冲突,最后通过finally块确保文件被删除,不会留下垃圾文件。 - 提示引导:可以预先写入提示内容(比如Git的提交模板风格),用户打开编辑器就能看到清晰的输入指引。
- 异常处理:
subprocess.run的check=True会在编辑器调用失败时抛出异常,你可以根据需求添加更细致的错误捕获逻辑。
使用体验
运行脚本后,终端会自动打开你指定的编辑器,编辑完成保存退出后,脚本就会读取到你输入的内容,完全复刻Git Commit的交互感。
内容的提问来源于stack exchange,提问作者Christian Pålbøl Jacobsen




