- 你是否喜欢 Cursor AI 代码编辑器 的 AI 功能,同时又偏爱在 Emacs 中工作?
- Aider 是一个知名且高效的终端 AI 结对编程工具。
- aider.el 为 Emacs 提供了一个简洁的 aider 用户界面,旨在最大限度地简化用户在 Emacs 环境中操作 aider 的流程。
- 本仓库中的大部分 Elisp 代码都是由 Aider 或 aider.el 生成的。
- aider.el 旨在成为我们可以日常使用的稳定生产力工具。我会在代码合并前仔细测试此库中的功能。
- 最近的变更历史
- Emacs 需要 >= 26.1
- 安装 aider
- 使用您的包管理器安装 Emacs 依赖库 Transient、Magit 和 Markdown-mode。
- 使用以下代码安装 aider.el:
使用 Straight
如果您已安装 Straight
(use-package aider
:straight (:host github :repo "tninja/aider.el")
:config
;; 对于最新的 claude sonnet 模型
(setq aider-args '("--model" "sonnet" "--no-auto-accept-architect"))
(setenv "ANTHROPIC_API_KEY" anthropic-api-key)
;; 或 chatgpt 模型
;; (setq aider-args '("--model" "o4-mini"))
;; (setenv "OPENAI_API_KEY" <your-openai-api-key>)
;; 或 gemini 模型
;; (setq aider-args '("--model" "gemini-exp"))
;; (setenv "GEMINI_API_KEY" <your-gemini-api-key>)
;; 或使用您的个人配置文件
;; (setq aider-args `("--config" ,(expand-file-name "~/.aider.conf.yml")))
;; ;;
;; 可选:为临时菜单设置键绑定
(global-set-key (kbd "C-c a") 'aider-transient-menu))
- *aider-args 直接传递给 aider CLI*,aider 选项参考
- 如果 aider-args 为空(默认),它将使用 ~/.aider.conf.yml 文件。这样,aider CLI 和 aider.el 共享相同的配置
使用 package-vc-install(Emacs 30+ 内置)
(package-vc-install '(aider :url "https://github.com/tninja/aider.el"))
配置部分与上面的 straight 相同
在 init.el 或 .emacs 文件中的 (require ‘package) 之后和 package-initialize 调用之前,通过向 package-archives 添加条目来启用从 MELPA 安装包:
(require 'package)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
;; 如果需要,可以注释/取消注释此行以启用 MELPA Stable。请参阅 `package-archive-priorities`
;; 和 `package-pinned-packages`。大多数用户不需要或不想这样做。
;;(add-to-list 'package-archives '("melpa-stable" . "https://stable.melpa.org/packages/") t)
(package-initialize)
- 使用 M-x package-refresh-contents 或 M-x package-list-packages 确保 Emacs 已获取 MELPA 包列表
- 使用 M-x package-install 安装 aider 包
- 将以下代码添加到您的 doom/packages.el
(package! aider :recipe (:host github :repo "tninja/aider.el"))
- 调整并将以下代码添加到您的 doom/config.el
(use-package aider
:config
(setq aider-args '("--model" "sonnet")))
aider 前缀是 ~A~。
- 启动并打开 aider 缓冲区:=[SPC] A o=
- 使用
[SPC] A a c
添加当前文件 - 使用
[SPC] A r
重置 aider 会话
- *然而,更推荐使用临时菜单而不是 doom 菜单*,因为我经常使用临时菜单,所以它得到了更好的维护。
- 任何想为 doom 菜单做贡献的人,欢迎帮助改进。谢谢。
Helm 为命令历史提示启用模糊搜索功能。由于我们很可能会使用之前写过的提示,这可能会节省大量输入时间。*如果您可以接受 helm,强烈推荐这个插件*。
如果您通过 melpa 和 package-install 安装了 aider.el,只需要 (require 'aider-helm)
- aider-run-aider
- 创建基于 comint 的、*特定于 git 仓库的 Aider 会话*,用于交互式对话。
- Git 仓库识别基于当前文件的路径
- 可以同时为不同的 Git 仓库运行多个 Aider 会话
- 当使用通用参数(~C-u~)调用时,将提示用户更改此会话的
aider-args
内容。 - 当在 dired、eshell 或 shell 缓冲区中运行时,它会询问您是否要添加 –subtree-only 标志,该标志仅考虑该目录中的文件,以使其更快
- aider-switch-to-buffer
- 切换到 Aider 缓冲区。
- 在菜单中使用
^
可以在当前框架内的其他窗口中切换打开 aider 会话,或为 aider 会话打开专用框架。当有多个显示器时,这很有用,一个框架/显示器用于保存代码的多个缓冲区,另一个框架/显示器保存 aider 会话。
- 在菜单中使用
- aider-add-current-file-or-dired-marked-files
- 添加当前缓冲区文件。如果在 dired 缓冲区中使用,添加所有 dired 标记的文件。
C-u
前缀以只读方式添加文件。
- aider-add-files-in-current-window
- 添加当前窗口中的所有缓冲区。
- aider-function-or-region-refactor
- 如果选择了区域,要求 Aider 重构所选区域。否则,要求 Aider 更改/重构光标下的函数。
- 当您使用 aider-helm.el 时,会提供几个常用的提示
- aider-implement-todo
- 在当前上下文中就地实现注释中的需求。
- 如果光标在注释行上,就地实现该特定注释。
- 如果有多行注释的选择区域,就地为这些注释实现代码。
- 如果光标在函数内,为该函数实现 TODO,否则为整个当前文件实现 TODO。
- 关键字(默认为 TODO)可以通过变量
aider-todo-keyword-pair
进行自定义。一个例子是使用 AI! 注释,这与 aider AI 注释功能相同。
- 关键字(默认为 TODO)可以通过变量
- aider-write-unit-test
- 如果当前缓冲区是主源代码文件,为当前函数或文件生成全面的单元测试。如果光标在测试源代码文件中,当光标在测试函数上时,实现该测试函数。否则,提供描述来实现测试函数(或规范)。
- 如果主源代码出现问题且测试函数失败,可以在失败的测试函数上使用
aider-function-or-region-refactor
要求 Aider 修复代码以使测试通过。
- aider-refactor-book-method
- 使用 Martin Flower 的重构书籍 中的技术进行代码重构
- aider-ask-question
- 向 Aider 询问当前上下文中的代码问题。如果选择了区域,使用该区域作为上下文。
- 您可以询问关于代码的任何问题。例如,解释函数、审查代码并找出错误等
- 使用 aider-helm.el 时提供了几个常用的提示
- aider-go-ahead
- 当您使用上述命令要求 aider 建议更改时,甚至在几轮讨论之后,当您对解决方案满意时,可以使用此命令要求 Aider 继续实施更改。
- 语法高亮、aider 命令补全、文件路径补全支持
- 使用
C-c a p
打开当前仓库专用的提示文件。您可以使用此文件组织任务,并撰写提示并将其发送到 Aider 会话。支持多行提示。 - 喜欢从编辑器缓冲区向 comint 缓冲区发送代码的人(例如 ESS、python-mode、scala-mode)可能会喜欢这个。这是一种交互式且可重现的方式。
C-c C-n
快捷键可用于将当前提示行发送至 comint 缓冲区。或者批量逐行发送所选区域。根据我的经验,这是 aider 提示文件中最常用的方法。C-c C-c
快捷键用于多行提示。以下示例显示了当光标在提示上时按下C-c C-c
键的情况。
- aider 的提示可能共享类似的结构。可以使用 Yasnippet 来帮助重用这些提示。
- Aider 提示文件现在支持 yasnippet。当前片段来自 这个 reddit 帖子、另一个 reddit 帖子 和一个 git 仓库。
- 您可以使用
M-x yas-describe-tables
查看可用的片段M-x yas-insert-snippet
插入片段。M-x yas-expand
展开光标下的片段。
- 欢迎在 片段文件夹 中添加更多片段/改进现有片段!
- / 键触发 aider 命令补全
- 文件路径补全会在某些命令后自动触发
- 使用 TAB 键从迷你缓冲区输入提示,或使用带补全的 helm
- 重构:改善既有代码的设计,作者 Martin Fowler:
aider-refactor-book-method
- 测试驱动开发:实例,作者 Kent Beck:
aider-tdd-cycle
- 修改代码的艺术,作者 Michael Feathers:
aider-legacy-code
- 代码阅读:开源视角,作者 Diomidis Spinellis:
aider-code-read
- 弹出菜单 (
aider-transient-menu
) - 针对 Git 仓库的专属 Aider 会话管理
- 将代码上下文(缓冲区/光标下的内容/选区)与 aider 整合,半自动构建提示。通过 helm 轻松搜索/重用之前的提示
- AI 辅助编程工作流的菜单项。AI 辅助敏捷开发方法。AI 辅助代码阅读
- Aider 提示文件用于组织相对较大的代码更改任务,并使其可重现。从中以 ESS 方式与 aider 会话交互。Yasnippet 支持重用社区的优秀提示。
- 基于经典书籍的 AI 辅助代码阅读工具
- 当前实现使用 comint 托管 aider 会话,这是 emacs 中使用的经典 CLI 交互解决方案,然而,comint-mode 最初_没有_ aider 的高级功能,例如代码块颜色渲染和文件跟踪。
- *应用了颜色渲染 markdown-mode.el 并大大改善了这一点*。
- 没有文件跟踪,aider.el 无法执行 AI 注释。*我们提供的解决方法是 ~aider-implement-todo~*,它使用 architect 命令要求 aider 默认实现光标下的注释。我经常使用此功能,感觉还可以。
- 通常,直接通过 comint 终端与 Aider 进行大量交互并不有利。 相反,由于 comint 终端与 emacs 的其他部分集成良好,建议生成提示并将其发送到终端,可以从以下任一方式进行:
- 直接从代码缓冲区通过 aider 代码更改相关命令 或 _提问相关命令_。这样可以减少上下文切换,并有助于构建提示,减少手动输入。
- Aider 提示文件(~aider-open-prompt-file~,~C-c a p~)。这是 emacs 中与 comint 缓冲区通信的传统方式(就像 ESS、python-mode、scala-mode 等)。它便于重新访问您使用过的命令,组织和管理需要更多提示的大型代码更改,并将它们分解为子任务(因为它是 org 格式),并且它便于多行提示。最近,为该文件添加了语法高亮、补全和代码片段,现在它是编写和组织提示的好地方。
- 感谢 LLM。使用 AI 生成大量代码非常容易。但生成代码并不能完成工作。
- 代码中可能隐藏着潜在的错误。需要验证功能是否按预期工作,以及代码更改是否破坏了现有功能。
- 开发人员可能缺乏对 AI 生成代码的理解。如果存在太多开发人员不太理解的代码,项目可能会失控,就像这样:
- *单元测试对上述两个问题都很有用*。aider 可以帮助编写单元测试。
- AI 生成的测试需要手动检查/修复。但通常测试代码更容易理解。
- 运行单元测试有助于验证代码的正确性/识别代码中的错误。它还有助于开发人员更好地理解 AI 生成的代码如何工作,并且可以给开发人员更多对新代码的信心。
一个弱 TDD 风格的 AI 编程工作流
- **实施或修改代码**:
- 对于现有代码:在函数中使用光标或在选定区域上使用
aider-function-or-region-refactor
- 对于新代码:在 TODO 注释上使用
aider-implement-todo
*添加新代码的示例*:
光标在此注释上:
# TODO: Implement a function that checks if a number is prime
运行
aider-implement-todo
可能会生成:def is_prime(n): if n <= 1: return False for i in range(2, int(n ** 0.5) + 1): if n % i == 0: return False return True
如果建议不令人满意,使用
Ask Question
进行改进,并使用Go Ahead
确认更改。 - 对于现有代码:在函数中使用光标或在选定区域上使用
- **生成测试**:使用
aider-write-unit-test
验证您的实现。运行测试以验证代码行为。aider-write-unit-test
可以在代码实现之前用于编写单元测试,只需在单元测试类中调用该函数。我用它测试过力扣问题,效果很好。
- **完善代码和测试**:根据需要使用其他提示或手动调整进一步重构。~aider-refactor-book-method~ 提供了 Martin Flower 的重构书籍 中的几种重构技术。
- 转到 1
- 或者,如果您更喜欢严格的 TDD 实践,您可能想尝试 ~aider-tdd-cycle~,它将遵循红-绿-重构循环。
- 如何审查/接受代码更改?
- 与 cursor 相比,aider 有不同的方式来处理代码更改。讨论
- 注意:*Aider v0.77.0 自动接受 /architect 命令的更改。如果您想像以前那样在接受更改之前审查代码更改(适用于 aider.el 中的许多命令),可以在 aider-args 或 .aider.conf.yml 中使用 “–no-auto-accept-architect” 禁用该标志*。
- 如何禁用 aider 的自动提交功能?
- 在 aider-args 中添加 –no-auto-commits。aider-args 直接传递给 aider CLI。aider 选项参考
- aider 支持哪些类型的模型?aider 是否支持本地模型?
- 在大型单体仓库中,aider 需要很长时间来扫描仓库。如何改进?
- Aider 使用 .aiderignore 文件来处理这个问题,详情,或者,您可以在 aider-args 中使用 –no-git 关闭 git。
- 或者,在 emacs 中通过以下方式使用 –subtree-only:
- 使用 dired、eshell 或 shell 缓冲区转到要包含的目录(子树)
- C-c a a 触发 aider-run-aider
- 回答关于 –subtree-only 的问题为是,它将添加该标志
- 如何让 aider 使用您的口语?
- 使用 aider 编码约定。在我的情况下,我在 CONVENTIONS.md 文件中添加了 “- reply in Chinese”,并通过 .aider.conf.yml 加载工作。或者,将类似以下内容放入 aider-args 变量中。
- “–read” (expand-file-name “~/.emacs.d/.emacs/aider/CONVENTIONS.md”)
- 使用 aider 编码约定。在我的情况下,我在 CONVENTIONS.md 文件中添加了 “- reply in Chinese”,并通过 .aider.conf.yml 加载工作。或者,将类似以下内容放入 aider-args 变量中。
- 如何在 aider 会话缓冲区中输入多行提示?
- aider 本身支持这一点,文档。
- 使用 aider 提示文件(~aider-open-prompt-file~,~C-c a p~)编写多行提示
- aider.el 能与 tramp 一起工作吗?(aider 在远程机器上运行)
- 如何自定义 aider-comint-mode 的提示和输入颜色?
- Spike-Leung 说 为其添加钩子会有帮助
- 更多上下文敏感的代码更改/代码阅读命令 [2/3]
- [X] 当前的 aider-ask-question 需要改进,因为可能有很多不同的问题要问
- [X] 如何将候选列表功能移植到 aider-plain-read-string
- [ ] 思考如何改进函数的候选列表
- 更多关于改进代码质量工具(如单元测试)的思考 [3/3]
- [X] 代码重构函数
- [X] TDD 函数
- [X] 代码阅读函数
- [ ] 遗留代码支持
- 更多关于如何简化菜单/命令的思考
- 更好的单元测试/集成测试。希望是自动化的。
- 受启发与致谢:
- ancilla.el:AI 编码助手支持代码生成/代码重写/讨论
- chatgpt-shell:ChatGPT 和 DALL-E Emacs shells + Org Babel,基于 comint 会话的想法
- copilot.el:GitHub Copilot 的 Emacs 插件
- copilot-chat.el:在 Emacs 中与 GitHub Copilot 聊天
- gptel:Emacs 中最受欢迎/广泛使用的 LLM 客户端
- 依赖此包的包
- ob-aider.el:用于 Aider.el 集成的 Org Babel 函数