240 lines
8.7 KiB
Python
240 lines
8.7 KiB
Python
#!/usr/bin/env python3
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from pathlib import Path
|
|
from textwrap import dedent
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parent
|
|
PALETTE_FILE = ROOT / "palette.json"
|
|
|
|
|
|
def load_palette() -> dict[str, str]:
|
|
data = json.loads(PALETTE_FILE.read_text())
|
|
return data["colors"]
|
|
|
|
|
|
def hex_no_hash(value: str) -> str:
|
|
return value.lstrip("#")
|
|
|
|
|
|
def camel_from_snake(name: str) -> str:
|
|
head, *tail = name.split("_")
|
|
return head + "".join(part.capitalize() for part in tail)
|
|
|
|
|
|
def write(path: Path, content: str) -> None:
|
|
path.write_text(content.rstrip() + "\n")
|
|
|
|
|
|
def render_palette_sh(colors: dict[str, str]) -> str:
|
|
lines = [
|
|
"# Generated from palette.json by generate.py. Do not edit directly.",
|
|
"",
|
|
]
|
|
for name, value in colors.items():
|
|
lines.append(f'export RIDER_{name.upper()}="{value}"')
|
|
return "\n".join(lines)
|
|
|
|
|
|
def render_palette_css(colors: dict[str, str]) -> str:
|
|
lines = [
|
|
"/* Generated from palette.json by generate.py. Do not edit directly. */",
|
|
":root {",
|
|
]
|
|
for name, value in colors.items():
|
|
lines.append(f" --rider-{name.replace('_', '-')}: {value};")
|
|
lines.append("}")
|
|
lines.append("")
|
|
for name, value in colors.items():
|
|
lines.append(f"@define-color rider-{name.replace('_', '-')} {value};")
|
|
return "\n".join(lines)
|
|
|
|
|
|
def render_palette_hypr(colors: dict[str, str]) -> str:
|
|
lines = [
|
|
"# Generated from palette.json by generate.py. Do not edit directly.",
|
|
"# Usage:",
|
|
"# source = ~/.config/rider-palette/palette.hyprland.conf",
|
|
"",
|
|
]
|
|
for name, value in colors.items():
|
|
lines.append(f"${name} = rgb({hex_no_hash(value)})")
|
|
lines.append(f"${camel_from_snake(name)}Alpha = {hex_no_hash(value)}")
|
|
return "\n".join(lines)
|
|
|
|
|
|
def render_palette_rasi(colors: dict[str, str]) -> str:
|
|
lines = [
|
|
"/* Generated from palette.json by generate.py. Do not edit directly. */",
|
|
"* {",
|
|
]
|
|
for name, value in colors.items():
|
|
lines.append(f" rider-{name.replace('_', '-')}: {value};")
|
|
lines.append("}")
|
|
return "\n".join(lines)
|
|
|
|
|
|
def render_tmux_conf(colors: dict[str, str]) -> str:
|
|
return dedent(
|
|
f"""
|
|
# Generated from palette.json by generate.py. Do not edit directly.
|
|
# Source this near the end of ~/.tmux.conf, after plugin/theme setup.
|
|
|
|
set -g status-style "bg={colors['bg']},fg={colors['fg_bright']}"
|
|
set -g status-left-style "bg={colors['bg']},fg={colors['fg_bright']}"
|
|
set -g status-right-style "bg={colors['bg']},fg={colors['fg_bright']}"
|
|
|
|
set -g message-style "bg={colors['cursor_line']},fg={colors['fg_bright']}"
|
|
set -g message-command-style "bg={colors['cursor_line']},fg={colors['fg_bright']}"
|
|
set -g mode-style "bg={colors['selection']},fg={colors['fg_bright']}"
|
|
|
|
set -g pane-border-style "fg={colors['border']}"
|
|
set -g pane-active-border-style "fg={colors['keyword']}"
|
|
set -g clock-mode-colour "{colors['keyword']}"
|
|
|
|
set -g window-status-style "bg={colors['bg']},fg={colors['fg_gutter']}"
|
|
set -g window-status-current-style "bg={colors['cursor_line']},fg={colors['fg_bright']}"
|
|
set -g window-status-current-format "#[fg={colors['func']},bg={colors['cursor_line']},bold] #I #W "
|
|
set -g window-status-format "#[fg={colors['fg_gutter']},bg={colors['bg']}] #I #W "
|
|
"""
|
|
).strip()
|
|
|
|
|
|
def render_bash_prompt() -> str:
|
|
return dedent(
|
|
"""
|
|
# Generated from palette.json by generate.py. Do not edit directly.
|
|
# Rider-colored bash prompt using the shared palette.
|
|
|
|
# shellcheck shell=bash
|
|
|
|
if [ -r "$HOME/.config/rider-palette/palette.sh" ]; then
|
|
. "$HOME/.config/rider-palette/palette.sh"
|
|
fi
|
|
|
|
rider_fg() {
|
|
local hex="${1#\\#}"
|
|
printf '\\[\\033[38;2;%d;%d;%dm\\]' "$((16#${hex:0:2}))" "$((16#${hex:2:2}))" "$((16#${hex:4:2}))"
|
|
}
|
|
|
|
RIDER_RESET='\\[\\033[0m\\]'
|
|
|
|
__rider_git_branch() {
|
|
command -v git >/dev/null 2>&1 || return 0
|
|
git rev-parse --is-inside-work-tree >/dev/null 2>&1 || return 0
|
|
|
|
local branch
|
|
branch="$(git symbolic-ref --quiet --short HEAD 2>/dev/null || git rev-parse --short HEAD 2>/dev/null)" || return 0
|
|
[ -n "$branch" ] || return 0
|
|
|
|
printf ' %sgit:%s%s' "$(rider_fg "$RIDER_FUNC")" "$branch" "$RIDER_RESET"
|
|
}
|
|
|
|
__rider_set_bash_prompt() {
|
|
PS1="${debian_chroot:+($debian_chroot)}$(rider_fg "$RIDER_FG_BRIGHT")\\u@\\h${RIDER_RESET}$(rider_fg "$RIDER_BORDER"):$(rider_fg "$RIDER_KEYWORD")\\w${RIDER_RESET}$(__rider_git_branch)$(rider_fg "$RIDER_BORDER") \\\\$ ${RIDER_RESET}"
|
|
}
|
|
|
|
PROMPT_COMMAND=__rider_set_bash_prompt
|
|
"""
|
|
).strip()
|
|
|
|
|
|
def render_p10k_zsh() -> str:
|
|
return dedent(
|
|
"""
|
|
# Generated from palette.json by generate.py. Do not edit directly.
|
|
# Rider-colored Powerlevel10k overrides using the shared palette.
|
|
|
|
[[ -r "$HOME/.config/rider-palette/palette.sh" ]] && source "$HOME/.config/rider-palette/palette.sh"
|
|
|
|
typeset -g POWERLEVEL9K_BACKGROUND="$RIDER_BG"
|
|
|
|
typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_PREFIX="%F{$RIDER_BORDER}╭─%f"
|
|
typeset -g POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_PREFIX="%F{$RIDER_BORDER}├─%f"
|
|
typeset -g POWERLEVEL9K_MULTILINE_LAST_PROMPT_PREFIX="%F{$RIDER_BORDER}╰─%f"
|
|
typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_SUFFIX="%F{$RIDER_BORDER}─╮%f"
|
|
typeset -g POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_SUFFIX="%F{$RIDER_BORDER}─┤%f"
|
|
typeset -g POWERLEVEL9K_MULTILINE_LAST_PROMPT_SUFFIX="%F{$RIDER_BORDER}─╯%f"
|
|
|
|
typeset -g POWERLEVEL9K_LEFT_SUBSEGMENT_SEPARATOR="%F{$RIDER_BORDER}\\uE0B1%f"
|
|
typeset -g POWERLEVEL9K_RIGHT_SUBSEGMENT_SEPARATOR="%F{$RIDER_BORDER}\\uE0B3%f"
|
|
|
|
typeset -g POWERLEVEL9K_OS_ICON_FOREGROUND="$RIDER_FG_BRIGHT"
|
|
|
|
typeset -g POWERLEVEL9K_DIR_FOREGROUND="$RIDER_KEYWORD"
|
|
typeset -g POWERLEVEL9K_DIR_SHORTENED_FOREGROUND="$RIDER_TYPE"
|
|
typeset -g POWERLEVEL9K_DIR_ANCHOR_FOREGROUND="$RIDER_FUNC"
|
|
|
|
typeset -g POWERLEVEL9K_VCS_VISUAL_IDENTIFIER_COLOR="$RIDER_FUNC"
|
|
typeset -g POWERLEVEL9K_VCS_LOADING_VISUAL_IDENTIFIER_COLOR="$RIDER_BORDER"
|
|
typeset -g POWERLEVEL9K_VCS_CLEAN_FOREGROUND="$RIDER_FUNC"
|
|
typeset -g POWERLEVEL9K_VCS_UNTRACKED_FOREGROUND="$RIDER_FIELD"
|
|
typeset -g POWERLEVEL9K_VCS_MODIFIED_FOREGROUND="$RIDER_NUMBER"
|
|
|
|
typeset -g POWERLEVEL9K_STATUS_OK_FOREGROUND="$RIDER_FUNC"
|
|
typeset -g POWERLEVEL9K_STATUS_OK_PIPE_FOREGROUND="$RIDER_FUNC"
|
|
typeset -g POWERLEVEL9K_STATUS_ERROR_FOREGROUND="$RIDER_ERROR"
|
|
typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL_FOREGROUND="$RIDER_ERROR"
|
|
typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE_FOREGROUND="$RIDER_ERROR"
|
|
|
|
typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_FOREGROUND="$RIDER_STRING"
|
|
typeset -g POWERLEVEL9K_TIME_FOREGROUND="$RIDER_FIELD"
|
|
typeset -g POWERLEVEL9K_DOTNET_VERSION_FOREGROUND="$RIDER_TYPE"
|
|
typeset -g POWERLEVEL9K_CONTEXT_FOREGROUND="$RIDER_FG_BRIGHT"
|
|
"""
|
|
).strip()
|
|
|
|
|
|
def render_readme() -> str:
|
|
return dedent(
|
|
"""
|
|
# Rider Palette Reuse
|
|
|
|
`palette.json` is the single source of truth for your shared Rider palette.
|
|
|
|
Regenerate all derived files with:
|
|
|
|
```bash
|
|
python3 ~/.config/rider-palette/generate.py
|
|
```
|
|
|
|
Generated outputs:
|
|
|
|
- `palette.sh`: shell env vars for prompts and scripts
|
|
- `palette.css`: CSS variables for Waybar and Wofi
|
|
- `palette.hyprland.conf`: Hyprlang variables for Hyprland and Hyprlock
|
|
- `palette.rasi`: Rasi variables for Rofi
|
|
- `tmux.conf`: tmux status and pane colors
|
|
- `bash-prompt.sh`: bash prompt using the shared palette
|
|
- `p10k.zsh`: Powerlevel10k overrides using the shared palette
|
|
|
|
This package is meant to be stowed from the dotfiles repo so that
|
|
`~/.config/rider-palette/*` becomes available to the rest of the system.
|
|
"""
|
|
).strip()
|
|
|
|
|
|
def main() -> None:
|
|
colors = load_palette()
|
|
|
|
outputs = {
|
|
ROOT / "palette.sh": render_palette_sh(colors),
|
|
ROOT / "palette.css": render_palette_css(colors),
|
|
ROOT / "palette.hyprland.conf": render_palette_hypr(colors),
|
|
ROOT / "palette.rasi": render_palette_rasi(colors),
|
|
ROOT / "tmux.conf": render_tmux_conf(colors),
|
|
ROOT / "bash-prompt.sh": render_bash_prompt(),
|
|
ROOT / "p10k.zsh": render_p10k_zsh(),
|
|
ROOT / "README.md": render_readme(),
|
|
}
|
|
|
|
for path, content in outputs.items():
|
|
write(path, content)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|