Skip to content

Commit 12ac344

Browse files
committed
feat(context): display full file paths instead of filenames only
Show complete file paths when adding files to context instead of just the basename. This enables LLMs to: - Use file paths correctly when calling tools/functions - Understand semantic meaning from directory structure - Distinguish between files with identical names in different locations
1 parent 6abda6f commit 12ac344

File tree

1 file changed

+50
-34
lines changed

1 file changed

+50
-34
lines changed

gptel-context.el

Lines changed: 50 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,9 @@ Asynchronous: A callback to call with the result, and the context alist.
7777
The context alist is structured as follows:
7878
7979
((buffer1 . (overlay1 overlay2)
80-
(\"path/to/file\")
80+
("path/to/file")
8181
(buffer2 . (overlay3 overlay4 overlay5))
82-
(\"path/to/image/file\" :mime \"image/jpeg\")))
82+
("path/to/image/file" :mime "image/jpeg")))
8383
8484
Each gptel \"context\" is either a file path or an overlay in a
8585
buffer. Each overlay covers a buffer region containing the
@@ -100,11 +100,11 @@ context chunk. This is accessible as, for example:
100100
(kill-region (point-min) (point-max))
101101
(goto-char (point-max))
102102
(unless (bobp)
103-
(insert "\n----\n")))
103+
(insert "\n----\n"))))))
104104
(insert kill)
105105
(gptel-context--add-region (current-buffer)
106106
(point-min) (point-max))
107-
(message "*current-kill* has been added as context."))))
107+
(message "*current-kill* has been added as context.")))))
108108

109109
(defun gptel-context-add (&optional arg confirm)
110110
"Add context to gptel in a DWIM fashion.
@@ -221,7 +221,7 @@ ACTION should be either `add' or `remove'."
221221
(gptel-context--add-binary-file file)
222222
(gptel-context--add-text-file file)))
223223
('remove
224-
(setf (alist-get file gptel-context--alist nil 'remove #'equal) nil)))))
224+
(setf (alist-get file gptel-context--alist nil 'remove #'equal) nil))))))
225225
files)
226226
(when (eq action 'remove)
227227
(message "Directory \"%s\" removed from context." path))))
@@ -260,12 +260,12 @@ If CONTEXT is a directory, recursively removes all files in it."
260260
(if (file-directory-p context)
261261
(gptel-context--add-directory context 'remove)
262262
(setf (alist-get context gptel-context--alist nil 'remove #'equal) nil)
263-
(message "File \"%s\" removed from context." context)))
263+
(message "File \"%s\" removed from context." context))))
264264
((region-active-p)
265265
(when-let* ((contexts (gptel-context--in-region (current-buffer)
266266
(region-beginning)
267267
(region-end))))
268-
(cl-loop for ctx in contexts do (delete-overlay ctx))))
268+
(cl-loop for ctx in contexts do (delete-overlay ctx)))))
269269
(t
270270
(when-let* ((ctx (gptel-context--at-point)))
271271
(delete-overlay ctx)))))
@@ -284,7 +284,7 @@ afterwards."
284284
if (bufferp source) do ;Buffers and buffer regions
285285
(mapc #'gptel-context-remove ovs)
286286
else do (gptel-context-remove source) ;files or other types
287-
finally do (setq gptel-context--alist nil)))
287+
finally do (setq gptel-context--alist nil))))
288288
(when verbose (message "Removed all gptel context sources."))))
289289

290290
(defun gptel-context--make-overlay (start end &optional advance)
@@ -348,9 +348,9 @@ This modifies the buffer."
348348
(concat "[\n[:blank:]]*"
349349
(and-let* ((prefix (gptel-prompt-prefix-string))
350350
((not (string-empty-p prefix))))
351-
(concat "\\(?:" (regexp-quote prefix) "\\)?"))))
351+
(concat "\(?:" (regexp-quote prefix) "\)?"))))
352352
(delete-region (match-beginning 0) (match-end 0)))
353-
(insert "\n" context-string "\n\n")))))
353+
(insert "\n" context-string "\n\n"))))))
354354

355355
(defun gptel-context--collect-media (&optional contexts)
356356
"Collect media CONTEXTS.
@@ -402,11 +402,19 @@ START and END signify the region delimiters."
402402
else collect (list buf) into elements
403403
finally return elements)))
404404

