branch: elpa/aidermacs commit d5480ad14b2f221eece1e188e73534fdb9effe72 Author: Mingde (Matthew) Zeng <matthew...@posteo.net> Commit: Mingde (Matthew) Zeng <matthew...@posteo.net>
Improve vterm backend --- aidermacs-backend-vterm.el | 85 +++++++++++----------------------------------- 1 file changed, 20 insertions(+), 65 deletions(-) diff --git a/aidermacs-backend-vterm.el b/aidermacs-backend-vterm.el index b7c81ab2b4..ec1f0f81f1 100644 --- a/aidermacs-backend-vterm.el +++ b/aidermacs-backend-vterm.el @@ -17,6 +17,14 @@ (defvar vterm-shell) (defvar vterm-buffer-name) +(defun aidermacs--is-aidermacs-vterm-buffer-p (&optional buffer) + "Check if BUFFER is an aidermacs vterm buffer. +If BUFFER is nil, check the current buffer. +Returns non-nil if the buffer name matches the aidermacs buffer pattern." + (let ((buf (or buffer (current-buffer)))) + (and (eq major-mode 'vterm-mode) + (string-match-p "^\\*aidermacs:" (buffer-name buf))))) + (defun aidermacs--vterm-check-finish-sequence-repeated (proc orig-filter start-point expected) "Check for the finish sequence in PROC's buffer. PROC is the process to check. ORIG-FILTER is the original process filter. @@ -31,13 +39,13 @@ pattern to match. If the finish sequence is detected, store the output via (condition-case nil (vterm--render) (error nil))) - + (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))) - + (when has-new-prompt ;; Only search for boundaries when we have a new prompt (let* ((seq-start (or (save-excursion @@ -47,10 +55,10 @@ pattern to match. If the finish sequence is detected, store the output via (error nil))) (point-min))) ;; Only get the prompt line, not the whole sequence - (prompt-line (buffer-substring-no-properties - seq-start + (prompt-line (buffer-substring-no-properties + seq-start (min (+ seq-start 200) (point-max))))) - + (when (string-match-p expected prompt-line) (let ((output (buffer-substring-no-properties start-point seq-start))) (aidermacs--store-output (string-trim output))) @@ -62,8 +70,7 @@ pattern to match. If the finish sequence is detected, store the output via 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 (and (bound-and-true-p aidermacs-minor-mode) - (eq major-mode 'vterm-mode)) + (if (aidermacs--is-aidermacs-vterm-buffer-p) (let* ((start-point (condition-case nil (vterm--get-prompt-point) (error (point-min)))) @@ -78,7 +85,7 @@ after each output chunk, reducing the need for timers." (lambda (proc string) ;; 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) @@ -86,7 +93,7 @@ after each output chunk, reducing the need for timers." (cancel-timer timer) (setq timer nil)) (return)) - + ;; If we haven't found it yet, set up a timer with adaptive frequency (unless timer (setq timer (run-with-timer @@ -98,7 +105,7 @@ after each output chunk, reducing the need for timers." proc orig-filter start-point expected) (cancel-timer timer) (setq timer nil)) - + ;; Just keep checking until we find the prompt ))))))) (apply orig-fun args)) @@ -119,7 +126,6 @@ BUFFER-NAME is the name for the vterm buffer." (vterm-shell cmd) (vterm-shell-orig vterm-shell)) (with-current-buffer (vterm-other-window) - (aidermacs-minor-mode 1) (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) @@ -127,8 +133,6 @@ BUFFER-NAME is the name for the vterm buffer." (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) - (define-key map (kbd aidermacs-vterm-multiline-send-key) #'aidermacs-vterm-send-multi-line) - (define-key map (kbd "C-c C-k") #'aidermacs-vterm-cancel-multi-line) (use-local-map map)) ;; Add cleanup hook (add-hook 'kill-buffer-hook #'aidermacs--vterm-cleanup nil t)))) @@ -137,22 +141,11 @@ BUFFER-NAME is the name for the vterm buffer." (defvar-local aidermacs--vterm-active-timer nil "Store the active timer for vterm output processing.") -(defvar-local aidermacs--vterm-multi-line-input nil - "Accumulated multi-line input in vterm mode.") - -(defvar-local aidermacs--vterm-multi-line-mode nil - "Non-nil when in multi-line input mode in vterm.") - (defcustom aidermacs-vterm-multiline-newline-key "S-<return>" "Key binding to enter a newline without sending in vterm." :type 'string :group 'aidermacs) -(defcustom aidermacs-vterm-multiline-send-key "C-<return>" - "Key binding to send multi-line input in vterm mode." - :type 'string - :group 'aidermacs) - (defun aidermacs--send-command-vterm (buffer command) "Send command to the aidermacs vterm buffer. BUFFER is the target buffer to send to. COMMAND is the text to send." @@ -161,57 +154,19 @@ BUFFER is the target buffer to send to. COMMAND is the text to send." (when aidermacs--vterm-active-timer (cancel-timer aidermacs--vterm-active-timer) (setq aidermacs--vterm-active-timer nil)) - ;; Reset multiline mode if active - (aidermacs-vterm-reset-multi-line-state) (vterm-send-string command) (vterm-send-return))) (defun aidermacs-vterm-insert-newline () - "Insert a newline in vterm multi-line input." + "Insert a newline in vterm without sending the command." (interactive) - (if aidermacs--vterm-multi-line-mode - (progn - (setq aidermacs--vterm-multi-line-input - (concat aidermacs--vterm-multi-line-input "\n")) - (let ((inhibit-read-only t)) - (vterm-insert "\n"))) - ;; If not in multi-line mode, enter it - (setq aidermacs--vterm-multi-line-mode t - aidermacs--vterm-multi-line-input "") - (let ((inhibit-read-only t)) - (vterm-insert "\n[multi-line mode] (Use Shift+Enter for new line, Ctrl+Enter to send)\n")))) - -(defun aidermacs-vterm-send-multi-line () - "Send accumulated multi-line input in vterm." - (interactive) - (when aidermacs--vterm-multi-line-mode - (let ((input (string-trim aidermacs--vterm-multi-line-input))) - (setq aidermacs--vterm-multi-line-mode nil - aidermacs--vterm-multi-line-input nil) - ;; Format and send the input - (vterm-send-string (format "{aidermacs\n%s\naidermacs}" input)) - (vterm-send-return)))) - -(defun aidermacs-vterm-cancel-multi-line () - "Cancel multiline input mode in vterm." - (interactive) - (when aidermacs--vterm-multi-line-mode - (setq aidermacs--vterm-multi-line-mode nil - aidermacs--vterm-multi-line-input nil) - (let ((inhibit-read-only t)) - (vterm-insert "\n[multi-line mode canceled]\n")))) - -(defun aidermacs-vterm-reset-multi-line-state () - "Reset multi-line state variables." - (setq aidermacs--vterm-multi-line-mode nil - aidermacs--vterm-multi-line-input nil)) + (vterm-insert "\n")) (defun aidermacs--vterm-cleanup () "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)) - (aidermacs-vterm-reset-multi-line-state)) + (setq aidermacs--vterm-active-timer nil))) (provide 'aidermacs-backend-vterm)