0

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:

Dialog still visible

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?

4
  • 1
    You could try using sit-for after you get the user's respond from completing-read but before you actually take the screenshot.
    – Dan
    Sep 8, 2020 at 14:34
  • @Dan It worked! Thanks. Unfortunately I think I can't upvote your comment (because I'm too new)? Sep 8, 2020 at 14:57
  • No problem. I added it as an answer post instead. Glad it worked!
    – Dan
    Sep 8, 2020 at 15:21
  • emacs.stackexchange.com/tags/elisp/info
    – Drew
    Sep 8, 2020 at 18:18

1 Answer 1

1

One option you have is to use the sit-for function after you get the user's response, but before you take the actual screenshot.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.