branch: elpa/aidermacs commit 74b1859c0070109c838ba64619e61a7581698f63 Author: Ryan Schmukler <rschmuk...@gmail.com> Commit: Ryan Schmukler <rschmuk...@gmail.com>
Add Tramp Support This commit adds support for using aidermacs via tramp. Interestingly enough the functionality was written almost completely with aider. Wild times! The main things are: 1. Processing file names before sending them to commands like `/add`, `/read`, etc. 2. Handling output from `/ls` related commands to handle remote files --- aidermacs-backends.el | 5 ++-- aidermacs.el | 81 +++++++++++++++++++++++++++++++-------------------- 2 files changed, 53 insertions(+), 33 deletions(-) diff --git a/aidermacs-backends.el b/aidermacs-backends.el index 2b127d3545..8e4f7e4880 100644 --- a/aidermacs-backends.el +++ b/aidermacs-backends.el @@ -91,7 +91,8 @@ This is used to avoid having to run /ls repeatedly.") (defun aidermacs--verify-tracked-files () "Verify files in `aidermacs--tracked-files` exist. Remove any files that don't exist." - (let ((project-root (aidermacs-project-root)) + (let* ((project-root (aidermacs-project-root)) + (is-remote (file-remote-p project-root)) (valid-files nil)) (dolist (file aidermacs--tracked-files) (let* ((is-readonly (string-match-p " (read-only)$" file)) @@ -99,7 +100,7 @@ Remove any files that don't exist." (substring file 0 (- (length file) 12)) file)) (full-path (expand-file-name actual-file project-root))) - (when (file-exists-p full-path) + (when (or (file-exists-p full-path) is-remote) (push file valid-files)))) (setq aidermacs--tracked-files valid-files))) diff --git a/aidermacs.el b/aidermacs.el index 5c9243991a..e9bc0be1a2 100644 --- a/aidermacs.el +++ b/aidermacs.el @@ -34,6 +34,7 @@ (require 'which-func) (require 'ansi-color) (require 'cl-lib) +(require 'tramp) (require 'aidermacs-backends) (require 'aidermacs-models) @@ -575,28 +576,18 @@ https://aidermacs.chat/docs/usage/commands.html#entering-multi-line-chat-message str)) ;;;###autoload -(defun aidermacs-act-on-current-file (command-prefix) - "Send a command with the current file path to the aidermacs buffer. -COMMAND-PREFIX is the command to prepend to the file path. -The full command will be \"COMMAND-PREFIX <current buffer file full path>\"." - ;; Ensure the current buffer is associated with a file +(defun aidermacs-drop-current-file () + "Drop the current file from aidermacs session." + (interactive) (if (not buffer-file-name) (message "Current buffer is not associated with a file.") - (let* ((file-path (buffer-file-name)) - ;; Use buffer-file-name directly + (let* ((file-path (aidermacs--localize-tramp-path buffer-file-name)) (formatted-path (if (string-match-p " " file-path) (format "\"%s\"" file-path) file-path)) - (command (format "%s %s" command-prefix formatted-path))) - ;; Use the shared helper function to send the command + (command (format "/drop %s" formatted-path))) (aidermacs--send-command command)))) -;;;###autoload -(defun aidermacs-drop-current-file () - "Drop the current file from aidermacs session." - (interactive) - (aidermacs-act-on-current-file "/drop")) - ;;;###autoload (defun aidermacs-general-command () "Prompt the user to input COMMAND and send it to the aidemracs." @@ -624,8 +615,9 @@ Returns a deduplicated list of such file names." (with-temp-buffer (insert output) (goto-char (point-min)) - (let ((files '()) - (base (aidermacs-project-root))) + (let* ((files '()) + (base (aidermacs-project-root)) + (is-remote (file-remote-p base))) ;; Parse read-only files section (when (search-forward "Read-only files:" nil t) (forward-line 1) @@ -633,11 +625,15 @@ Returns a deduplicated list of such file names." (string-match-p "^[[:space:]]" (thing-at-point 'line t))) (let* ((line (string-trim (thing-at-point 'line t))) (file (car (split-string line)))) - (when (and file (file-exists-p (expand-file-name file base))) - ;; Store relative path with read-only marker - (push (concat (file-relative-name (expand-file-name file base) base) - " (read-only)") - files))) + ;; For remote files, we don't try to verify existence or convert paths + (when file + (if is-remote + (push (concat file " (read-only)") files) + ;; For local files, verify existence and convert to relative path + (when (file-exists-p (expand-file-name file base)) + (push (concat (file-relative-name (expand-file-name file base) base) + " (read-only)") + files))))) (forward-line 1))) ;; Parse files in chat section @@ -647,9 +643,13 @@ Returns a deduplicated list of such file names." (string-match-p "^[[:space:]]" (thing-at-point 'line t))) (let* ((line (string-trim (thing-at-point 'line t))) (file (car (split-string line)))) - (when (and file (file-exists-p (expand-file-name file base))) - ;; Store relative path - (push (file-relative-name (expand-file-name file base) base) files))) + ;; For remote files, we don't try to verify existence or convert paths + (when file + (if is-remote + (push file files) + ;; For local files, verify existence and convert to relative path + (when (file-exists-p (expand-file-name file base)) + (push (file-relative-name (expand-file-name file base) base) files))))) (forward-line 1))) ;; Remove duplicates and return @@ -682,7 +682,8 @@ Sends the \"/ls\" command and returns the list of files via callback." (lambda (files) (if-let* ((file (completing-read "Select file to drop: " files nil t)) (clean-file (replace-regexp-in-string " (read-only)$" "" file))) - (aidermacs--send-command (format "/drop ./%s" clean-file)) + (let ((command (aidermacs--prepare-file-paths-for-command "/drop" (list (concat "./" clean-file))))) + (aidermacs--send-command command)) (message "No files available to drop"))))) @@ -841,17 +842,33 @@ PREFIX is the text to prepend. COMMAND is the text to send." (aidermacs-add-current-file) (aidermacs--send-command (concat prefix command))) +(defun aidermacs--localize-tramp-path (file) + "If FILE is a TRAMP path, extract the local part of the path. +Otherwise, return FILE unchanged." + (if (and (fboundp 'tramp-tramp-file-p) (tramp-tramp-file-p file)) + (let ((local-name (tramp-file-name-localname (tramp-dissect-file-name file)))) + local-name) + file)) + +(defun aidermacs--prepare-file-paths-for-command (command files) + "Prepare FILES for use with COMMAND in aider. +Handles TRAMP paths by extracting local parts and formats the command string." + (let ((localized-files (mapcar #'aidermacs--localize-tramp-path (delq nil files)))) + (if localized-files + (format "%s %s" command + (mapconcat #'identity localized-files " ")) + (format "%s" command)))) + (defun aidermacs--add-files-helper (files read-only &optional message) "Helper function to add files with read-only flag. FILES is a list of file paths to add. READ-ONLY determines if files are added as read-only. Optional MESSAGE can override the default success message." (let* ((cmd (if read-only "/read-only" "/add")) + (command (aidermacs--prepare-file-paths-for-command cmd files)) (files (delq nil files))) (if files (progn - (aidermacs--send-command - (format "%s %s" cmd - (mapconcat #'identity files " "))) + (aidermacs--send-command command) (message (or message (format "Added %d files as %s" (length files) @@ -1010,7 +1027,8 @@ snippets, or other content to the session." (insert ";; Add your code snippets, functions, or other content here\n") (insert ";; Just edit and save - changes will be available to aider\n\n") (write-file filename)) - (aidermacs--send-command (format "/read %s" filename)) + (let ((command (aidermacs--prepare-file-paths-for-command "/read" (list filename)))) + (aidermacs--send-command command)) (find-file-other-window filename) (message "Created and added scratchpad to session: %s" filename))) @@ -1027,7 +1045,8 @@ specific session." nil nil t initial)))) (if (not (file-exists-p file)) (message "File does not exist: %s" file) - (aidermacs--send-command (format "/read %s" file) nil t)))) + (let ((command (aidermacs--prepare-file-paths-for-command "/read" (list file)))) + (aidermacs--send-command command nil t))))) (defun aidermacs--is-comment-line (line) "Check if LINE is a comment line based on current buffer's comment syntax.