branch: elpa/aidermacs
commit f3c8d006f524f807f2a43922b0d30c7af26862eb
Author: Matthew Zeng <matthew...@posteo.net>
Commit: GitHub <nore...@github.com>

    Refactor output and ediff code into its own file (#80)
    
    * Refactor into aidermacs-output.el
    
    Signed-off-by: Mingde (Matthew) Zeng <matthew...@posteo.net>
    
    * Add aidermacs--command-may-edit-files
    
    Signed-off-by: Mingde (Matthew) Zeng <matthew...@posteo.net>
    
    * Remove aggressive cleanup
    
    Signed-off-by: Mingde (Matthew) Zeng <matthew...@posteo.net>
    
    * Rewrite aidermacs--prepare-for-code-edit
    
    Signed-off-by: Mingde (Matthew) Zeng <matthew...@posteo.net>
    
    * Fix linting
    
    Signed-off-by: Mingde (Matthew) Zeng <matthew...@posteo.net>
    
    * Fix capture file state font lock problem with treesitter
    
    Signed-off-by: Mingde (Matthew) Zeng <matthew...@posteo.net>
    
    ---------
    
    Signed-off-by: Mingde (Matthew) Zeng <matthew...@posteo.net>
---
 aidermacs-backend-comint.el |  21 +--
 aidermacs-backend-vterm.el  |  20 +--
 aidermacs-backends.el       | 155 +----------------
 aidermacs-output.el         | 400 ++++++++++++++++++++++++++++++++++++++++++++
 aidermacs.el                | 289 +++-----------------------------
 5 files changed, 453 insertions(+), 432 deletions(-)

diff --git a/aidermacs-backend-comint.el b/aidermacs-backend-comint.el
index 1797ce53dd..3d30f6bbad 100644
--- a/aidermacs-backend-comint.el
+++ b/aidermacs-backend-comint.el
@@ -28,14 +28,15 @@
 (require 'map)
 
 ;; Forward declarations
-(declare-function aidermacs--prepare-for-code-edit "aidermacs")
-(declare-function aidermacs--cleanup-temp-buffers "aidermacs")
-(declare-function aidermacs--show-ediff-for-edited-files "aidermacs")
-(declare-function aidermacs--detect-edited-files "aidermacs")
-(declare-function aidermacs--process-message-if-multi-line "aidermacs" (str))
-(declare-function aidermacs--parse-output-for-files "aidermacs-backends" 
(output))
-(declare-function aidermacs--store-output "aidermacs-backends" (output))
-(declare-function aidermacs--is-aidermacs-buffer-p "aidermacs-backends" 
(&optional buffer))
+(declare-function aidermacs--prepare-for-code-edit "aidermacs-output")
+(declare-function aidermacs--process-message-if-multi-line "aidermacs")
+(declare-function aidermacs--command-may-edit-files "aidermacs")
+(declare-function aidermacs--store-output "aidermacs-output")
+(declare-function aidermacs--is-aidermacs-buffer-p "aidermacs-backends")
+(declare-function aidermacs--parse-output-for-files "aidermacs-output")
+(declare-function aidermacs--show-ediff-for-edited-files "aidermacs-output")
+(declare-function aidermacs--cleanup-temp-buffers "aidermacs-output")
+(declare-function aidermacs--detect-edited-files "aidermacs-output")
 
 (defvar aidermacs--last-command)
 
@@ -288,8 +289,8 @@ PROC is the process to send to.  STRING is the command to 
send."
     (if (member (downcase string) '("" "y" "n" "d" "yes" "no"))
         (aidermacs--parse-output-for-files aidermacs--comint-output-temp)
       (setq aidermacs--last-command string)
-      ;; Always prepare for potential edits
-      (aidermacs--prepare-for-code-edit)))
+      (when (aidermacs--command-may-edit-files string)
+        (aidermacs--prepare-for-code-edit))))
   (comint-simple-send proc (aidermacs--process-message-if-multi-line string)))
 
 (defun aidermacs-run-comint (program args buffer-name)
diff --git a/aidermacs-backend-vterm.el b/aidermacs-backend-vterm.el
index 7ad1634ec4..e71c3dbf8b 100644
--- a/aidermacs-backend-vterm.el
+++ b/aidermacs-backend-vterm.el
@@ -19,8 +19,6 @@
 ;; - Custom multi-line input keybindings
 ;; - Aider process management in VTerm
 
-;; Originally forked from: Kang Tu <tni...@gmail.com> Aider.el
-
 ;;; Code:
 
 (require 'vterm nil 'noerror)
@@ -40,15 +38,15 @@
 (declare-function vterm-insert "vterm")
 (declare-function vterm-send-C-c "vterm")
 
-(declare-function aidermacs--prepare-for-code-edit "aidermacs")
-(declare-function aidermacs--cleanup-temp-buffers "aidermacs")
-(declare-function aidermacs--show-ediff-for-edited-files "aidermacs")
 (declare-function aidermacs--detect-edited-files "aidermacs")
-(declare-function aidermacs--store-output "aidermacs")
+(declare-function aidermacs--command-may-edit-files "aidermacs")
 (declare-function aidermacs--is-aidermacs-buffer-p "aidermacs")
 (declare-function aidermacs-get-buffer-name "aidermacs")
-
-(declare-function aidermacs--parse-output-for-files "aidermacs-backends" 
(output))
+(declare-function aidermacs--store-output "aidermacs-output")
+(declare-function aidermacs--prepare-for-code-edit "aidermacs-output")
+(declare-function aidermacs--parse-output-for-files "aidermacs-output" 
(output))
+(declare-function aidermacs--show-ediff-for-edited-files "aidermacs-output")
+(declare-function aidermacs--cleanup-temp-buffers "aidermacs-output")
 
 (declare-function evil-define-minor-mode-key "evil-core")
 
@@ -158,6 +156,8 @@ Use BUFFER if provided, otherwise retrieve it from 
`aidermacs-get-buffer-name'."
 
 
 (defun aidermacs--vterm-filter-buffer-substring (beg end &optional delete)
+  "Filter text from BEG to END in vterm buffer for cleaner display.
+When DELETE is non-nil, extract and delete the region instead of copying it."
   (let* ((text (cond
                 (delete
                  (save-excursion
@@ -308,8 +308,8 @@ BUFFER is the target buffer to send to.  COMMAND is the 
text to send."
                        (line-end-position))))
         (when (not (string-empty-p command))
           (setq-local aidermacs--last-command command)
-          ;; Always prepare for potential edits
-          (aidermacs--prepare-for-code-edit))))))
+          (when (aidermacs--command-may-edit-files command)
+            (aidermacs--prepare-for-code-edit)))))))
 
 (defun aidermacs--vterm-cleanup ()
   "Clean up vterm resources when buffer is killed."
diff --git a/aidermacs-backends.el b/aidermacs-backends.el
index 7087441507..3d923ba392 100644
--- a/aidermacs-backends.el
+++ b/aidermacs-backends.el
@@ -18,8 +18,6 @@
 ;; - Abstracts backend-specific Aider functions
 ;; - Manages output history and callbacks
 
-;; Originally forked from: Kang Tu <tni...@gmail.com> Aider.el
-
 ;;; Code:
 
 (require 'aidermacs-backend-comint)
@@ -28,8 +26,8 @@
 
 (declare-function aidermacs-run-vterm "aidermacs-backend-vterm" (program args 
buffer-name))
 (declare-function aidermacs--send-command-vterm "aidermacs-backend-vterm" 
(buffer command))
-(declare-function aidermacs-project-root "aidermacs" ())
-(declare-function aidermacs--prepare-for-code-edit "aidermacs" ())
+(declare-function aidermacs--prepare-for-code-edit "aidermacs-output")
+(declare-function aidermacs-project-root "aidermacs")
 (declare-function aidermacs--get-files-in-session "aidermacs" (callback))
 
 (defgroup aidermacs-backends nil
@@ -44,155 +42,18 @@ of using a comint process."
   :type '(choice (const :tag "Comint" comint)
                  (const :tag "VTerm" vterm)))
 
-(defcustom aidermacs-output-limit 10
-  "Maximum number of output entries to keep in history."
-  :type 'integer)
-
-(defvar-local aidermacs--output-history nil
-  "List to store aidermacs output history.
-Each entry is a cons cell (timestamp . output-text).")
-
-(defvar-local aidermacs--last-command nil
-  "Store the last command sent to aidermacs.")
-
-(defvar-local aidermacs--current-output ""
-  "Accumulator for current output being captured as a string.")
-
-(defcustom aidermacs-before-run-backend-hook nil
-  "Hook run before the aidermacs backend is startd."
-  :type 'hook)
-
-(defun aidermacs-get-output-history (&optional limit)
-  "Get the output history, optionally limited to LIMIT entries.
-LIMIT is the maximum number of entries to return.
-Returns a list of (timestamp . output-text) pairs, most recent first."
-  (let ((history aidermacs--output-history))
-    (if limit
-        (seq-take history limit)
-      history)))
-
-(defun aidermacs-clear-output-history ()
-  "Clear the output history."
-  (interactive)
-  (setq aidermacs--output-history nil))
-
 (defvar-local aidermacs--current-callback nil
   "Store the callback function for the current command.")
 
 (defvar-local aidermacs--in-callback nil
   "Flag to prevent recursive callbacks.")
 
-(defvar-local aidermacs--tracked-files nil
-  "List of files that have been mentioned in the aidermacs output.
-This is used to avoid having to run /ls repeatedly.")
-
-(defun aidermacs--parse-output-for-files (output)
-  "Parse OUTPUT for files and add them to `aidermacs--tracked-files'."
-  (when output
-    (let ((lines (split-string output "\n"))
-          (last-line "")
-          (in-udiff nil)
-          (current-udiff-file nil))
-      (dolist (line lines)
-        (cond
-         ;; Applied edit to <filename>
-         ((string-match "Applied edit to \\(\\./\\)?\\(.+\\)" line)
-          (when-let* ((file (match-string 2 line)))
-            (add-to-list 'aidermacs--tracked-files file)))
-
-         ;; Added <filename> to the chat.
-         ((string-match "Added \\(\\./\\)?\\(.+\\) to the chat" line)
-          (when-let* ((file (match-string 2 line)))
-            (add-to-list 'aidermacs--tracked-files file)))
-
-         ;; Removed <filename> from the chat (with or without ./ prefix)
-         ((string-match "Removed \\(\\./\\)?\\(.+\\) from the chat" line)
-          (when-let* ((file (match-string 2 line)))
-            (setq aidermacs--tracked-files (delete file 
aidermacs--tracked-files))))
-
-         ;; Added <filename> to read-only files.
-         ((string-match "Added \\(\\./\\)?\\(.+\\) to read-only files" line)
-          (when-let* ((file (match-string 2 line)))
-            (add-to-list 'aidermacs--tracked-files (concat file " 
(read-only)"))))
-
-         ;; Moved <file> from editable to read-only files in the chat
-         ((string-match "Moved \\(\\./\\)?\\(.+\\) from editable to read-only 
files in the chat" line)
-          (when-let* ((file (match-string 2 line)))
-            (let ((editable-file (replace-regexp-in-string " (read-only)$" "" 
file)))
-              (setq aidermacs--tracked-files (delete editable-file 
aidermacs--tracked-files))
-              (add-to-list 'aidermacs--tracked-files (concat file " 
(read-only)")))))
-
-         ;; Moved <file> from read-only to editable files in the chat
-         ((string-match "Moved \\(\\./\\)?\\(.+\\) from read-only to editable 
files in the chat" line)
-          (when-let* ((file (match-string 2 line)))
-            (let ((read-only-file (concat file " (read-only)")))
-              (setq aidermacs--tracked-files (delete read-only-file 
aidermacs--tracked-files))
-              (add-to-list 'aidermacs--tracked-files file))))
-
-         ;; <file>\nAdd file to the chat?
-         ((string-match "Add file to the chat?" line)
-          (add-to-list 'aidermacs--tracked-files last-line)
-          (aidermacs--prepare-for-code-edit))
-
-         ;; <file> is already in the chat as an editable file
-         ((string-match "\\(\\./\\)?\\(.+\\) is already in the chat as an 
editable file" line)
-          (when-let* ((file (match-string 2 line)))
-            (add-to-list 'aidermacs--tracked-files file)))
-
-         ;; Handle udiff format
-         ;; Detect start of udiff with "--- filename"
-         ((string-match "^--- \\(\\./\\)?\\(.+\\)" line)
-          (setq in-udiff t
-                current-udiff-file (match-string 2 line)))
-
-         ;; Confirm udiff file with "+++ filename" line
-         ((and in-udiff
-               current-udiff-file
-               (string-match "^\\+\\+\\+ \\(\\./\\)?\\(.+\\)" line))
-          (let ((plus-file (match-string 2 line)))
-            ;; Only add if the filenames match (ignoring ./ prefix)
-            (when (string= (file-name-nondirectory current-udiff-file)
-                           (file-name-nondirectory plus-file))
-              (add-to-list 'aidermacs--tracked-files current-udiff-file)
-              (setq in-udiff nil
-                    current-udiff-file nil)))))
-
-        (setq last-line line))
-
-      ;; Verify all tracked files exist
-      (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))
-                 (actual-file (if is-readonly
-                                  (substring file 0 (- (length file) 12))
-                                file))
-                 (full-path (expand-file-name actual-file project-root)))
-            (when (or (file-exists-p full-path) is-remote)
-              (push file valid-files))))
-        (setq aidermacs--tracked-files valid-files)))))
-
-(defun aidermacs--store-output (output)
-  "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."
-  (when (stringp output)
-    ;; Store the output
-    (setq aidermacs--current-output (substring-no-properties output))
-    (push (cons (current-time) (substring-no-properties output)) 
aidermacs--output-history)
-    ;; Trim history if needed
-    (when (> (length aidermacs--output-history) aidermacs-output-limit)
-      (setq aidermacs--output-history
-            (seq-take aidermacs--output-history aidermacs-output-limit)))
-    ;; Parse files from output
-    (aidermacs--parse-output-for-files output)
-    ;; Handle callback if present
-    (unless aidermacs--in-callback
-      (when (functionp aidermacs--current-callback)
-        (let ((aidermacs--in-callback t))
-          (funcall aidermacs--current-callback)
-          (setq aidermacs--current-callback nil))))))
+(defcustom aidermacs-before-run-backend-hook nil
+  "Hook run before the aidermacs backend is startd."
+  :type 'hook)
+
+(defconst aidermacs-prompt-regexp "^[^[:space:]<]*>[[:space:]]+$"
+  "Regexp to match Aider's command prompt.")
 
 ;; Backend dispatcher functions
 (defun aidermacs-run-backend (program args buffer-name)
diff --git a/aidermacs-output.el b/aidermacs-output.el
new file mode 100644
index 0000000000..d2ec8b840b
--- /dev/null
+++ b/aidermacs-output.el
@@ -0,0 +1,400 @@
+;;; aidermacs-output.el --- Output manipulation for Aidermacs -*- 
lexical-binding: t; -*-
+;; Author: Mingde (Matthew) Zeng <matthew...@posteo.net>
+;; Version: 1.0
+;; Keywords: ai emacs llm aider ai-pair-programming tools
+;; URL: https://github.com/MatthewZMD/aidermacs
+;; SPDX-License-Identifier: Apache-2.0
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; This file contains the output and diff functionality for Aidermacs.
+
+;;; Code:
+
+(require 'ediff)
+(require 'cl-lib)
+
+(declare-function aidermacs-get-buffer-name "aidermacs")
+(declare-function aidermacs-project-root "aidermacs")
+(declare-function aidermacs--is-aidermacs-buffer-p "aidermacs")
+(declare-function aidermacs--prepare-file-paths-for-command "aidermacs")
+
+(defgroup aidermacs-output nil
+  "Output manipulation for Aidermacs."
+  :group 'aidermacs)
+
+(defvar-local aidermacs--tracked-files nil
+  "List of files that have been mentioned in the aidermacs output.
+This is used to avoid having to run /ls repeatedly.")
+
+(defvar-local aidermacs--output-history nil
+  "List to store aidermacs output history.
+Each entry is a cons cell (timestamp . output-text).")
+
+(defvar-local aidermacs--last-command nil
+  "Store the last command sent to aidermacs.")
+
+(defvar-local aidermacs--current-output ""
+  "Accumulator for current output being captured as a string.")
+
+(defcustom aidermacs-output-limit 10
+  "Maximum number of output entries to keep in history."
+  :type 'integer)
+
+(defcustom aidermacs-show-diff-after-change t
+  "When non-nil, enable ediff for reviewing AI-generated changes.
+When nil, skip preparing temp buffers and showing ediff comparisons."
+  :type 'boolean
+  :group 'aidermacs)
+
+(defvar-local aidermacs--pre-edit-file-buffers nil
+  "Alist of (filename . temp-buffer) storing file state before Aider edits.
+These contain the original content of files that might be modified by Aider.")
+
+(defvar-local aidermacs--ediff-queue nil
+  "Buffer-local queue of files waiting to be processed by ediff.")
+
+(defvar aidermacs--pre-ediff-window-config nil
+  "Window configuration before starting ediff sessions.")
+
+(defun aidermacs--ensure-current-file-tracked ()
+  "Ensure current file is tracked in the aidermacs session."
+  (when buffer-file-name
+    (let* ((session-buffer (get-buffer (aidermacs-get-buffer-name)))
+           (filename buffer-file-name)
+           (relative-path (file-relative-name filename 
(aidermacs-project-root))))
+      (when session-buffer
+        (with-current-buffer session-buffer
+          (unless (member relative-path aidermacs--tracked-files)
+            (push relative-path aidermacs--tracked-files)
+            (let ((command (aidermacs--prepare-file-paths-for-command "/add" 
(list relative-path))))
+              (aidermacs--send-command-backend session-buffer command 
nil))))))))
+
+(defun aidermacs--capture-file-state (filename)
+  "Store the current state of FILENAME in a temporary buffer.
+Creates a read-only buffer with the file's content, appropriate major mode,
+and syntax highlighting to match the original file."
+  (when (and filename (file-exists-p filename))
+    (condition-case err
+        (let ((temp-buffer (generate-new-buffer
+                            (format " *aidermacs-pre-edit:%s*"
+                                    (file-name-nondirectory filename)))))
+          (with-current-buffer temp-buffer
+            (insert-file-contents filename)
+            (set-buffer-modified-p nil)
+            ;; Use same major mode as the original file
+            (let ((buffer-file-name filename)
+                  (delay-mode-hooks t))
+              (set-auto-mode)
+              ;; Ensure syntax highlighting is applied
+              (font-lock-mode 1))
+            ;; Make buffer read-only
+            (setq buffer-read-only t))
+          (cons filename temp-buffer))
+      (error
+       (message "Error capturing file state for %s: %s"
+                filename (error-message-string err))
+       nil))))
+
+(defun aidermacs--cleanup-temp-buffers ()
+  "Clean up all temporary buffers created for ediff sessions.
+This is called when all ediff sessions are complete.
+Kills all pre-edit buffers that were created to store original file content."
+  (interactive)
+  (with-current-buffer (get-buffer (aidermacs-get-buffer-name))
+    ;; Clean up buffers in the tracking list
+    (dolist (file-pair aidermacs--pre-edit-file-buffers)
+      (let ((temp-buffer (cdr file-pair)))
+        (when (and temp-buffer (buffer-live-p temp-buffer))
+          (kill-buffer temp-buffer))))
+    ;; Clear the list after cleanup
+    (setq aidermacs--pre-edit-file-buffers nil)))
+
+(defun aidermacs--prepare-for-code-edit ()
+  "Prepare for code edits by capturing current file states in memory buffers.
+Creates temporary buffers containing the original content of all tracked files.
+This is skipped if `aidermacs-show-diff-after-change' is nil."
+  (when aidermacs-show-diff-after-change
+    (when-let* ((files aidermacs--tracked-files))
+      (let ((attempts 0)
+            (max-attempts 3))
+        ;; Use iteration rather than recursion with a limit on attempts
+        (while (and (zerop (length aidermacs--pre-edit-file-buffers))
+                    (< attempts max-attempts))
+          (setq aidermacs--pre-edit-file-buffers
+                (cl-remove-duplicates
+                 (delq nil
+                       (mapcar (lambda (file)
+                                 (let* ((clean-file (replace-regexp-in-string 
" (read-only)$" "" file))
+                                        (full-path (expand-file-name 
clean-file (aidermacs-project-root))))
+                                   ;; Only capture state if we don't already 
have it
+                                   (or (assoc full-path 
aidermacs--pre-edit-file-buffers)
+                                       (aidermacs--capture-file-state 
full-path))))
+                               files))
+                 :test (lambda (a b) (equal (car a) (car b)))))
+          (setq attempts (1+ attempts))
+          ;; Add a small delay before retry to allow for file system operations
+          (when (and (zerop (length aidermacs--pre-edit-file-buffers))
+                     (< attempts max-attempts))
+            (sit-for 0.1)))
+
+        (if (zerop (length aidermacs--pre-edit-file-buffers))
+            (message "Warning: Failed to capture file states after %d 
attempts" max-attempts)
+          (message "Prepared code edit for %d files" (length 
aidermacs--pre-edit-file-buffers)))))))
+
+(defun aidermacs--ediff-quit-handler ()
+  "Handle ediff session cleanup and process next files in queue.
+This function is called when an ediff session is quit and processes
+the next file in the ediff queue if any remain."
+  (when (and (boundp 'ediff-buffer-A)
+             (buffer-live-p ediff-buffer-A)
+             (string-match " \\*aidermacs-pre-edit:"
+                           (buffer-name ediff-buffer-A)))
+    (aidermacs--process-next-ediff-file)))
+
+(defun aidermacs--setup-ediff-cleanup-hooks ()
+  "Set up hooks to ensure proper cleanup of temporary buffers after ediff.
+Only adds the hook if it's not already present."
+  (unless (member #'aidermacs--ediff-quit-handler ediff-quit-hook)
+    (add-hook 'ediff-quit-hook #'aidermacs--ediff-quit-handler)))
+
+(defun aidermacs--parse-output-for-files (output)
+  "Parse OUTPUT for files and add them to `aidermacs--tracked-files'."
+  (when output
+    (let ((lines (split-string output "\n"))
+          (last-line "")
+          (in-udiff nil)
+          (current-udiff-file nil))
+      (dolist (line lines)
+        (cond
+         ;; Applied edit to <filename>
+         ((string-match "Applied edit to \\(\\./\\)?\\(.+\\)" line)
+          (when-let* ((file (match-string 2 line)))
+            (add-to-list 'aidermacs--tracked-files file)))
+
+         ;; Added <filename> to the chat.
+         ((string-match "Added \\(\\./\\)?\\(.+\\) to the chat" line)
+          (when-let* ((file (match-string 2 line)))
+            (add-to-list 'aidermacs--tracked-files file)))
+
+         ;; Removed <filename> from the chat (with or without ./ prefix)
+         ((string-match "Removed \\(\\./\\)?\\(.+\\) from the chat" line)
+          (when-let* ((file (match-string 2 line)))
+            (setq aidermacs--tracked-files (delete file 
aidermacs--tracked-files))))
+
+         ;; Added <filename> to read-only files.
+         ((string-match "Added \\(\\./\\)?\\(.+\\) to read-only files" line)
+          (when-let* ((file (match-string 2 line)))
+            (add-to-list 'aidermacs--tracked-files (concat file " 
(read-only)"))))
+
+         ;; Moved <file> from editable to read-only files in the chat
+         ((string-match "Moved \\(\\./\\)?\\(.+\\) from editable to read-only 
files in the chat" line)
+          (when-let* ((file (match-string 2 line)))
+            (let ((editable-file (replace-regexp-in-string " (read-only)$" "" 
file)))
+              (setq aidermacs--tracked-files (delete editable-file 
aidermacs--tracked-files))
+              (add-to-list 'aidermacs--tracked-files (concat file " 
(read-only)")))))
+
+         ;; Moved <file> from read-only to editable files in the chat
+         ((string-match "Moved \\(\\./\\)?\\(.+\\) from read-only to editable 
files in the chat" line)
+          (when-let* ((file (match-string 2 line)))
+            (let ((read-only-file (concat file " (read-only)")))
+              (setq aidermacs--tracked-files (delete read-only-file 
aidermacs--tracked-files))
+              (add-to-list 'aidermacs--tracked-files file))))
+
+         ;; <file>\nAdd file to the chat?
+         ((string-match "Add file to the chat?" line)
+          (add-to-list 'aidermacs--tracked-files last-line)
+          (aidermacs--prepare-for-code-edit))
+
+         ;; <file> is already in the chat as an editable file
+         ((string-match "\\(\\./\\)?\\(.+\\) is already in the chat as an 
editable file" line)
+          (when-let* ((file (match-string 2 line)))
+            (add-to-list 'aidermacs--tracked-files file)))
+
+         ;; Handle udiff format
+         ;; Detect start of udiff with "--- filename"
+         ((string-match "^--- \\(\\./\\)?\\(.+\\)" line)
+          (setq in-udiff t
+                current-udiff-file (match-string 2 line)))
+
+         ;; Confirm udiff file with "+++ filename" line
+         ((and in-udiff
+               current-udiff-file
+               (string-match "^\\+\\+\\+ \\(\\./\\)?\\(.+\\)" line))
+          (let ((plus-file (match-string 2 line)))
+            ;; Only add if the filenames match (ignoring ./ prefix)
+            (when (string= (file-name-nondirectory current-udiff-file)
+                           (file-name-nondirectory plus-file))
+              (add-to-list 'aidermacs--tracked-files current-udiff-file)
+              (setq in-udiff nil
+                    current-udiff-file nil)))))
+
+        (setq last-line line))
+
+      ;; Verify all tracked files exist
+      (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))
+                 (actual-file (if is-readonly
+                                  (substring file 0 (- (length file) 12))
+                                file))
+                 (full-path (expand-file-name actual-file project-root)))
+            (when (or (file-exists-p full-path) is-remote)
+              (push file valid-files))))
+        (setq aidermacs--tracked-files valid-files)))))
+
+(defun aidermacs--store-output (output)
+  "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."
+  (when (stringp output)
+    ;; Store the output
+    (setq aidermacs--current-output (substring-no-properties output))
+    (push (cons (current-time) (substring-no-properties output)) 
aidermacs--output-history)
+    ;; Trim history if needed
+    (when (> (length aidermacs--output-history) aidermacs-output-limit)
+      (setq aidermacs--output-history
+            (seq-take aidermacs--output-history aidermacs-output-limit)))
+    ;; Parse files from output
+    (aidermacs--parse-output-for-files output)
+    ;; Handle callback if present
+    (unless aidermacs--in-callback
+      (when (functionp aidermacs--current-callback)
+        (let ((aidermacs--in-callback t))
+          (funcall aidermacs--current-callback)
+          (setq aidermacs--current-callback nil))))))
+
+(defun aidermacs-show-output-history ()
+  "Display the AI output history in a new buffer."
+  (interactive)
+  (let ((buf (get-buffer-create "*aidermacs-history*"))
+        (history aidermacs--output-history))
+    (with-current-buffer buf
+      (org-mode)
+      (setq buffer-read-only nil)
+      (erase-buffer)
+      (display-line-numbers-mode 1)
+      (dolist (entry history)
+        (let ((timestamp (format-time-string "%F %T" (car entry)))
+              (output (cdr entry)))
+          (insert (format "* %s\n#+BEGIN_SRC\n%s\n#+END_SRC\n" timestamp 
output))))
+      (goto-char (point-min))
+      (setq buffer-read-only t)
+      (local-set-key (kbd "q") #'kill-this-buffer)
+      (switch-to-buffer-other-window buf))))
+
+(defun aidermacs-clear-output-history ()
+  "Clear the output history."
+  (interactive)
+  (setq aidermacs--output-history nil))
+
+(defun aidermacs-get-last-output ()
+  "Get the most recent output from aidermacs."
+  (interactive)
+  (when (stringp aidermacs--current-output)
+    (message "%s" aidermacs--current-output)
+    (kill-new aidermacs--current-output)
+    aidermacs--current-output))
+
+(defun aidermacs--detect-edited-files ()
+  "Parse current output to find files edited by Aider.
+Returns a list of files that have been modified according to the output."
+  (let ((project-root (aidermacs-project-root))
+        (output aidermacs--current-output)
+        (edited-files)
+        (unique-files)
+        (valid-files))
+    (when output
+      (with-temp-buffer
+        (insert output)
+        (goto-char (point-min))
+
+        ;; Case 1: Find "Applied edit to" lines
+        (while (search-forward "Applied edit to" nil t)
+          (beginning-of-line)
+          (when-let* ((file (and (looking-at ".*Applied edit to 
\\(\\./\\)?\\([^[:space:]]+\\)")
+                                (match-string-no-properties 2))))
+            (push file edited-files))
+          (forward-line 1))
+
+        ;; Case 2: Find triple backtick blocks with filenames
+        (goto-char (point-min))
+        (while (search-forward "```" nil t)
+          (save-excursion
+            (forward-line -1)
+            (let ((potential-file (string-trim (buffer-substring 
(line-beginning-position) (line-end-position)))))
+              (when (and (not (string-empty-p potential-file))
+                         (not (string-match-p "\\`[[:space:]]*\\'" 
potential-file))
+                         (not (string-match-p "^```" potential-file)))
+                (push potential-file edited-files))))
+          (forward-line 1))
+
+        ;; Case 3: Handle udiff format
+        (goto-char (point-min))
+        (while (search-forward "--- " nil t)
+          (let* ((line-end (line-end-position))
+                 (current-udiff-file (buffer-substring (point) line-end)))
+            (forward-line 1)
+            (when (looking-at "\\+\\+\\+ ")
+              (let ((plus-file (buffer-substring (+ (point) 4) 
(line-end-position))))
+                (when (string= (file-name-nondirectory current-udiff-file)
+                               (file-name-nondirectory plus-file))
+                  (push current-udiff-file edited-files)))))))
+
+      ;; Filter the list to only include valid files
+      (setq unique-files (delete-dups edited-files))
+      (setq valid-files (nreverse (cl-remove-if-not
+                                   (lambda (file)
+                                     (file-exists-p (expand-file-name file 
project-root)))
+                                   unique-files)))
+      ;; Display a message about which files were changed
+      (message "Modified file(s): %s" valid-files)
+      valid-files)))
+
+(defun aidermacs--show-ediff-for-edited-files (edited-files)
+  "Show ediff for each file in EDITED-FILES.
+This is skipped if `aidermacs-show-diff-after-change' is nil."
+  (when (and aidermacs-show-diff-after-change edited-files)
+    ;; Save current window configuration
+    (setq aidermacs--pre-ediff-window-config (current-window-configuration))
+    ;; Set up the queue in the current buffer
+    (setq-local aidermacs--ediff-queue edited-files)
+    ;; Process the first file
+    (aidermacs--process-next-ediff-file)))
+
+(defun aidermacs--process-next-ediff-file ()
+  "Process the next file in the ediff queue for the current buffer."
+  (with-current-buffer (get-buffer (aidermacs-get-buffer-name))
+    (if aidermacs--ediff-queue
+        (let ((file (pop aidermacs--ediff-queue)))
+          (aidermacs--show-ediff-for-file file))
+      (aidermacs--cleanup-temp-buffers)
+      ;; Restore original window configuration
+      (when aidermacs--pre-ediff-window-config
+        (set-window-configuration aidermacs--pre-ediff-window-config)
+        (setq aidermacs--pre-ediff-window-config nil)))))
+
+(defun aidermacs--show-ediff-for-file (file)
+  "Uses the pre-edit buffer stored to compare with the current FILE state."
+  (let* ((full-path (expand-file-name file (aidermacs-project-root)))
+         (pre-edit-pair (assoc full-path aidermacs--pre-edit-file-buffers))
+         (pre-edit-buffer (and pre-edit-pair (cdr pre-edit-pair))))
+    (if (and pre-edit-buffer (buffer-live-p pre-edit-buffer))
+        (progn
+          (let ((current-buffer (or (get-file-buffer full-path)
+                                    (find-file-noselect full-path))))
+            (with-current-buffer current-buffer
+              (revert-buffer t t t))
+            (delete-other-windows (get-buffer-window (switch-to-buffer 
current-buffer)))
+            ;; Start ediff session
+            (ediff-buffers pre-edit-buffer current-buffer)))
+      ;; If no pre-edit buffer found, continue with next file
+      (message "No pre-edit buffer found for %s, skipping" file)
+      (aidermacs--process-next-ediff-file))))
+
+(provide 'aidermacs-output)
+;;; aidermacs-output.el ends here
diff --git a/aidermacs.el b/aidermacs.el
index 7cf439a982..597aa85225 100644
--- a/aidermacs.el
+++ b/aidermacs.el
@@ -28,7 +28,6 @@
 (require 'compat)
 (require 'comint)
 (require 'dired)
-(require 'ediff)
 (require 'project)
 (require 'transient)
 (require 'vc-git)
@@ -40,28 +39,21 @@
 
 (require 'aidermacs-backends)
 (require 'aidermacs-models)
+(require 'aidermacs-output)
+
+(declare-function magit-show-commit "magit-diff" (rev &optional noselect 
module))
 
 (defgroup aidermacs nil
   "AI pair programming with Aider."
   :group 'aidermacs)
 
-(defvar-local aidermacs--current-mode nil
-  "Buffer-local variable to track the current aidermacs mode.
-Possible values: `code', `ask', `architect', `help'.")
-
-(declare-function magit-show-commit "magit-diff" (rev &optional noselect 
module))
-
-(defcustom aidermacs-show-diff-after-change t
-  "When non-nil, enable ediff for reviewing AI-generated changes.
-When nil, skip preparing temp buffers and showing ediff comparisons."
-  :type 'boolean)
-
 (defcustom aidermacs-program "aider"
   "The name or path of the aidermacs program."
   :type 'string)
 
-(define-obsolete-variable-alias 'aidermacs-args 'aidermacs-extra-args "0.5.0"
-  "Old name for `aidermacs-extra-args', please update your config.")
+(defvar-local aidermacs--current-mode nil
+  "Buffer-local variable to track the current aidermacs mode.
+Possible values: `code', `ask', `architect', `help'.")
 
 (defcustom aidermacs-config-file nil
   "Path to aider configuration file.
@@ -70,6 +62,9 @@ ignoring other configuration settings except 
`aidermacs-extra-args'."
   :type '(choice (const :tag "None" nil)
                  (file :tag "Config file")))
 
+(define-obsolete-variable-alias 'aidermacs-args 'aidermacs-extra-args "0.5.0"
+  "Old name for `aidermacs-extra-args', please update your config.")
+
 (defcustom aidermacs-extra-args '()
   "Additional arguments to pass to the aidermacs command."
   :type '(repeat string))
@@ -134,13 +129,6 @@ This function tries multiple methods to determine the 
project root."
 This is the file name without path."
   :type 'string)
 
-(defconst aidermacs-prompt-regexp "^[^[:space:]<]*>[[:space:]]+$"
-  "Regexp to match Aider's command prompt.")
-
-(defvar-local aidermacs--pre-edit-file-buffers nil
-  "Alist of (filename . temp-buffer) storing file state before Aider edits.
-These contain the original content of files that might be modified by Aider.")
-
 (transient-define-prefix aidermacs-transient-menu ()
   "AI Pair Programming Interface."
   ["Aidermacs: AI Pair Programming"
@@ -327,196 +315,16 @@ This is useful for working in monorepos where you want 
to limit aider's scope."
   (let ((aidermacs-subtree-only t))
     (aidermacs-run)))
 
-(defun aidermacs--capture-file-state (filename)
-  "Store the current state of FILENAME in a temporary buffer.
-Creates a read-only buffer with the file's content, appropriate major mode,
-and syntax highlighting to match the original file."
-  (when (and filename (file-exists-p filename))
-    (condition-case err
-        (let ((temp-buffer (generate-new-buffer
-                            (format " *aidermacs-pre-edit:%s*"
-                                    (file-name-nondirectory filename)))))
-          (with-current-buffer temp-buffer
-            (insert-file-contents filename)
-            (set-buffer-modified-p nil)
-            ;; Use same major mode as the original file
-            (let ((buffer-file-name filename))
-              (set-auto-mode)
-              ;; Ensure syntax highlighting is applied
-              (font-lock-ensure))
-            ;; Make buffer read-only
-            (setq buffer-read-only t))
-          (cons filename temp-buffer))
-      (error
-       (message "Error capturing file state for %s: %s"
-                filename (error-message-string err))
-       nil))))
-
-(defun aidermacs--cleanup-temp-buffers ()
-  "Clean up all temporary buffers created for ediff sessions.
-This is called when all ediff sessions are complete.
-Kills all pre-edit buffers that were created to store original file content."
-  (interactive)
-  (with-current-buffer (get-buffer (aidermacs-get-buffer-name))
-    ;; Clean up buffers in the tracking list
-    (dolist (file-pair aidermacs--pre-edit-file-buffers)
-      (let ((temp-buffer (cdr file-pair)))
-        (when (and temp-buffer (buffer-live-p temp-buffer))
-          (kill-buffer temp-buffer))))
-    ;; Also clean up any stray pre-edit buffers that might have been missed
-    (dolist (buf (buffer-list))
-      (when (and (string-match " \\*aidermacs-pre-edit:" (buffer-name buf))
-                 (buffer-live-p buf))
-        (kill-buffer buf)))
-    ;; Clear the list after cleanup
-    (setq aidermacs--pre-edit-file-buffers nil)))
-
-(defun aidermacs--prepare-for-code-edit ()
-  "Prepare for code edits by capturing current file states in memory buffers.
-Creates temporary buffers containing the original content of all tracked files.
-This is skipped if `aidermacs-show-diff-after-change' is nil."
-  (when aidermacs-show-diff-after-change
-    (let ((files aidermacs--tracked-files))
-      (when files
-        (message "Preparing code edit for %s" files)
-        (setq aidermacs--pre-edit-file-buffers
-              (cl-remove-duplicates
-               (mapcar (lambda (file)
-                         (let* ((clean-file (replace-regexp-in-string " 
(read-only)$" "" file))
-                                (full-path (expand-file-name clean-file 
(aidermacs-project-root))))
-                           ;; Only capture state if we don't already have it
-                           (or (assoc full-path 
aidermacs--pre-edit-file-buffers)
-                               (aidermacs--capture-file-state full-path))))
-                       files)
-               :test (lambda (a b) (equal (car a) (car b)))))
-        ;; Remove nil entries from the list (where capture failed or was 
skipped)
-        (setq aidermacs--pre-edit-file-buffers (delq nil 
aidermacs--pre-edit-file-buffers))
-        ;; Run again if it's nil
-        (unless aidermacs--pre-edit-file-buffers
-          (aidermacs--prepare-for-code-edit))))))
-
-(defun aidermacs--ediff-quit-handler ()
-  "Handle ediff session cleanup and process next files in queue.
-This function is called when an ediff session is quit and processes
-the next file in the ediff queue if any remain."
-  (when (and (boundp 'ediff-buffer-A)
-             (buffer-live-p ediff-buffer-A)
-             (string-match " \\*aidermacs-pre-edit:"
-                           (buffer-name ediff-buffer-A)))
-    (aidermacs--process-next-ediff-file)))
-
-(defun aidermacs--setup-ediff-cleanup-hooks ()
-  "Set up hooks to ensure proper cleanup of temporary buffers after ediff.
-Only adds the hook if it's not already present."
-  (unless (member #'aidermacs--ediff-quit-handler ediff-quit-hook)
-    (add-hook 'ediff-quit-hook #'aidermacs--ediff-quit-handler)))
-
-(defun aidermacs--detect-edited-files ()
-  "Parse current output to find files edited by Aider.
-Returns a list of files that have been modified according to the output."
-  (let ((project-root (aidermacs-project-root))
-        (output aidermacs--current-output)
-        (edited-files)
-        (unique-files)
-        (valid-files))
-    (when output
-      (with-temp-buffer
-        (insert output)
-        (goto-char (point-min))
-
-        ;; Case 1: Find "Applied edit to" lines
-        (while (search-forward "Applied edit to" nil t)
-          (beginning-of-line)
-          (when-let* ((file (and (looking-at ".*Applied edit to 
\\(\\./\\)?\\([^[:space:]]+\\)")
-                                (match-string-no-properties 2))))
-            (push file edited-files))
-          (forward-line 1))
-
-        ;; Case 2: Find triple backtick blocks with filenames
-        (goto-char (point-min))
-        (while (search-forward "```" nil t)
-          (save-excursion
-            (forward-line -1)
-            (let ((potential-file (string-trim (buffer-substring 
(line-beginning-position) (line-end-position)))))
-              (when (and (not (string-empty-p potential-file))
-                         (not (string-match-p "\\`[[:space:]]*\\'" 
potential-file))
-                         (not (string-match-p "^```" potential-file)))
-                (push potential-file edited-files))))
-          (forward-line 1))
-
-        ;; Case 3: Handle udiff format
-        (goto-char (point-min))
-        (while (search-forward "--- " nil t)
-          (let* ((line-end (line-end-position))
-                 (current-udiff-file (buffer-substring (point) line-end)))
-            (forward-line 1)
-            (when (looking-at "\\+\\+\\+ ")
-              (let ((plus-file (buffer-substring (+ (point) 4) 
(line-end-position))))
-                (when (string= (file-name-nondirectory current-udiff-file)
-                               (file-name-nondirectory plus-file))
-                  (push current-udiff-file edited-files)))))))
-
-      ;; Filter the list to only include valid files
-      (setq unique-files (delete-dups edited-files))
-      (setq valid-files (cl-remove-if-not
-                         (lambda (file)
-                           (file-exists-p (expand-file-name file 
project-root)))
-                         unique-files))
-      (nreverse valid-files))))
-
-(defvar-local aidermacs--ediff-queue nil
-  "Buffer-local queue of files waiting to be processed by ediff.")
-
-(defvar aidermacs--pre-ediff-window-config nil
-  "Window configuration before starting ediff sessions.")
-
-(defun aidermacs--process-next-ediff-file ()
-  "Process the next file in the ediff queue for the current buffer."
-  (with-current-buffer (get-buffer (aidermacs-get-buffer-name))
-    (if aidermacs--ediff-queue
-        (let ((file (pop aidermacs--ediff-queue)))
-          (aidermacs--show-ediff-for-file file))
-      (aidermacs--cleanup-temp-buffers)
-      ;; Restore original window configuration
-      (when aidermacs--pre-ediff-window-config
-        (set-window-configuration aidermacs--pre-ediff-window-config)
-        (setq aidermacs--pre-ediff-window-config nil)))))
-
-(defun aidermacs--show-ediff-for-file (file)
-  "Uses the pre-edit buffer stored to compare with the current FILE state."
-  (let* ((full-path (expand-file-name file (aidermacs-project-root)))
-         (pre-edit-pair (assoc full-path aidermacs--pre-edit-file-buffers))
-         (pre-edit-buffer (and pre-edit-pair (cdr pre-edit-pair))))
-    (if (and pre-edit-buffer (buffer-live-p pre-edit-buffer))
-        (progn
-          (let ((current-buffer (or (get-file-buffer full-path)
-                                    (find-file-noselect full-path))))
-            (with-current-buffer current-buffer
-              (revert-buffer t t t))
-            (delete-other-windows (get-buffer-window (switch-to-buffer 
current-buffer)))
-            ;; Start ediff session
-            (ediff-buffers pre-edit-buffer current-buffer)))
-      ;; If no pre-edit buffer found, continue with next file
-      (message "No pre-edit buffer found for %s, skipping" file)
-      (aidermacs--process-next-ediff-file))))
-
-(defun aidermacs--show-ediff-for-edited-files (edited-files)
-  "Show ediff for each file in EDITED-FILES.
-This is skipped if `aidermacs-show-diff-after-change' is nil."
-  (when (and aidermacs-show-diff-after-change edited-files)
-    ;; Save current window configuration
-    (setq aidermacs--pre-ediff-window-config (current-window-configuration))
-
-    ;; Display a message about which files were changed
-    (message "Modified %d file(s): %s"
-             (length edited-files)
-             (mapconcat #'identity edited-files ", "))
-
-    ;; Set up the queue in the current buffer
-    (setq-local aidermacs--ediff-queue edited-files)
-
-    ;; Process the first file
-    (aidermacs--process-next-ediff-file)))
+(defun aidermacs--command-may-edit-files (command)
+  "Check if COMMAND may result in file edits.
+Returns t if the command is likely to modify files, nil otherwise.
+In code/architect mode, commands without prefixes may edit.
+Commands containing /code or /architect always may edit."
+  (and (stringp command)
+       (or (and (memq aidermacs--current-mode '(code architect))
+                (not (string-match-p "^/" command)))
+           (string-match-p "/code" command)
+           (string-match-p "/architect" command))))
 
 (defun aidermacs--send-command (command &optional no-switch-to-buffer 
use-existing redirect callback)
   "Send command to the corresponding aidermacs process.
@@ -530,16 +338,16 @@ If CALLBACK is non-nil it will be called after the 
command finishes."
                      (progn (aidermacs-run)
                             (get-buffer buffer-name))))
          (processed-command (aidermacs--process-message-if-multi-line 
command)))
-    ;; Reset current output before sending new command
+    ;; Check if command may edit files and prepare accordingly
     (with-current-buffer buffer
+      ;; Reset current output before sending new command
       (setq aidermacs--current-output "")
       (setq aidermacs--current-callback callback)
       (setq aidermacs--last-command processed-command)
-      ;; Always prepare for potential edits
       (aidermacs--cleanup-temp-buffers)
-      ;; Ensure current file is tracked before preparing for code edit
       (aidermacs--ensure-current-file-tracked)
-      (aidermacs--prepare-for-code-edit)
+      (when (aidermacs--command-may-edit-files command)
+        (aidermacs--prepare-for-code-edit))
       (aidermacs--send-command-backend buffer processed-command redirect))
     (when (and (not no-switch-to-buffer)
                (not (string= (buffer-name) buffer-name)))
@@ -721,8 +529,7 @@ Sends the \"/ls\" command and displays the results in a 
Dired buffer."
   (aidermacs--send-command "/drop"))
 
 (defun aidermacs-batch-drop-dired-marked-files ()
-  "Drop Dired marked files from the aidermacs session.
-If called from the special aidermacs files buffer, kill the buffer after 
dropping files."
+  "Drop Dired marked files from the aidermacs session."
   (interactive)
   (unless (derived-mode-p 'dired-mode)
     (user-error "This command can only be used in Dired mode"))
@@ -735,54 +542,6 @@ If called from the special aidermacs files buffer, kill 
the buffer after droppin
       (message "Closing aidermacs file buffer after dropping files")
       (kill-buffer (aidermacs-get-buffer-name nil " Files")))))
 
-(defun aidermacs-show-output-history ()
-  "Display the AI output history in a new buffer."
-  (interactive)
-  (let ((buf (get-buffer-create "*aidermacs-history*"))
-        (history aidermacs--output-history))
-    (with-current-buffer buf
-      (org-mode)
-      (setq buffer-read-only nil)
-      (erase-buffer)
-      (display-line-numbers-mode 1)
-      (dolist (entry history)
-        (let ((timestamp (format-time-string "%F %T" (car entry)))
-              (output (cdr entry)))
-          (insert (format "* %s\n#+BEGIN_SRC\n%s\n#+END_SRC\n" timestamp 
output))))
-      (goto-char (point-min))
-      (setq buffer-read-only t)
-      (local-set-key (kbd "q") #'kill-this-buffer)
-      (switch-to-buffer-other-window buf))))
-
-(defun aidermacs-get-last-output ()
-  "Get the most recent output from aidermacs."
-  (interactive)
-  (when (stringp aidermacs--current-output)
-    (message "%s" aidermacs--current-output)
-    (kill-new aidermacs--current-output)
-    aidermacs--current-output))
-
-(defun aidermacs--ensure-current-file-tracked ()
-  "Ensure current file is tracked in the aidermacs session."
-  (when buffer-file-name
-    (let* ((session-buffer (get-buffer (aidermacs-get-buffer-name)))
-           (filename buffer-file-name)
-           (relative-path (file-relative-name filename 
(aidermacs-project-root))))
-      (when session-buffer
-        (with-current-buffer session-buffer
-          (unless (member relative-path aidermacs--tracked-files)
-            (push relative-path aidermacs--tracked-files)
-            (let ((command (aidermacs--prepare-file-paths-for-command "/add" 
(list relative-path))))
-              (aidermacs--send-command-backend session-buffer command 
nil))))))))
-
-(defvar aidermacs--read-string-history nil
-  "History list for aidermacs read string inputs.")
-(if (bound-and-true-p savehist-loaded)
-    (add-to-list 'savehist-additional-variables 
'aidermacs--read-string-history)
-  (add-hook 'savehist-mode-hook
-            (lambda ()
-              (add-to-list 'savehist-additional-variables 
'aidermacs--read-string-history))))
-
 (defun aidermacs--form-prompt (command &optional prompt-prefix guide 
ignore-context)
   "Get command based on context with COMMAND and PROMPT-PREFIX.
 COMMAND is the text to prepend.  PROMPT-PREFIX is the text to add after 
COMMAND.

Reply via email to