I've written an elisp script to automate the process of taking screenshots. The script uses maim and imgur.sh. Not really important however. Here is the code:
;;; ../../.local/share/git/dotArch/.config/doom/userconfig/screenshot.el -*- lexical-binding: t; -*-
(defun db/screenshot ()
"Interactive menu for screenshots. Requires main, xsel, xclip and curl to be installed."
(interactive)
(let* ((actions '("Section" "Whole Screen"))
(targets '("Imgur" "Clipboard" "Locally"))
;; The default extension used for images.
(ext "png")
;; The default temporary directory used to store images.
(tmp-dir "/tmp/")
;; The default temporary name used for images.
(tmp-name "screenshot")
;; The full file path to a temporary image.
(tmp-file (concat tmp-dir tmp-name "." ext)))
(setq action (completing-read "Take screenshot of ..." actions )
target (completing-read "Save screenshot ..." targets ))
(setq result (db/screenshot-return-cmd action target tmp-file ext))
(call-process-shell-command (nth 1 result) nil nil nil)
(cond ((equal target "Locally")
(message (concat "Image will be saved to: " (nth 0 result))))
((equal target "Imgur")
(message "Image will be uploaded to Imgur. URL will be saved to the clipboard."))
((equal target "Clipboard")
(message "Image will be saved to the clipboard.")))))
(defun db/screenshot-return-cmd (source target tmp-file ext)
"Build the command to be executed for taking screenshots."
(let ((cmd ""))
(cond ((equal source "Section")
(cond ((equal target "Locally")
(print "section local")
(setq tmp-file (concat (read-directory-name "Select directory: " "~/") (read-string "File name (Without extension): ") "." ext))
(setq cmd (concat "maim -s " tmp-file)))
((equal target "Imgur")
(setq cmd (concat "maim -s " tmp-file "; imgur " tmp-file " | xclip -selection clipboard")))
((equal target "Clipboard")
(setq cmd (concat "maim -s | xclip -selection clipboard -t image/png")))))
((equal source "Whole Screen")
(cond ((equal target "Locally")
(setq tmp-file (concat (read-directory-name "Select directory: " "~/") (read-string "File name (Without extension): ") "." ext))
(setq cmd (concat "maim " tmp-file)))
((equal target "Imgur")
(setq cmd (concat "maim " tmp-file "; imgur " tmp-file " | xclip -selection clipboard")))
((equal target "Clipboard")
(setq cmd (concat "maim | xclip -selection clipboard -t image/png"))))))
(list tmp-file cmd)))
I'm still a noob with elisp, so any suggestions regarding my code are welcome.
I use completing-read
to ask the user what he wants to screenshot and where to save it (For example 1: Whole screen, 2: Upload to imgur):
;; ...
(setq action (completing-read "Take screenshot of ..." actions )
target (completing-read "Save screenshot ..." targets ))
;; ...
After that I execute the corresponding command using maim
. However the problem is that the second completing-read
-dialog, where the user selects the target is still visible when maim takes the screenshot, resulting in something like this:
I hope you get my problem. I want the completing-read
to close before I take the screenshot. Does anyone know how to achieve that?
sit-for
after you get the user's respond fromcompleting-read
but before you actually take the screenshot. – Dan Sep 08 '20 at 14:34