~mdkcore/dotbins

04711048cbb21ca6f6e2a3a82dffd8a6cd5dafe4 — Rodrigo Oliveira 1 year, 10 months ago 8af279e
[generate-colors|synchronize-colors] Add generate-colors.py and synchronize-colors.sh
3 files changed, 190 insertions(+), 0 deletions(-)

M README.md
A generate-colors.py
A synchronize-colors.sh
M README.md => README.md +18 -0
@@ 99,6 99,24 @@ unset PINENTRY_USER_DATA
...
```

## generate-colors.py && synchronize-colors.sh
**files**: [generate-colors.py](generate-colors.py),
[synchronize-colors.sh](synchronize-colors.sh)

Generate application specific color theme based on a template and the current
[base16 shell theme](https://github.com/chriskempson/base16-shell) in use, and
syncronize them all across some applications, refreshing and reloading them.

**Usage**:
```shell
$ base16_solarized-dark && synchronize-colors
```

`synchronize-colors.sh` will call `generate-colors.py`. They are tailored for
my need, but suggestions and improvements are wellcome. See my [dotfiles](
https://git.sr.ht/~mdkcore/dotfiles/commit/c0e752793a47a93df9e6f42448cbe4d2fd178d29)
for a pratical example of the use.

# dotfiles
You can take a look on them on my [dotfiles repo](
https://git.sr.ht/~mdkcore/dotfiles) ;)

A generate-colors.py => generate-colors.py +68 -0
@@ 0,0 1,68 @@
#!/usr/bin/env python3
import re
import sys
from pathlib import Path
from subprocess import run


class Generator:
    color_table = {}

    def __init__(self):
        self.read_colors()

    def read_colors(self):
        command = ["xrdb", "-query"]
        result = run(command, capture_output=True, text=True)

        regex = r"(?P<name>color[0-9]+):\s*#(?P<color>[a-f,0-9]{6})"
        r = re.compile(regex)

        match = r.finditer(result.stdout)
        for m in match:
            self.color_table[m.group("name")] = m.group("color")

    def print_colors(self):
        for color in self.color_table:
            line = "{} #{}".format(f"{color}:".ljust(8), self.color_table[color])

            print(line)

    def generate(self, template, output):
        def repl(match):
            if match:
                return self.color_table.get(match["tag"], "00ffff")

        outfile = open(output, "w")

        regex = r"{{(?P<tag>color[0-9]*)}}"
        r = re.compile(regex)

        with open(template) as template_file:
            for line in template_file:
                outline = r.sub(repl, line)
                outfile.write(outline)

        outfile.close()


if __name__ == "__main__":
    # XXX use ArgumentParser (and add option to just print the color table)
    if len(sys.argv) < 3:
        print("Usage: {} <template> <output>".format(sys.argv[0]))
        sys.exit()

    template = sys.argv[1]
    output = sys.argv[2]

    if not Path(template).is_file():
        print(f"Template file {template} doesn't exist!")
        sys.exit(-1)

    if Path(output).is_file():
        # XXX ask user if should ovewrite or cancel/ add flag to define
        # behaviour
        print(f"WARNING: Output file {output} exists, overwriting")

    generator = Generator()
    generator.generate(template, output)

A synchronize-colors.sh => synchronize-colors.sh +104 -0
@@ 0,0 1,104 @@
#!/bin/sh

ALACRITTY_PATH=$HOME/.config/alacritty
ROFI_PATH=$HOME/.config/rofi
XRESOURCES_PATH=$HOME


echo "Syncronizing colors based on $BASE16_THEME"

# set Xresources
(
    xresources="base16-$BASE16_THEME-256.Xresources"
    echo "  Setting Xresources ($xresources)"

    echo "#include \"./downloads/GIT/base16-xresources/xresources/$xresources\"" \
        > "$XRESOURCES_PATH"/.Xresources
    xrdb -load "$XRESOURCES_PATH"/.Xresources
)

# generate colors for alacritty and rofi based on template
(
    echo "  Generating colors for alacritty (color_template.yml -> colors.yml)"
    output=$(generate-colors.py "$ALACRITTY_PATH"/color_template.yml \
        "$ALACRITTY_PATH"/colors.yml)

    [ -n "$output" ] && echo "    $output"

    echo "  Generating colors for rofi (color_template.rasi -> colors.rasi)"
    output=$(generate-colors.py "$ROFI_PATH"/color_template.rasi \
        "$ROFI_PATH"/colors.rasi)

    [ -n "$output" ] && echo "    $output"
)

# reload i3, dunst and polybar
(
    echo "  Reloading i3"

    unset I3SOCK && \
        i3-msg reload > /dev/null && \
        i3-msg restart > /dev/null
)


# reload tmux
(
    current_session=$(tmux display-message -p '#S')
    echo "  Refreshing tmux sessions"

    temp_window="sync_color$(date "+%Y%m%d%H%M%S")"
    for session in $(tmux list-sessions | awk -F ":" '{print $1}' | \
        grep -v "$current_session")
    do
        echo "    $session... "

        tmux new-window -t "$session" -n "$temp_window"
        sleep 2
        tmux kill-window -t "$session:$temp_window"
    done
)


# reload nvim
(
    echo "  Refreshing nvim instances"

    eval "$(pyenv init -)"
    PYENV_VIRTUALENV_DISABLE_PROMPT=1 pyenv activate py3nvim

    for pid in $(pidof nvim)
    do
        socket=$(lsof -U -a -p "$pid" -w | grep tmp | awk '{print $9}')
        nvim_command=$(ps -o command= -p "$pid")
        echo "    $pid:$nvim_command ($socket)... "

        # source base16 colors and airline only (not need to source $MYVIMRC)
        # [0, 0, "nvim_command", ["source..."]]
        python3 -c "from pynvim import attach; \
            nvim = attach(\"socket\", path=\"$socket\"); \
            nvim.command(\"source $HOME/.vimrc_background | AirlineRefresh\")"
    done

    pyenv deactivate
)


# just some fanciness :)
(
    echo "  Listing new colors"
    printf "    "

    i=0
    while [ "$i" -lt 16 ]
    do
        printf "%s  %s" "$(tput setab $i)" "$(tput sgr0)"
        [ "$i" -eq 7 ] && echo && printf "    "

        i=$(( i + 1 ))
    done

    echo
)

echo "All done!"