Skip to content

Pywal Integration

BuddhiLW edited this page Jul 19, 2024 · 2 revisions

Table of Contents

Requirements

  • python (anaconda, conda etc.)
  • pywal
pip install pywal

Pywal basic workings

Pywal will cache colors schemes-data in ~/.cache/wal.

ls .cache/wal/
colors                      colors-sway          colors.css
colors-kitty.conf           colors-tty.sh        colors.hs
colors-kitty.config         colors-wal-dmenu.h   colors.json
colors-konsole.colorscheme  colors-wal-dwm.h     colors.scss
colors-oomox                colors-wal-st.h      colors.sh
colors-putty.reg            colors-wal-tabbed.h  colors.yml
colors-rofi-dark.rasi       colors-wal.vim       schemes
colors-rofi-light.rasi      colors-waybar.css    sequences
colors-speedcrunch.json     colors.Xresources    wal

We are interested in the json file, specifically.

Everytime we use lazywal in a new video-loop, this file will update.

cat .cache/wal/colors.json
{
    "wallpaper": "/home/euler/b640deb4-eff2-416f-847b-f35ac3d84de5.png",
    "alpha": "100",

    "special": {
        "background": "#080F19",
        "foreground": "#b0c6d8",
        "cursor": "#b0c6d8"
    },
    "colors": {
        "color0": "#080F19",
        "color1": "#334D6F",
        "color2": "#4F4767",
        "color3": "#A96977",
        "color4": "#3B5F87",
        "color5": "#4F6D94",
        "color6": "#6389AF",
        "color7": "#b0c6d8",
        "color8": "#7b8a97",
        "color9": "#334D6F",
        "color10": "#4F4767",
        "color11": "#A96977",
        "color12": "#3B5F87",
        "color13": "#4F6D94",
        "color14": "#6389AF",
        "color15": "#b0c6d8"
    }
}

Watch pywal changes

Create a watcher for ~/.cache/wal/color.json.

Mine is called ewal-watch, under ~/.local/bin.

When the colorscheme changes, we want to notify Emacs. So, it can update it's themes too. In this example, I wrote a function blw/reload-ewal-doom-one-theme, that update those themes, and I use emacsclient to run it, upon change.

#!/usr/bin/bash

inotifywait -m -e close_write --format '%w%f' ~/.cache/wal/colors.json |      while read file; do
  emacsclient -e '(blw/reload-ewal-doom-one-theme)'
done

Emacs (doom themes) and hot-reloading themes

Explanation

There are two doom themes that can use pywal color-schemes: ewal-doom-one and ewal-doom-one-vibrant.

But, the themes are cached. M-x theme-load will use the current wal colors.

So, we must also reload the themes, e.g., (load-theme 'ewal-doom-one t).

Implementation

The following code also will automatically start ewal-watch, when we select a doom-theme. But, only once, because it checks if there is an existing ewal-watch process running.

;;; ../dotfiles/.doom.d/blw-func/ewal.el --- Ewal smart-hooks integration -*- lexical-binding: t; -*-
;;;
;;; Commentary:
;;;
;;; This file contains functions to manage ewal-related themes and processes.
;;; It includes functionality to start `ewal-watch` if it is not already running,
;;; and to reload ewal doom themes. Additionally, a hook is provided to ensure these
;;; functions are executed when any ewal doom theme is applied.
;;;
;;; Code:

(defun blw/start-ewal-watch-if-needed ()
  "Check if `ewal-watch` or `inotifywait` processes are running.
If not, start `ewal-watch`."
  (interactive)
  (let* ((ewal-watch-process (shell-command-to-string "pgrep -f ewal-watch"))
         (inotifywait-process (shell-command-to-string "pgrep -f inotifywait")))
    (unless (or (not (string-empty-p ewal-watch-process))
                (not (string-empty-p inotifywait-process)))
      (call-process "nohup" nil 0 nil "ewal-watch" "&")
      (message "Started ewal-watch process."))))

(defun blw/reload-ewal-doom-one-theme ()
  "Reload the ewal-doom-one and ewal-doom-vibrant themes."
  (interactive)
  (load-theme 'ewal-doom-one t)
  (load-theme 'ewal-doom-vibrant t))

;; (defun blw/apply-ewal-themes ()
;;   "Apply ewal themes and ensure supporting processes are running."
;;   (blw/start-ewal-watch-if-needed)
;;   (blw/reload-ewal-doom-one-theme))

(add-hook 'doom-load-theme-hook 'blw/start-ewal-watch-if-needed)

(provide 'ewal)
;;; ewal.el ends here

Final step

Call this code in your config.el.

In my case, I have (load! "./blw-func/ewal.el").

Vim

No need to setup anything. It should work out of the box.