Skip to content

Commit e07cc70

Browse files
author
Kang Tu
committed
Merge branch 'main' of github.com:tninja/ai-code-interface.el
2 parents 6bdfbc9 + e2012ce commit e07cc70

File tree

4 files changed

+72
-67
lines changed

4 files changed

+72
-67
lines changed

README.org

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ An Emacs interface for AI-assisted software development. *The purpose is to prov
4848
- `org`: Org-mode support
4949
- `magit`: Git integration
5050
- `transient`: For the menu system
51-
- Claude Code (`[[https://github.com/stevemolitor/claude-code.el][claude-code.el]]`)
51+
- Claude Code (`[[https://github.com/stevemolitor/claude-code.el][claude-code.el]]`), (use straight to install, NOT MELPA version)
5252
- eat / vterm need to be installed to support various AI coding CLI backends.
5353

5454
*** Optional Dependencies

ai-code-backends.el

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,13 @@ Sets `ai-code-cli-*' defaliases and updates `ai-code-cli'."
168168
(when (and feature (not (featurep feature)))
169169
(user-error "Backend '%s' is not available. Please install the package providing '%s' and try again."
170170
label (symbol-name feature)))
171-
(unless (and (fboundp start) (fboundp switch) (fboundp send))
172-
(user-error "Backend '%s' is not available (missing functions). Please install the package providing '%s'."
173-
label (symbol-name feature)))
171+
(let ((missing-fns (seq-filter (lambda (fn) (not (fboundp fn)))
172+
(list start switch send))))
173+
(when missing-fns
174+
(user-error "Backend '%s' is not available (missing functions: %s). Please install the package providing '%s'."
175+
label
176+
(mapconcat #'symbol-name missing-fns ", ")
177+
(symbol-name feature))))
174178
(defalias 'ai-code-cli-start start)
175179
(defalias 'ai-code-cli-switch-to-buffer switch)
176180
(defalias 'ai-code-cli-send-command send)

ai-code-change.el

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -320,13 +320,13 @@ ARG is the prefix argument for clipboard context."
320320
(region-text
321321
(unless (ai-code--is-comment-block region-text)
322322
(user-error "Selected region must be a comment block"))
323-
(format (concat
324-
"Please implement code for this requirement comment block in the selected region. "
325-
"Keep the comment in place and ensure it begins with a DONE prefix (change TODO to DONE or prepend DONE if no prefix). "
323+
(format (concat
324+
"Please implement code for this requirement comment block in the selected region first. "
325+
"After implementing, keep the comment in place and ensure it begins with a DONE prefix (change TODO to DONE or prepend DONE if no prefix). "
326326
"If this is a pure new code block, place it after the comment; otherwise keep the existing structure and make corresponding change for the context.\n%s\n%s%s%s")
327327
region-location-line region-text function-context files-context-string))
328328
(is-comment
329-
(format "Please implement code for this requirement comment on line %d: '%s'. Keep the comment in place and ensure it begins with a DONE prefix (change TODO to DONE or prepend DONE if needed). If this is a pure new code block, place it after the comment; otherwise keep the existing structure and make corresponding change for the context.%s%s"
329+
(format "Please implement code for this requirement comment on line %d: '%s' first. After implementing, keep the comment in place and ensure it begins with a DONE prefix (change TODO to DONE or prepend DONE if needed). If this is a pure new code block, place it after the comment; otherwise keep the existing structure and make corresponding change for the context.%s%s"
330330
current-line-number current-line function-context files-context-string))
331331
;; (function-name
332332
;; (format "Please implement code after all TODO comments in function '%s'. The TODOs are TODO comments. Keep each comment in place and ensure each begins with a DONE prefix (change TODO to DONE or prepend DONE if needed) before adding implementation code after it. Keep the existing code structure and only add code after these marked items.%s"

ai-code-discussion.el

Lines changed: 60 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -387,69 +387,70 @@ or the default note file path (.ai.code.notes.org in the git root).
387387
Add the section title as a headline at the end of the note file, and put the
388388
selected region as content of that section."
389389
(interactive)
390-
(unless (region-active-p)
391-
(user-error "No region selected. Please select the text you want to save as notes"))
392-
(let* ((region-text (filter-buffer-substring (region-beginning) (region-end) nil))
393-
(git-root (condition-case nil
390+
(let* ((git-root (condition-case nil
394391
(magit-toplevel)
395392
(error nil)))
396393
(default-note-file (if git-root
397394
(expand-file-name ai-code-notes-file-name git-root)
398-
(expand-file-name ai-code-notes-file-name default-directory)))
399-
;; Get all org-mode buffers with associated files
400-
(org-buffers (seq-filter
401-
(lambda (buf)
402-
(with-current-buffer buf
403-
(and (eq major-mode 'org-mode)
404-
(buffer-file-name))))
405-
(buffer-list)))
406-
(org-buffer-files (mapcar #'buffer-file-name org-buffers))
407-
;; Create candidates list with default file first, then existing org buffers
408-
(candidates (delete-dups
409-
(mapcar #'file-truename
410-
(cons default-note-file org-buffer-files))))
411-
;; Select note file from candidates
412-
(note-file (completing-read "Note file: " candidates nil nil (file-truename default-note-file)))
413-
(default-title (when ai-code-notes-use-gptel-headline
414-
(condition-case err
415-
(string-trim
416-
(ai-code-call-gptel-sync
417-
(format "Generate a concise headline (max 10 words) for this note content. Only return the headline text without quotes or extra formatting:\n\n%s"
418-
(if (> (length region-text) 500)
419-
(substring region-text 0 500)
420-
region-text))))
421-
(error
422-
(message "GPTel headline generation failed: %s" (error-message-string err))
423-
""))))
424-
(section-title (ai-code-read-string "Section title: " (or default-title ""))))
425-
(when (string-empty-p section-title)
426-
(user-error "Section title cannot be empty"))
427-
;; Create note file directory if it doesn't exist
428-
(let ((note-dir (file-name-directory note-file)))
429-
(unless (file-exists-p note-dir)
430-
(make-directory note-dir t)))
431-
;; Append section to note file
432-
(with-current-buffer (find-file-noselect note-file)
433-
(save-excursion
434-
(goto-char (point-max))
435-
;; Add newline before new section if file is not empty
436-
(unless (bobp)
437-
(insert "\n\n"))
438-
;; Insert headline
439-
(insert "* " section-title "\n")
440-
;; Insert timestamp
441-
(org-insert-time-stamp (current-time) t nil)
442-
(insert "\n\n")
443-
;; Insert region content
444-
(insert region-text)
445-
(insert "\n"))
446-
(save-buffer))
447-
;; Open note file in other window and scroll to bottom
448-
(let ((note-buffer (find-file-other-window note-file)))
449-
(with-selected-window (get-buffer-window note-buffer)
450-
(goto-char (point-max))
451-
(recenter -1)))
452-
(message "Notes added to %s under section: %s" note-file section-title)))
395+
(expand-file-name ai-code-notes-file-name default-directory))))
396+
(if (not (region-active-p))
397+
(find-file-other-window default-note-file)
398+
(let* ((region-text (filter-buffer-substring (region-beginning) (region-end) nil))
399+
(default-note-file-truename (file-truename default-note-file))
400+
;; Get all org-mode buffers with associated files
401+
(org-buffers (seq-filter
402+
(lambda (buf)
403+
(with-current-buffer buf
404+
(and (eq major-mode 'org-mode)
405+
(buffer-file-name))))
406+
(buffer-list)))
407+
(org-buffer-files (mapcar #'buffer-file-name org-buffers))
408+
;; Create candidates list with default file first, then existing org buffers
409+
(candidates (delete-dups
410+
(mapcar #'file-truename
411+
(cons default-note-file-truename org-buffer-files))))
412+
;; Select note file from candidates
413+
(note-file (completing-read "Note file: " candidates))
414+
(default-title (when ai-code-notes-use-gptel-headline
415+
(condition-case err
416+
(string-trim
417+
(ai-code-call-gptel-sync
418+
(format "Generate a concise headline (max 10 words) for this note content. Only return the headline text without quotes or extra formatting:\n\n%s"
419+
(if (> (length region-text) 500)
420+
(substring region-text 0 500)
421+
region-text))))
422+
(error
423+
(message "GPTel headline generation failed: %s" (error-message-string err))
424+
""))))
425+
(section-title (ai-code-read-string "Section title: " (or default-title ""))))
426+
(when (string-empty-p section-title)
427+
(user-error "Section title cannot be empty"))
428+
;; Create note file directory if it doesn't exist
429+
(let ((note-dir (file-name-directory note-file)))
430+
(unless (file-exists-p note-dir)
431+
(make-directory note-dir t)))
432+
;; Append section to note file
433+
(with-current-buffer (find-file-noselect note-file)
434+
(save-excursion
435+
(goto-char (point-max))
436+
;; Add newline before new section if file is not empty
437+
(unless (bobp)
438+
(insert "\n\n"))
439+
;; Insert headline
440+
(insert "* " section-title "\n")
441+
;; Insert timestamp
442+
(org-insert-time-stamp (current-time) t nil)
443+
(insert "\n\n")
444+
;; Insert region content
445+
(insert region-text)
446+
(insert "\n"))
447+
(save-buffer))
448+
;; Open note file in other window and scroll to bottom
449+
(let ((note-buffer (find-file-other-window note-file)))
450+
(with-selected-window (get-buffer-window note-buffer)
451+
(goto-char (point-max))
452+
(recenter -1)))
453+
(message "Notes added to %s under section: %s" note-file section-title)))))
453454

454455
(provide 'ai-code-discussion)
455456

0 commit comments

Comments
 (0)