branch: elpa/aidermacs
commit 46712fe697e608f9e0812e6ba671958c0329c4be
Author: Mingde (Matthew) Zeng <matthew...@posteo.net>
Commit: Mingde (Matthew) Zeng <matthew...@posteo.net>

    Make vterm backend work with ediff
    
    Fixes #46
---
 aidermacs-backend-vterm.el | 114 ++++++++++++++++++++++++---------------------
 aidermacs-backends.el      |  25 +++++-----
 aidermacs.el               |   2 +-
 3 files changed, 76 insertions(+), 65 deletions(-)

diff --git a/aidermacs-backend-vterm.el b/aidermacs-backend-vterm.el
index 7d7635aba7..b30caad4c7 100644
--- a/aidermacs-backend-vterm.el
+++ b/aidermacs-backend-vterm.el
@@ -98,23 +98,31 @@ If the finish sequence is detected, store the output via
                  (prompt-line-end (min (+ seq-start 200) (point-max)))
                  (prompt-line (buffer-substring-no-properties seq-start 
prompt-line-end)))
 
-            ;; If we found a shell prompt
+            ;; If we found a shell prompt indicating output finished
             (when (string-match-p expected prompt-line)
-              (let ((output (buffer-substring-no-properties start-point 
seq-start))
-                    (edited-files (aidermacs--detect-edited-files)))
+              (let ((output (buffer-substring-no-properties start-point 
seq-start)))
+                (setq-local aidermacs--vterm-processing-command nil)
                 (aidermacs--store-output (string-trim output))
+                (let ((edited-files (aidermacs--detect-edited-files)))
                 ;; Check if any files were edited and show ediff if needed
-                (if edited-files
-                    (aidermacs--show-ediff-for-edited-files edited-files)
-                  (aidermacs--cleanup-all-temp-files)))
-              (set-process-filter proc orig-filter))))))))
+                  (if edited-files
+                      (aidermacs--show-ediff-for-edited-files edited-files)
+                    (aidermacs--cleanup-all-temp-files))
+                  ;; Restore the original process filter now that we've 
finished processing
+                  ;; this command's output. This returns vterm to its normal 
behavior.
+                  (set-process-filter proc orig-filter)
+                  (aidermacs--maybe-cancel-active-timer (process-buffer 
proc)))))))))))
+
+(defvar-local aidermacs--vterm-processing-command nil
+  "Flag to indicate if we're currently processing a command.")
 
 (defun aidermacs--vterm-output-advice (orig-fun &rest args)
   "Capture vterm output until the finish sequence appears.
 ORIG-FUN is the original function being advised.  ARGS are its arguments.
 This sets a temporary process filter that checks for the finish sequence
 after each output chunk, reducing the need for timers."
-  (if (aidermacs--is-aidermacs-buffer-p)
+  (if (and (aidermacs--is-aidermacs-buffer-p)
+           (not (string-empty-p aidermacs--last-command)))
       (let* ((start-point (condition-case nil
                               (vterm--get-prompt-point)
                             (error (point-min))))
@@ -124,35 +132,33 @@ after each output chunk, reducing the need for timers."
         ;; Store the command for tracking in the correct buffer
         (with-current-buffer (process-buffer proc)
           (when (and args (car args) (stringp (car args)))
-            (setq-local aidermacs--last-command (car args))))
-
-        ;; Initialize tracking variables
-        (setq-local aidermacs--vterm-last-check-point nil)
-
-        ;; Set our temporary process filter
-        (set-process-filter
-         proc
-         (lambda (proc string)
-           ;; Call the original filter
-           (funcall orig-filter proc string)
-
-           ;; Only set up a timer if we don't already have one
-           (unless aidermacs--vterm-active-timer
-             ;; Set up a timer to check for completion
-             (setq aidermacs--vterm-active-timer
-                   (run-with-timer
-                    aidermacs-vterm-check-interval
-                    aidermacs-vterm-check-interval
-                    (lambda ()
-                      (when (aidermacs--vterm-check-finish-sequence-repeated
-                             proc orig-filter start-point)
-                        (when (timerp aidermacs--vterm-active-timer)
-                          (cancel-timer aidermacs--vterm-active-timer)
-                          (setq aidermacs--vterm-active-timer nil))
-                        (set-process-filter proc orig-filter))))))))
-        (apply orig-fun args))
+            (setq aidermacs--last-command (car args)))
+          ;; Set flag that we're processing a command
+          (setq aidermacs--vterm-processing-command t)
+          ;; Initialize tracking variables
+          (setq aidermacs--vterm-last-check-point nil)
+          ;; Cancel any existing timer first
+          (aidermacs--maybe-cancel-active-timer)
+
+          ;; Create a new timer immediately to start checking for command 
completion
+          (setq aidermacs--vterm-active-timer
+                (run-with-timer
+                 aidermacs-vterm-check-interval
+                 aidermacs-vterm-check-interval
+                 (lambda ()
+                   ; Check if we're still in a valid state
+                   (aidermacs--vterm-check-finish-sequence-repeated proc 
orig-filter start-point))))
+          (apply orig-fun args)))
     (apply orig-fun args)))
 
