From 6f047a4590a9354c3760bfb6eedff8346616903a Mon Sep 17 00:00:00 2001 From: skittishdev <42278215+skittishdev@users.noreply.github.com> Date: Wed, 3 Dec 2025 14:19:40 -0800 Subject: [PATCH] Improve tramp support. Also add support for per-workspace cache variables. Fixes: https://github.com/MatthewZMD/aidermacs/issues/175 --- aidermacs.el | 85 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 56 insertions(+), 29 deletions(-) diff --git a/aidermacs.el b/aidermacs.el index 54c541f..29a5365 100644 --- a/aidermacs.el +++ b/aidermacs.el @@ -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. @@ -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. @@ -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