branch: elpa/aidermacs
commit d60824add8884a2baf4bb73344983f2026bc4b1a
Author: Kang Tu <tni...@gmail.com>
Commit: GitHub <nore...@github.com>

    Refactor: combine function under cursor function and region based function 
as single one (#34)
    
    * feat(aider): add explain-symbol-under-point command
    
    * feat: add function to explain function under cursor
    
    * feat(aider): add support for Gemini model and function explanation command
    
    * docs(readme): reorganize and expand code explanation features
    
    * refactor: remove unused syntax table code in buffer setup
    
    * feat: add function to add files with same suffix under current dir
    
    * feat: Add function to add same-type files under a directory to Aider
    
    * feat: Add command to add files of same type under current directory
    
    * refactor: Use helper function for adding/reading current file in aider.el
    
    * refactor: Comment out unused functions in aider-main-menu-map
    
    * refactor: move git repository functions to separate file
    
    * refactor: Combine region and function explain commands into one
    
    * feat: Add function to refactor region or function based on selection
    
    * feat: Add function to refactor function or region based on selection
    
    * refactor(ui): simplify code change menu options
    
    * refactor(doom): update menu itemsc
    
    * feat: append region text to question in `aider-ask-question`
    
    * fix: Escape newlines in region text for `aider-ask-question`
    
    * refactor: Extract string escaping logic into dedicated function
    
    This commit refactors the string escaping logic in `aider.el` into a 
dedicated function, `aider--escape-string-for-aider`. This improves code 
readability, maintainability, and reusability by centralizing the escaping 
logic in one place. The function replaces newline characters with escaped 
newlines, and is now used in `aider-ask-question`, `aider-debug-exception`, 
`aider-region-refactor-generate-command`, and `aider-region-explain`. The 
`aider-plain-read-string` function no longer per [...]
    
    * refactor: Centralize newline escaping in `aider--send-command`
    
    * fix: Remove extra parenthesis in message call in aider--send-command
    
    * bug fix
    
    * refactor: Remove unnecessary parentheses in `aider-send-command`
    
    * refactor: Refactor aider-send-paragraph to send lines individually
    
    * refactor: Use dash library for list manipulation
    
    * bug fix
    
    * fix: improve `aider-send-paragraph` to handle newlines correctly
    
    * fix: Send whole buffer content when no files are added to chat
    
    * ```
    refactor: Only send non-empty lines in `aider-send-paragraph`
    ```
    
    * refactor: Send non-empty lines to aider in `aider-send-current-test`
    
    * refactor: Improve `aider-send-paragraph` to send whole paragraph to aider
    
    * refactor: remove dash.el dependency
    
    ---------
    
    Co-authored-by: Kang Tu <kang...@apple.com>
---
 aider-doom.el | 36 ++++++++++++++-----------
 aider.el      | 86 ++++++++++++++++++++++++++++++++++++++---------------------
 2 files changed, 75 insertions(+), 47 deletions(-)

diff --git a/aider-doom.el b/aider-doom.el
index bfd6f0d476..d2a149000d 100644
--- a/aider-doom.el
+++ b/aider-doom.el
@@ -16,40 +16,44 @@
           (:prefix ("A" . "Aider")
                    (:prefix ("a" . "Add")
                     :desc "Current file" "c" #'aider-add-current-file
+                    :desc "File read-only" "f" #'aider-current-file-read-only
                     :desc "Files in window" "w" 
#'aider-add-files-in-current-window
+                    :desc "Add Same Type Files under dir" "d" 
#'aider-add-same-type-files-under-dir
                     :desc "Batch direct marked files" "b" 
#'aider-batch-add-dired-marked-files
-                    :desc "Find files in repo" "g" #'aider-repo-find-name-dired
-                    :desc "Open repo root" "d" #'aider-git-repo-root-dired)
+                    )
 
                    (:prefix ("b" . "Buffer")
+                    :desc "Open Aider" "o" #'aider-run-aider
                     :desc "Switch to Aider" "b" #'aider-switch-to-buffer
-                    :desc "Clear Aider" "c" #'aider-clear)
+                    :desc "Clear Aider" "c" #'aider-clear
+                    :desc "Reset Aider" "r" #'aider-reset
+                    :desc "Exit Aider" "x" #'aider-exit
+                    )
 
                    (:prefix ("s" . "Send")
-                    :desc "File read-only" "f" #'aider-current-file-read-only
                     :desc "Line at cursor" "l" #'aider-send-line-under-cursor
-                    :desc "Paragraph at cursor" "p" #'aider-send-paragraph)
+                    :desc "Paragraph at cursor" "p" #'aider-send-paragraph
+                    )
 
                    (:prefix ("c" . "Code")
+                    :desc "Architecture" "d" #'aider-architect-discussion
                     :desc "Change" "c" #'aider-code-change
-                    :desc "Refactor region" "r" #'aider-region-refactor
-                    :desc "Undo change" "u" #'aider-undo-last-change)
+                    :desc "Refactor Function or Region" "r" 
#'aider-function-or-region-refactor
+                    :desc "Undo change" "u" #'aider-undo-last-change
+                    :desc "Show last commit" "g" #'aider-magit-show-last-commit
+                    )
 
                    (:prefix ("d" . "Discuss")
                     :desc "Ask question" "a" #'aider-ask-question
-                    :desc "Architecture" "d" #'aider-architect-discussion
-                    :desc "Region explanation" "r" #'aider-region-explain
-                    :desc "Exception debugggin" "e" #'aider-debug-exception)
+                    :desc "Explain Function or Region" "r" 
#'aider-function-or-region-explain
+                    :desc "Exception debugging" "e" #'aider-debug-exception
+                    )
 
                    (:prefix ("z" . "Other")
                     :desc "General command" "c" #'aider-general-command
                     :desc "Help" "h" #'aider-help
-                    :desc "Show last commit" "g" 
#'aider-magit-show-last-commit)
-
-
-                   :desc "Open Aider" "o" #'aider-run-aider
-                   :desc "Reset Aider" "r" #'aider-reset
-                   :desc "Exit Aider" "x" #'aider-exit))))
+                   )
+                   ))))
 
 ;; Add the setup function to appropriate hooks
 (add-hook 'find-file-hook #'aider-doom-setup-keys)
