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

    Improve aidermacs--vterm-check-finish-sequence-repeated
    
    Addresses #41
---
 aidermacs-backend-vterm.el | 64 +++++++++++++++++++++++++++-------------------
 1 file changed, 37 insertions(+), 27 deletions(-)

diff --git a/aidermacs-backend-vterm.el b/aidermacs-backend-vterm.el
index ec7e376adc..71bdaa13e0 100644
--- a/aidermacs-backend-vterm.el
+++ b/aidermacs-backend-vterm.el
@@ -15,6 +15,7 @@
 ;;; Code:
 
 (require 'vterm nil 'noerror)
+(require 'cl-lib)
 
 ;; we want to ensure these two variables are dynamic binding
 (defvar vterm-shell)
@@ -32,6 +33,14 @@
 (defvar-local aidermacs--vterm-active-timer nil
   "Store the active timer for vterm output processing.")
 
+(defvar-local aidermacs--vterm-last-check-point nil
+  "Store the last position checked in the vterm buffer.")
+
+
+(defvar-local aidermacs-vterm-check-interval 0.2
+  "Interval in seconds between checks for command completion in vterm.")
+
+
 (defcustom aidermacs-vterm-multiline-newline-key "S-<return>"
   "Key binding to enter a newline without sending in vterm."
   :type 'string
@@ -58,31 +67,33 @@ pattern to match.  If the finish sequence is detected, 
store the output via
         (condition-case nil
             (vterm--render)
           (error nil)))
-
+      ;; Get current prompt point
       (let* ((prompt-point (condition-case nil
                                (vterm--get-prompt-point)
                              (error (point-max))))
-             ;; Only do these expensive operations if we have a new prompt
-             (has-new-prompt (< start-point prompt-point)))
+             ;; Only check if we have a new prompt or haven't checked this 
position yet
+             (last-check (or aidermacs--vterm-last-check-point start-point))
+             (should-check (> prompt-point last-check)))
 
-        (when has-new-prompt
-          ;; Only search for boundaries when we have a new prompt
+        ;; Update the last check point
+        (setq aidermacs--vterm-last-check-point prompt-point)
+
+        (when should-check
           (let* ((seq-start (or (save-excursion
                                   (goto-char prompt-point)
                                   (condition-case nil
                                       (search-backward "\n" nil t)
                                     (error nil)))
                                 (point-min)))
-                 ;; Only get the prompt line, not the whole sequence
-                 (prompt-line (buffer-substring-no-properties
-                               seq-start
-                               (min (+ seq-start 200) (point-max)))))
+                 ;; Only get the prompt line, not the whole sequence (limit to 
200 chars)
+                 (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
             (when (string-match-p expected prompt-line)
               (let ((output (buffer-substring-no-properties start-point 
seq-start)))
                 (aidermacs--store-output (string-trim output)))
-              (set-process-filter proc orig-filter)
-              t)))))))
+              (set-process-filter proc orig-filter))))))))
 
 (defun aidermacs--vterm-output-advice (orig-fun &rest args)
   "Capture vterm output until the finish sequence appears.
@@ -97,25 +108,24 @@ after each output chunk, reducing the need for timers."
              ;; Simplified pattern that just looks for a shell prompt
              (expected "^[^[:space:]]*>[[:space:]]")
              (orig-filter (process-filter proc)))
-        ;; Set our temporary process filter.
+
+        ;; 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.
+           ;; Call the original filter
            (funcall orig-filter proc string)
 
-           ;; Check immediately after receiving output
-           (when (aidermacs--vterm-check-finish-sequence-repeated proc 
orig-filter start-point expected)
-             (when (timerp aidermacs--vterm-active-timer)
-               (cancel-timer aidermacs--vterm-active-timer)
-               (setq aidermacs--vterm-active-timer nil))
-             (set-process-filter proc orig-filter))
-
-           ;; If we haven't found it yet, set up a timer with adaptive 
frequency
+           ;; 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
-                    0.05 0.05
+                    aidermacs-vterm-check-interval
+                    aidermacs-vterm-check-interval
                     (lambda ()
                       (when (aidermacs--vterm-check-finish-sequence-repeated
                              proc orig-filter start-point expected)
@@ -140,11 +150,10 @@ BUFFER-NAME is the name for the vterm buffer."
            (vterm-buffer-name buffer-name)
            (vterm-shell cmd))
       (with-current-buffer (vterm-other-window)
+        (setq-local vterm-max-scrollback 1000
+                    aidermacs--vterm-active-timer nil
+                    aidermacs--vterm-last-check-point nil)
         (advice-add 'vterm-send-return :around 
#'aidermacs--vterm-output-advice)
-        ;; Set a reasonable scrollback limit to prevent memory issues
-        (setq-local vterm-max-scrollback 5000)
-        ;; Initialize timer variable
-        (setq-local aidermacs--vterm-active-timer nil)
         ;; Set up multi-line key binding
         (let ((map (make-sparse-keymap)))
           (set-keymap-parent map (current-local-map))
@@ -174,7 +183,8 @@ BUFFER is the target buffer to send to.  COMMAND is the 
text to send."
   "Clean up vterm resources when buffer is killed."
   (when aidermacs--vterm-active-timer
     (cancel-timer aidermacs--vterm-active-timer)
-    (setq aidermacs--vterm-active-timer nil)))
+    (setq-local aidermacs--vterm-active-timer nil))
+  (setq-local aidermacs--vterm-last-check-point nil))
 
 (provide 'aidermacs-backend-vterm)
 

Reply via email to