@@ -873,7 +873,7 @@ Returns a list of context plists found in the prompt field."
873873 (user-error (eca-error " This chat is closed" )))
874874 (let* ((prompt-start (eca-chat--prompt-field-start-point))
875875 (prompt-contexts (eca-chat--extract-contexts-from-prompt))
876- (refined-contexts (-map #'eca-chat--refine-context
876+ (refined-contexts (-map #'eca-chat--refine-context
877877 (append eca-chat--context prompt-contexts))))
878878 (when (seq-empty-p eca-chat--history) (eca-chat--clear))
879879 (add-to-list 'eca-chat--history prompt)
@@ -1681,6 +1681,56 @@ CHILD, NAME, DOCSTRING and BODY are passed down."
16811681 (declare (indent defun ))
16821682 `(define-derived-mode , child , eca-chat-parent-mode , name , docstring ,@body ))
16831683
1684+ (defconst eca-chat-media--mime-extension-map
1685+ '((" image/png" . " png" )
1686+ (" image/x-png" . " png" )
1687+ (" image/jpeg" . " jpg" )
1688+ (" image/jpg" . " jpg" )
1689+ (" image/gif" . " gif" )
1690+ (" image/webp" . " webp" )
1691+ (" image/heic" . " heic" )
1692+ (" image/heif" . " heif" )
1693+ (" image/svg+xml" . " svg" ))
1694+ " Mapping of mime types to screenshot file extensions." )
1695+
1696+ (defun eca-chat-media--extension-for-type (type )
1697+ " Return file extension (without dot) for mime TYPE.
1698+ TYPE can be a string or symbol."
1699+ (let* ((type-str (if (symbolp type) (symbol-name type) type))
1700+ (clean (and type-str (string-trim type-str))))
1701+ (or (cdr (assoc-string clean eca-chat-media--mime-extension-map t ))
1702+ (when clean
1703+ (let* ((parts (split-string clean " /" ))
1704+ (raw-subtype (cadr parts))
1705+ (subtype (car (split-string (or raw-subtype " " ) " \\ +" ))))
1706+ (unless (string-empty-p subtype)
1707+ subtype)))
1708+ " png" )))
1709+
1710+ (defun eca-chat-media--yank-image-handler (type data )
1711+ " Handler for `yank-media' to insert images from clipboard.
1712+ TYPE is the MIME type (e.g., image/png).
1713+ DATA is the binary image data as a string."
1714+ (when-let* ((session (eca-session))
1715+ (chat-buffer (eca-chat--get-last-buffer session))
1716+ (extension (eca-chat-media--extension-for-type type))
1717+ (output-path (make-temp-file " eca-screenshot-" nil (concat " ." extension))))
1718+ (condition-case err
1719+ (progn
1720+ (with-temp-file output-path
1721+ (set-buffer-multibyte nil )
1722+ (insert data))
1723+ (when (f-exists? output-path)
1724+ (eca-chat--with-current-buffer chat-buffer
1725+ (let ((context (list :type " file" :path output-path)))
1726+ (eca-chat--insert-prompt (concat (eca-chat--context->str context 'static ) " " ))
1727+ (eca-chat--select-window)
1728+ (goto-char (line-end-position )))
1729+ (eca-info " Image yanked and added to prompt: %s"
1730+ (file-size-human-readable (file-attribute-size (file-attributes output-path)))))))
1731+ (error
1732+ (eca-error " Failed to save yanked image: %s" (error-message-string err))))))
1733+
16841734; ; Public
16851735
16861736(eca-chat-define-derived-mode eca-chat-mode " eca-chat"
@@ -1692,7 +1742,7 @@ CHILD, NAME, DOCSTRING and BODY are passed down."
16921742 (setq-local eca-chat--history '())
16931743 (setq-local eca-chat--history-index -1 )
16941744
1695- ; ; Show diff blocks in markdown-mode with colors.
1745+ ; ; Show diff blocks in markdown-mode with colors.
16961746 (when (fboundp 'yank-media-handler )
16971747 (yank-media-handler " image/.*" #'eca-chat-media--yank-image-handler ))
16981748 (setq-local markdown-fontify-code-blocks-natively t )
@@ -2742,6 +2792,20 @@ Returns selected message plist or nil if no messages or cancelled."
27422792 (save-buffer ))
27432793 (eca-info (format " Saved chat to '%s ' " file)))))
27442794
2795+ ;;;### autoload
2796+ (defun eca-chat-media-yank-screenshot ()
2797+ " Yank image from clipboard and add to context.
2798+ Uses native `yank-media' . Requires Emacs 29+."
2799+ (interactive )
2800+ (unless (fboundp 'yank-media )
2801+ (user-error " Screenshot yanking requires Emacs 29+ with yank-media support" ))
2802+ (let* ((session (eca-session))
2803+ (chat-buffer (eca-chat--get-last-buffer session)))
2804+ (eca-assert-session-running session)
2805+ (unless chat-buffer
2806+ (user-error " Open an ECA chat buffer before yanking a screenshot" ))
2807+ (eca-chat--select-window)
2808+ (yank-media)))
2809+
27452810(provide 'eca-chat )
2746- (require 'eca-chat-media )
27472811; ;; eca-chat.el ends here
0 commit comments