branch: elpa/aidermacs
commit 73eda045ac57c97a71f78dbafbadc948d8f9ec57
Merge: 47918c434d 764a99dd5e
Author: Reindert-Jan Ekker <[email protected]>
Commit: GitHub <[email protected]>
Merge branch 'main' into match-theme
---
.gitignore | 4 ++
CHANGELOG.md | 16 +++++
README.md | 67 ++++++++++-------
aidermacs-backend-comint.el | 15 +++-
aidermacs-backend-vterm.el | 18 +++--
aidermacs-backends.el | 171 +++++++++++++++++++++-----------------------
aidermacs-models.el | 6 +-
aidermacs.el | 56 +++++++++------
8 files changed, 208 insertions(+), 145 deletions(-)
diff --git a/.gitignore b/.gitignore
index 7364d48a21..05d1193288 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,7 @@
.env
__pycache__
/*.elc
+
+# ELPA-generated files.
+/aidermacs-pkg.el
+/aidermacs-autoloads.el
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000000..4955e59dc5
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,16 @@
+# CHANGELOG
+
+## 1.0 - Initial Release
+
+### Features
+
+- **Built-in Ediff Integration:** Review AI-generated changes with Emacs'
familiar `ediff` interface.
+- **Intelligent Model Selection:** Automatically discover and integrate with
multiple AI providers (OpenAI, Anthropic, DeepSeek, Google Gemini, OpenRouter).
+- **Flexible Terminal Backend Support:** Choose between `comint` and `vterm`
backends for the best terminal compatibility and performance.
+- **Enhanced File Management:** Easily manage files within your Aider
session with commands for adding, dropping, listing, and more. Full support for
remote files via Tramp (SSH, Docker, etc.).
+- **Streamlined Transient Menu Selection:** Access all Aidermacs features
through a redesigned and ergonomic transient menu system.
+- **Prompt Files Minor Mode:** Work seamlessly with prompt files and other
Aider-related files with convenient keybindings and automatic mode activation.
+- **Claude 3.7 Sonnet Thinking Tokens:** Enable and configure thinking
tokens using the `/think-tokens` in-chat command or the `--thinking-tokens`
command-line argument.
+- **Architect Mode Confirmation:** Control whether to automatically accept
Architect mode changes with the `aidermacs-auto-accept-architect` variable.
+- **Re-Enable Auto-Commits:** Aider automatically commits AI-generated
changes by default. We consider this behavior *very* intrusive, so we've
disabled it. You can re-enable auto-commits by setting `aidermacs-auto-commits`
to `t`.
+- **Customizing Aider Options with `aidermacs-extra-args`:** Pass any
Aider-supported command-line options.
diff --git a/README.md b/README.md
index ed82176d0b..3d9c67f1dd 100644
--- a/README.md
+++ b/README.md
@@ -82,6 +82,24 @@ Here's what the community is saying about Aidermacs:
## Configuration
+#### Pre-Run Hook
+
+You can use the `aidermacs-before-run-backend-hook` to run custom setup code
before starting the Aider backend. This is particularly useful for:
+
+- Setting environment variables
+- Injecting secrets
+- Performing any other pre-run configuration
+
+Example usage to securely set an OpenAI API key from password-store:
+
+```elisp
+(add-hook 'aidermacs-before-run-backend-hook
+ (lambda ()
+ (setenv "OPENAI_API_KEY" (password-store-get
"code/openai_api_key"))))
+```
+
+This approach keeps sensitive information out of your dotfiles while still
making it available to Aidermacs.
+
### Default Model Selection
You can customize the default AI model used by Aidermacs by setting the
`aidermacs-default-model` variable:
@@ -133,7 +151,19 @@ When Architect mode is enabled, the
`aidermacs-default-model` setting is ignored
(setq aidermacs-editor-model "deepseek/deepseek-chat") ;; defaults to
aidermacs-default-model
```
-*Note: This configuration will be overwritten by the existence of an
`.aider.conf.yml` file (see
[details](#Overwrite-Configuration-with-Configuration-File)).*
+*Note: These configurations will be overwritten by the existence of an
`.aider.conf.yml` file (see
[details](#Overwrite-Configuration-with-Configuration-File)).*
+
+#### Architect Mode Confirmation
+
+By default, Aidermacs requires explicit confirmation before applying changes
proposed in Architect mode. This gives you a chance to review the AI's plan
before any code is modified.
+
+If you prefer to automatically accept all Architect mode changes without
confirmation (similar to Aider's default behavior), you can enable this with:
+
+```emacs-lisp
+(setq aidermacs-auto-accept-architect t)
+```
+
+*Note: These configurations will be overwritten by the existence of an
`.aider.conf.yml` file (see
[details](#Overwrite-Configuration-with-Configuration-File)).*
### Terminal Backend Selection
@@ -252,30 +282,19 @@ Aidermacs supports project-specific configurations via
`.aider.conf.yml` files.
### Claude 3.7 Sonnet Thinking Tokens
-Aider can work with Sonnet 3.7's [new thinking
tokens](https://www.anthropic.com/news/claude-3-7-sonnet), but does not ask
Sonnet to use thinking tokens by default.
-
-Enabling thinking currently requires manual configuration. Create an
`.aider.model.settings.yml` in your home dir, project's root, or the current
directory, then add the following to the file. Adjust the `budget_tokens` value
to change the target number of thinking tokens.
-
-```yaml
-- name: anthropic/claude-3-7-sonnet-20250219
- edit_format: diff
- weak_model_name: anthropic/claude-3-5-haiku-20241022
- use_repo_map: true
- examples_as_sys_msg: true
- use_temperature: false
- extra_params:
- extra_headers:
- anthropic-beta:
prompt-caching-2024-07-31,pdfs-2024-09-25,output-128k-2025-02-19
- max_tokens: 64000
- thinking:
- type: enabled
- budget_tokens: 32000 # Adjust this number
- cache_control: true
- editor_model_name: anthropic/claude-3-7-sonnet-20250219
- editor_edit_format: editor-diff
-```
+Aider can work with Sonnet 3.7's [new thinking
tokens](https://www.anthropic.com/news/claude-3-7-sonnet). You can now enable
and configure thinking tokens more easily using the following methods:
+
+1. **In-Chat Command:** Use the `/think-tokens` command followed by the
desired token budget. For example: `/think-tokens 8k` or `/think-tokens 10000`.
Supported formats include `8096`, `8k`, `10.5k`, and `0.5M`.
+
+2. **Command-Line Argument:** Set the `--thinking-tokens` argument when
starting Aidermacs. For example, you can add this to your
`aidermacs-extra-args`:
+
+ ```emacs-lisp
+ (setq aidermacs-extra-args '("--thinking-tokens" "16k"))
+ ```
+
+These methods provide a more streamlined way to control thinking tokens
without requiring manual configuration of `.aider.model.settings.yml` files.
-More streamlined support will be coming soon.
+*Note: If you are using an `.aider.conf.yml` file, you can also set the
`thinking_tokens` option there.*
## Usage
diff --git a/aidermacs-backend-comint.el b/aidermacs-backend-comint.el
index 4b73907d4b..d891d04e7f 100644
--- a/aidermacs-backend-comint.el
+++ b/aidermacs-backend-comint.el
@@ -1,6 +1,6 @@
;;; aidermacs-backend-comint.el --- Comint backend for aidermacs -*-
lexical-binding: t; -*-
;; Author: Mingde (Matthew) Zeng <[email protected]>
-;; Version: 1.0.0
+;; Version: 1.0
;; Keywords: ai emacs llm aider ai-pair-programming tools
;; URL: https://github.com/MatthewZMD/aidermacs
;; SPDX-License-Identifier: Apache-2.0
@@ -31,6 +31,15 @@
(declare-function aidermacs--show-ediff-for-edited-files "aidermacs")
(declare-function aidermacs--detect-edited-files "aidermacs")
(declare-function aidermacs--process-message-if-multi-line "aidermacs" (str))
+(declare-function aidermacs--parse-output-for-files "aidermacs-backends"
(output))
+(declare-function aidermacs--store-output "aidermacs-backends" (output))
+(declare-function aidermacs--is-aidermacs-buffer-p "aidermacs-backends"
(&optional buffer))
+
+(defvar aidermacs--last-command)
+
+(defgroup aidermacs-backend-comint nil
+ "Comint backend for Aidermacs."
+ :group 'aidermacs)
(defcustom aidermacs-language-name-map '(("elisp" . "emacs-lisp")
("bash" . "sh")
@@ -41,6 +50,8 @@
:type '(alist :key-type (string :tag "Language Name/Alias")
:value-type (string :tag "Mode Name (without -mode)")))
+;; FIXME: Hmm... seems to use standard diff3 markers. Maybe some code
+;; in `smerge-mode.el' could be (re)used?
(defconst aidermacs-search-marker "<<<<<<< SEARCH")
(defconst aidermacs-diff-marker "=======")
(defconst aidermacs-replace-marker ">>>>>>> REPLACE")
@@ -63,7 +74,7 @@ This allows for multi-line input without sending the command."
"Face for commands sent to aidermacs buffer.")
(defface aidermacs-search-replace-block
- '((t :inherit 'diff-refine-added :bold t))
+ '((t :inherit diff-refine-added :bold t))
"Face for search/replace block content.")
(defvar aidermacs-font-lock-keywords
diff --git a/aidermacs-backend-vterm.el b/aidermacs-backend-vterm.el
index 24dee78147..d4fbc3af1a 100644
--- a/aidermacs-backend-vterm.el
+++ b/aidermacs-backend-vterm.el
@@ -1,6 +1,6 @@
;;; aidermacs-backend-vterm.el --- VTerm backend for aidermacs -*-
lexical-binding: t; -*-
;; Author: Mingde (Matthew) Zeng <[email protected]>
-;; Version: 1.0.0
+;; Version: 1.0
;; Keywords: ai emacs llm aider ai-pair-programming tools
;; URL: https://github.com/MatthewZMD/aidermacs
;; SPDX-License-Identifier: Apache-2.0
@@ -47,26 +47,30 @@
(declare-function aidermacs--is-aidermacs-buffer-p "aidermacs")
(declare-function aidermacs-get-buffer-name "aidermacs")
-;; useful because we want to override "RET" key for evil mode insert state
+(declare-function aidermacs--parse-output-for-files "aidermacs-backends"
(output))
+
(declare-function evil-define-minor-mode-key "evil-core")
+(defvar aidermacs-prompt-regexp)
+(defvar aidermacs--last-command)
+
+(defgroup aidermacs-backend-vterm nil
+ "VTerm backend for Aidermacs."
+ :group 'aidermacs)
+
(defvar-local aidermacs--vterm-active-timer nil
"Store the active timer for vterm output processing.")
(defvar-local aidermacs--vterm-last-check-point nil
"Store the last position checked in the vterm buffer.")
-
(defvar-local aidermacs-vterm-check-interval 0.7
"Interval in seconds between checks for command completion in vterm.")
-
(defcustom aidermacs-vterm-multiline-newline-key "S-<return>"
"Key binding to enter a newline without sending in vterm."
:type 'string)
-(defvar aidermacs-prompt-regexp)
-
(defun aidermacs--vterm-check-finish-sequence-repeated (proc orig-filter
start-point)
"Check for the finish sequence in PROC's buffer.
PROC is the process to check. ORIG-FILTER is the original process filter.
@@ -145,7 +149,7 @@ after each output chunk, reducing the need for timers."
(defun aidermacs--maybe-cancel-active-timer (&optional buffer)
"Cancel the active timer if it exists.
Use BUFFER if provided, otherwise retrieve it from
`aidermacs-get-buffer-name'."
- (when-let ((buf (get-buffer (or buffer (aidermacs-get-buffer-name)))))
+ (when-let* ((buf (get-buffer (or buffer (aidermacs-get-buffer-name)))))
(with-current-buffer buf
(when (timerp aidermacs--vterm-active-timer)
(cancel-timer aidermacs--vterm-active-timer)
diff --git a/aidermacs-backends.el b/aidermacs-backends.el
index 2556c6e256..9f37f4da0d 100644
--- a/aidermacs-backends.el
+++ b/aidermacs-backends.el
@@ -1,6 +1,6 @@
;;; aidermacs-backends.el --- Backend dispatcher for aidermacs -*-
lexical-binding: t; -*-
;; Author: Mingde (Matthew) Zeng <[email protected]>
-;; Version: 1.0.0
+;; Version: 1.0
;; Keywords: ai emacs llm aider ai-pair-programming tools
;; URL: https://github.com/MatthewZMD/aidermacs
;; SPDX-License-Identifier: Apache-2.0
@@ -32,6 +32,10 @@
(declare-function aidermacs--prepare-for-code-edit "aidermacs" ())
(declare-function aidermacs--get-files-in-session "aidermacs" (callback))
+(defgroup aidermacs-backends nil
+ "Backend dispatcher for aidermacs."
+ :group 'aidermacs)
+
(defcustom aidermacs-backend 'comint
"Backend to use for the aidermacs process.
Options are `comint' (the default) or `vterm'. When set to `vterm',
@@ -54,6 +58,10 @@ Each entry is a cons cell (timestamp . output-text).")
(defvar-local aidermacs--current-output ""
"Accumulator for current output being captured as a string.")
+(defcustom aidermacs-before-run-backend-hook nil
+ "Hook run before the aidermacs backend is startd."
+ :type 'hook)
+
(defun aidermacs-get-output-history (&optional limit)
"Get the output history, optionally limited to LIMIT entries.
LIMIT is the maximum number of entries to return.
@@ -81,91 +89,81 @@ This is used to avoid having to run /ls repeatedly.")
(defun aidermacs--parse-output-for-files (output)
"Parse OUTPUT for files and add them to `aidermacs--tracked-files'."
(when output
- (let ((tracked-files aidermacs--tracked-files))
- (with-temp-buffer
- (insert output)
- (goto-char (point-min))
-
- ;; Applied edit to <filename>
- (while (search-forward "Applied edit to" nil t)
- (beginning-of-line)
- (when-let ((file (and (looking-at ".*Applied edit to
\\(\\./\\)?\\(.+\\)")
- (match-string-no-properties 2))))
- (add-to-list 'tracked-files file))
- (forward-line 1))
-
- ;; Combined file tracking logic
- (goto-char (point-min))
- (while (re-search-forward
- "\\(Added\\|Removed\\|Moved\\) \\(\\./\\)?\\([^ ]+\\)
\\(to\\|from\\) \\(the chat\\|editable\\|read-only\\) files?"
- nil t)
- (let* ((action (match-string 1))
- (file (match-string 3))
- (state (match-string 5)))
- (cond
- ;; Added files
- ((string= action "Added")
- (add-to-list 'tracked-files
- (if (string= state "read-only")
- (concat file " (read-only)")
- file)))
-
- ;; Removed files
- ((string= action "Removed")
- (setq tracked-files (delete file tracked-files)))
-
- ;; Moved files
- ((string= action "Moved")
- (let* ((from-state (if (string= state "editable") "read-only"
"editable"))
- (old-file (if (string= from-state "read-only")
- (concat file " (read-only)")
- file))
- (new-file (if (string= state "read-only")
- (concat file " (read-only)")
- file)))
- (setq tracked-files (delete old-file tracked-files))
- (add-to-list 'tracked-files new-file))))))
-
- ;; <file> is already in the chat as an editable file
- (goto-char (point-min))
- (while (search-forward " is already in the chat as an editable file"
nil t)
- (beginning-of-line)
- (when-let ((file (and (looking-at "\\(\\./\\)?\\(.+\\) is already in
the chat as an editable file")
- (match-string-no-properties 2))))
- (add-to-list 'tracked-files file))
- (forward-line 1))
-
- ;; Add file to the chat?
- (goto-char (point-min))
- (while (search-forward "Add file to the chat?" nil t)
- (save-excursion
- (forward-line -1)
- (let ((potential-file (string-trim (buffer-substring
(line-beginning-position) (line-end-position)))))
- (when (not (string-empty-p potential-file))
- (add-to-list 'tracked-files potential-file)
- (aidermacs--prepare-for-code-edit))))
- (forward-line 1))
-
- ;; Handle udiff format
- (goto-char (point-min))
- (while (search-forward "--- " nil t)
- (message "processing %s " tracked-files)
- (let* ((line-end (line-end-position))
- (current-udiff-file (when (looking-at "\\(\\./\\)?\\(.+\\)")
- (match-string-no-properties 2))))
- (when current-udiff-file
- (forward-line 1)
- (when (looking-at "\\+\\+\\+ \\(\\./\\)?\\(.+\\)")
- (let ((plus-file (match-string-no-properties 2)))
- (when (string= (file-name-nondirectory current-udiff-file)
- (file-name-nondirectory plus-file))
- (add-to-list 'tracked-files current-udiff-file))))))))
+ (let ((lines (split-string output "\n"))
+ (last-line "")
+ (in-udiff nil)
+ (current-udiff-file nil))
+ (dolist (line lines)
+ (cond
+ ;; Applied edit to <filename>
+ ((string-match "Applied edit to \\(\\./\\)?\\(.+\\)" line)
+ (when-let ((file (match-string 2 line)))
+ (add-to-list 'aidermacs--tracked-files file)))
+
+ ;; Added <filename> to the chat.
+ ((string-match "Added \\(\\./\\)?\\(.+\\) to the chat" line)
+ (when-let ((file (match-string 2 line)))
+ (add-to-list 'aidermacs--tracked-files file)))
+
+ ;; Removed <filename> from the chat (with or without ./ prefix)
+ ((string-match "Removed \\(\\./\\)?\\(.+\\) from the chat" line)
+ (when-let ((file (match-string 2 line)))
+ (setq aidermacs--tracked-files (delete file
aidermacs--tracked-files))))
+
+ ;; Added <filename> to read-only files.
+ ((string-match "Added \\(\\./\\)?\\(.+\\) to read-only files" line)
+ (when-let ((file (match-string 2 line)))
+ (add-to-list 'aidermacs--tracked-files (concat file "
(read-only)"))))
+
+ ;; Moved <file> from editable to read-only files in the chat
+ ((string-match "Moved \\(\\./\\)?\\(.+\\) from editable to read-only
files in the chat" line)
+ (when-let ((file (match-string 2 line)))
+ (let ((editable-file (replace-regexp-in-string " (read-only)$" ""
file)))
+ (setq aidermacs--tracked-files (delete editable-file
aidermacs--tracked-files))
+ (add-to-list 'aidermacs--tracked-files (concat file "
(read-only)")))))
+
+ ;; Moved <file> from read-only to editable files in the chat
+ ((string-match "Moved \\(\\./\\)?\\(.+\\) from read-only to editable
files in the chat" line)
+ (when-let ((file (match-string 2 line)))
+ (let ((read-only-file (concat file " (read-only)")))
+ (setq aidermacs--tracked-files (delete read-only-file
aidermacs--tracked-files))
+ (add-to-list 'aidermacs--tracked-files file))))
+
+ ;; <file>\nAdd file to the chat?
+ ((string-match "Add file to the chat?" line)
+ (add-to-list 'aidermacs--tracked-files last-line)
+ (aidermacs--prepare-for-code-edit))
+
+ ;; <file> is already in the chat as an editable file
+ ((string-match "\\(\\./\\)?\\(.+\\) is already in the chat as an
editable file" line)
+ (when-let ((file (match-string 2 line)))
+ (add-to-list 'aidermacs--tracked-files file)))
+
+ ;; Handle udiff format
+ ;; Detect start of udiff with "--- filename"
+ ((string-match "^--- \\(\\./\\)?\\(.+\\)" line)
+ (setq in-udiff t
+ current-udiff-file (match-string 2 line)))
+
+ ;; Confirm udiff file with "+++ filename" line
+ ((and in-udiff
+ current-udiff-file
+ (string-match "^\\+\\+\\+ \\(\\./\\)?\\(.+\\)" line))
+ (let ((plus-file (match-string 2 line)))
+ ;; Only add if the filenames match (ignoring ./ prefix)
+ (when (string= (file-name-nondirectory current-udiff-file)
+ (file-name-nondirectory plus-file))
+ (add-to-list 'aidermacs--tracked-files current-udiff-file)
+ (setq in-udiff nil
+ current-udiff-file nil)))))
+
+ (setq last-line line))
;; Verify all tracked files exist
(let* ((project-root (aidermacs-project-root))
(is-remote (file-remote-p project-root))
(valid-files nil))
- (dolist (file tracked-files)
+ (dolist (file aidermacs--tracked-files)
(let* ((is-readonly (string-match-p " (read-only)$" file))
(actual-file (if is-readonly
(substring file 0 (- (length file) 12))
@@ -173,15 +171,7 @@ This is used to avoid having to run /ls repeatedly.")
(full-path (expand-file-name actual-file project-root)))
(when (or (file-exists-p full-path) is-remote)
(push file valid-files))))
- (setq tracked-files valid-files))
- (setq aidermacs--tracked-files tracked-files))))
-
-(defun aidermacs-reset-tracked-files ()
- "Reset the list of tracked files and force a refresh."
- (interactive)
- (setq aidermacs--tracked-files nil)
- (aidermacs--get-files-in-session (lambda (files)
- (message "Refreshed file list: %s"
files))))
+ (setq aidermacs--tracked-files valid-files)))))
(defun aidermacs--store-output (output)
"Store output string in the history with timestamp.
@@ -210,6 +200,7 @@ If there's a callback function, call it with the output."
PROGRAM is the aidermacs executable path. ARGS are command line arguments.
BUFFER-NAME is the name for the aidermacs buffer."
(message "Running %s with %s" program args)
+ (run-hooks 'aidermacs-before-run-backend-hook)
(cond
((eq aidermacs-backend 'vterm)
(aidermacs-run-vterm program args buffer-name))
diff --git a/aidermacs-models.el b/aidermacs-models.el
index 0fdcdafa9e..60f4db8305 100644
--- a/aidermacs-models.el
+++ b/aidermacs-models.el
@@ -1,6 +1,6 @@
;;; aidermacs-models.el --- Model selection for aidermacs -*- lexical-binding:
t; -*-
;; Author: Mingde (Matthew) Zeng <[email protected]>
-;; Version: 1.0.0
+;; Version: 1.0
;; Keywords: ai emacs llm aider ai-pair-programming tools
;; URL: https://github.com/MatthewZMD/aidermacs
;; SPDX-License-Identifier: Apache-2.0
@@ -32,6 +32,10 @@
(declare-function aidermacs-buffer-name "aidermacs" ())
(declare-function aidermacs-exit "aidermacs" ())
+(defgroup aidermacs-models nil
+ "Model selection for Aidermacs."
+ :group 'aidermacs)
+
(defcustom aidermacs-default-model "sonnet"
"Default AI model to use for aidermacs sessions when not in Architect mode."
:type 'string)
diff --git a/aidermacs.el b/aidermacs.el
index 238bd39478..cbcd75dffd 100644
--- a/aidermacs.el
+++ b/aidermacs.el
@@ -1,6 +1,6 @@
;;; aidermacs.el --- AI pair programming with Aider -*- lexical-binding: t; -*-
;; Author: Mingde (Matthew) Zeng <[email protected]>
-;; Version: 1.0.0
+;; Version: 1.0
;; Package-Requires: ((emacs "29.1"))
;; Keywords: ai emacs llm aider ai-pair-programming tools
;; URL: https://github.com/MatthewZMD/aidermacs
@@ -35,10 +35,15 @@
(require 'ansi-color)
(require 'cl-lib)
(require 'tramp)
+(require 'find-dired)
(require 'aidermacs-backends)
(require 'aidermacs-models)
+(defgroup aidermacs nil
+ "AI pair programming with Aider."
+ :group 'aidermacs)
+
(defvar-local aidermacs--current-mode nil
"Buffer-local variable to track the current aidermacs mode.
Possible values: `code', `ask', `architect', `help'.")
@@ -78,10 +83,15 @@ This is useful for working in monorepos where you want to
limit aider's scope."
When nil, disable auto-commits requiring manual git commits."
:type 'boolean)
+(defcustom aidermacs-auto-accept-architect nil
+ "When non-nil, automatically accept architect mode changes.
+When nil, require explicit confirmation before applying changes."
+ :type 'boolean)
+
(defun aidermacs-project-root ()
"Get the project root using project.el, VC, or fallback to file directory.
This function tries multiple methods to determine the project root."
- (or (when-let ((proj (project-current)))
+ (or (when-let* ((proj (project-current)))
(project-root proj))
(vc-git-root default-directory)
(when buffer-file-name
@@ -255,8 +265,10 @@ This function sets up the appropriate arguments and
launches the process."
"--editor-model" aidermacs-editor-model)
(unless has-model-arg
(list "--model" aidermacs-default-model)))
- (when (not aidermacs-auto-commits)
+ (unless aidermacs-auto-commits
'("--no-auto-commits"))
+ (unless aidermacs-auto-accept-architect
+ '("--no-auto-accept-architect"))
(when aidermacs-subtree-only
'("--subtree-only")))))
(final-args (append backend-args flat-extra-args)))
@@ -376,7 +388,7 @@ Returns a list of files that have been modified according
to the output."
;; Case 1: Find "Applied edit to" lines
(while (search-forward "Applied edit to" nil t)
(beginning-of-line)
- (when-let ((file (and (looking-at ".*Applied edit to
\\(\\./\\)?\\([^[:space:]]+\\)")
+ (when-let* ((file (and (looking-at ".*Applied edit to
\\(\\./\\)?\\([^[:space:]]+\\)")
(match-string-no-properties 2))))
(push file edited-files))
(forward-line 1))
@@ -514,7 +526,7 @@ If the current buffer is already the aidermacs buffer, do
nothing."
(buffer
(pop-to-buffer buffer))
(t
- (error "No aidermacs buffer exists.")))))
+ (error "No aidermacs buffer exists")))))
(defun aidermacs-clear-chat-history ()
"Send the command \"/clear\" to the aidermacs buffer."
@@ -643,7 +655,8 @@ Sends the \"/ls\" command and displays the results in a
Dired buffer."
;; The executed command is on the 2nd line; it can get
;; quite long, so we delete it to avoid cluttering the
;; buffer.
- (goto-line 2)
+ (goto-char (point-min))
+ (forward-line 1) ;; Move to the 2nd line
(when (looking-at "^ *find " t)
(let ((inhibit-read-only t))
(delete-region (line-beginning-position)
(line-end-position)))))
@@ -665,6 +678,7 @@ Sends the \"/ls\" command and displays the results in a
Dired buffer."
(defun aidermacs-drop-all-files ()
"Drop all files from the current chat session."
(interactive)
+ (setq aidermacs--tracked-files nil)
(aidermacs--send-command "/drop"))
(defun aidermacs-batch-drop-dired-marked-files ()
@@ -719,7 +733,7 @@ Use highlighted region as context unless IGNORE-CONTEXT is
set to non-nil."
(let* ((region-text (when (and (use-region-p) (not ignore-context))
(buffer-substring-no-properties (region-beginning)
(region-end))))
(context (when region-text
- (format " regarding this section:\n```\n%s\n```\n"
region-text)))
+ (format " in %s regarding this section:\n```\n%s\n```\n"
(buffer-name) region-text)))
(user-command (read-string (concat command " " prompt-prefix context
(when guide (format " (%s)"
guide)) ": "))))
(concat command (and (not (string-empty-p user-command))
@@ -728,7 +742,7 @@ Use highlighted region as context unless IGNORE-CONTEXT is
set to non-nil."
(defun aidermacs-direct-change ()
"Prompt the user for an input and send it to aidemracs prefixed with \"/code
\"."
(interactive)
- (when-let ((command (aidermacs--form-prompt "/code" "Make this change" "will
edit file")))
+ (when-let* ((command (aidermacs--form-prompt "/code" "Make this change"
"will edit file")))
(aidermacs--ensure-current-file-tracked)
(aidermacs--send-command command)))
@@ -738,7 +752,7 @@ If a region is active, include the region text in the
question.
If cursor is inside a function, include the function name as context.
If called from the aidermacs buffer, use general question instead."
(interactive)
- (when-let ((command (aidermacs--form-prompt "/ask" "Propose a solution"
"won't edit file")))
+ (when-let* ((command (aidermacs--form-prompt "/ask" "Propose a solution"
"won't edit file")))
(aidermacs--ensure-current-file-tracked)
(aidermacs--send-command command)))
@@ -747,26 +761,26 @@ If called from the aidermacs buffer, use general question
instead."
If region is active, inspect that region.
If point is in a function, inspect that function."
(interactive)
- (when-let ((command (aidermacs--form-prompt "/architect" "Design a solution"
"confirm before edit")))
+ (when-let* ((command (aidermacs--form-prompt "/architect" "Design a
solution" "confirm before edit")))
(aidermacs--ensure-current-file-tracked)
(aidermacs--send-command command)))
(defun aidermacs-question-general ()
"Prompt the user for a general question without code context."
(interactive)
- (when-let ((command (aidermacs--form-prompt "/ask" nil "empty for ask mode"
t)))
+ (when-let* ((command (aidermacs--form-prompt "/ask" nil "empty for ask mode"
t)))
(aidermacs--send-command command)))
(defun aidermacs-help ()
"Prompt the user for an input prefixed with \"/help \"."
(interactive)
- (when-let ((command (aidermacs--form-prompt "/help" nil "question how to use
aider, empty for all commands" t)))
+ (when-let* ((command (aidermacs--form-prompt "/help" nil "question how to
use aider, empty for all commands" t)))
(aidermacs--send-command command)))
(defun aidermacs-debug-exception ()
"Prompt the user for an input and send it to aidemracs prefixed with
\"/debug \"."
(interactive)
- (when-let ((command (aidermacs--form-prompt "/ask" "Debug exception")))
+ (when-let* ((command (aidermacs--form-prompt "/ask" "Debug exception")))
(aidermacs--send-command command)))
(defun aidermacs-accept-change ()
@@ -939,7 +953,7 @@ Otherwise:
- Otherwise generate unit tests for the entire file"
(interactive)
(if (not buffer-file-name)
- (user-error "Current buffer is not visiting a file.")
+ (user-error "Current buffer is not visiting a file")
(let ((function-name (which-function)))
(cond
;; Test file case
@@ -972,7 +986,7 @@ Otherwise:
"Report the current test failure to aidermacs and ask it to fix the code.
This function assumes the cursor is on or inside a test function."
(interactive)
- (if-let ((test-function-name (which-function)))
+ (if-let* ((test-function-name (which-function)))
(let* ((initial-input (format "The test '%s' is failing. Please analyze
and fix the code to make the test pass. Don't break any other test"
test-function-name))
(command (aidermacs--form-prompt "/architect" initial-input)))
@@ -1002,7 +1016,7 @@ snippets, or other content to the session."
(message "Created and added scratchpad to session: %s" filename)))
(defun aidermacs-add-file-to-session (&optional file)
- "Interactively add a file to an existing aidermacs session using /read.
+ "Interactively add a FILE to an existing aidermacs session using /read.
This allows you to add the file's content to a specific session."
(interactive
(let* ((initial (when buffer-file-name
@@ -1046,7 +1060,7 @@ Otherwise implement TODOs for the entire current file."
(message "Current buffer is not visiting a file.")
(let* ((current-line (string-trim (thing-at-point 'line t)))
(is-comment (aidermacs--is-comment-line current-line)))
- (when-let ((command (aidermacs--form-prompt
+ (when-let* ((command (aidermacs--form-prompt
"/architect"
(concat "Please implement the TODO items."
(and is-comment
@@ -1119,10 +1133,10 @@ sample prompt."
;;;###autoload
(defvar aidermacs-minor-mode-map
(let ((map (make-sparse-keymap)))
- (define-key map (kbd "C-c C-n") 'aidermacs-send-line-or-region)
- (define-key map (kbd "C-<return>") 'aidermacs-send-line-or-region)
- (define-key map (kbd "C-c C-c") 'aidermacs-send-block-or-region)
- (define-key map (kbd "C-c C-z") 'aidermacs-switch-to-buffer)
+ (define-key map (kbd "C-c C-n") #'aidermacs-send-line-or-region)
+ (define-key map (kbd "C-<return>") #'aidermacs-send-line-or-region)
+ (define-key map (kbd "C-c C-c") #'aidermacs-send-block-or-region)
+ (define-key map (kbd "C-c C-z") #'aidermacs-switch-to-buffer)
map)
"Keymap for `aidermacs-minor-mode'.")