branch: elpa/aidermacs commit 04209e9e35d5551ef5407117be31c9ba3aed6f3d Merge: d775ffafaa 9ce579a061 Author: Matthew Zeng <matthew...@posteo.net> Commit: GitHub <nore...@github.com>
Merge pull request #21 from CeleritasCelery/redirect-wip Use redirection for sending commands to aider --- aidermacs-backend-comint.el | 32 ++++++++++++++++++-------------- aidermacs-backends.el | 18 ++++++++++++------ aidermacs-models.el | 6 ++---- aidermacs.el | 34 +++++++++++++++++++++------------- 4 files changed, 53 insertions(+), 37 deletions(-) diff --git a/aidermacs-backend-comint.el b/aidermacs-backend-comint.el index cfa098b5dd..f489eb56ac 100644 --- a/aidermacs-backend-comint.el +++ b/aidermacs-backend-comint.el @@ -221,24 +221,11 @@ This allows for multi-line input without sending the command." (when (bufferp aidermacs--syntax-work-buffer) (kill-buffer aidermacs--syntax-work-buffer))) -(defvar-local aidermacs--comint-output-temp "" - "Temporary output variable storing the raw output string.") - (defun aidermacs-input-sender (proc string) "Reset font-lock state before executing a command." (aidermacs-reset-font-lock-state) (comint-simple-send proc (aidermacs--process-message-if-multi-line string))) -(defun aidermacs--comint-output-filter (output) - "Accumulate OUTPUT string until a prompt is detected, then store it." - (unless (string-empty-p output) - (setq aidermacs--comint-output-temp - (concat aidermacs--comint-output-temp (substring-no-properties output))) - ;; Check if the output contains a prompt - (when (string-match-p "\n[^[:space:]]*>[[:space:]]$" aidermacs--comint-output-temp) - (aidermacs--store-output aidermacs--comint-output-temp) - (setq aidermacs--comint-output-temp "")))) - (defun aidermacs-run-comint (program args buffer-name) "Create a comint-based buffer and run aidermacs PROGRAM with ARGS in BUFFER-NAME." (let ((comint-terminfo-terminal "eterm-color") @@ -247,12 +234,12 @@ This allows for multi-line input without sending the command." (apply 'make-comint-in-buffer "aidermacs" buffer-name program nil args) (with-current-buffer buffer-name (comint-mode) + (setq-local comint-prompt-regexp "^> $") (setq-local comint-input-sender 'aidermacs-input-sender) (setq aidermacs--syntax-work-buffer (get-buffer-create (concat " *aidermacs-syntax" buffer-name))) (add-hook 'kill-buffer-hook #'aidermacs-kill-buffer nil t) (add-hook 'comint-output-filter-functions #'aidermacs-fontify-blocks 100 t) - (add-hook 'comint-output-filter-functions #'aidermacs--comint-output-filter) (let ((local-map (make-sparse-keymap))) (set-keymap-parent local-map comint-mode-map) (define-key local-map (kbd aidermacs-comint-multiline-newline-key) #'comint-accumulate) @@ -273,6 +260,23 @@ This allows for multi-line input without sending the command." (set-marker (process-mark process) (point)) (comint-send-string process (concat command "\n"))))) +(defun aidermacs--send-command-redirect-comint (buffer command) + "Send COMMAND to the aidermacs comint BUFFER and collect result into OUTPUT-BUFFER." + (with-current-buffer buffer + (let ((process (get-buffer-process buffer)) + (output-buffer (get-buffer-create " *aider-redirect-buffer*"))) + (with-current-buffer output-buffer + (erase-buffer)) + (goto-char (process-mark process)) + (comint-redirect-send-command command output-buffer nil t) + (unwind-protect + (while (or quit-flag (null comint-redirect-completed)) + (accept-process-output nil 0.1)) + (unless comint-redirect-completed + (comint-redirect-cleanup))) + (aidermacs--store-output (with-current-buffer output-buffer + (buffer-string)))))) + (provide 'aidermacs-backend-comint) ;;; aidermacs-backend-comint.el ends here diff --git a/aidermacs-backends.el b/aidermacs-backends.el index 88667c5612..a371b33d45 100644 --- a/aidermacs-backends.el +++ b/aidermacs-backends.el @@ -92,17 +92,23 @@ and BUFFER-NAME is the name for the aidermacs buffer." (t (aidermacs-run-comint program args buffer-name)))) -(defun aidermacs--send-command-backend (buffer command &optional callback) +(defun aidermacs--send-command-backend (buffer command) + "Send COMMAND to BUFFER using the appropriate backend." + (setq aidermacs--last-command command + aidermacs--current-output nil) + (if (eq aidermacs-backend 'vterm) + (aidermacs--send-command-vterm buffer command) + (aidermacs--send-command-comint buffer command))) + +(defun aidermacs--send-command-redirect-backend (buffer command &optional callback) "Send COMMAND to BUFFER using the appropriate backend. CALLBACK if provided will be called with the command output when available." (setq aidermacs--last-command command aidermacs--current-output nil aidermacs--current-callback callback) - (cond - ((eq aidermacs-backend 'vterm) - (aidermacs--send-command-vterm buffer command)) - (t - (aidermacs--send-command-comint buffer command)))) + (if (eq aidermacs-backend 'vterm) + (aidermacs--send-command-vterm buffer command) + (aidermacs--send-command-redirect-comint buffer command))) (provide 'aidermacs-backends) diff --git a/aidermacs-models.el b/aidermacs-models.el index 2879a4dc45..a011952aad 100644 --- a/aidermacs-models.el +++ b/aidermacs-models.el @@ -92,8 +92,8 @@ Returns a list of model names with appropriate prefixes based on the API provide (defun aidermacs--get-available-models () "Get list of models supported by aider using the /models command." - (aidermacs--send-command - "/models /" t + (aidermacs--send-command-redirect + "/models /" (lambda (output) (let* ((supported-models (seq-filter @@ -115,8 +115,6 @@ Returns a list of model names with appropriate prefixes based on the API provide (filtered-models (seq-filter (lambda (model) (member model supported-models)) fetched-models))) - ;; (message "Fetched models from %s: %S" url fetched-models) - ;; (message "Filtered models from %s: %S" url filtered-models) (setq models (append models filtered-models))) (error (message "Failed to fetch models from %s: %s" url err)))) (setq aidermacs--cached-models models) diff --git a/aidermacs.el b/aidermacs.el index 00828920b0..4b60d4244d 100644 --- a/aidermacs.el +++ b/aidermacs.el @@ -263,19 +263,28 @@ This is useful for working in monorepos where you want to limit aider's scope." (default-directory (file-truename default-directory))) (aidermacs-run nil))) -(defun aidermacs--send-command (command &optional switch-to-buffer callback) +(defun aidermacs--send-command (command &optional switch-to-buffer) "Send COMMAND to the corresponding aidermacs process. -If SWITCH-TO-BUFFER is non-nil, switch to the aidermacs buffer. -If CALLBACK is provided, it will be called with the command output when available." +If SWITCH-TO-BUFFER is non-nil, switch to the aidermacs buffer." (let* ((buffer-name (aidermacs-buffer-name)) (buffer (or (get-buffer buffer-name) (progn (aidermacs-run) (get-buffer buffer-name)))) (processed-command (aidermacs--process-message-if-multi-line command))) - (aidermacs--send-command-backend buffer processed-command callback) + (aidermacs--send-command-backend buffer processed-command) (when (and switch-to-buffer (not (string= (buffer-name) buffer-name))) (aidermacs-switch-to-buffer)))) +(defun aidermacs--send-command-redirect (command callback) + "Send COMMAND to the corresponding aidermacs process in the background. +CALLBACK will be called with the command output when available." + (let* ((buffer-name (aidermacs-buffer-name)) + (buffer (or (get-buffer buffer-name) + (progn (aidermacs-run) + (get-buffer buffer-name)))) + (processed-command (aidermacs--process-message-if-multi-line command))) + (aidermacs--send-command-redirect-backend buffer processed-command callback))) + ;; Function to switch to the aidermacs buffer ;;;###autoload @@ -434,8 +443,8 @@ Returns a deduplicated list of such file names." "List all files currently added to the chat session. Sends the \"/ls\" command and returns the list of files via callback." (interactive) - (aidermacs--send-command - "/ls" t + (aidermacs--send-command-redirect + "/ls" (lambda (output) (let ((files (aidermacs--parse-ls-output output))) (message "%s" (prin1-to-string files)) @@ -445,14 +454,13 @@ Sends the \"/ls\" command and returns the list of files via callback." (defun aidermacs-drop-file () "Drop a file from the chat session by selecting from currently added files." (interactive) - (aidermacs--send-command - "/ls" t + (aidermacs--send-command-redirect + "/ls" (lambda (output) - (with-local-quit - (if-let* ((files (aidermacs--parse-ls-output output)) - (file (completing-read "Select file to drop: " files nil t))) - (aidermacs--send-command (format "/drop %s" file)) - (message "No files available to drop")))))) + (if-let* ((files (aidermacs--parse-ls-output output)) + (file (completing-read "Select file to drop: " files nil t))) + (aidermacs--send-command (format "/drop ./%s" file)) + (message "No files available to drop"))))) ;;;###autoload