405+
(defun gptel-context--format-buffer-name (buffer)
406+
"Format buffer name with file path if applicable."
407+
(let ((buffer-name (buffer-name buffer))
408+
(file-name (buffer-file-name buffer)))
409+
(if file-name
410+
(format "%s (%s)" buffer-name (abbreviate-file-name file-name))
411+
buffer-name)))
412+
405413
(defun gptel-context--insert-buffer-string (buffer contexts)
406414
"Insert at point a context string from all CONTEXTS in BUFFER."
407415
(let ((is-top-snippet t)
408416
(previous-line 1))
409-
(insert (format "In buffer `%s`:" (buffer-name buffer))
417+
(insert (format "In buffer `%s`:" (gptel-context--format-buffer-name buffer))
410418
"\n\n```" (gptel--strip-mode-suffix (buffer-local-value
411419
'major-mode buffer))
412420
"\n")
@@ -433,11 +441,19 @@ START and END signify the region delimiters."
433441
(unless (zerop column) (insert " ..."))
434442
(if is-top-snippet
435443
(setq is-top-snippet nil)
436-
(unless (= previous-line lineno) (insert "\n"))))
444+
(unless (= previous-line lineno) (insert "\n")))))
437445
(insert content)))
438446
(unless (>= (overlay-end (car (last contexts))) (point-max))
439447
(insert "\n..."))
440-
(insert "\n```")))
448+
(insert "\n```"))))
449+
450+
(defun gptel-context--insert-file-string (path)
451+
"Insert at point the contents of the file at PATH as context."
452+
(insert (format "In file `%s`:" (abbreviate-file-name path))
453+
"\n\n```\n")
454+
(insert-file-contents path)
455+
(goto-char (point-max))
456+
(insert "\n```\n"))
441457

442458
(defun gptel-context--string (context-alist)
443459
"Format the aggregated gptel context as annotated markdown fragments.
@@ -449,14 +465,14 @@ context overlays, see `gptel-context--alist'."
449465
if (bufferp buf)
450466
do (gptel-context--insert-buffer-string buf ovs)
451467
else if (not (plist-get ovs :mime))
452-
do (gptel--insert-file-string buf) end
468+
do (gptel-context--insert-file-string buf) end
453469
do (insert "\n\n")
454470
finally do
455471
(skip-chars-backward "\n\t\r ")
456472
(delete-region (point) (point-max))
457473
(unless (bobp)
458474
(goto-char (point-min))
459-
(insert "Request context:\n\n"))
475+
(insert "Request context:\n\n")))
460476
finally return
461477
(and (> (buffer-size) 0)
462478
(buffer-string)))))
@@ -486,12 +502,12 @@ context overlays, see `gptel-context--alist'."
486502
(setq header-line-format
487503
(substitute-command-keys
488504
(concat
489-
"\\[gptel-context-flag-deletion]: Mark/unmark deletion, "
490-
"\\[gptel-context-next]/\\[gptel-context-previous]: next/previous, "
491-
"\\[gptel-context-visit]: visit, "
492-
"\\[gptel-context-confirm]: apply, "
493-
"\\[gptel-context-quit]: cancel, "
494-
"\\[quit-window]: quit")))
505+
"\[gptel-context-flag-deletion]: Mark/unmark deletion, "
506+
"\[gptel-context-next]/\[gptel-context-previous]: next/previous, "
507+
"\[gptel-context-visit]: visit, "
508+
"\[gptel-context-confirm]: apply, "
509+
"\[gptel-context-quit]: cancel, "
510+
"\[quit-window]: quit"))))
495511
(save-excursion
496512
(let ((contexts gptel-context--alist))
497513
(if (length> contexts 0)
@@ -504,7 +520,7 @@ context overlays, see `gptel-context--alist'."
504520
(setq l1 (line-number-at-pos (overlay-start source-ov))
505521
l2 (line-number-at-pos (overlay-end source-ov))))
506522
(insert (propertize (format "In buffer %s (lines %d-%d):\n\n"
507-
(buffer-name buf) l1 l2)
523+
(gptel-context--format-buffer-name buf) l1 l2)
508524
'face 'bold))
509525
(setq beg (point))
510526
(insert-buffer-substring
@@ -516,7 +532,7 @@ context overlays, see `gptel-context--alist'."
516532
(overlay-put ov 'evaporate t)
517533
(insert "\n" (make-separator-line) "\n"))
518534
;; BUF is a file path, not a buffer
519-
(insert (propertize (format "In file %s:\n\n" (file-name-nondirectory buf))
535+
(insert (propertize (format "In file %s:\n\n" (abbreviate-file-name buf))
520536
'face 'bold))
521537
(setq beg (point))
522538
(if-let* ((mime (plist-get ovs :mime)))
@@ -527,16 +543,16 @@ context overlays, see `gptel-context--alist'."
527543
(insert
528544
buf " " (propertize "(No preview for binary file)"
529545
'face '(:inherit shadow :slant italic))))
530-
(insert-file-contents buf))
546+
(insert-file-contents buf)))
531547
(goto-char (point-max))
532548
(insert "\n")
533549
(setq ov (make-overlay beg (point)))
534550
(overlay-put ov 'gptel-context buf)
535551
(overlay-put ov 'gptel-overlay t)
536552
(overlay-put ov 'evaporate t)
537-
(insert "\n" (make-separator-line) "\n")))
538-
(goto-char (point-min)))
539-
(insert "There are no active gptel contexts.")))))
553+
(insert "\n" (make-separator-line) "\n"))))
554+
(goto-char (point-min))))
555+
(insert "There are no active gptel contexts."))))
540556
(display-buffer (current-buffer)
541557
`((display-buffer-reuse-window
542558
display-buffer-reuse-mode-window
@@ -561,7 +577,7 @@ If non-nil, indicates backward movement.")
561577
(overlay-put highlight-overlay 'face nil))
562578
(when context-overlay
563579
(overlay-put context-overlay 'face 'highlight))
564-
(setq highlight-overlay context-overlay))))))
580+
(setq highlight-overlay context-overlay)))))))
565581

