Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 56 additions & 29 deletions aidermacs.el
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,36 @@
If it is a list, Aidermacs will try each program in order."
:type '(choice string (repeat :tag "Program fallbacks" string)))

(defvar aidermacs--resolved-program nil
"Cached path to the resolved Aider program.")
(defvar aidermacs--resolved-programs (make-hash-table :test 'equal)
"Hash table of cached resolved Aider program paths keyed by workspace.")

(defvar aidermacs--cached-versions (make-hash-table :test 'equal)
"Hash table of cached aider versions keyed by workspace.")

(defun aidermacs--get-cache-key ()
"Generate a unique cache key based on current workspace context.
Returns a string combining the remote connection (if any) and project root."
(let ((remote-prefix (file-remote-p default-directory))
(root (aidermacs-project-root)))
(concat (or remote-prefix "local") "::" root)))


(defun aidermacs-get-program ()
"Resolve and return the path to the Aider program.
The value is cached in `aidermacs--resolved-program`.
The value is cached per-workspace in `aidermacs--resolved-programs`.
It respects `aidermacs-program` which can be a string or a list of strings."
(or aidermacs--resolved-program
(let* ((programs (if (listp aidermacs-program) aidermacs-program (list aidermacs-program)))
(program (cl-some #'executable-find programs)))
(unless program
(error "Aider executable not found. Checked: %s" programs))
(setq aidermacs--resolved-program program))))
(let* ((key (aidermacs--get-cache-key))
(cached (gethash key aidermacs--resolved-programs)))
(or cached
(let* ((programs (if (listp aidermacs-program) aidermacs-program (list aidermacs-program)))
(finder-fn (if (file-remote-p default-directory)
(lambda (prog) (executable-find prog t))
#'executable-find))
(program (cl-some finder-fn programs)))
(unless program
(error "Aider executable not found. Checked: %s" programs))
(puthash key program aidermacs--resolved-programs)
program))))

(defvar-local aidermacs--current-mode nil
"Buffer-local variable to track the current aidermacs mode.
Expand Down Expand Up @@ -180,27 +197,37 @@ These will be available for selection when using aidermacs commands."
(defun aidermacs-aider-version ()
"Check the installed aider version.
Returns a version string like \"0.77.0\" or nil if version can't be determined.
Uses cached version if available to avoid repeated process calls."
Uses cached version per-workspace if available to avoid repeated process calls."
(interactive)
(let ((path exec-path))
(or aidermacs--cached-version
(setq aidermacs--cached-version
(with-temp-buffer
(setq-local exec-path path)
(when (= 0 (process-file (aidermacs-get-program) nil t nil "--version"))
(goto-char (point-min))
(when (re-search-forward
"\\([0-9]+\\.[0-9]+\\.[0-9]+\\)" nil t)
(match-string 0)))))))
(message "Aider version %s" aidermacs--cached-version)
aidermacs--cached-version)

(defun aidermacs-clear-aider-version-cache ()
(let* ((path exec-path)
(key (aidermacs--get-cache-key))
(cached (gethash key aidermacs--cached-versions)))
(unless cached
(let ((version
(with-temp-buffer
(setq-local exec-path path)
(when (= 0 (process-file (aidermacs-get-program) nil t nil "--version"))
(goto-char (point-min))
(when (re-search-forward
"\\([0-9]+\\.[0-9]+\\.[0-9]+\\)" nil t)
(match-string 0))))))
(puthash key version aidermacs--cached-versions)
(setq cached version)))
(message "Aider version %s" (or cached "unknown"))
cached))

(defun aidermacs-clear-aider-version-cache (&optional all)
"Clear the cached aider version.
With prefix argument ALL (C-u), clear all cached versions.
Without prefix, clear only the cache for the current workspace.
Call this after upgrading aider to ensure the correct version is detected."
(interactive)
(setq aidermacs--cached-version nil)
(message "Aider version cache cleared."))
(interactive "P")
(if all
(progn
(clrhash aidermacs--cached-versions)
(message "Aider version cache cleared for all workspaces."))
(remhash (aidermacs--get-cache-key) aidermacs--cached-versions)
(message "Aider version cache cleared for current workspace.")))

(defun aidermacs-project-root ()
"Get the project root using VC-git, or fallback to file directory.
Expand Down Expand Up @@ -438,8 +465,8 @@ set `aidermacs-default-chat-mode' to 'architect' instead."
(when aidermacs-weak-model
(list "--weak-model" aidermacs-weak-model))
;; Aider-CE Only Option
(when (and aidermacs--resolved-program
(string-match-p "aider-ce" aidermacs--resolved-program))
(when (let ((prog (gethash (aidermacs--get-cache-key) aidermacs--resolved-programs)))
(and prog (string-match-p "aider-ce" prog)))
'("--linear-output"))
(when aidermacs-global-read-only-files
(apply #'append
Expand Down