branch: elpa/aidermacs commit 3fd6f56033271dc4bdd8eebd1109241673311f46 Author: Kang Tu <tni...@gmail.com> Commit: GitHub <nore...@github.com>
doc: Update README, add AI assisted development workflow with aider.el (#71) * feat: Add usage.org to the project * docs: Update Feature development section with best practice instructions * docs: Update usage instructions for developing new features with aider.el * docs: Update step 3 to emphasize in-place implementation commands for features * docs: Update usage instructions for aider.el feature development * docs: Clarify usage of aider-implement-todo for inline one-line comments * docs: Update usage instructions for inline comment implementations * docs: Update inline comment example with org-mode babel code block * docs: Update personal experience description in usage documentation * docs: Update example for inline one-line comment implementations in usage.org * docs: Update usage instructions for aider.el with additional details * docs: Update usage.org with detailed instructions for refactoring code * docs: Update usage instructions for refactoring and TDD explanation * docs: Replace comment with explanation on TDD for AI-generated code * docs: merge usage guide into readme and reorder menu items * docs: update transient menu screenshot * docs: clarify importance of unit testing in AI-assisted development * docs: clarify code change options in feature development guide * docs(readme): add notes about aider helper commands * docs: remove TODO sections from README * docs: update model name from gpt-4o-mini to o3-mini * docs: add note about test file integration with projectile * docs: add gptel.el reference to README * docs(readme): add note about using aider for documentation * revise text * docs: update development timeline of tic-tac-toe and connect4 examples * test: Fix incorrect function name in aider-write-unit-test-behavior test --- README.org | 67 +++++++++++++++++++++++++++++++++++++++++++++++----- aider.el | 8 +++---- examples/README.org | 2 ++ test_aider.el | 4 ++-- transient_menu.png | Bin 91139 -> 98526 bytes 5 files changed, 69 insertions(+), 12 deletions(-) diff --git a/README.org b/README.org index 80b1c1d885..aed97966d6 100644 --- a/README.org +++ b/README.org @@ -9,7 +9,7 @@ - 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`. -* Why Use `aider.el` in Emacs? +* Integrating aider with emacs coding context and UI - Pop-up Menu: No need to remember commands. (aider-transient-menu) @@ -29,7 +29,7 @@ When being called with the universal argument (`C-u`), a prompt will offer the u - (`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) - - gpt-4o-mini + - 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) @@ -60,6 +60,7 @@ When being called with the universal argument (`C-u`), a prompt will offer the u *** And More: 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. + * Installation - Emacs need to be >= 26.1 @@ -79,7 +80,7 @@ If you have Straight installed (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" "gpt-4o-mini")) + ;; (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")) @@ -104,7 +105,7 @@ Add the config (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" "gpt-4o-mini")) + ;; (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")) @@ -129,7 +130,7 @@ Add the config #+BEGIN_SRC emacs-lisp (use-package aider :config - (setq aider-args '("--model" "gpt-4o-mini"))) + (setq aider-args '("--model" "o3-mini"))) #+END_SRC The aider prefix is "A". @@ -169,6 +170,59 @@ You can enable Helm-based completion with the following code: (aider-minor-mode 1)))) #+END_SRC +* My personal development experience using aider.el + +- Here I just share my personal experience. You might have different / better way to use aider.el. + +** Feature development + +To develop new features effectively with aider.el, follow these steps: + +1. Start an Aider session specific to your current git repository by running the command “aider-run-aider”. This links your session to your project context. + +2. Add relevant files to the session using commands such as “aider-add-current-file”, “aider-add-files-in-current-window”, etc, so that the AI has access to the complete codebase. + +3. Use the in-place implementation commands—for example, “aider-implement-todo” to implement requirements directly in comments or “aider-function-or-region-refactor” to make code change or refactor existing code—since these approaches are preferred for feature development as they apply minimal, context-aware changes. + - For inline one-line comment implementations: + For example, if you have the following Python code snippet: + + #+BEGIN_SRC python :eval never + # TODO: Implement a function that checks if a number is prime + #+END_SRC + + Place the cursor on the TODO comment line and run “aider-implement-todo”. This command will send only that inline comment to Aider, which will then generate new code—for example, a complete implementation of an is_prime function—while leaving existing code unchanged. A possible generated output might be: + + #+BEGIN_SRC python :eval never + 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 + #+END_SRC + + This example demonstrates using aider-implement-todo to generate entirely new code rather than modifying existing code. + + Actually, this function can also help writing document. + + - If you are not satisfied with the change aider suggested. You can enter N to refuse accept that, and then use Ask Question (or /ask in aider session buffer) to ask aider modify the change given your more specific requirement. When you satisfy with that, use "Go Ahead" (or "go ahead" in aider session buffer) + + - When you need to adjust an existing function, class, or code block, do the following: + 1. If you wish to change only a part of the code, select that region; otherwise, simply place the cursor inside the target function or block. + 2. Run “aider-function-or-region-refactor”. + 3. When prompted, enter a clear code change / refactoring instruction (for example, “Rename variable 'temp' to 'result'” or “Make the function static”). + 4. Aider will process your instruction and return a revised version of the code with your changes applied in place while preserving the overall structure. + 5. Review the output and, if needed, refine your instructions further (e.g., by using “Ask Question”) to get the desired result. + + - aider-architect-discussion and aider-code-change are also helpful, but it is less context aware than the above two commands. + +4. Validate and evolve your feature with test-driven commands like “aider-write-unit-test” and “aider-fix-failing-test-under-cursor” as needed. + +AI-generated code is beneficial for quickly implementing features but can sometimes introduce subtle bugs or inconsistencies. That’s why Unit Test (or even more, Test-Driven Development) is critical: by writing tests before and after integrating AI-generated changes, you ensure that each incremental improvement is validated immediately. Implement your tests in small iteration steps—running your full test suite after each change—to catch issues early and maintain robust control over your [...] + +Right now I am using projectile function to jump between main code and test code, and add them to session. It would be better if there is a way to easily add test code to session. + * Screenshot [[file:./screenshot.png]] @@ -182,6 +236,7 @@ You can enable Helm-based completion with the following code: - Inspired by, and Thanks to: - [[https://github.com/shouya/ancilla.el][ancilla.el]]: AI Coding Assistant support code generation / code rewrite / discussion - - [[https://github.com/xenodium/chatgpt-shell][chatgpt-shell]]: ChatGPT and DALL-E Emacs shells + Org Babel + - [[https://github.com/xenodium/chatgpt-shell][chatgpt-shell]]: ChatGPT and DALL-E Emacs shells + Org Babel, comint session based idea - [[https://github.com/copilot-emacs/copilot.el][copilot.el]]: Emacs plugin for GitHub Copilot - [[https://github.com/chep/copilot-chat.el][copilot-chat.el]]: Chat with GitHub Copilot in Emacs + - [[https://github.com/karthink/gptel][gptel]]: Most stared / widely used LLM client in Emacs diff --git a/aider.el b/aider.el index 0654ed9e50..0243b6676b 100644 --- a/aider.el +++ b/aider.el @@ -38,11 +38,11 @@ When nil, use standard `display-buffer' behavior." :type 'boolean :group 'aider) -(defcustom aider-popular-models '("gemini/gemini-exp-1206" ;; free - "anthropic/claude-3-5-sonnet-20241022" ;; really good in practical +(defcustom aider-popular-models '("anthropic/claude-3-5-sonnet-20241022" ;; really good in practical + "o3-mini" ;; very powerful + "gemini/gemini-exp-1206" ;; free "r1" ;; performance match o1, price << claude sonnet. weakness: small context "deepseek/deepseek-chat" ;; chatgpt-4o level performance, price is 1/100. weakness: small context - "gpt-4o-mini" ) "List of available AI models for selection. Each model should be in the format expected by the aider command line interface. @@ -138,9 +138,9 @@ Affects the system message too.") ("t" "Architect Discuss and Change" aider-architect-discussion) ("c" "Code Change" aider-code-change) ("r" "Refactor Function or Region" aider-function-or-region-refactor) + ("i" "Implement Requirement in-place" aider-implement-todo) ("U" "Write Unit Test" aider-write-unit-test) ("T" "Fix Failing Test Under Cursor" aider-fix-failing-test-under-cursor) - ("i" "Implement Requirement in-place" aider-implement-todo) ("m" "Show Last Commit with Magit" aider-magit-show-last-commit) ("u" "Undo Last Change" aider-undo-last-change) ] diff --git a/examples/README.org b/examples/README.org index c166a21841..532b14264e 100644 --- a/examples/README.org +++ b/examples/README.org @@ -6,6 +6,8 @@ Two games were written with the assistance of aider / aider.el - using DeepSeek model - 1.5h to iterate and add human vs. computer mode - using Claude model + - 1h to have a better AI + - using OpenAI o3-mini model - [[./connect4][connect4]] - https://en.wikipedia.org/wiki/Connect_Four - 0.5h to write the game with basic human vs. computer mode - 0.5h to iterate the AI and make it more effective diff --git a/test_aider.el b/test_aider.el index 460a898cf4..de2b93dad8 100644 --- a/test_aider.el +++ b/test_aider.el @@ -87,7 +87,7 @@ ;; Test when buffer is a test file (with-temp-buffer (let ((buffer-file-name "test_something.py")) - (should (progn (aider-write-test) + (should (progn (aider-write-unit-test) (equal (current-message) "Current buffer appears to be a test file."))))) ;; Test when buffer is a regular file with no function under cursor @@ -99,7 +99,7 @@ (lambda (prompt initial) aider-read-string-result)) ((symbol-function 'aider-add-current-file) (lambda () t)) ((symbol-function 'aider--send-command) (lambda (cmd switch) t))) - (aider-write-test) + (aider-write-unit-test) (should (not (equal (current-message) "Current buffer is not visiting a file."))) (should (not (equal (current-message) "Current buffer appears to be a test file."))))))) diff --git a/transient_menu.png b/transient_menu.png index 0d60c75389..2305d017b7 100644 Binary files a/transient_menu.png and b/transient_menu.png differ