- 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 interactive interface to communicate with Aider in Emacs.
- Most of the Elisp code in this repository was generated by Aider or `aider.el`.
- Pop-up Menu: No need to remember commands. (aider-transient-menu)
- The following commands are integrated into the aider menu:
- (`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 of `aider-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
- (`aider-change-model`): Interactively select and change AI model in current aider session
- Customize `aider-popular-models` to define your preferred models list. Default models are (as date of 2025-01-26):
- anthropic/claude-3-5-sonnet-20241022 (really good in practical)
- o3-mini (new released. very powerful, not expensive)
- gemini/gemini-exp-1206 (free)
- r1 (performance matches o1, price << claude sonnet. weakness: small context)
- deepseek/deepseek-chat (chatgpt-4o level performance, price is 1/100. weakness: small context)
- use “@” in the menu to toggle add file between read-write mode and read-only mode
- (`aider-add-current-file`): Add the current buffer file.
- (`aider-add-files-in-current-window`): Add all buffers in the current window.
- (`aider-add-same-type-files-under-dir`): Add all files with the same suffix as the current file under the current directory to Aider.
- (`aider-batch-add-dired-marked-files`): Add multiple Dired marked files to the Aider buffer.
- (`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.
- (`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 cursor is inside a function, implement TODOs for that function.
- Otherwise implement TODOs for the entire current file.
- (`aider-ask-question`): Ask Aider a question about the code in the current context. If a region is selected, use the region as context.
- (`aider-function-or-region-explain`): If a region is selected, ask Aider to explain the selected region. Otherwise, ask Aider to explain the function under the cursor.
- (`aider-explain-symbol-under-point`): Ask Aider to explain the symbol under cursor, given the line as context.
- (`aider-write-unit-test`): Generate comprehensive unit tests for the current function or file. The generated tests will include normal cases, edge cases, and error handling scenarios.
- (`aider-fix-failing-test-under-cursor`): Place cursor on a failing test function and ask Aider to analyze and fix the code to make tests pass.
You can add your own Elisp functions to support your specific use cases. Feel free to ask Aider/`aider.el` to help you create them.
- Emacs need to be >= 26.1
- Install aider
- Install the emacs dependency library Transient, and Magit 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"))
:config
;; Use claude-3-5-sonnet cause it is best in aider benchmark
(setq aider-args '("--model" "anthropic/claude-3-5-sonnet-20241022"))
(setenv "ANTHROPIC_API_KEY" anthropic-api-key)
;; Or use chatgpt model since it is most well known
;; (setq aider-args '("--model" "o3-mini"))
;; (setenv "OPENAI_API_KEY" <your-openai-api-key>)
;; Or use gemini v2 model since it is very good and free
;; (setq aider-args '("--model" "gemini/gemini-exp-1206"))
;; (setenv "GEMINI_API_KEY" <your-gemini-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))
With package-vc-install (emacs built-in)
Install Aider.el by running the following code within Emacs
(package-vc-install '(aider :url "https://github.com/tninja/aider.el"))
Add the config
(use-package aider
:config
;; Use claude-3-5-sonnet cause it is best in aider benchmark
(setq aider-args '("--model" "anthropic/claude-3-5-sonnet-20241022"))
(setenv "ANTHROPIC_API_KEY" anthropic-api-key)
;; Or use chatgpt model since it is most well known
;; (setq aider-args '("--model" "o3-mini"))
;; (setenv "OPENAI_API_KEY" <your-openai-api-key>)
;; Or use gemini v2 model since it is very good and free
;; (setq aider-args '("--model" "gemini/gemini-exp-1206"))
;; (setenv "GEMINI_API_KEY" <your-gemini-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))
- Add the following code to your doom/packages.el
(package! aider :recipe (:host github :repo "tninja/aider.el" :files ("aider.el" "aider-doom.el")))
- Adjust and add the following code to your doom/config.el
(use-package aider
:config
(setq aider-args '("--model" "o3-mini")))
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
Helm enables fuzzy searching functionality for command history prompts
You can enable Helm-based completion with the following code:
(use-package aider
:straight (:host github :repo "tninja/aider.el" :files ("aider.el" "aider-helm.el")))
- If you prefer writing Aider commands in a separate file and sending them to an Aider session (similar to working with Python or R scripts and sending code blocks to a REPL), you might want to try aider-minor-mode. It provides the following key bindings:
- C-c C-n: If region is active, send selected region line by line; otherwise, send current line
- C-c C-c: Send current region line by line to aider session
- C-c C-r: Send current region as a single block to aider session
- Enable aider-minor-mode for your editing buffer
- To automatically enable aider-minor-mode for any file with “aider” in its filename:
(add-hook 'find-file-hook
(lambda ()
(when (and (buffer-file-name)
(string-match-p "aider" (buffer-file-name)))
(aider-minor-mode 1))))
- Here I just share my personal experience. You might have different / better way to use aider.el.
- Begin an Aider session specific to the current git repository by running the command “aider-run-aider”. This command links the session with the project context.
- Next, consider adding relevant files to the session using commands such as “aider-add-current-file” or “aider-add-files-in-current-window”. This provides Aider with additional context that may prove useful.
- For making changes, it might be either adding new code or changing existing code.
- Add new code with one-line comment implementation:
Suppose the following Python snippet is encountered:
# TODO: Implement a function that checks if a number is prime
With the cursor positioned on the TODO comment line, running “aider-implement-todo” will send only that inline comment to Aider, which may then generate revised code—for example, a complete implementation of an is_prime function—while preserving the existing code. For instance, Aider might produce:
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
This example demonstrates how aider-implement-todo can assist in introducing new code. (This command may also be useful for some documentation tasks.)
- In cases where the suggested change is not entirely satisfactory, the option exists to decline it (for example, by entering N). Following that, the “Ask Question” command (or /ask within the aider session buffer) can be used to request a modification with more detailed guidance. Once an acceptable suggestion is obtained, confirmation via the “Go Ahead” command (or “go ahead” in the aider session buffer) is possible.
- Change existing code for an existing function, class, or code block:
- If only a portion of the code is to be modified, the relevant region may be selected; otherwise, placing the cursor within the target function or class will suffice.
- Execute “aider-function-or-region-refactor”.
- When prompted, provide a clear description of the intended change (for example, “Rename variable ‘temp’ to ‘result’” or “Make the function static”).
- A revised version of the code that incorporates these suggestions will then be generated while preserving the overall structure.
- The output may be reviewed and, if further refinement is necessary, additional adjustments can be requested using “Ask Question” followed by confirmation with “Go Ahead”, until the desired result is achieved.
- Note that aider-architect-discussion and aider-code-change are available alternatives, although these may offer less context sensitivity than the aforementioned commands.
- Add new code with one-line comment implementation:
Suppose the following Python snippet is encountered:
- Generate test It is advisable to validate and iteratively improve the feature using test-driven commands such as “aider-write-unit-test” and “aider-fix-failing-test-under-cursor”. Although AI-generated code can serve as a helpful starting point, it may occasionally introduce subtle issues. Running tests before and after integrating changes ensures that each incremental improvement is properly verified. Executing the full test suite after every change is recommended to catch any issues early.
(As an aside, a projectile function is currently employed to switch between the main code and test code and add them to the session—but further improvements to include test code seamlessly are always welcome.)
- Refactor code and test Finally, the AI-generated code and tests may be refactored further as necessary—either with additional prompts or manually—to best suit the project’s requirements.
- The screenshot above shows Aider being asked to generate an aider-help function and add its corresponding entry to the menu (top right window).
- Aider successfully received the command and generated the appropriate commit (bottom left).
- 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