Skip to content

Commit de58390

Browse files
tninjaKang TuCopilot
authored
Feat: Add note taking functions, useful during discussing with AI (#46)
* add function for notes taking * Add .ai.code.notes.org to config and gitignore entries * Bump version to 0.52 and add HISTORY * Update ai-code-discussion.el Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Refactor note file name customization and gitignore entries for AI code notes * Update ai-code-discussion.el Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update ai-code-discussion.el Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Kang Tu <kang_tu@apple.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent ffdc76f commit de58390

File tree

4 files changed

+89
-3
lines changed

4 files changed

+89
-3
lines changed

HISTORY.org

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
** Main branch change
55

6+
- Feat: Add note taking functions, useful during discussing with AI
67
- Fix function detection for TODO comments preceding method definitions
78
- Addressing [[https://github.com/tninja/ai-code-interface.el/issues/40][Wrong function detection]], suggested by @Silex
89
- Refactor: error investigation prompt, run command with comint buffer

ai-code-discussion.el

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
(declare-function ai-code-read-string "ai-code-input")
1818
(declare-function ai-code--insert-prompt "ai-code-prompt-mode")
1919
(declare-function ai-code--get-clipboard-text "ai-code-interface")
20+
(declare-function ai-code-call-gptel-sync "ai-code-prompt-mode")
2021

2122
;;;###autoload
2223
(defun ai-code-ask-question (arg)
@@ -324,7 +325,6 @@ Explain what this function does, its parameters, return value, algorithm, and it
324325
(when final-prompt
325326
(ai-code--insert-prompt final-prompt)))))
326327

327-
328328
(defun ai-code--explain-file ()
329329
"Explain the current file."
330330
(let ((file-name (or buffer-file-name "current buffer")))
@@ -334,6 +334,85 @@ Explain what this function does, its parameters, return value, algorithm, and it
334334
(when final-prompt
335335
(ai-code--insert-prompt final-prompt)))))
336336

337+
;;;###autoload
338+
(defcustom ai-code-notes-file-name ".ai.code.notes.org"
339+
"Default note file name relative to the project root.
340+
This value is used by `ai-code-take-notes' when suggesting where to store notes."
341+
:type 'string
342+
:group 'ai-code)
343+
344+
;;;###autoload
345+
(defcustom ai-code-notes-use-gptel-headline nil
346+
"Whether to use GPTel to generate headline for notes.
347+
If non-nil, call `ai-code-call-gptel-sync` to generate a smart default
348+
headline based on the selected content. Otherwise, prompt with empty default."
349+
:type 'boolean
350+
:group 'ai-code)
351+
352+
;;;###autoload
353+
(defun ai-code-take-notes ()
354+
"Take notes from selected region and save to a note file.
355+
When there is a selected region, ask for note file path (default is
356+
.ai.code.notes.org in the git root) and section title. Add the section
357+
title as a headline at the end of the note file, and put the selected
358+
region as content of that section."
359+
(interactive)
360+
(unless (region-active-p)
361+
(user-error "No region selected. Please select the text you want to save as notes"))
362+
(let* ((region-text (buffer-substring-no-properties (region-beginning) (region-end)))
363+
(git-root (condition-case nil
364+
(magit-toplevel)
365+
(error nil)))
366+
(default-note-file (if git-root
367+
(expand-file-name ai-code-notes-file-name git-root)
368+
(expand-file-name ai-code-notes-file-name default-directory)))
369+
(note-file (read-file-name
370+
"Note file: "
371+
(file-name-directory default-note-file)
372+
default-note-file
373+
nil
374+
(file-name-nondirectory default-note-file)))
375+
(default-title (when ai-code-notes-use-gptel-headline
376+
(condition-case err
377+
(string-trim
378+
(ai-code-call-gptel-sync
379+
(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"
380+
(if (> (length region-text) 500)
381+
(substring region-text 0 500)
382+
region-text))))
383+
(error
384+
(message "GPTel headline generation failed: %s" (error-message-string err))
385+
""))))
386+
(section-title (ai-code-read-string "Section title: " (or default-title ""))))
387+
(when (string-empty-p section-title)
388+
(user-error "Section title cannot be empty"))
389+
;; Create note file directory if it doesn't exist
390+
(let ((note-dir (file-name-directory note-file)))
391+
(unless (file-exists-p note-dir)
392+
(make-directory note-dir t)))
393+
;; Append section to note file
394+
(with-current-buffer (find-file-noselect note-file)
395+
(save-excursion
396+
(goto-char (point-max))
397+
;; Add newline before new section if file is not empty
398+
(unless (bobp)
399+
(insert "\n\n"))
400+
;; Insert headline
401+
(insert "* " section-title "\n")
402+
;; Insert timestamp
403+
(org-insert-time-stamp (current-time) t nil)
404+
(insert "\n\n")
405+
;; Insert region content
406+
(insert region-text)
407+
(insert "\n"))
408+
(save-buffer))
409+
;; Open note file in other window and scroll to bottom
410+
(let ((note-buffer (find-file-other-window note-file)))
411+
(with-selected-window (get-buffer-window note-buffer)
412+
(goto-char (point-max))
413+
(recenter -1)))
414+
(message "Notes added to %s under section: %s" note-file section-title)))
415+
337416
(provide 'ai-code-discussion)
338417

339418
;;; ai-code-discussion.el ends here

ai-code-git.el

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,12 @@ If not inside a Git repository, do nothing."
545545
(if (not git-root)
546546
(message "ai-code-update-git-ignore: not in a git repository, skipped")
547547
(let* ((gitignore-path (expand-file-name ".gitignore" git-root))
548-
(required-entries '(".ai.code.prompt.org" ".projectile" "GTAGS" "GRTAGS" "GPATH"))
548+
(required-entries (list ai-code-prompt-file-name
549+
ai-code-notes-file-name
550+
".projectile"
551+
"GTAGS"
552+
"GRTAGS"
553+
"GPATH"))
549554
(gitignore-content (when (file-exists-p gitignore-path)
550555
(with-temp-buffer
551556
(insert-file-contents gitignore-path)

ai-code-interface.el

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
;;; ai-code-interface.el --- AI code interface for editing AI prompt files -*- lexical-binding: t; -*-
22

33
;; Author: Kang Tu <tninja@gmail.com>
4-
;; Version: 0.51
4+
;; Version: 0.52
55
;; Package-Requires: ((emacs "26.1") (transient "0.8.0") (magit "2.1.0"))
66

77
;; SPDX-License-Identifier: Apache-2.0
@@ -174,6 +174,7 @@ Shows the current backend label to the right."
174174
("k" "Copy Cur File Name (C-u: full)" ai-code-copy-buffer-file-name-to-clipboard)
175175
("o" "Open Clipboard file dir" ai-code-open-clipboard-file-path-as-dired)
176176
("m" "Debug python MCP server" ai-code-debug-mcp)
177+
("n" "Take notes from AI session region" ai-code-take-notes)
177178
]
178179
])
179180

0 commit comments

Comments
 (0)