- Introduction
- Installation
- Most used features (integrated into the aider menu)
- Be careful about AI generated code
- FAQ
- Future work
- Other Emacs AI coding tool
- Do you enjoy the AI features of the Cursor AI Code Editor but prefer working within Emacs?
- Aider is a well-known and highly effective AI pair programming tool for the terminal.
- The aider.el package offers an simple UI to communicate with Aider in Emacs. It aim to minimize the user’s effort using aider in emacs.
- Most of the Elisp code in this repository was generated by Aider or aider.el.
- aider.el aim to be a stable productivity tool we can use daily. I will carefully test the Features / Functions in this library before code merging.
- Recent change history
- Pop-up Menu (
aider-transient-menu
)
- Git repository-specific Aider session management
- Integrating context (buffer / things under cursor / region) with aider, semi-automatically build up prompt. easy search / reuse previous prompt with helm
- Menu items for AI-assistant programming workflow. TDD style loop to reduce potential AI introduced error
- Aider prompt file to organize relative large code change task, and make it reproducible. Interacting with aider session from it following ESS way. Yasnippet support to reuse good prompts from community.
- The current implementation is using comint to host aider session, a classic CLI interactive solution used in emacs, However, comint-mode initially doesn’t have the advance features such as codeblock color rendering and file tracking from aider.
- color rendering markdown-mode.el is applied and largely improved this.
- Without file tracking, aider.el cannot do AI comments. The work around we provided is ~aider-implement-todo~, It use architect command to ask aider to implement comment under cursor by default. I constantly use this feature and feel it is OK.
- It’s generally not advantageous to interact with Aider extensively through the comint terminal directly. Instead, since the comint terminal is well integrated with other parts of emacs, it is encouraged to generate and send prompt to it, either from:
- Code buffer directly by aider code change related commands or ask question related commands. It make less context switching, and it help building up prompt, reducing manual typing.
- Aider prompt file (
aider-open-prompt-file
,C-c a p
). This is the traditional way in emacs to communicate with comint buffer (just like ESS, python-mode, scala-mode, etc). It is easy to revisit your used commands, organize and manage large code change requiring more prompts and break them into sub-tasks (cause it is org), and it is easy for multi-line prompts. Recently, syntax highlight, completion and snippets were added to this file, and it is now a good place to write and organize your prompts.
- More Focus on build prompts using your code (buffer/selection).
- Reuse prompts easily, fuzzy search with helm.
- Organize project with repo specific Aider prompt file
- More Focus on code quality tool (Code Review, TDD + AI).
- Snippets for community prompts.
- Emacs need to be >= 26.1
- Install aider
- Install the emacs dependency library Transient, Magit, and Markdown-mode using your package manager.
- Install aider.el with the following code:
With Straight
If you have Straight installed
(use-package aider
:straight (:host github :repo "tninja/aider.el" :files ("aider.el" "aider-core.el" "aider-file.el" "aider-code-change.el" "aider-discussion.el" "aider-prompt-mode.el"))
:config
;; For latest claude sonnet model
(setq aider-args '("--model" "sonnet"))
(setenv "ANTHROPIC_API_KEY" anthropic-api-key)
;; Or chatgpt model
;; (setq aider-args '("--model" "o3-mini"))
;; (setenv "OPENAI_API_KEY" <your-openai-api-key>)
;; Or use your personal config file
;; (setq aider-args `("--config" ,(expand-file-name "~/.aider.conf.yml")))
;; ;;
;; Optional: Set a key binding for the transient menu
(global-set-key (kbd "C-c a") 'aider-transient-menu))
- aider-args just passed directly to aider CLI, aider options reference
- if aider-args is empty (default), it will use ~/.aider.conf.yml file. In this way, aider CLI and aider.el share same configuration
With package-vc-install (Emacs 30+ built-in)
- Install aider.el by running the following code within Emacs
(package-vc-install '(aider :url "https://github.com/tninja/aider.el"))
The config part is as same as above straight one
Enable installation of packages from MELPA by adding an entry to package-archives after (require ‘package) and before the call to package-initialize in your init.el or .emacs file:
(require 'package)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
;; Comment/uncomment this line to enable MELPA Stable if desired. See `package-archive-priorities`
;; and `package-pinned-packages`. Most users will not need or want to do this.
;;(add-to-list 'package-archives '("melpa-stable" . "https://stable.melpa.org/packages/") t)
(package-initialize)
- Use M-x package-refresh-contents or M-x package-list-packages to ensure that Emacs has fetched the MELPA package list
- Use M-x package-install to install aider package
- Add the following code to your doom/packages.el
(package! aider :recipe (:host github :repo "tninja/aider.el" :files ("aider.el" "aider-core.el" "aider-file.el" "aider-code-change.el" "aider-discussion.el" "aider-prompt-mode.el" "aider-doom.el")))
- Adjust and add the following code to your doom/config.el
(use-package aider
:config
(setq aider-args '("--model" "sonnet")))
The aider prefix is A
.
- Start and open the aider buffer:
[SPC] A o
- Add the current file with
[SPC] A a c
- Reset the aider session with
[SPC] A r
- However, transient menu is more recommended than doom menu, cause I constantly use that one so it is better maintained.
- Anyone want to contribute to doom menu, feel free to help on it. Thanks.
Helm enables fuzzy searching functionality for command history prompts. Since it is very possible that we use prompt written before, it could potentially save lots of time typing. This plugin is highly recommended if you are OK with helm.
If you used installed aider.el through melpa and package-install, just neecd to (require 'aider-helm)
Otherwise, You can have helm-based completion with run the following code, after install helm library:
(use-package aider
:straight (:host github :repo "tninja/aider.el" :files ("aider.el" "aider-core.el" "aider-file.el" "aider-code-change.el" "aider-discussion.el" "aider-prompt-mode.el" "aider-doom.el" "aider-helm.el")))
- aider-run-aider
- Creates a comint-based, git repo-specific Aider session for interactive conversation.
- Git repository identification is based on the current file’s path
- Multiple Aider sessions can run simultaneously for different Git repositories
- When being called with the universal argument (
C-u
), a prompt will offer the user to change the content ofaider-args
for this session.
- aider-switch-to-buffer
- Switch to the Aider buffer.
- use
^
in the menu to toggle open aider session in other window inside current frame, or open a dedicate frame for aider session. This is useful when there is more than one monitor, and one frame / monitor is used to hold multi buffers for code, and another frame / monitor hold aider session.
- use
- aider-add-current-file-or-dired-marked-files
- Add the current buffer file. If it is used in dired buffer, add all dired marked files.
C-u
prefix to add files read-only.
- aider-add-files-in-current-window
- Add all buffers in the current window.
- aider-function-or-region-refactor
- If a region is selected, ask Aider to refactor the selected region. Otherwise, ask Aider to change / refactor the function under the cursor.
- A couple common used prompts provided when you are using aider-helm.el
- aider-implement-todo
- Implement requirement in comments in-place, in current context.
- If cursor is on a comment line, implement that specific comment in-place.
- If there is a selection region of multi-line comments, implement code for those comments in-place.
- If cursor is inside a function, implement TODOs for that function, otherwise implement TODOs for the entire current file.
- The keyword (TODO by default) can be customized with the variable
aider-todo-keyword-pair
. One example is to use AI! comment, which is as same as aider AI comment feature.
- The keyword (TODO by default) can be customized with the variable
- aider-write-unit-test
- If the current buffer is main source code file, generate comprehensive unit tests for the current function or file. If the cursor is in a test source code file, when the cursor is on a test function, implement the test function. Otherwise, provide description to implement the test function (or spec).
- If main source code break and test function fails, use
aider-function-or-region-refactor
on the failed test function to ask Aider to fix the code to make the test pass.
- aider-ask-question
- Ask Aider a question about the code in the current context. If a region is selected, use the region as context.
- You can ask any question on the code. Eg. Explain the function, review the code and find the bug, etc
- A couple common used prompts provided when you are using aider-helm.el
- aider-go-ahead
- When you are asking aider to suggest a change using above command, maybe even after several round of discussion, when you are satisfied with the solution, you can use this command to ask Aider to go ahead and implement the change.
- Syntax highlight, aider command completion, file path completion supported
- Use
C-c a p
to open the repo specific prompt file. You can use this file to organize tasks, and write prompt and send them to the Aider session. multi-line prompts are supported. - People happy with sending code from editor buffer to comint buffer (eg. ESS, python-mode, scala-mode) might like this. This is a interactive and reproducible way
C-c C-n
key can be used to send the current prompt line to the comint buffer. Or batch send selected region line by line. To my experience, this is the most used method in aider prompt file.C-c C-c
key is for multi-line prompt. The following example showsC-c C-c
key pressed when cursor is on the prompt.
- Prompts for aider might share similar structure. Yasnippet can be used to help reusing these prompts.
- Aider prompt file now support yasnippet. Current snippets came from this reddit post, another reddit post, and a git repo.
- You can use
M-x yas-describe-tables
to see the available snippetsM-x yas-insert-snippet
to insert a snippet.M-x yas-expand
to expand the snippet under cursor.
- Welcome to add more snippets / improve existing snippets in the snippets folder!
- / key to trigger aider command completion
- file path completion will be triggered automatically after certain command
- use TAB key to enter prompt from mini-buffer, or helm with completion
- Thanks to LLM. It is so easy to generate bunch of code with AI. But generating code doesn’t complete the work.
- There might be potential bug hidden inside. It need to be verified that the feature work as expected, and code change didn’t break existing features.
- Developer might be lack of understanding of AI generated code. If there is too many code developer don’t quite understand, the project could be out of control.
- Unit-test can be useful on both of the above concern. And aider can help writing unit tests.
- The AI generated test need to be manually checked / fixed. But generally test code is easier to understand.
- Running the unit-tests can help verifying the correctness / identifying the bug of code. It also help developer better understanding how the AI generated code work, and it can give developer more confidence on the new code.
A TDD-style AI programming workflow
- **Implement or modify code**:
- For existing code: Use
aider-function-or-region-refactor
with cursor in function or on selected region - For new code: Use
aider-implement-todo
on TODO comments
Example of adding new code:
With cursor on this comment:
# TODO: Implement a function that checks if a number is prime
Running
aider-implement-todo
might generate: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
If suggestions aren’t satisfactory, use
Ask Question
for refinements andGo Ahead
to confirm changes. - For existing code: Use
- **Generate tests**: Validate your implementation with
aider-write-unit-test
. Do run the test to validate code behavior.aider-write-unit-test
can be used to write unit-test before the code is implemented, just call the function in the unit-test class. I tried it with leetcode problems and it works pretty well.
- **Refine code and tests**: Further refactor as needed using additional prompts or manual adjustments.
- Goto 1
- How to review / accept the code change?
- Comparing to cursor, aider have a different way to do that. Discussion
- Note: Aider v0.77.0 automatically accept changes for /architect command. If you want to review the code change before accepting it like before for many commands in aider.el, you can disable that flag with “–no-auto-accept-architect” in either aider-args or .aider.conf.yml.
- How to disable to aider auto-commit?
- add –no-auto-commits to aider-args. aider-args is passed to aider CLI directly. aider options reference
- What kind of model aider support? Can aider support local model?
- Yes. Aider support it through LiteLLM. Please refer aider document.
- How to let aider work with your speaking language?
- use aider coding conventions. In my case, I added “- reply in Chinese” to the CONVENTIONS.md file, and load work through .aider.conf.yml. Or, put sth like following into aider-args variable.
- “–read” (expand-file-name “~/.emacs.d/.emacs/aider/CONVENTIONS.md”)
- use aider coding conventions. In my case, I added “- reply in Chinese” to the CONVENTIONS.md file, and load work through .aider.conf.yml. Or, put sth like following into aider-args variable.
- How to enter multi-line prompts in aider session buffer?
- aider itself support that, doc.
- use aider prompt file (
aider-open-prompt-file
,C-c a p
) to write multi-line prompts
- Can aider.el work with tramp? (aider running on remote machine)
- More context sensitive code change / code reading commands [1/1]
- [X] Current aider-ask-question need to be improved, since there could be so many different question to ask
- [ ] Thinking on how to improve the candidate list for the function
- [ ] How to port the candidate list feature to aider-plain-read-string
- More thinking on how to simplify the menu / commands
- More thinking on improving code quality tool such as unit-test
- Tag release version, make it available on melpa stable
- Better unit-test / integration test of this package. Hopefully it is automated.
- Inspired by, and Thanks to:
- ancilla.el: AI Coding Assistant support code generation / code rewrite / discussion
- chatgpt-shell: ChatGPT and DALL-E Emacs shells + Org Babel, comint session based idea
- copilot.el: Emacs plugin for GitHub Copilot
- copilot-chat.el: Chat with GitHub Copilot in Emacs
- gptel: Most stared / widely used LLM client in Emacs
- Package depends on this
- ob-aider.el: Org Babel functions for Aider.el integration