AIGC 工具 ChatGPT 遇上老牌的文本编辑器 Vim,二者会擦出什么样的火花。本文作者 Lachlan Gray 动手尝试了一下,得到了自动化的意外之喜,不妨一起来看下。
原文:https://lachlan-gray.com/Controlling+Vim+With+ChatGPT
未经允许,禁止转载。
作者 | Lachlan Gray
翻译工具 | ChatGPT 责编 | 苏宓
出品 | CSDN(ID:CSDNnews)
以下为译文:
Vim 是一款基于文本的文本编辑器。作为使用者,你可以从 Vim 中获取的每一项信息都以文本形式表示,你发送给它的每一项信息也都是文本。同样,我们也主要通过文本信息去使用时下流行的 ChatGPT。对于这两款工具而言,都是用文本的形式去使用,那我们是否可以去掉中间的环节,譬如,直接使用 ChatGPT 来控制 Vim?
可在此处获取代码:https://github.com/LachlanGray/vim-agent
天作之合
Vim 非常奇特,它的设计使得你知道如何使用该编辑器,也就意味着你知道如何使用编辑器实现自动化。简而言之,你与编辑器的每一次交互都可以转化为一个 Vim 程序。任何涉及键入、更改、删除、编辑命令、Shell 命令、打开文件等任意组合的操作序列都可以由一个程序完成。这对人类是否有利还有待商榷,但如果你将其和一个语言模型结合起来,那么这个功能就无价了。
Vim 已经存在很长时间了,互联网上充斥着用于完成各种乏味任务的 Vim。Vim 基本上是一种专门用于操作文本的领域特定编程语言。由于它的年代久远和僵化而受到一些批评,但它在其应该做的事情上表现出色。对我们来说,这意味着 ChatGPT 和它搭档将会非常顺利,理论上可以做我能做的一切与编辑器相关的事情。
Neovim API
ChatGPT 将如何实际控制编辑器呢?方便的是,Neovim 拥有一个 Python 客户端(https://pynvim.readthedocs.io/en/latest/),允许你通过 Python API 来控制编辑器。这非常方便。
首先,你可以通过以下方式启动 Neovim 并设置一个监听地址:
1nvim--listen127.0.0.1:7777
这将启动一个常规的 Neovim 实例,但它将监听连接。现在,通过 Python API,我们可以告诉 Neovim 执行操作。Python API 使用 TCP(传输控制协议)连接到 Neovim,这是一种网络协议,旨在确保数据被完整接收,并按照发送的顺序到达。我们创建一个 vim 对象来管理 Neovim 的状态:
1vim= attach('tcp', address='127.0.0.1', port=7777)
该 vim 对象为我们提供了对 Neovim 的完全访问权限,其中包括对编辑器状态和功能的编程访问。在众多便捷包装器中,它提供了 vim.request,这是一个全能工具,可以与 API 文档中的所有内容一起使用(https://neovim.io/doc/user/api.html)。它使我们可以做几乎任何事情,例如运行一个命令:
1vim.request('nvim_command', "q!")
以下是我们的计划:封装我们关心的所有功能,并简化它们,以便能够轻松地与语言模型进行交互。我们将称这个包装器为 VimInstance,它将包含 vim 对象,并具有简单的属性来访问信息,以及控制 Vim 实例的方法:
1classVimInstance:
2def__init__(self):
3self.vim = attach('tcp', address='127.0.0.1', port=7777)
4
5@property
6defcurrent_buffer_content(self):
7returnself.vim.request(
8'nvim_buf_get_lines',
9self.vim.current.buffer,
100, -1, True)
11
12# ...
13
14definput(self, keys):
15self.vim.input(keys)
16
17# ...
然后我们可以做类似的事情:
1vim = VimInstance
2
3# list containing each line of current file
4text = vim.current_buffer_content
5
6# type "hello" at the start of the file and save
7vim.input("ggIhello<Esc>:w<CR>")
给我代码!
生活中的一个极大的确定性是 ChatGPT 会告诉你它正在做什么。而且通常情况下,即使你不要求,它也会说一些。我们肯定会立刻遇到这个问题。与其哄着模型,不如只是等待代码出现,然后在代码完成时挂断连接可能更容易。
OpenAI 的聊天完成端点的流式传输功能对此很有用。它允许我们在文本块到达时监视它们,并实时决定如何处理。我们可以通过产生类似这样的文本块来迭代处理到达的完成结果:
1importopenai
2
3defchat_3(messages: list[dict]):
4completion = openai.ChatCompletion.create(
5model = "gpt-3.5-turbo",
6messages = messages,
7temperature = 0.9,
8stream=True
9)
10forchunk incompletion:
11if"content"inchunk.choices[0].delta:
12yieldchunk.choices[0].delta["content"]
现在我们可以在不等待模型完成的情况下处理模型的响应:
1deffiltered_chat(request: str):
2messages = [{"role":"user"}, {"content": request}]
3forchunk inchat_3(messages):
4if<condition>:
5yieldchunk
要收集代码,我们可以在响应滚动到达时进行监视,并等待开头的代码块模式(```.*?(\n.*)))出现。一旦匹配成功,我们就知道是时候开始监听了。然后我们可以继续监听,直到遇到更多的反引号。如果一切顺利,我们应该只有代码。
GPT 接管控制
现在我们已经拥有了将 ChatGPT 接入编辑器所需的一切。对于基本设置,让我们告诉 ChatGPT 该做什么。一个基本的提示策略如下:
以下是结果。左侧是打开文件的 Neovim,右侧我正在键入指令。它…有点奏效:
已关注
关注
重播分享赞
关闭
观看更多
更多
正在加载
正在加载
退出全屏
视频加载失败,请刷新页面再试
刷新
视频详情
对于基本的操作,比如删除和重新排列屏幕上的内容,它表现得相当不错,但在处理更高级的请求方面,比如将注释转换为猪拉丁语(儿童暗语),它的可靠性不高。好消息是,有数以百万计的改进方式,因此自动文本编辑前景看起来很有希望!下一步是制定一个更好的提示策略,而不是采用这种一刀切的制作脚本方式。一旦我们有了一套良好的基本操作,我想构建一个类似"Voyager"(https://github.com/MineDojo/Voyager)的代理程序,看看它能走多远。
▶大模型时代,开发者成长指南 | 新程序员
▶九问中国大模型掌门人,万字长文详解大模型进度趋势
▶两种技术乱象:为什么前者更容易让程序员背锅?