Skip to content

Commit 917dc35

Browse files
committed
Improvements to eca-chat yank screenshot
1 parent a4ffd31 commit 917dc35

File tree

2 files changed

+67
-97
lines changed

2 files changed

+67
-97
lines changed

eca-chat-media.el

Lines changed: 0 additions & 94 deletions
This file was deleted.

eca-chat.el

Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)