Skip to content
107 changes: 77 additions & 30 deletions ai-code-prompt-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -218,19 +218,77 @@ NOTE: This does not handle file paths containing spaces."
"Return FILE relative to GIT-ROOT-TRUENAME, prefixed with '@'."
(concat "@" (file-relative-name (file-truename file) git-root-truename)))

(defun ai-code--visible-window-files (git-root-truename)
"Return visible window file list under GIT-ROOT-TRUENAME."
(defun ai-code--normalize-path (file)
"Return normalized absolute path for FILE.
If FILE exists, return its truename. Otherwise return expanded path."
(let ((full (expand-file-name file)))
(if (file-exists-p full)
(file-truename full)
full)))
Comment thread
tninja marked this conversation as resolved.
Comment thread
tninja marked this conversation as resolved.

(defun ai-code--candidate-path (file git-root-truename)
"Return completion candidate for FILE.
Return '@'-prefixed path relative to GIT-ROOT-TRUENAME when FILE is under
that root, otherwise return the absolute path."
(let ((full-truename (ai-code--normalize-path file)))
(if (string-prefix-p git-root-truename full-truename)
(ai-code--relative-filepath full-truename git-root-truename)
full-truename)))
Comment thread
tninja marked this conversation as resolved.

(defun ai-code--current-frame-dired-paths (git-root-truename)
"Return dired directory candidates from current frame under GIT-ROOT-TRUENAME."
(let ((paths '()))
(dolist (win (window-list nil 'no-minibuffer))
(with-current-buffer (window-buffer win)
(when (derived-mode-p 'dired-mode)
(let ((dir (if (fboundp 'dired-current-directory)
(dired-current-directory)
default-directory)))
(when (and dir
(file-directory-p dir)
(string-prefix-p git-root-truename
(file-truename dir))
(not (ai-code--git-ignored-repo-file-p
dir
git-root-truename)))
(push (ai-code--relative-filepath dir
git-root-truename)
Comment thread
tninja marked this conversation as resolved.
paths))))))
(nreverse (delete-dups paths))))

(defun ai-code--visible-window-files ()
"Return files from visible windows in current frame."
(let ((files '())
(selected (selected-window)))
(dolist (win (cons selected
(delq selected (window-list nil 'no-minibuffer))))
(let* ((buf (window-buffer win))
(file (buffer-file-name buf)))
(when (and (ai-code--file-in-git-repo-p file git-root-truename)
(not (ai-code--git-ignored-repo-file-p file git-root-truename)))
(let ((file (buffer-file-name (window-buffer win))))
(when file
(push file files))))
(nreverse (delete-dups files))))

(defun ai-code--recent-buffer-paths (git-root-truename)
"Return candidate paths for most recent 5 visited buffer files or directories."
(let ((files '())
(count 0))
(dolist (buf (buffer-list))
(when (< count 5)
(with-current-buffer buf
(if (derived-mode-p 'dired-mode)
(let ((dir (if (fboundp 'dired-current-directory)
(dired-current-directory)
default-directory)))
(when dir
(push dir files)
(setq count (1+ count))))
(let ((file (buffer-file-name buf)))
(when file
(push file files)
(setq count (1+ count))))))))
(mapcar (lambda (file)
Comment thread
tninja marked this conversation as resolved.
(ai-code--candidate-path file git-root-truename))
(nreverse files))))
Comment thread
tninja marked this conversation as resolved.

(defun ai-code--buffer-file-list (git-root-truename &optional skip-files)
"Return buffer file list under GIT-ROOT-TRUENAME, skipping SKIP-FILES."
(let ((files '()))
Expand Down Expand Up @@ -262,39 +320,28 @@ NOTE: This does not handle file paths containing spaces."
(let* ((git-root-truename (file-truename git-root))
(current-file (buffer-file-name (current-buffer)))
(current-frame-dired-paths
(let ((paths '()))
(dolist (win (window-list nil 'no-minibuffer))
(with-current-buffer (window-buffer win)
(when (derived-mode-p 'dired-mode)
(let ((dir (if (fboundp 'dired-current-directory)
(dired-current-directory)
default-directory)))
(when (and dir
(file-directory-p dir)
(string-prefix-p git-root-truename
(file-truename dir))
(not (ai-code--git-ignored-repo-file-p
dir
git-root-truename)))
(push (ai-code--relative-filepath dir
git-root-truename)
paths))))))
(nreverse (delete-dups paths))))
(visible-files (ai-code--visible-window-files git-root-truename))
(skip-files (mapcar #'file-truename visible-files))
(ai-code--current-frame-dired-paths git-root-truename))
(visible-files (ai-code--visible-window-files))
(skip-files (mapcar #'ai-code--normalize-path visible-files))
Comment thread
tninja marked this conversation as resolved.
(buffer-files (ai-code--buffer-file-list git-root-truename skip-files))
(recent-files (ai-code--repo-recent-files git-root-truename))
(ignore-prefix (concat "@" ai-code-files-dir-name "/"))
(visible-paths (mapcar (lambda (file)
(ai-code--relative-filepath file git-root-truename))
(ai-code--candidate-path file git-root-truename))
visible-files))
(recent-buffer-paths
(ai-code--recent-buffer-paths git-root-truename))
(buffer-paths (mapcar (lambda (file)
(ai-code--relative-filepath file git-root-truename))
(ai-code--candidate-path file git-root-truename))
buffer-files))
(recent-paths (mapcar (lambda (file)
(ai-code--relative-filepath file git-root-truename))
(ai-code--candidate-path file git-root-truename))
recent-files))
(combined (append current-frame-dired-paths visible-paths buffer-paths recent-paths))
(combined (append current-frame-dired-paths
visible-paths
recent-buffer-paths
buffer-paths
recent-paths))
(deduped (ai-code--dedupe-preserve-order combined))
(filtered '()))
(dolist (item deduped)
Expand Down
8 changes: 5 additions & 3 deletions ai-code.el
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ Shows the current backend label to the right."
("x" "Explain code in scope" ai-code-explain)
("<SPC>" "Send command (C-u: context)" ai-code-send-command)
("@" "Add context (C-u: clear)" ai-code-context-action)
("K" "Create or open task file" ai-code-create-or-open-task-file)]
]

["AI Agile Development"
("r" "Refactor Code" ai-code-refactor-book-method)
Expand All @@ -238,7 +238,10 @@ Shows the current backend label to the right."
("!" "Run Current File or Command" ai-code-run-current-file-or-shell-cmd)
("b" "Build project" ai-code-build-project)
("p" "Open prompt history file" ai-code-open-prompt-file)
("I" "Insert function name at point" ai-code-insert-function-at-point)]
;; ("I" "Insert function name at point" ai-code-insert-function-at-point)
("K" "Create or open task file" ai-code-create-or-open-task-file)
("n" "Take notes from AI session region" ai-code-take-notes)
]

["Other Tools"
("." "Init projectile and gtags" ai-code-init-project)
Expand All @@ -249,7 +252,6 @@ Shows the current backend label to the right."
("o" "Open recent file (C-u: insert)" ai-code-git-repo-recent-modified-files)
;; ("o" "Open Clipboard file dir" ai-code-open-clipboard-file-path-as-dired)
("m" "Debug python MCP server" ai-code-debug-mcp)
("n" "Take notes from AI session region" ai-code-take-notes)
("N" "Toggle notifications" ai-code-notifications-toggle)]])


Expand Down
Loading