diff --git a/aider.el b/aider.el
index a0f9560ed2..6a219bcc4e 100644
--- a/aider.el
+++ b/aider.el
@@ -12,9 +12,9 @@
 ;;; Code:
 
 (require 'comint)
+(require 'dired)
 (require 'transient)
 (require 'which-func)
-(require 'dired)
 
 (defgroup aider nil
   "Customization group for the Aider package."
@@ -42,13 +42,16 @@
   "Font lock keywords for aider buffer.")
 
 
+(defun aider--escape-string-for-aider (str)
+  "Escape special characters in STR for sending to Aider.
+Currently, this function replaces newlines with \\\\n."
+  (replace-regexp-in-string "\n" "\\\\n" str))
+
 ;;;###autoload
 (defun aider-plain-read-string (prompt &optional initial-input)
   "Read a string from the user with PROMPT and optional INITIAL-INPUT.
 This function can be customized or redefined by the user."
-  (let* ((input (read-string prompt initial-input))
-         (processed-input (replace-regexp-in-string "\n" "\\\\n" input)))
-    processed-input))
+  (read-string prompt initial-input))
 
 (defalias 'aider-read-string 'aider-plain-read-string)
 
@@ -74,24 +77,21 @@ This function can be customized or redefined by the user."
     ("b" "Batch Add Dired Marked Files" aider-batch-add-dired-marked-files)
     ]
    ["Code Change"
-    ("c" "Code Change" aider-code-change)
     ("t" "Architect Discuss and Change" aider-architect-discussion)
-    ("r" "Refactor Code in Selected Region" aider-region-refactor)
-    ("R" "Refactor Function Under Cursor" aider-function-refactor)
+    ("c" "Code Change" aider-code-change)
+    ("r" "Refactor Function or Region" aider-function-or-region-refactor)
     ("T" "Fix Failing Test Under Cursor" aider-fix-failing-test-under-cursor)
     ("m" "Show Last Commit with Magit" aider-magit-show-last-commit)
     ("u" "Undo Last Change" aider-undo-last-change)
     ]
    ["Discussion"
     ("q" "Ask Question" aider-ask-question)
-    ("e" "Explain Code in Selected Region" aider-region-explain)
-    ("E" "Explain Function Under Cursor" aider-function-explain)
-    ("p" "Explain Symbol Under Cursor" aider-explain-symbol-under-point)
+    ("e" "Explain Function or Region" aider-function-or-region-explain)
     ("D" "Debug Exception" aider-debug-exception)
     ]
    ["Other"
     ("g" "General Command" aider-general-command)
-    ("h" "Help" aider-help) ;; Menu item for help command
+    ("h" "Help" aider-help)
     ]
    ])
 
@@ -205,21 +205,20 @@ If not in a git repository, an error is raised."
 COMMAND should be a string representing the command to send."
   ;; Check if the corresponding aider buffer exists
   (if-let ((aider-buffer (get-buffer (aider-buffer-name))))
-      (let ((aider-process (get-buffer-process aider-buffer)))
+      (let* ((command (aider--escape-string-for-aider command))
+             (aider-process (get-buffer-process aider-buffer)))
         ;; Check if the corresponding aider buffer has an active process
         (if (and aider-process (comint-check-proc aider-buffer))
             (progn
-              ;; Ensure the command ends with a newline
-              (unless (string-suffix-p "\n" command)
-                (setq command (concat command "\n")))
               ;; Send the command to the aider process
-              (aider--comint-send-large-string aider-buffer command)
+              (aider--comint-send-large-string aider-buffer (concat command 
"\n"))
               ;; Provide feedback to the user
               ;; (message "Sent command to aider buffer: %s" (string-trim 
command))
               (when switch-to-buffer
                 (aider-switch-to-buffer)))
           (message "No active process found in buffer %s." 
(aider-buffer-name))))
-    (message "Buffer %s does not exist. Please start 'aider' first." 
(aider-buffer-name))))
+    (message "Buffer %s does not exist. Please start 'aider' first." 
(aider-buffer-name))
+    ))
 
 ;;;###autoload
 (defun aider-add-or-read-current-file (command-prefix)
@@ -282,10 +281,16 @@ COMMAND should be a string representing the command to 
send."
 ;; New function to get command from user and send it prefixed with "/ask "
 ;;;###autoload
 (defun aider-ask-question ()
-  "Prompt the user for a command and send it to the corresponding aider comint 
buffer prefixed with \"/ask \"."
+  "Prompt the user for a command and send it to the corresponding aider comint 
buffer prefixed with \"/ask \".
+If a region is active, append the region text to the question."
   (interactive)
-  (let ((command (aider-read-string "Enter question to ask: ")))
-    (aider-send-command-with-prefix "/ask " command)))
+  (let ((question (aider-read-string "Enter question to ask: "))
+        (region-text (and (region-active-p) (buffer-substring-no-properties 
(region-beginning) (region-end)))))
+    (let ((command (if region-text
+                       (format "/ask %s: %s" question region-text)
+                     (format "/ask %s" question))))
+      (aider-add-current-file)
+      (aider--send-command command t))))
 
 ;; New function to get command from user and send it prefixed with "/help "
 ;;;###autoload
