How I Automated My Dotfiles Screenshots
How I automated taking screenshots of my terminal environment
Albin Groen
Posted 2021-06-16
Recently I've been working a lot on my terminal environment and dotfiles structure. My strategy has been to keep everything on GitHub so I can just pull it down when I want to start working on a new machine. While doing this, I also wanted to show what everything looks like in the README file, so I created a little automation that opens a new Tmux session, splits into a couple of sections, opens a few applications, and then take a screenshot that gets uploaded to Cloudinary and then copied to my clipboard.
Now, to do this I started by creating a new Application in the Automator app for Mac. I started by dragging in an Applescript block. In this script, I start with opening Kitty (my terminal emulator of choice), and then open everything, before I take a screenshot using Cleanshot. After I'm done with this, I run a sub-application that basically just runs a Node.js script that uploads the newly taken screenshot to Cloudinary and then copies it to the system clipboard.
Take screenshot
This script is a little bit finicky since what it mostly relies on is the use of manually executing keystrokes and key codes, and adding a couple of delay statements in between time-intensive tasks. This can unfortunately sometimes result in a Tmux split missing, or the screenshot turning out to be taken on a browser or finder window, instead of the actual Terminal. In most cases though, the script works, and then it's really nice to use.
on run {input, parameters}
tell application "kitty"
-- Open Kitty terminal emulator
activate
tell application "System Events"
tell process "kitty"
delay 2
keystroke "a" using control down
keystroke ":new"
key code 36
keystroke "cd && vim tracing.ts"
key code 36
keystroke "a" using control down
keystroke "v"
keystroke "clear && neofetch"
key code 36
keystroke "a" using control down
keystroke "-"
keystroke "htop"
key code 36
delay 4
key code 26 using {shift down, command down}
delay 1
key code 36
delay 2
keystroke "a" using control down
keystroke "x"
keystroke "y"
keystroke "a" using control down
keystroke "x"
keystroke "y"
keystroke "a" using control down
keystroke "x"
keystroke "y"
keystroke "w" using command down
end tell
end tell
end tell
return input
end run
Upload screenshot
What this script does is that it looks inside of the screenshot folder for the latest screenshot, and then uploads it to Cloudinary using its Node.js SDK. After it's been successfully uploaded and sent back in the callback, we take the secure URL of the image and copies it to the system clipboard.
import { v2 as cloudinary } from "cloudinary";
import clipboardy from "clipboardy";
import dotenv from "dotenv";
import fs from "fs";
dotenv.config();
cloudinary.config({
cloud_name: process.env.CLOUDINARY_CLOUD_NAME,
api_secret: process.env.CLOUDINARY_API_SECRET,
api_key: process.env.CLOUDINARY_API_KEY,
});
function main() {
console.log("Uploading image...");
const dirPath = "/Users/albin/Screenshots";
const files = fs
.readdirSync(dirPath, "utf8")
.filter((file) => !file.startsWith("."));
const imagePath = [dirPath, files[files.length - 1]].join("/");
cloudinary.uploader.upload(imagePath, (err, res) => {
if (err) {
return console.log(err);
}
if (res) {
fs.rmSync(imagePath);
clipboardy.writeSync(res.secure_url);
return console.log("Done!");
}
console.log("No result returned");
});
}
main();
After running the script, here's what the screenshot turned out like:
If you made it all the way down here, consider following me on twitter @albingroen. Have a nice day!