Skip to content

Commit 20a8d55

Browse files
committed
Check for images on clipboard
1 parent 917dc35 commit 20a8d55

File tree

2 files changed

+42
-27
lines changed

2 files changed

+42
-27
lines changed

eca-chat.el

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,12 @@ Must be a positive integer."
186186
:type 'integer
187187
:group 'eca)
188188

189+
(defcustom eca-chat-yank-image-context-location 'system
190+
"Where to paste images from clipboard."
191+
:type '(choice (const :tag "System context area" system)
192+
(const :tag "user context area" user))
193+
:group 'eca)
194+
189195
(defvar-local eca-chat--tool-call-prepare-counters (make-hash-table :test 'equal)
190196
"Hash table mapping toolCall ID to message count.")
191197

@@ -442,7 +448,6 @@ Must be a positive integer."
442448
(define-key map (kbd "C-c <up>") #'eca-chat-go-to-prev-expandable-block)
443449
(define-key map (kbd "C-c <down>") #'eca-chat-go-to-next-expandable-block)
444450
(define-key map (kbd "C-c <tab>") #'eca-chat-toggle-expandable-block)
445-
(define-key map (kbd "C-c C-y") #'eca-chat-media-yank-screenshot)
446451
map)
447452
"Keymap used by `eca-chat-mode'.")
448453

@@ -1707,7 +1712,7 @@ TYPE can be a string or symbol."
17071712
subtype)))
17081713
"png")))
17091714

1710-
(defun eca-chat-media--yank-image-handler (type data)
1715+
(defun eca-chat--yank-image-handler (type data)
17111716
"Handler for `yank-media' to insert images from clipboard.
17121717
TYPE is the MIME type (e.g., image/png).
17131718
DATA is the binary image data as a string."
@@ -1722,15 +1727,31 @@ DATA is the binary image data as a string."
17221727
(insert data))
17231728
(when (f-exists? output-path)
17241729
(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) " "))
1730+
(let ((context (list :type "file" :path output-path))
1731+
(file-size (file-size-human-readable (file-attribute-size (file-attributes output-path)))))
17271732
(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)))))))
1733+
(if (eq 'system eca-chat-yank-image-context-location)
1734+
(eca-chat--add-context context)
1735+
(eca-chat--insert-prompt (concat (eca-chat--context->str context 'static) " ")))
1736+
(eca-info "Image added, size: %s" file-size)))))
17311737
(error
17321738
(eca-error "Failed to save yanked image: %s" (error-message-string err))))))
17331739

1740+
(defun eca-chat--yank-considering-image (orig-fun &rest args)
1741+
"Around advice for paste commands to use `yank-media' for images.
1742+
Call ORIG-FUN with ARGS if not media."
1743+
(if (and (derived-mode-p 'eca-chat-mode)
1744+
(fboundp 'yank-media)
1745+
(boundp 'yank-media--registered-handlers)
1746+
yank-media--registered-handlers
1747+
(when-let* ((targets (gui-get-selection 'CLIPBOARD 'TARGETS)))
1748+
(seq-some (lambda (type)
1749+
(and (symbolp type)
1750+
(string-match-p "^image/" (symbol-name type))))
1751+
(if (vectorp targets) (append targets nil) targets))))
1752+
(call-interactively #'yank-media)
1753+
(apply orig-fun args)))
1754+
17341755
;; Public
17351756

17361757
(eca-chat-define-derived-mode eca-chat-mode "eca-chat"
@@ -1740,11 +1761,9 @@ DATA is the binary image data as a string."
17401761
(visual-line-mode)
17411762
(hl-line-mode -1)
17421763
(setq-local eca-chat--history '())
1743-
(setq-local eca-chat--history-index -1)
1764+
(setq-local eca-chat--history-index -1)
17441765

17451766
;; Show diff blocks in markdown-mode with colors.
1746-
(when (fboundp 'yank-media-handler)
1747-
(yank-media-handler "image/.*" #'eca-chat-media--yank-image-handler))
17481767
(setq-local markdown-fontify-code-blocks-natively t)
17491768
;; Enable gfm-view-mode-like rendering without read-only
17501769
(setq-local markdown-hide-markup t)
@@ -1786,6 +1805,18 @@ DATA is the binary image data as a string."
17861805

17871806
(add-hook 'kill-buffer-hook #'eca-chat--delete-chat nil t)
17881807

1808+
;; Paste image from clipboard support
1809+
(when (fboundp 'yank-media-handler)
1810+
(yank-media-handler "image/png" #'eca-chat--yank-image-handler)
1811+
(yank-media-handler "image/jpeg" #'eca-chat--yank-image-handler)
1812+
(yank-media-handler "image/jpg" #'eca-chat--yank-image-handler)
1813+
(yank-media-handler "image/gif" #'eca-chat--yank-image-handler)
1814+
(yank-media-handler "image/webp" #'eca-chat--yank-image-handler)
1815+
(advice-add 'yank :around #'eca-chat--yank-considering-image)
1816+
(when (featurep 'evil)
1817+
(advice-add 'evil-paste-after :around #'eca-chat--yank-considering-image)
1818+
(advice-add 'evil-paste-before :around #'eca-chat--yank-considering-image)))
1819+
17891820
(let ((chat-buffer (current-buffer)))
17901821
(run-with-timer
17911822
0.05
@@ -2792,20 +2823,5 @@ Returns selected message plist or nil if no messages or cancelled."
27922823
(save-buffer))
27932824
(eca-info (format "Saved chat to '%s'" file)))))
27942825

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-
28102826
(provide 'eca-chat)
28112827
;;; eca-chat.el ends here

eca-util.el

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,7 @@ Inheirits BASE-MAP."
223223
("s" "Add to system prompt" eca-chat-add-context-to-system-prompt)
224224
("u" "Add to user prompt" eca-chat-add-context-to-user-prompt)
225225
("d" "Drop from system prompt" eca-chat-drop-context-from-system-prompt)
226-
("A" "Accept next pending tool call" eca-chat-tool-call-accept-next)
227-
("y" "Yank screenshot" eca-chat-media-yank-screenshot)]
226+
("A" "Accept next pending tool call" eca-chat-tool-call-accept-next)]
228227

229228
["Navigation"
230229
("N h" "Message history" eca-chat-timeline)

0 commit comments

Comments
 (0)