@@ -331,7 +336,7 @@ If Magit is not installed, report that it is required."
 
 (defun aider-region-refactor-generate-command (region-text function-name 
user-command)
   "Generate the command string based on REGION-TEXT, FUNCTION-NAME, and 
USER-COMMAND."
-  (let ((processed-region-text (replace-regexp-in-string "\n" "\\\\n" 
region-text)))
+  (let ((processed-region-text region-text))
     (if function-name
         (format "/architect \"in function %s, for the following code block, 
%s: %s\"\n"
                 function-name user-command processed-region-text)
@@ -366,6 +371,14 @@ The command will be formatted as \"/architect \" followed 
by the user command an
         (aider--send-command command t))
     (message "No region selected.")))
 
+;;;###autoload
+(defun aider-function-or-region-refactor ()
+  "Call aider-function-refactor when no region is selected, otherwise call 
aider-region-refactor."
+  (interactive)
+  (if (region-active-p)
+      (aider-region-refactor)
+    (aider-function-refactor)))
+
 ;; New function to explain the code in the selected region
 ;;;###autoload
 (defun aider-region-explain ()
@@ -375,7 +388,7 @@ The command will be formatted as \"/ask \" followed by the 
text from the selecte
   (if (use-region-p)
       (let* ((region-text (buffer-substring-no-properties (region-beginning) 
(region-end)))
              (function-name (which-function))
-             (processed-region-text (replace-regexp-in-string "\n" "\\\\n" 
region-text))
+             (processed-region-text region-text)
              (command (if function-name
                           (format "/ask in function %s, explain the following 
code block: %s"
                                   function-name
@@ -397,6 +410,14 @@ The command will be formatted as \"/ask \" followed by the 
text from the selecte
         (aider--send-command command t))
     (message "No function found at cursor position.")))
 
+;;;###autoload
+(defun aider-function-or-region-explain ()
+  "Call aider-function-explain when no region is selected, otherwise call 
aider-region-explain."
+  (interactive)
+  (if (region-active-p)
+      (aider-region-explain)
+    (aider-function-explain)))
+
 ;; New function to explain the symbol at line
 ;;;###autoload
 (defun aider-explain-symbol-under-point ()
@@ -480,16 +501,19 @@ This function assumes the cursor is on or inside a test 
function."
 ;;; New function to send the current paragraph to the Aider buffer
 ;;;###autoload
 (defun aider-send-paragraph ()
-  "Send the current paragraph to the Aider buffer."
+  "Get the whole text of the current paragraph, split them into lines,
+   strip the newline character from each line,
+   for each non-empty line, send it to aider session"
   (interactive)
-  (let ((paragraph (buffer-substring-no-properties
-                    (save-excursion
-                      (backward-paragraph)
-                      (point))
-                    (save-excursion
-                      (forward-paragraph)
-                      (point)))))
-    (aider--send-command (string-trim paragraph) t)))
+  (let ((paragraph (save-excursion
+                     (backward-paragraph)
+                     (let ((start (point)))
+                       (forward-paragraph)
+                       (buffer-substring-no-properties start (point))))))
+    (mapc (lambda (line)
+            (unless (string-empty-p line)
+              (aider--send-command line t)))
+          (split-string paragraph "\n" t))))
 
 ;; Define the keymap for Aider Minor Mode
 (defvar aider-minor-mode-map

Reply via email to