原文地址:https://yinxiuqu.github.io/post/zai-Emacs-zhong-shi-yong-copilot.el-bu-quan-dai-ma.html
最近用了vscode使用copilot插件补全代码,很丝滑。能理解我程序编码上下文的意思,推算我接下来该写哪些代码。这和DeepSeek的通过文字描述直接给出一段功能代码是不同的。因为有些代码你是必须按自己的构想手写出来,一句一句审核,很多时候并不方便用文字去向AI描述一个功能。
最不可思议的是,常常是一次性补全一大段代码,而且几乎没有错误。
其次是模仿我编码的习惯,如LaTeX里我喜欢用\overline表示共轭,用\bm表示粗体向量,补全建议时,它都是模仿这些习惯的。
第三是,在数学排版过程中,我列出代数式,它立即帮我把后面的计算步骤和计算结果都补全出来,而且是用LaTeX代码排版好。
vscode中能用了,就立即想到要在Emacs中实现。搜索了一下,还真找到了copilot.el这个插件,我安装和配置如下:
1.配置文件
;; 本文件用于配置AI
;; 安装copilot.el
(use-package copilot
:ensure t)
;; 使用copilot进行补全
(add-hook 'prog-mode-hook 'copilot-mode)
(add-hook 'LaTeX-mode-hook 'copilot-mode)
(add-hook 'pyton-mode-hook 'copilot-mode)
(add-hook 'TeX-mode-hook 'copilot-mode)
;; Tab 键接受全部补全
(define-key copilot-mode-map (kbd "<tab>") 'copilot-accept-completion)
;; Ctrl+→ 逐字符接受部分补全插入
(define-key copilot-mode-map (kbd "C-<right>") 'copilot-accept-completion-by-word)
;; 文件结尾
(provide 'init-ai)
2.安装 Copilot 语言服务器
M-x copilot-install-server
这个过程比较久,要等它全部完成。
3.登录GitHub Copilot账户
M-x copilot-login
按提示登陆GitHub账户,输入权限验证码。
这样设置后,copilot可以在elisp, python, LaTeX等语言上使用copilot补全了,效果和vscode完全一样。但是,有个小警告我想了很多办法都一直无法消除,当前模式偏移量无法找到合适值:
Warning (copilot): copilot--infer-indentation-offset found no mode-specific indentation offset. Disable showing Disable logging
我尝试过手工设置偏移量,全局模式和针对各特定模式都设置过,还是有这个警告。哪位帮忙看看如何消除。
2 个赞
rua
2025 年2 月 28 日 11:33
4
;; 由于 `lisp-indent-offset' 的默认值是 nil,在编辑 elisp 时每敲一个字
;; 符都会跳出一个 warning,将其默认值设置为 t 以永不显示这个 warning
(setq-default copilot--indent-warning-printed-p t
copilot-indent-offset-warning-disable t)
;; 文件超出 `copilot-max-char' 的时候不要弹出一个 warning 的 window
(defun my-copilot-get-source-suppress-warning (original-function &rest args)
"Advice to suppress display-warning in copilot--get-source."
(cl-letf (((symbol-function 'display-warning) (lambda (&rest args) nil)))
(apply original-function args)))
(advice-add 'copilot--get-source :around #'my-copilot-get-source-suppress-warning)
1 个赞
谁能做个codegeex的emacs插件就好,感觉这个国产的补全很不错,而且免费.和copilot不相上下.
已经有copilot的账户的同学,除了copilot.el非常好必须得用,也推荐GitHub - chep/copilot-chat.el: Chat with Github copilot in Emacs ! ,
流量是免费的,可以切换gpt模型和claude。
不过说实话由于deepseek和gemini这两个模型已经太便宜了,就算有copilot账户,copilot-chat.el也没多少优势了,因为有gptel的存在。如果用deepseek or gemini这两个便宜的模型,emacs AI助手还是gptel,以及基于gptel的更好。
之前工作中一直用 phpstorm + github copilot 非常好用,只是用来生成。最近试了试 vscode 的,发现还有编辑的功能,比补全更近了一步。这两天打算捡起不用多年的 Emacs,好奇目前 AI 在 Emacs 中的效果,特别是编程方面的,copilot.el 和官方的比效果如何呢?特别是 neovim 的,毕竟 vscode 是亲生的,肯定比不上,其他的也很有名。
哈哈哈老哥很久没用Emacs了啊,补全我还没用AI,但生成方面,可以看看Aidermacs:
我GPT Plus会员日常高强度用,代码是claude>deepseek>gemini混着用,取决于难度和性价比。
Aidermacs和gptel是平行关系,可以都用,Aidermacs强调对项目的总体理解和Pair Programming能力,直接对标的是Cursor,gptel我个人用得很少,但更多是对其他非项目相关的文本处理有时候会用一下(但更多时候我直接ChatGPT了)
Aidermacs相对于Aider.el有10点主要优势 :
内置Ediff集成
自动捕获AI编辑前的文件状态
使用Emacs原生的ediff界面进行代码比较
支持语法高亮,使代码变更更清晰易读
提供交互式工作流,可以逐行接受或拒绝变更
智能模型选择
自动从OpenAI、Anthropic、DeepSeek等多个供应商获取可用模型
实时检查模型与当前Aider版本的兼容性
自动过滤仅显示当前API密钥支持的模型
缓存常用模型列表,提高访问速度
支持动态发现和预配置模型
灵活的终端后端支持
支持comint和vterm两种终端后端
可根据需求选择最适合的终端模拟方式
更智能的…
2 个赞
copilot.el 用的就是官方的客户端,只是包装到了 emacs 里,所以能力上是一样的,只是交互可能有些功能没有 VSCode 那么花哨。
如果只是用自动补全,copilot.el 非常好用。
如果是类似聊天对话让它替你编辑,那可以考虑楼上推荐的 aider,它比微软的 copilot chat 好用多了。
楼上提到的 gptel-aibo 是一个不错的选择。
除此之外也可以考虑 minuet-ai.el,它提供了类似 copilot 的悬浮 ghost text 的 UI 交互体验。我是这个插件的作者,有问题欢迎问我。
需要注意的是 minuet 仅提供补全功能。
如果想要使用基于 chat 的和 LLM 进行多轮对话修改代码的体验,可以使用 aidermacs 或者 gpetl (以及楼上基于 gptel 的拓展插件 gptel-aibo)
大家好!我很高兴向大家正式发布 minuet-ai.el 插件。此前我曾在帖子中分享过直接调用大模型进行代码补全的方案,现在这个项目终于与大家见面了。
minuet-ai.el 是 Emacs 代码补全插件,其主要特点是:
直接通过 curl 调用大语言模型进行代码补全
支持两种补全模式:
基于 chat LLM 的 prompt building 方式,解析 LLM 的回答并构建补全方案。
通过 openai completion API 实现的 fill-in-the-middle (FIM) 方式
目前支持的模型包括:
OpenAI
Claude
Gemini
Codestral
所有兼容 OpenAI chat API 的模型(如 Fireworks、DeepSeek、Ollama)
所有兼容 OpenAI completion API 的模型(如 DeepSeek、Ollama)
插件提供了简单的配置方案,默认使用 DeepSeek 模型(需要提前设置 DEEPSEEK_API_KEY 环境变量)。此外,还有 Ollama 和 Gemini 的实例配置
默…
2 个赞
为 minuet 打 call。目前我自己已经停用了 copliot.el 改用 minuet
minuet 唯一缺点是似乎只能传递单 buffer 的上下文到 api,copilot.el 我观察到会记得自己在别的 buffer(文件)中看到过的内容。不过差不多够用了
简单试过了上面提到的工具,初步的印象:
工具
第三方依赖
API 费用
备注
gptel
无
花钱
聊天功能,容易理解是工作原理,方便提前预估 token 数量
copilot-chat
无
免费
代码聊天,它直接调用 GitHub Copilot Chat 官方接口
aidermacs
aider (Python 命令行工具)
花钱
代码编辑,类似 GitHub Copilot 官方的 Edit 功能,选择项目文件,按指令编辑
minuet
无
花钱
代码补全,这是这个包中代码量最少的,应该也是最简单的库了,上下文理解能力估计不强 |
copilot
@github /copilot-language-server (NPM 包)
免费
代码补全,通过微软官方 LSP 服务实现,但我对 LSP 在 Emacs 中印象不够好
可能受制于 Emacs 环境,代码实时补全的用户体验都不行,和 VS Code 没法儿比。
2 个赞
纠正一下哈。
copilot 免费的每个月补全数量是有限额的。
但是 minuet 你可以切换不同的免费模型用,使用数量是无上限的。
我在 README 里有写的,哪些模型是免费的。目前 codestral 和 gemini 都是免费的。而且除此之外还有硅基流动也可以用免费的,选 FIM 模型, 7b 模型就够了。
而且如果你的 gpu 很强,可以直接运行本地的模型,本地模型通常配合 aider 之类的这种对智能要求比较高的任务其实差点意思,但是用来补全是够用的,7b 模型就完全够了
补全本身确实比基于聊天的交互要简单很多,这个没什么好说的。
2 个赞
似乎只能传递单 buffer 的上下文到 api
可以传递多 buffer 的内容的。对于 chat-LLM (如 gemini,claude 等通过 conversatipn 的形式调 API 的模型)可以通过 customize minuet-default-chat-input-template
这个变量来实现将多 buffer 的内容传入 prompt。
对于 FIM model (如 qwen-2.5-coder,starcoder 等本地模型,或者是 codestral 这样通过直接传入 prompt 本身来调 API 的模型)可以通过 customize minuet-openai-fim-compatible-options :template :prefix
这个函数来传入多 buffer 的上下文。
需要注意的是不同的 FIM 模型对于 repo context 的 special tokens 是不同的。有的 FIM 模型支持 通过special tokens 来识别不同的文档的内容,有的 FIM 模型压根就不支持。比如 Qwen-2.5-coder 是支持通过 <|file_sep|>
作为 special token 来作为分隔符区分不同的文件。但也正因为不同的 FIM 模型的 支持力度不同,形式也不统一,special token 也不一样。因此这个东西的定制性太强了,不好做成统一的。
具体的可以看一下 minuet 的 github repo 里的 recipes.md
里面有详细的介绍该如何去 customize 这些 prompt 变量。
毕竟咱是 emacs 用户 嘛,API 的接口已经提供了, prompt 的生成方式当然是用户发挥自己创造力的时刻了。
接下来是有几个选择什么样的多 buffer 的内容注入的思路。
第一种是通过 RAG 的方式,用 elisp 来做 rag 感觉不太好做。目前有一个 github 项目: Davidyz/VectorCode
是一个 python 项目。他提供了一个命令行接口,也提供了 MCP 的接口。可以通过传递当前 buffer 的 content,来获得想要获取的 RAG 文档。然后将 RAG 文档传入 prompt。
第二种思路不需要 RAG,也比较简单。我感觉早期的 github copilot 应该也是这个思路。就是直接从你最近访问过的 buffer 并且相同编程语言的,然后从那个 buffer 的 point 处附近抽取一定的上下文去注入。
第三个也是我接下来有时间就准备做的一个方案,我打算把 aider 的 repomap 的那部分做成一个单独的 CLI,然后就可以把 repomap 注入到 LLM 的 prompt 里去。这个 repomap 因为是基于 treesitter ,速度较快,而且不需要像 RAG 那样还需要配置本地的向量化数据库,以及计算 embedding 等操作。当然也有缺点就是支持的语言较有限。
1 个赞
lsp-bridge 也支持 github copilot,而且 copilot.el 一样都是 lsp 方案,这两者使用上有区别吗?
lsp-bridge 感觉设置有点复杂,等有机会再试试看。
copilot.el 只有一千行代码,功能简陋也可以理解。
lsp-bridge 里面的 copilot 方案是移植 vim 的,版本很老了,也好久没维护了。
现在 copilot 是官方出 npm 包,lsp-bridge 没有跟进。
lsp-bridge 也支持 github copilot,而且 copilot.el 一样都是 lsp 方案,这两者使用上有区别吗?
copilot.el 是通过 overlay 的类似 ghost text 那样的 UI。lsp-bridge 是弹窗补全。
copilot.el 只有一千行代码,功能简陋也可以理解。
copilot.el 已经实现 project goal 了,就是代码补全。建立和 copilot lsp 的连接,发送 completion 请求,以及绘制 overlay UI。那 copilot.el 还需要什么其他的功能呢,并不能说它简陋吧?
lsp-bridge 里面的 copilot 方案是移植 vim 的,版本很老了,也好久没维护了。
现在 copilot 是官方出 npm 包,lsp-bridge 没有跟进。
现在官方推出的 lsp 就是在以前 vim 版本上继续维护发布的。实质上的功能还是一样的。
需要注意的是,copilot 仅仅只是利用了 LSP 协议的 json RPC 规范进行通信而已。实际上它实现的都是私有方法,而不是 LSP 协议规范的方法。因此如果使用一个通用的 LSP client 其实是使用不了任何 copilot 的功能的。
在 LSP 最新规范 3.18 里,一些 copilot 的私有方法升级成为了规范的一部分 (主要就是加入了新的请求方法 inlineCompletion),因此如果 LSP client 实现了最新的规范,将能够支持使用 copilot 进行补全。但是 copilot 的私有方法仍然提供了比列入规范的 inlineCompletion 更多的功能。
注意的是 lsp-bridge 对 copilot 的支持也是单独实现了一个 core/copilot.py
进行支持,而不是将 copilot 当作一个普通的 lsp 进行对待。
因此在 emacs 里使用 copilot,最好还是使用 copilot.el 或者用 lsp-bridge 利用其专门实现的 copilot 支持
1 个赞