+(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'"
+  (with-current-buffer (get-buffer (aidermacs-get-buffer-name))
+    (when (timerp aidermacs--vterm-active-timer)
+      (cancel-timer aidermacs--vterm-active-timer)
+      (setq aidermacs--vterm-active-timer nil))))
+
 (defun aidermacs-run-vterm (program args buffer-name)
   "Create a vterm-based buffer and run aidermacs program.
 PROGRAM is the command to run.  ARGS is a list of command line arguments.
@@ -173,7 +179,7 @@ BUFFER-NAME is the name for the vterm buffer."
         (advice-add 'vterm-send-return :around 
#'aidermacs--vterm-output-advice)
         (advice-add 'vterm-send-return :before 
#'aidermacs--vterm-capture-keyboard-input)
         (advice-add 'vterm--self-insert :after 
#'aidermacs--cleanup-temp-files-on-interrupt-vterm)
-        ;; Set up multi-line key binding
+        ;; Set up multi-line keybinding
         (let ((map (make-sparse-keymap)))
           (set-keymap-parent map (current-local-map))
           (define-key map (kbd aidermacs-vterm-multiline-newline-key) 
#'aidermacs-vterm-insert-newline)
@@ -187,22 +193,25 @@ BUFFER-NAME is the name for the vterm buffer."
 BUFFER is the target buffer to send to.  COMMAND is the text to send."
   (with-current-buffer buffer
     ;; Cancel any existing timer to prevent resource leaks
-    (when aidermacs--vterm-active-timer
-      (cancel-timer aidermacs--vterm-active-timer)
-      (setq aidermacs--vterm-active-timer nil))
-    (vterm-send-string command)
-    (vterm-send-return)))
+    (aidermacs--maybe-cancel-active-timer)
+    ;; Only process if we have a non-empty command
+    (when (and command (not (string-empty-p (string-trim command))))
+      ;; Set processing flag to true before sending command
+      (setq-local aidermacs--vterm-processing-command t)
+      ;; Store the command for tracking
+      (setq-local aidermacs--last-command command)
+      ;; Send the command
+      (vterm-send-string command)
+      (vterm-send-return))))
 
 (defun aidermacs-vterm-insert-newline ()
   "Insert a newline in vterm without sending the command."
   (interactive)
   (vterm-insert "\n"))
 
-(defun aidermacs--vterm-capture-keyboard-input (orig-fun &rest args)
-  "Capture keyboard input in vterm.
-ORIG-FUN is the original function being advised. ARGS are its arguments."
-  (when (and (aidermacs--is-aidermacs-buffer-p)
-             (eq this-command 'vterm-send-return))
+(defun aidermacs--vterm-capture-keyboard-input ()
+  "Capture keyboard input in vterm."
+  (when (aidermacs--is-aidermacs-buffer-p)
     ;; Get the current line content which should be the command
     ;; TODO: current line may not be enough
     (save-excursion
@@ -215,15 +224,13 @@ ORIG-FUN is the original function being advised. ARGS are 
its arguments."
         (when (not (string-empty-p command))
           (setq-local aidermacs--last-command command)
           ;; Always prepare for potential edits
-          (aidermacs--prepare-for-code-edit)))))
-  (apply orig-fun args))
+          (aidermacs--prepare-for-code-edit))))))
 
 (defun aidermacs--vterm-cleanup ()
   "Clean up vterm resources when buffer is killed."
-  (when aidermacs--vterm-active-timer
-    (cancel-timer aidermacs--vterm-active-timer)
-    (setq-local aidermacs--vterm-active-timer nil))
+  (aidermacs--maybe-cancel-active-timer)
   (setq-local aidermacs--vterm-last-check-point nil)
+  (setq-local aidermacs--vterm-processing-command nil)
   (advice-remove 'vterm-send-return #'aidermacs--vterm-capture-keyboard-input))
 
 (defun aidermacs--cleanup-temp-files-on-interrupt-vterm (&rest _args)
@@ -231,8 +238,11 @@ ORIG-FUN is the original function being advised. ARGS are 
its arguments."
 _ARGS are the arguments."
   (when (and (aidermacs--is-aidermacs-buffer-p)
              (equal (this-command-keys) "\C-c\C-c"))
+    ;; Reset processing flag when user interrupts
+    (setq-local aidermacs--vterm-processing-command nil)
+    ;; Cancel any active timer
+    (aidermacs--maybe-cancel-active-timer)
     (aidermacs--cleanup-all-temp-files)))
 
 (provide 'aidermacs-backend-vterm)
-
 ;;; aidermacs-backend-vterm.el ends here
diff --git a/aidermacs-backends.el b/aidermacs-backends.el
index fed3f98883..9f803acd83 100644
--- a/aidermacs-backends.el
+++ b/aidermacs-backends.el
@@ -168,18 +168,19 @@ Remove any files that don't exist."
   "Store output string in the history with timestamp.
 OUTPUT is the string to store.
 If there's a callback function, call it with the output."
-  (setq aidermacs--current-output (substring-no-properties output))
-  (push (cons (current-time) (substring-no-properties output)) 
aidermacs--output-history)
-  (when (> (length aidermacs--output-history) aidermacs-output-limit)
-    (setq aidermacs--output-history
-          (seq-take aidermacs--output-history aidermacs-output-limit)))
-  ;; Parse output for file mentions
-  (aidermacs--parse-output-for-files output)
-  (unless aidermacs--in-callback
-    (when aidermacs--current-callback
-      (let ((aidermacs--in-callback t))
-        (funcall aidermacs--current-callback)
-        (setq aidermacs--current-callback nil)))))
+  (when (stringp output)
+    (setq aidermacs--current-output (substring-no-properties output))
+    (push (cons (current-time) (substring-no-properties output)) 
aidermacs--output-history)
+    (when (> (length aidermacs--output-history) aidermacs-output-limit)
+      (setq aidermacs--output-history
+            (seq-take aidermacs--output-history aidermacs-output-limit)))
+    ;; Parse output for file mentions
+    (aidermacs--parse-output-for-files output)
+    (unless aidermacs--in-callback
+      (when (functionp aidermacs--current-callback)
+        (let ((aidermacs--in-callback t))
+          (funcall aidermacs--current-callback)
+          (setq aidermacs--current-callback nil))))))
 
 ;; Backend dispatcher functions
 (defun aidermacs-run-backend (program args buffer-name)
diff --git a/aidermacs.el b/aidermacs.el
index 55dbb6991a..f3c64b7f40 100644
--- a/aidermacs.el
+++ b/aidermacs.el
@@ -758,7 +758,7 @@ GUIDE is displayed in the prompt but not included in the 
final command."
          (prompt (concat command " " prompt-prefix context
                         (when guide (format "(%s)" guide)) ": "))
          (user-command (aidermacs-read-string prompt)))
-    (concat command (unless (string= user-command "")
+    (concat command (unless (string-empty-p user-command)
                       (concat " " prompt-prefix context ": " user-command)))))
 
 (defun aidermacs-architect-this-code ()

Reply via email to