Skip to content

Commit 8dd47f8

Browse files
committed
Improve prompt support for contexts
1 parent 31c1fc7 commit 8dd47f8

File tree

1 file changed

+91
-51
lines changed

1 file changed

+91
-51
lines changed

eca-chat.el

Lines changed: 91 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -675,13 +675,22 @@ the prompt/context line."
675675
(let* ((cur-ov (car (overlays-in (line-beginning-position) (line-end-position))))
676676
(text (thing-at-point 'symbol))
677677
(context-item (-some->> text
678-
(get-text-property 0 'eca-chat-context-item))))
678+
(get-text-property 0 'eca-chat-context-item)))
679+
(context-str-length (-some->> text
680+
(get-text-property 0 'eca-chat-context-item-str-length))))
679681
(cond
680682
((and cur-ov
681683
context-item)
682684
(setq-local eca-chat--context (delete context-item eca-chat--context))
683-
(eca-chat--refresh-context)
684-
(end-of-line))
685+
(if (eca-chat--point-at-prompt-field-p)
686+
(progn
687+
;; go to next char with no property eca-chat-context-item
688+
(while (and (not (eolp))
689+
(get-text-property (point) 'eca-chat-context-item))
690+
(forward-char 1))
691+
(delete-region (- (point) context-str-length) (point)))
692+
(end-of-line))
693+
(eca-chat--refresh-context))
685694

686695
((and cur-ov
687696
(<= (point) (overlay-start cur-ov)))
@@ -712,6 +721,30 @@ the prompt/context line."
712721
(plist-put :position (plist-get eca-chat--cursor-context :position))))
713722
(_ context)))
714723

724+
(defun eca-chat--expand-contexts-in-prompt (prompt)
725+
"If PROMPT contain any @context in text, expand for more details.
726+
Checks for text property `eca-chat-context-item' to identify context mentions
727+
and replaces them with their full path representation."
728+
(let ((result "")
729+
(pos 0))
730+
(while (< pos (length prompt))
731+
(let* ((next-change (next-single-property-change pos 'eca-chat-context-item prompt (length prompt)))
732+
(context (get-text-property pos 'eca-chat-context-item prompt)))
733+
(if context
734+
;; Found a context mention - expand it
735+
(let ((expanded (pcase (plist-get context :type)
736+
("file" (concat "@" (plist-get context :path)))
737+
("directory" (concat "@" (plist-get context :path)))
738+
("repoMap" "@repoMap")
739+
("cursor" "@cursor")
740+
("mcpResource" (concat "@" (plist-get context :server) ":" (plist-get context :name)))
741+
(_ (substring prompt pos next-change)))))
742+
(setq result (concat result expanded)))
743+
;; No context property - copy the text as-is
744+
(setq result (concat result (substring prompt pos next-change))))
745+
(setq pos next-change)))
746+
result))
747+
715748
(defun eca-chat--send-prompt (session prompt)
716749
"Send PROMPT to server for SESSION."
717750
(let* ((prompt-start (eca-chat--prompt-field-start-point))
@@ -725,7 +758,7 @@ the prompt/context line."
725758
(eca-api-request-async
726759
session
727760
:method "chat/prompt"
728-
:params (list :message prompt
761+
:params (list :message (eca-chat--expand-contexts-in-prompt prompt)
729762
:request-id (cl-incf eca-chat--last-request-id)
730763
:chatId eca-chat--id
731764
:model (eca-chat--model session)
@@ -742,7 +775,7 @@ the prompt/context line."
742775
(session (eca-session))
743776
(prompt (save-excursion
744777
(goto-char prompt-start)
745-
(string-trim (buffer-substring-no-properties (point) (point-max))))))
778+
(string-trim (buffer-substring (point) (point-max))))))
746779
(cond
747780
;; check prompt
748781
((and (not (string-empty-p prompt))
@@ -1124,6 +1157,50 @@ If FORCE? decide to CLOSE? or not."
11241157
'font-lock-face 'eca-chat-system-messages-face)
11251158
eca-chat--spinner-string)))))
11261159

1160+
(defun eca-chat--context->str (context &optional static?)
1161+
"Convert CONTEXT to a presentable str in buffer.
1162+
If STATIC? return strs with no dynamic values."
1163+
(-let* (((&plist :type type) context)
1164+
(context-str
1165+
(pcase type
1166+
("file" (propertize (concat eca-chat-context-prefix
1167+
(eca-chat--context-presentable-path (plist-get context :path))
1168+
(-when-let ((&plist :start start :end end) (plist-get context :linesRange))
1169+
(format " (%d-%d)" start end)))
1170+
'font-lock-face 'eca-chat-context-file-face))
1171+
("directory" (propertize (concat eca-chat-context-prefix (eca-chat--context-presentable-path (plist-get context :path)))
1172+
'font-lock-face 'eca-chat-context-file-face))
1173+
("repoMap" (propertize (concat eca-chat-context-prefix "repoMap")
1174+
'font-lock-face 'eca-chat-context-repo-map-face))
1175+
("mcpResource" (propertize (concat eca-chat-context-prefix (plist-get context :server) ":" (plist-get context :name))
1176+
'font-lock-face 'eca-chat-context-mcp-resource-face))
1177+
("cursor" (propertize (if static?
1178+
(concat eca-chat-context-prefix "cursor")
1179+
(concat eca-chat-context-prefix "cursor"
1180+
"("
1181+
(-some-> (plist-get eca-chat--cursor-context :path)
1182+
(f-filename))
1183+
":"
1184+
(-some->>
1185+
(-> eca-chat--cursor-context
1186+
(plist-get :position)
1187+
(plist-get :start)
1188+
(plist-get :line))
1189+
(funcall #'number-to-string))
1190+
":"
1191+
(-some->>
1192+
(-> eca-chat--cursor-context
1193+
(plist-get :position)
1194+
(plist-get :start)
1195+
(plist-get :character))
1196+
(funcall #'number-to-string))
1197+
")"))
1198+
'font-lock-face 'eca-chat-context-cursor-face))
1199+
(_ (concat eca-chat-context-prefix "unkown:" type)))))
1200+
(propertize context-str
1201+
'eca-chat-context-item-str-length (length context-str)
1202+
'eca-chat-context-item context)))
1203+
11271204
(defun eca-chat--refresh-context ()
11281205
"Refresh chat context."
11291206
(save-excursion
@@ -1132,48 +1209,8 @@ If FORCE? decide to CLOSE? or not."
11321209
(goto-char))
11331210
(delete-region (point) (line-end-position))
11341211
(seq-doseq (context eca-chat--context)
1135-
(-let (((&plist :type type) context))
1136-
(insert
1137-
(pcase type
1138-
("file" (propertize (concat eca-chat-context-prefix
1139-
(eca-chat--context-presentable-path (plist-get context :path))
1140-
(-when-let ((&plist :start start :end end) (plist-get context :linesRange))
1141-
(format " (%d-%d)" start end)))
1142-
'eca-chat-context-item context
1143-
'font-lock-face 'eca-chat-context-file-face))
1144-
("directory" (propertize (concat eca-chat-context-prefix (eca-chat--context-presentable-path (plist-get context :path)))
1145-
'eca-chat-context-item context
1146-
'font-lock-face 'eca-chat-context-file-face))
1147-
("repoMap" (propertize (concat eca-chat-context-prefix "repoMap")
1148-
'eca-chat-context-item context
1149-
'font-lock-face 'eca-chat-context-repo-map-face))
1150-
("mcpResource" (propertize (concat eca-chat-context-prefix (plist-get context :server) ":" (plist-get context :name))
1151-
'eca-chat-context-item context
1152-
'font-lock-face 'eca-chat-context-mcp-resource-face))
1153-
("cursor" (propertize (concat eca-chat-context-prefix "cursor"
1154-
"("
1155-
(-some-> (plist-get eca-chat--cursor-context :path)
1156-
(f-filename))
1157-
":"
1158-
(-some->>
1159-
(-> eca-chat--cursor-context
1160-
(plist-get :position)
1161-
(plist-get :start)
1162-
(plist-get :line))
1163-
(funcall #'number-to-string))
1164-
":"
1165-
(-some->>
1166-
(-> eca-chat--cursor-context
1167-
(plist-get :position)
1168-
(plist-get :start)
1169-
(plist-get :character))
1170-
(funcall #'number-to-string))
1171-
")")
1172-
'eca-chat-context-item context
1173-
'font-lock-face 'eca-chat-context-cursor-face))
1174-
(_ (propertize (concat eca-chat-context-prefix "unkown:" type)
1175-
'eca-chat-context-item context))))
1176-
(insert " ")))
1212+
(insert (eca-chat--context->str context))
1213+
(insert " "))
11771214
(insert (propertize eca-chat-context-prefix 'font-lock-face 'eca-chat-context-unlinked-face))))
11781215

11791216
(defconst eca-chat--kind->symbol
@@ -1238,9 +1275,12 @@ If FORCE? decide to CLOSE? or not."
12381275
(defun eca-chat--completion-context-from-prompt-exit-function (item _status)
12391276
"Add to context the selected ITEM.
12401277
Add text property to prompt text to match context."
1241-
(eca-chat--add-context (get-text-property 0 'eca-chat-completion-item item))
1242-
(put-text-property (1- (- (point) (length item))) (point) 'font-lock-face (get-text-property 0 'face item))
1243-
(end-of-line)
1278+
(let ((context (get-text-property 0 'eca-chat-completion-item item)))
1279+
(eca-chat--add-context context)
1280+
(let ((start-pos (1- (- (point) (length item))))
1281+
(end-pos (point)))
1282+
(delete-region start-pos end-pos)
1283+
(insert (eca-chat--context->str context 'static))))
12441284
(insert " "))
12451285

12461286
(defun eca-chat--completion-prompt-exit-function (item _status)
@@ -2120,7 +2160,7 @@ if ARG is current prefix, ask for file, otherwise add current file."
21202160
(session (eca-session))
21212161
(prompt (save-excursion
21222162
(goto-char prompt-start)
2123-
(string-trim (buffer-substring-no-properties (point) (point-max))))))
2163+
(string-trim (buffer-substring (point) (point-max))))))
21242164
(when (and (not (string-empty-p prompt))
21252165
(not eca-chat--chat-loading))
21262166
(eca-chat--send-prompt session prompt)))))

0 commit comments

Comments
 (0)