Screenshots into emacs org files in Windows
Related to my previous post, I needed to resolve the need to quickly take screenshots from Windows and put them in an org file in emacs. This proved a bit more difficult than I’d hoped; triggering a screenshot in Windows from emacs is non-obvious, and my attempts to use yank-media
suggested that screenshots didn’t end up on the clipboard in a way emacs could see them. Other options I could find in melpa knew how to screenshot from XWindows, but not Windows.
It turns out when you just use PrintScr
to snag a screenshot in Windows, the result ends up in the Pictures/Screenshots
directory. So instead of solving the screenshotting problem, I just solved the problem of copying the most recent screenshot file into an images/
directory next to the org file, then inserting a reference to the file at point.
I set this up using org-babel’s literate emacs initialization feature, so rather than break this down in the blog post, I’ll let the config file itself do the talking. You can save this file to win-screenshots.org
and then load it with (org-babel-load-file "win-screenshots.org")
.
To use the resulting tool:
- configure
win-screenshot-source-dir
with the full path to yourPictures/Screenshots
directory - take a screenshot
- in your org file,
M-x win-screenshot-here
to grab the most recently-taken screenshot, put it in theimages/
directory, and insert a link to it at the cursor.
* Variables
#+BEGIN_SRC emacs-lisp
(defvar win-screenshot-source-dir "C:/Users/mtomc/Pictures/Screenshots"
"Directory screenshots live in.")
#+END_SRC
* Helpers
** Get screenshot file
#+BEGIN_SRC emacs-lisp
(defun win-screenshot-most-recent-file ()
"Get full path of most recent file in win-screenshot-source-dir"
(caar (sort
(directory-files-and-attributes win-screenshot-source-dir t "\\(.*\\).png$" t)
:key #'file-attribute-modification-time
:lessp #'time-less-p
:reverse t)))
#+END_SRC
** Copy most recent screenshot file to CWD/images/<timestamp>.png and return relative path
#+BEGIN_SRC emacs-lisp
(defun win-screenshot-capture-file-as-screenshot (screenshot-file)
"Copy SCREENSHOT-FILE to <pwd>/images/<timestamp>.png and return relative path (images/<timestamp>.png)."
(let*
((relative-path (concat "images/" (string-replace ":" "-" (format-time-string "%Y-%m-%dT%T" (current-time))) ".png"))
(full-path (concat default-directory relative-path)))
(copy-file screenshot-file full-path nil t t t)
relative-path))
#+END_SRC
* Public interface
** Put screenshot in file at point
#+BEGIN_SRC emacs-lisp
(defun win-screenshot-here ()
"Copy most recent screenshot to images/ directory and insert org image embed at point."
(interactive)
(insert (concat
"[[./"
(win-screenshot-capture-file-as-screenshot (win-screenshot-most-recent-file))
"]]\n"))
;; need to do this to force the newly-added image to show up.
(org-redisplay-inline-images))
#+END_SRC
Comments