Synchronizing OSX, Terminal, and Emacs Dark/Light Appearance

Composing Shell, Applescript, and Emacs Eval

Throughout the day, I find myself toggling between Light and Dark modes. This evening I wrote up a shell script to keep Macintosh Operating System (MacOS 📖), Emacs (Emacs 📖), and my Terminal synchronized.

I named the script dark. Now, from the command-line, I can type dark to switch between Light and Dark mode.

Below is a copy of that script:

#!/bin/sh

# This script toggles the Operating System, Terminal, and Emacs
# themes.  It uses the state of the Operating System to determine
# if the terminal and Emacs should be "dark" or "light".

# First, tell OS-x to toggle dark mode.
osascript -e 'tell application "System Events" to tell appearance preferences to set dark mode to not dark mode'

# Second, determine what is the newly set appearance.
appearance=`defaults read -g AppleInterfaceStyle 2>/dev/null`
if [ -z "$appearance" ]
then
  # No value for AppleInterfaceStyle, so the OS has us in light
  # mode, proceed accordingly.
  sh $HOME/.config/base16-shell/scripts/base16-google-light.sh
  editor --eval "(disable-theme 'modus-vivendi)" \
    --eval "(modus-operandi-theme-load)" 1> /dev/null
else
  # AppleInterfaceStyle is set, and that means we're now in "Dark"
  # mode.
  sh $HOME/.config/base16-shell/scripts/base16-google-dark.sh
  editor --eval "(disable-theme 'modus-operandi)" \
    --eval "(modus-vivendi-theme-load)" 1> /dev/null
fi

Nothing fancy.

update

Emacs Configuration

Later on , I started tinkering to see about Emacs synchronizing with the Dark/Light mode of MacOS.

(defun jnf-dark ()
  "Toggle system-wide Dark or Light setting."
  (interactive)
  (shell-command "osascript -e 'tell application \"System Events\" to tell appearance preferences to set dark mode to not dark mode'")
  (jnf-emacs-theme-by-osx-appearance))


(defun jnf-emacs-theme-by-osx-appearance ()
  "Set theme based on OSX apperance state."
  (if (equal "Dark" (substring
                      (shell-command-to-string
                        "defaults read -g AppleInterfaceStyle") 0 4))
  (progn
    (disable-theme 'modus-operandi)
    (modus-vivendi-theme-load))
  (progn
    (disable-theme 'modus-vivendi)
    (modus-operandi-theme-load))))

;; Load the appropriate Emacs theme based on OSX appearance
(jnf-emacs-theme-by-osx-appearance)

I added this to my one of the files I load for Emacs.