566582
(defun gptel-context-visit ()
567583
"Display the location of this gptel context chunk in its original buffer."
@@ -588,7 +604,7 @@ If non-nil, indicates backward movement.")
588604
(when (and (/= (point-max) next-start) ov-here)
589605
;; We were inside the overlay, so we want the next overlay change, which
590606
;; would be the start of the next overlay.
591-
(setq next-start (next-overlay-change next-start)))
607+
(setq next-start (next-overlay-change next-start))))
592608
(when (/= next-start (point-max))
593609
(setq gptel-context--buffer-reverse nil)
594610
(goto-char next-start)
@@ -598,9 +614,9 @@ If non-nil, indicates backward movement.")
598614
"Move to previous gptel context chunk."
599615
(interactive)
600616
(let ((ov-here (car (overlays-at (point)))))
601-
(when ov-here (goto-char (overlay-start ov-here)))
617+
(when ov-here (goto-char (overlay-start ov-here))))
602618
(let ((previous-context-pos (previous-overlay-change
603-
(previous-overlay-change (point)))))
619+
(previous-overlay-change (point))))))
604620
;; Prevent point from jumping to the start of the buffer.
605621
(unless (= previous-context-pos (point-min))
606622
(goto-char previous-context-pos)
@@ -626,7 +642,7 @@ If non-nil, indicates backward movement.")
626642
(overlay-put deletion-ov 'gptel-context (overlay-get ov 'gptel-context))
627643
(overlay-put deletion-ov 'priority -80)
628644
(overlay-put deletion-ov 'face 'gptel-context-deletion-face)
629-
(overlay-put deletion-ov 'gptel-context-deletion-mark t)))))
645+
(overlay-put deletion-ov 'gptel-context-deletion-mark t))))))
630646
(if (use-region-p)
631647
(deactivate-mark)
632648
(if gptel-context--buffer-reverse
@@ -652,8 +668,8 @@ If non-nil, indicates backward movement.")
652668
(overlays-in (point-min) (point-max))))))
653669
(mapc #'gptel-context-remove deletion-marks)
654670
(gptel-context--collect) ;Update contexts and revert buffer (#482)
655-
(revert-buffer))
671+
(revert-buffer)))
656672
(gptel-context-quit))
657673

658674
(provide 'gptel-context)
659-
;;; gptel-context.el ends here.
675+
;;; gptel-context.el ends here.

0 commit comments

Comments
 (0)