macos: clipboard image paste via cmd+v (pngpaste)
my/smart-paste bound to s-v (cmd+v) in org-mode and markdown-mode: - clipboard has image → my/paste-image-from-clipboard - clipboard has text → normal yank my/paste-image-from-clipboard: - saves to attachments/ relative to current file - filename: image-YYYYMMDD-HHMMSS.png - org-mode: [[./attachments/image-....png]] - markdown-mode:  - creates attachments/ dir if missing Requires: brew install pngpaste
This commit is contained in:
58
config.el
58
config.el
@@ -84,6 +84,64 @@
|
|||||||
(after! evil
|
(after! evil
|
||||||
(setq evil-want-clipboard t))
|
(setq evil-want-clipboard t))
|
||||||
|
|
||||||
|
;;; ============================================================
|
||||||
|
;;; CLIPBOARD IMAGE PASTE (macOS — cmd+v)
|
||||||
|
;;; ============================================================
|
||||||
|
;; Requires: brew install pngpaste
|
||||||
|
;;
|
||||||
|
;; cmd+v behaviour:
|
||||||
|
;; clipboard has image → saves to attachments/ → inserts link
|
||||||
|
;; clipboard has text → normal paste (yank)
|
||||||
|
;;
|
||||||
|
;; Org: [[./attachments/image-TIMESTAMP.png]]
|
||||||
|
;; Markdown: 
|
||||||
|
;;
|
||||||
|
;; attachments/ is always relative to the current file's directory.
|
||||||
|
|
||||||
|
(defun my/clipboard-has-image-p ()
|
||||||
|
"Return non-nil if macOS clipboard contains an image (requires pngpaste)."
|
||||||
|
(and (executable-find "pngpaste")
|
||||||
|
(let ((tmp (make-temp-file "emacs-imgcheck" nil ".png")))
|
||||||
|
(prog1 (= 0 (call-process "pngpaste" nil nil nil tmp))
|
||||||
|
(ignore-errors (delete-file tmp))))))
|
||||||
|
|
||||||
|
(defun my/paste-image-from-clipboard ()
|
||||||
|
"Save clipboard image to attachments/ subdir and insert link at point.
|
||||||
|
File: image-YYYYMMDD-HHMMSS.png. Supports org-mode and markdown-mode."
|
||||||
|
(interactive)
|
||||||
|
(let* ((base-dir (if buffer-file-name
|
||||||
|
(file-name-directory (buffer-file-name))
|
||||||
|
default-directory))
|
||||||
|
(attach-dir (expand-file-name "attachments" base-dir))
|
||||||
|
(filename (format-time-string "image-%Y%m%d-%H%M%S.png"))
|
||||||
|
(filepath (expand-file-name filename attach-dir))
|
||||||
|
(relpath (concat "attachments/" filename)))
|
||||||
|
(make-directory attach-dir t)
|
||||||
|
(if (= 0 (call-process "pngpaste" nil nil nil filepath))
|
||||||
|
(progn
|
||||||
|
(insert (pcase major-mode
|
||||||
|
('org-mode (format "[[./%s]]" relpath))
|
||||||
|
('markdown-mode (format "" filename relpath))
|
||||||
|
(_ relpath)))
|
||||||
|
(message "✓ Image saved: %s" relpath))
|
||||||
|
(error "pngpaste failed — no image in clipboard?"))))
|
||||||
|
|
||||||
|
(defun my/smart-paste ()
|
||||||
|
"Paste image if clipboard has one, else normal yank (text paste).
|
||||||
|
Bound to cmd+v in org-mode and markdown-mode."
|
||||||
|
(interactive)
|
||||||
|
(if (my/clipboard-has-image-p)
|
||||||
|
(my/paste-image-from-clipboard)
|
||||||
|
(yank)))
|
||||||
|
|
||||||
|
;; Bind cmd+v to smart paste in org and markdown
|
||||||
|
(map! :after org
|
||||||
|
:map org-mode-map
|
||||||
|
"s-v" #'my/smart-paste)
|
||||||
|
(map! :after markdown-mode
|
||||||
|
:map markdown-mode-map
|
||||||
|
"s-v" #'my/smart-paste)
|
||||||
|
|
||||||
;; macOS Zoom accessibility — cancel persp-mode's 2.5s cache timer after startup
|
;; macOS Zoom accessibility — cancel persp-mode's 2.5s cache timer after startup
|
||||||
;; (reduces unnecessary redraws that cause Zoom to jump)
|
;; (reduces unnecessary redraws that cause Zoom to jump)
|
||||||
(run-with-timer 3 nil
|
(run-with-timer 3 nil
|
||||||
|
|||||||
Reference in New Issue
Block a user