#!/usr/bin/env bash
# |
# | Early pre-requisites check
# | ===========================================
UUIDGEN="${UUIDGEN:-$(command -v uuidgen | xargs echo)}"
DCONF="${DCONF:-$(command -v dconf | xargs echo)}"
GCONF="${GCONF:-$(command -v gconftool-2 | xargs echo)}"
GS="${GS:-$(command -v gsettings | xargs echo)}"
# Note: xargs echo is to make the command sucessful even if it was not
# otherwise the script will exit if the command does not exist (elementary os)
# |
# | Make sure all exported variables get unset no matter what
# | Defining this in this script because it gets called even if
# | gogh.sh was not called. Exported variables in gogh.sh gets
# | handled there in case there was en error before this script was called
# | ============================================
GLOBAL_VAR_CLEANUP() {
unset PROFILE_NAME
unset PROFILE_SLUG
unset scratchdir
unset TILIX_RES
unset TERMINAL
unset LOOP
unset OPTLENGTH
for c in $(seq -s " " -w 16); do
unset DEMO_COLOR_${c}
unset COLOR_${c}
done
unset BACKGROUND_COLOR
unset FOREGROUND_COLOR
unset CURSOR_COLOR
unset HIGHLIGHT_FG_COLOR
unset HIGHLIGHT_BG_COLOR
unset USE_SYS_TRANSPARENCY
unset PROFILE_NAME
}
# Note: Since all scripts gets invoked in a subshell the traps from the parent shell
# will not get inherited. Hence traps defined in gogh.sh and print-themes.sh will still trigger
trap 'GLOBAL_VAR_CLEANUP; trap - EXIT' EXIT HUP INT QUIT PIPE TERM
# |
# | Second test for TERMINAL in case user ran
# | theme script directly instead of gogh.sh
# | ============================================
if [[ -z "${TERMINAL:-}" ]]; then
# |
# | Check for the terminal name (depening on os)
# | ===========================================
OS="$(uname)"
if [[ "$TERM" = "xterm-kitty" ]]; then
TERMINAL="kitty"
elif [[ "$OS" = "Darwin" ]]; then
TERMINAL=$TERM_PROGRAM
elif [[ "${OS#CYGWIN}" != "${OS}" ]]; then
TERMINAL="mintty"
else
# |
# | Depending on how the script was invoked, we need
# | to loop until pid is no longer a subshell
# | ===========================================
pid="$$"
TERMINAL="$(ps -h -o comm -p $pid)"
while [[ "${TERMINAL:(-2)}" == "sh" ]]; do
pid="$(ps -h -o ppid -p $pid)"
TERMINAL="$(ps -h -o comm -p $pid)"
done
fi
fi
case "${TERMINAL}" in
pantheon-terminal|io.elementary.t* )
if [[ -z "${GS}" ]]; then
printf '\n%s\n' "Error gsettings not found"
printf '%s\n' "sudo apt install dconf?"
printf '%s\n\n' "or export GS=/path/to/gsettings"
exit 1
fi
;;
mintty )
CFGFILE="${HOME}/.minttyrc"
if [[ ! -f "${CFGFILE}" ]]; then
printf '\n%s\n' "Warning: Couldn't find an existing configuration file, so one will be created for you."
printf '%s\n\n' "Warning: Are you really running Cygwin's mintty?"
touch "${CFGFILE}"
fi
;;
guake|tilix|mate-terminal|gnome-terminal* )
case "${TERMINAL}" in
guake|gnome-terminal* )
if [[ -z "${DCONF}" ]] && [[ -z "${GCONF}" ]]; then
printf '\n%s\n' "Error gconftool not found!"
printf '%s\n' "sudo apt install gconftool?"
printf '%s\n\n' "or export GCONF=/path/to/gconftool-2/"
exit 1
fi
;;
esac
if [[ -z "${DCONF}" ]]; then
printf '\n%s\n' "Error dconf not found"
printf '%s\n' "sudo apt install dconf?"
printf '%s\n\n' "or export DCONF=/path/to/dconf"
exit 1
fi
;;
foot )
CFGFILE="${HOME}/.config/foot/foot.ini"
if [[ ! -f "${CFGFILE}" ]]; then
printf '\n%s\n' "Error: Couldn't find an existing configuration file."
exit 1
fi
;;
kitty )
if [[ -z "${KITTY_CONFIG_DIRECTORY:-}" ]]; then
KITTY_CONFIG_DIRECTORY="${HOME}/.config/kitty"
fi
CFGFILE="${KITTY_CONFIG_DIRECTORY}/kitty.conf"
if [[ ! -f "${CFGFILE}" ]]; then
printf '\n%s\n' "Error: Couldn't find an existing configuration file for Kitty."
exit 1
fi
;;
konsole )
CFGFILE="${HOME}/.config/konsolerc"
if [[ ! -f "${CFGFILE}" ]]; then
printf '\n%s\n' "Error: Couldn't find an existing configuration file for Konsole."
exit 1
fi
;;
esac
# |
# | Convert RGB to gnome colors
# | ===========================================
gnome_color () {
AA=${1:1:2}
BB=${1:3:2}
CC=${1:5:2}
if [[ -n "${AA:-}" ]]; then
echo "#${AA}${AA}${BB}${BB}${CC}${CC}"
fi
}
hexToDec () {
echo "$((16#${1}))"
}
hexRGBtoDecRGB () {
R="$(hexToDec "${1:1:2}")"
G="$(hexToDec "${1:3:2}")"
B="$(hexToDec "${1:5:2}")"
echo "${R}" "${G}" "${B}"
}
convertRGBtoMac () {
local color="${1}"
set --
set -- $(hexRGBtoDecRGB "${color}")
R=${1}; shift; G=${1}; shift; B=${1}; shift
R=$(echo "${R} / 255" | bc -l)
G=$(echo "${G} / 255" | bc -l)
B=$(echo "${B} / 255" | bc -l)
echo "${R}" "${G}" "${B}"
}
createMinttyEntry () {
local name="${1}"
local color="${2}"
set --
set -- $(hexRGBtoDecRGB "${color}")
R=${1}; shift; G=${1}; shift; B=${1}; shift
echo "${name}=${R},${G},${B}"
}
updateMinttyConfig () {
local config="${1}"
local color="${2}"
local name="${3}"
sed -i -r -e "s/^${name}=.+/$(createMinttyEntry "${name}" "${color}")/g" "${config}"
}
updateFootConfig () {
local config="${1}"
local color="${2}"
local name="${3}"
sed -i -r -e "s/^${name}=.+/${name}=${color/\#/}/g" "${config}"
}
createKonsoleEntry () {
local name="${1}"
local color="${2}"
set --
set -- $(hexRGBtoDecRGB "${color}")
R=${1}; shift; G=${1}; shift; B=${1}; shift
echo -e "[$name]\nColor=${R},${G},${B}\n"
}
createKonsoleTriple () {
local name="${1}"
local colorn="${2}" # normal and faint
local colori="${3}" # intense
createKonsoleEntry "${name}" "${colorn}"
createKonsoleEntry "${name}Faint" "${colorn}"
createKonsoleEntry "${name}Intense" "${colori}"
}
convertNameAndRGBtoITerm() {
local name="${1}"
local color="${2}"
set --
set -- $(convertRGBtoMac "${color}")
R=${1}; shift; G=${1}; shift; B=${1}; shift
echo "${name}Blue Component${B}Green Component${G}Red Component${R}"
}
dset() {
local key="${1}"; shift
local val="${1}"
"${DCONF}" write "${PROFILE_KEY}/${key}" "${val}"
}
# Because dconf still doesn't have "append"
dlist_append() {
local key="${1}"; shift
local val="${1}"; shift
local entries
entries="$(
{
"${DCONF}" read "${key}" | tr -d "[]" | tr , "\n" | grep -F -v "${val}"
echo "'${val}'"
} | head -c-1 | tr "\n" ,
)"
"${DCONF}" write "${key}" "[${entries}]"
}
gcset() {
local type="${1}"; shift
local key="${1}"; shift
local val="${1}"
"${GCONF}" --set --type "${type}" "${PROFILE_KEY}/${key}" -- "${val}"
}
# Because gconftool doesn't have "append"
glist_append() {
local type="${1}"; shift
local key="${1}"; shift
local val="${1}"; shift
local entries
entries="$(
{
"${GCONF}" --get "${key}" | tr -d "[]" | tr , "\n" | grep -F -v "${val}"
echo "${val}"
} | head -c-1 | tr "\n" ,
)"
"${GCONF}" --set --type list --list-type "${type}" "${key}" "[${entries}]"
}
gset() {
local key="${1}"; shift
local val="${1}"
"${GS}" set "${PROFILE_KEY}" "${key}" "${val}"
}
set_theme() {
dset visible-name "'${PROFILE_NAME}'"
dset background-color "'${BACKGROUND_COLOR}'"
dset foreground-color "'${FOREGROUND_COLOR}'"
dset cursor-colors-set "true"
dset cursor-background-color "'${CURSOR_COLOR}'"
dset cursor-foreground-color "'${BACKGROUND_COLOR}'"
if [[ -n "${HIGHLIGHT_BG_COLOR:-}" ]]; then
dset highlight-colors-set "true"
dset highlight-background-color "'${HIGHLIGHT_BG_COLOR}'"
if [[ -n "${HIGHLIGHT_FG_COLOR:-}" ]]; then
dset highlight-foreground-color "'${HIGHLIGHT_FG_COLOR}'"
fi
fi
if [[ -n "${BOLD_COLOR:-}" ]]; then
dset bold-color "'${BOLD_COLOR}'"
dset bold-color-same-as-fg "false"
else
dset bold-color "'${FOREGROUND_COLOR}'"
dset bold-color-same-as-fg "true"
fi
dset use-theme-colors "false"
dset use-theme-background "false"
dset use-theme-transparency "${USE_SYS_TRANSPARENCY:-false}"
}
legacy_set_theme() {
gcset string visible_name "${PROFILE_NAME}"
gcset string background_color "${BACKGROUND_COLOR}"
gcset string foreground_color "${FOREGROUND_COLOR}"
if [[ -n "${BOLD_COLOR:-}" ]]; then
gcset string bold_color "${BOLD_COLOR}"
gcset bool bold_color_same_as_fg "false"
else
gcset string bold_color "${FOREGROUND_COLOR}"
gcset bool bold_color_same_as_fg "true"
fi
gcset bool use_theme_colors "false"
gcset bool use_theme_background "false"
}
# |
# | If terminal supports truecolor then we can show theme colors without applying the theme
# | ===========================================
if [[ "${COLORTERM:-}" == "truecolor" ]] || [[ "${COLORTERM:-}" == "24bit" ]]; then
# gogh_colors have been moved here to avoid multiple definitions
function gogh_colors () {
# Build up the color string to avoid visual rendering
local color_str
# Note: {01..16} does not work on OSX
for c in $(seq -s " " -w 16); do
local color="COLOR_$c"
set -- $(hexRGBtoDecRGB "${!color}")
color_str+="\033[38;2;${1};${2};${3}m█████$(tput sgr0)"
[[ ${GOGH_DRY_RUN:-0} -eq 1 ]] && export "DEMO_COLOR_$c=\033[38;2;${1};${2};${3}m"
[[ "$c" == "08" ]] && color_str+="\n" # new line
done
printf '\n%b\n\n\n' "${color_str}"
unset color_str
}
else
function gogh_colors () {
# Build up the color string to avoid visual rendering
local color_str
for c in {0..15}; do
color_str+="$(tput setaf $c)█████$(tput sgr0)"
[[ $c == 7 ]] && color_str+="\n" # new line
done
printf '\n%b\n\n' "${color_str}"
unset color_str
}
fi
# |
# | Print theme colors
# | ===========================================
gogh_colors
if [[ ${GOGH_DRY_RUN:-0} -eq 1 ]]; then
color
# End here if dry run was initiated
exit 0
fi
apply_elementary() {
# |
# | Applying values on elementary/pantheon terminal
# | ===========================================
local BG_COLOR="${BACKGROUND_COLOR}"
# If the background color is in the format #rrggbb, convert it to rgba(r,g,b,0.95).
# This makes it 5% transparent, which is the default in elementary OS.
if [[ ${BACKGROUND_COLOR} =~ ^#[[:xdigit:]]{6}$ ]]; then
local R="$((16#${BACKGROUND_COLOR:1:2}))"
local G="$((16#${BACKGROUND_COLOR:3:2}))"
local B="$((16#${BACKGROUND_COLOR:5:2}))"
BG_COLOR="rgba($R,$G,$B,0.95)"
fi
gset background "${BG_COLOR}"
gset foreground "${FOREGROUND_COLOR}"
gset cursor-color "${CURSOR_COLOR}"
gset palette "${COLOR_01}:${COLOR_02}:${COLOR_03}:${COLOR_04}:${COLOR_05}:${COLOR_06}:${COLOR_07}:${COLOR_08}:${COLOR_09}:${COLOR_10}:${COLOR_11}:${COLOR_12}:${COLOR_13}:${COLOR_14}:${COLOR_15}:${COLOR_16}"
}
apply_cygwin() {
# |
# | Applying values on mintty (cygwin)
# | ===========================================
echo "Patching mintty configuration file (${CFGFILE}) with new colors..."
updateMinttyConfig "$CFGFILE" "$COLOR_01" "Black"
updateMinttyConfig "$CFGFILE" "$COLOR_02" "Red"
updateMinttyConfig "$CFGFILE" "$COLOR_03" "Green"
updateMinttyConfig "$CFGFILE" "$COLOR_04" "Yellow"
updateMinttyConfig "$CFGFILE" "$COLOR_05" "Blue"
updateMinttyConfig "$CFGFILE" "$COLOR_06" "Magenta"
updateMinttyConfig "$CFGFILE" "$COLOR_07" "Cyan"
updateMinttyConfig "$CFGFILE" "$COLOR_08" "White"
updateMinttyConfig "$CFGFILE" "$COLOR_09" "BoldBlack"
updateMinttyConfig "$CFGFILE" "$COLOR_10" "BoldRed"
updateMinttyConfig "$CFGFILE" "$COLOR_11" "BoldGreen"
updateMinttyConfig "$CFGFILE" "$COLOR_12" "BoldYellow"
updateMinttyConfig "$CFGFILE" "$COLOR_13" "BoldBlue"
updateMinttyConfig "$CFGFILE" "$COLOR_14" "BoldMagenta"
updateMinttyConfig "$CFGFILE" "$COLOR_15" "BoldCyan"
updateMinttyConfig "$CFGFILE" "$COLOR_16" "BoldWhite"
updateMinttyConfig "$CFGFILE" "$BACKGROUND_COLOR" "Backgroundcolor"
updateMinttyConfig "$CFGFILE" "$FOREGROUND_COLOR" "Foregroundcolor"
updateMinttyConfig "$CFGFILE" "$CURSOR_COLOR" "Cursorcolor"
echo "Done - please reopen your Cygwin terminal to see the changes"
}
apply_alacritty() {
# |
# | Applying values on Alacritty
# | ===========================================
json_str="\
{ \
\"colors\": \
{\
\"primary\":\
{\
\"background\": \"$BACKGROUND_COLOR\",\
\"foreground\": \"$FOREGROUND_COLOR\"\
},\
\"normal\":\
{\
\"black\": \"$COLOR_01\",\
\"red\": \"$COLOR_02\",\
\"green\": \"$COLOR_03\",\
\"yellow\":\"$COLOR_04\",\
\"blue\":\"$COLOR_05\",\
\"magenta\": \"$COLOR_06\",\
\"cyan\":\"$COLOR_07\",\
\"white\": \"$COLOR_08\"\
},\
\"bright\":\
{\
\"black\":\"$COLOR_09\",\
\"red\":\"$COLOR_10\",\
\"green\":\"$COLOR_11\",\
\"yellow\": \"$COLOR_12\",\
\"blue\": \"$COLOR_13\",\
\"magenta\":\"$COLOR_14\",\
\"cyan\": \"$COLOR_15\",\
\"white\":\"$COLOR_16\"\
} \
}\
}"
SCRIPT_PATH="${SCRIPT_PATH:-$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)}"
PARENT_PATH="$(dirname "${SCRIPT_PATH}")"
# Allow developer to change url to forked url for easier testing
# IMPORTANT: Make sure you export this variable if your main shell is not bash
BASE_URL=${BASE_URL:-"https://raw.githubusercontent.com/Gogh-Co/Gogh/master"}
if [[ -e "${SCRIPT_PATH}/apply-alacritty.py" ]]; then
python3 "${SCRIPT_PATH}/apply-alacritty.py" "$json_str"
else
if [[ "$(uname)" = "Darwin" ]]; then
# OSX ships with curl and ancient bash
python3 -c "$(curl -so- "${BASE_URL}/apply-alacritty.py")" "$json_str"
else
# Linux ships with wget
python3 -c "$(wget -qO- "${BASE_URL}/apply-alacritty.py")" "$json_str"
fi
fi
}
apply_foot() {
# |
# | Applying values on foot
# | ===========================================
echo "Patching foot configuration file (${CFGFILE}) with new colors..."
updateFootConfig "$CFGFILE" "$COLOR_01" "regular0"
updateFootConfig "$CFGFILE" "$COLOR_02" "regular1"
updateFootConfig "$CFGFILE" "$COLOR_03" "regular2"
updateFootConfig "$CFGFILE" "$COLOR_04" "regular3"
updateFootConfig "$CFGFILE" "$COLOR_05" "regular4"
updateFootConfig "$CFGFILE" "$COLOR_06" "regular5"
updateFootConfig "$CFGFILE" "$COLOR_07" "regular6"
updateFootConfig "$CFGFILE" "$COLOR_08" "regular7"
updateFootConfig "$CFGFILE" "$COLOR_09" "bright0"
updateFootConfig "$CFGFILE" "$COLOR_10" "bright1"
updateFootConfig "$CFGFILE" "$COLOR_11" "bright2"
updateFootConfig "$CFGFILE" "$COLOR_12" "bright3"
updateFootConfig "$CFGFILE" "$COLOR_13" "bright4"
updateFootConfig "$CFGFILE" "$COLOR_14" "bright5"
updateFootConfig "$CFGFILE" "$COLOR_15" "bright6"
updateFootConfig "$CFGFILE" "$COLOR_16" "bright7"
updateFootConfig "$CFGFILE" "$BACKGROUND_COLOR" "background"
updateFootConfig "$CFGFILE" "$FOREGROUND_COLOR" "foreground"
echo "Done - please reopen your foot terminal to see the changes"
}
apply_kitty() {
# |
# | Applying values on Kitty
# | ===========================================
echo "Patching kitty configuration file ($CFGFILE) with include of color theme file..."
COLOR_FILE="colors.conf"
if ! grep -q "^include $COLOR_FILE$" "$CFGFILE" ; then
echo "" >> "$CFGFILE"
echo "# Added by Gogh" >> "$CFGFILE"
echo "include $COLOR_FILE" >> "$CFGFILE"
fi
CFGFILE="${KITTY_CONFIG_DIRECTORY}/$COLOR_FILE"
echo "Updating color theme file ($CFGFILE) with theme..."
rm -f "$CFGFILE"
echo "# Color theme: $PROFILE_NAME" >> "$CFGFILE"
echo "# Auto-generated by Gogh (https://Gogh-Co.github.io/Gogh/)" >> "$CFGFILE"
echo "" >> "$CFGFILE"
echo "color0 $COLOR_01" >> "$CFGFILE"
echo "color1 $COLOR_02" >> "$CFGFILE"
echo "color2 $COLOR_03" >> "$CFGFILE"
echo "color3 $COLOR_04" >> "$CFGFILE"
echo "color4 $COLOR_05" >> "$CFGFILE"
echo "color5 $COLOR_06" >> "$CFGFILE"
echo "color6 $COLOR_07" >> "$CFGFILE"
echo "color7 $COLOR_08" >> "$CFGFILE"
echo "color8 $COLOR_09" >> "$CFGFILE"
echo "color9 $COLOR_10" >> "$CFGFILE"
echo "color10 $COLOR_11" >> "$CFGFILE"
echo "color11 $COLOR_12" >> "$CFGFILE"
echo "color12 $COLOR_13" >> "$CFGFILE"
echo "color13 $COLOR_14" >> "$CFGFILE"
echo "color14 $COLOR_15" >> "$CFGFILE"
echo "color15 $COLOR_16" >> "$CFGFILE"
echo "background $BACKGROUND_COLOR" >> "$CFGFILE"
echo "foreground $FOREGROUND_COLOR" >> "$CFGFILE"
[ -n "$HIGHLIGHT_FG_COLOR" ] && echo "selection_foreground $HIGHLIGHT_FG_COLOR" >> "$CFGFILE"
[ -n "$HIGHLIGHT_BG_COLOR" ] && echo "selection_background $HIGHLIGHT_BG_COLOR" >> "$CFGFILE"
echo "cursor $CURSOR_COLOR" >> "$CFGFILE"
echo "Done - please reopen your kitty terminal to see the changes"
}
apply_konsole() {
# |
# | Applying values on Konsole
# | ===========================================
PARENT=$(grep -o "^DefaultProfile=.*$" ${CFGFILE} | cut -d '=' -f 2)
if [[ -z "${PARENT}" ]]; then
PARENT="FALLBACK/"
fi
if [[ -z "${XDG_DATA_HOME:-}" ]]; then
KDIR="${HOME}/.local/share/konsole"
else
KDIR="${XDG_DATA_HOME}/konsole"
fi
KPROFILE="${KDIR}/${PROFILE_NAME}.profile"
if [[ -f "${KPROFILE}" ]]; then
echo "Profile ${PROFILE_NAME} already exists in Konsole confiuration (${KONSOLE_DIR}); Skipping ..."
exit 0
fi
touch "${KPROFILE}"
echo -e "[Appearance]\nColorScheme=${PROFILE_NAME}\n" >> "${KPROFILE}"
echo -e "[General]\nName=${PROFILE_NAME}\nParent=$PARENT" >> "${KPROFILE}"
KCOLORSCHEME="${KDIR}/${PROFILE_NAME}.colorscheme"
if [[ -f "${KCOLORSCHEME}" ]]; then
echo "Color Scheme ${PROFILE_NAME} already exists in Konsole confiuration (${KONSOLE_DIR}); Skipping ..."
exit 0
fi
touch "${KCOLORSCHEME}"
createKonsoleTriple "Background" "${BACKGROUND_COLOR}" "${BACKGROUND_COLOR}" >> "${KCOLORSCHEME}"
createKonsoleTriple "Color0" "${COLOR_01}" "${COLOR_09}" >> "${KCOLORSCHEME}"
createKonsoleTriple "Color1" "${COLOR_02}" "${COLOR_10}" >> "${KCOLORSCHEME}"
createKonsoleTriple "Color2" "${COLOR_03}" "${COLOR_11}" >> "${KCOLORSCHEME}"
createKonsoleTriple "Color3" "${COLOR_04}" "${COLOR_12}" >> "${KCOLORSCHEME}"
createKonsoleTriple "Color4" "${COLOR_05}" "${COLOR_13}" >> "${KCOLORSCHEME}"
createKonsoleTriple "Color5" "${COLOR_06}" "${COLOR_14}" >> "${KCOLORSCHEME}"
createKonsoleTriple "Color6" "${COLOR_07}" "${COLOR_15}" >> "${KCOLORSCHEME}"
createKonsoleTriple "Color7" "${COLOR_08}" "${COLOR_16}" >> "${KCOLORSCHEME}"
createKonsoleTriple "Foreground" "${FOREGROUND_COLOR}" "${FOREGROUND_COLOR}" >> "${KCOLORSCHEME}"
echo "[General]" >> "${KCOLORSCHEME}"
echo "Blur=false" >> "${KCOLORSCHEME}"
echo "ColorRandomization=false" >> "${KCOLORSCHEME}"
echo "Description=${PROFILE_NAME}" >> "${KCOLORSCHEME}"
echo "Opacity=1" >> "${KCOLORSCHEME}"
echo "Wallpaper=" >> "${KCOLORSCHEME}"
}
apply_darwin() {
# |
# | Applying values on iTerm2
# | ===========================================
BACKGROUND_COLOR=$(convertNameAndRGBtoITerm "Background Color" "$BACKGROUND_COLOR")
FOREGROUND_COLOR=$(convertNameAndRGBtoITerm "Foreground Color" "$FOREGROUND_COLOR")
COLOR_01=$(convertNameAndRGBtoITerm "Ansi 0 Color" "$COLOR_01")
COLOR_02=$(convertNameAndRGBtoITerm "Ansi 1 Color" "$COLOR_02")
COLOR_03=$(convertNameAndRGBtoITerm "Ansi 2 Color" "$COLOR_03")
COLOR_04=$(convertNameAndRGBtoITerm "Ansi 3 Color" "$COLOR_04")
COLOR_05=$(convertNameAndRGBtoITerm "Ansi 4 Color" "$COLOR_05")
COLOR_06=$(convertNameAndRGBtoITerm "Ansi 5 Color" "$COLOR_06")
COLOR_07=$(convertNameAndRGBtoITerm "Ansi 6 Color" "$COLOR_07")
COLOR_08=$(convertNameAndRGBtoITerm "Ansi 7 Color" "$COLOR_08")
COLOR_09=$(convertNameAndRGBtoITerm "Ansi 8 Color" "$COLOR_09")
COLOR_10=$(convertNameAndRGBtoITerm "Ansi 9 Color" "$COLOR_10")
COLOR_11=$(convertNameAndRGBtoITerm "Ansi 10 Color" "$COLOR_11")
COLOR_12=$(convertNameAndRGBtoITerm "Ansi 11 Color" "$COLOR_12")
COLOR_13=$(convertNameAndRGBtoITerm "Ansi 12 Color" "$COLOR_13")
COLOR_14=$(convertNameAndRGBtoITerm "Ansi 13 Color" "$COLOR_14")
COLOR_15=$(convertNameAndRGBtoITerm "Ansi 14 Color" "$COLOR_15")
COLOR_16=$(convertNameAndRGBtoITerm "Ansi 15 Color" "$COLOR_16")
# Assemble color scheme file contents
ITERMCOLORS=''${BACKGROUND_COLOR}${FOREGROUND_COLOR}${COLOR_01}${COLOR_02}${COLOR_03}${COLOR_04}${COLOR_05}${COLOR_06}${COLOR_07}${COLOR_08}${COLOR_09}${COLOR_10}${COLOR_11}${COLOR_12}${COLOR_13}${COLOR_14}${COLOR_15}''
# Dump iTerm color scheme to file and import it by opening it
echo "${ITERMCOLORS}" > "${PROFILE_NAME}.itermcolors"
open "${PROFILE_NAME}.itermcolors"
rm "${PROFILE_NAME}.itermcolors"
}
apply_gtk() {
# |
# | Applying values to gnome/mate/tilix
# | ===========================================
local legacy="${1:-}"
# This is to avoid doing the profile loop definition twice
if [[ -z "${legacy}" ]]; then
CONFTOOL="${DCONF} read"
VISIBLE_NAME="visible-name"
else
CONFTOOL="${GCONF} --get"
VISIBLE_NAME="visible_name"
fi
# Check first wether profile already exists
profile_hashes=($(${CONFTOOL} "${PROFILE_LIST_KEY}" | tr "[]'," " "))
for profile in "${profile_hashes[@]}"; do
if [[ "$(${CONFTOOL} "${BASE_DIR}${profile}/${VISIBLE_NAME}" | tr -d "'")" == "${PROFILE_NAME}" ]]; then
printf '%s\n' "Profile already exists" "Skipping..."
exit 0
fi
done
# Fallback if there is no default profile
set -- $(${CONFTOOL} ${PROFILE_LIST_KEY} | tr "[]'," " ")
: ${DEFAULT_SLUG:="$1"}
: ${PROFILE_NAME:="Default"}
: ${PROFILE_SLUG:="Default"}
DEFAULT_KEY="${BASE_DIR}${DEFAULT_SLUG:-}"
PROFILE_KEY="${BASE_DIR}${PROFILE_SLUG:-}"
if [[ -z "${legacy}" ]]; then
if [[ -z "$(${DCONF} list ${BASE_DIR%:})" ]]; then
# Provide a user friendly error text if no saved profile exists, otherwise it will display "Error gconftool not found!"
# it could happen on a newly installed system. (happened on CentOS 7)
printf '%s\n' \
"Error, no saved profiles found!" \
"Possible fix, new a profile (Terminal > Edit > Preferences > Profiles > New, then Close) and try again." \
"You can safely delete the created profile after the installation."
exit 1
fi
BACKGROUND_COLOR=$(gnome_color "$BACKGROUND_COLOR")
FOREGROUND_COLOR=$(gnome_color "$FOREGROUND_COLOR")
CURSOR_COLOR=$(gnome_color "$CURSOR_COLOR")
HIGHLIGHT_BG_COLOR=$(gnome_color "$HIGHLIGHT_BG_COLOR")
HIGHLIGHT_FG_COLOR=$(gnome_color "$HIGHLIGHT_FG_COLOR")
COLOR_01=$(gnome_color "$COLOR_01")
COLOR_02=$(gnome_color "$COLOR_02")
COLOR_03=$(gnome_color "$COLOR_03")
COLOR_04=$(gnome_color "$COLOR_04")
COLOR_05=$(gnome_color "$COLOR_05")
COLOR_06=$(gnome_color "$COLOR_06")
COLOR_07=$(gnome_color "$COLOR_07")
COLOR_08=$(gnome_color "$COLOR_08")
COLOR_09=$(gnome_color "$COLOR_09")
COLOR_10=$(gnome_color "$COLOR_10")
COLOR_11=$(gnome_color "$COLOR_11")
COLOR_12=$(gnome_color "$COLOR_12")
COLOR_13=$(gnome_color "$COLOR_13")
COLOR_14=$(gnome_color "$COLOR_14")
COLOR_15=$(gnome_color "$COLOR_15")
COLOR_16=$(gnome_color "$COLOR_16")
# copy existing settings from default profile
$DCONF dump "${DEFAULT_KEY}/" | $DCONF load "${PROFILE_KEY}/"
# add new copy to global list of profiles
dlist_append "${PROFILE_LIST_KEY}" "${PROFILE_SLUG#:}"
set_theme
dset palette "${LEFT_WRAPPER:-}'${COLOR_01}${PALETTE_DELIM}${COLOR_02}${PALETTE_DELIM}${COLOR_03}${PALETTE_DELIM}${COLOR_04}${PALETTE_DELIM}${COLOR_05}${PALETTE_DELIM}${COLOR_06}${PALETTE_DELIM}${COLOR_07}${PALETTE_DELIM}${COLOR_08}${PALETTE_DELIM}${COLOR_09}${PALETTE_DELIM}${COLOR_10}${PALETTE_DELIM}${COLOR_11}${PALETTE_DELIM}${COLOR_12}${PALETTE_DELIM}${COLOR_13}${PALETTE_DELIM}${COLOR_14}${PALETTE_DELIM}${COLOR_15}${PALETTE_DELIM}${COLOR_16}'${RIGHT_WRAPPER:-}"
${LEGACY_BOLD:-} && dset allow-bold "true" # mate
else
# Append the Base16 profile to the profile list
glist_append string "${PROFILE_LIST_KEY}" "${PROFILE_SLUG}"
legacy_set_theme
gcset string palette "${COLOR_01}:${COLOR_02}:${COLOR_03}:${COLOR_04}:${COLOR_05}:${COLOR_06}:${COLOR_07}:${COLOR_08}:${COLOR_09}:${COLOR_10}:${COLOR_11}:${COLOR_12}:${COLOR_13}:${COLOR_14}:${COLOR_15}:${COLOR_16}"
${LEGACY_BOLD:-} && gcset bool allow-bold "true"
fi
}
apply_guake() {
# |
# | Applying values to guake
# | ===========================================
local legacy="${1:-}"
PROFILE_KEY="/apps/guake/style/font"
if [[ -z "${legacy}" ]]; then
dset palette "'${COLOR_01}:${COLOR_02}:${COLOR_03}:${COLOR_04}:${COLOR_05}:${COLOR_06}:${COLOR_07}:${COLOR_08}:${COLOR_09}:${COLOR_10}:${COLOR_11}:${COLOR_12}:${COLOR_13}:${COLOR_14}:${COLOR_15}:${COLOR_16}:${FOREGROUND_COLOR}:${BACKGROUND_COLOR}'"
dset palette-name "'${PROFILE_NAME}'"
dset allow-bold 'true'
else
gcset string color "${FOREGROUND_COLOR}"
gcset string palette "${COLOR_01}:${COLOR_02}:${COLOR_03}:${COLOR_04}:${COLOR_05}:${COLOR_06}:${COLOR_07}:${COLOR_08}:${COLOR_09}:${COLOR_10}:${COLOR_11}:${COLOR_12}:${COLOR_13}:${COLOR_14}:${COLOR_15}:${COLOR_16}"
gcset string palette-name "${PROFILE_NAME}"
PROFILE_KEY="/apps/guake/style/background"
gcset string color "${BACKGROUND_COLOR}"
fi
}
appy_tilixschemes() {
# |
# | Applying values to tilix colorschemes
# | ===========================================
if [[ ${TILIX_RES::1} =~ ^(y|Y)$ ]]; then
[[ -d "${HOME}/.config/tilix/schemes" ]] || mkdir -p "${HOME}/.config/tilix/schemes"
TILIXCOLORS='{\n\t"name": "'${PROFILE_NAME}'",\n\t"comment": "Generated by Gogh",\n\t"foreground-color": "'${FOREGROUND_COLOR}'",\n\t"background-color":"'${BACKGROUND_COLOR}'",\n\t"cursor-background-color": "'${CURSOR_COLOR}'",\n\t"palette": [\n\t\t"'${COLOR_01}'",\n\t\t"'${COLOR_02}'",\n\t\t"'${COLOR_03}'",\n\t\t"'${COLOR_04}'",\n\t\t"'${COLOR_05}'",\n\t\t"'${COLOR_06}'",\n\t\t"'${COLOR_07}'",\n\t\t"'${COLOR_08}'",\n\t\t"'${COLOR_09}'",\n\t\t"'${COLOR_10}'",\n\t\t"'${COLOR_11}'",\n\t\t"'${COLOR_12}'",\n\t\t"'${COLOR_13}'",\n\t\t"'${COLOR_14}'",\n\t\t"'${COLOR_15}'",\n\t\t"'${COLOR_16}'"\n\t],\n\t"use-badge-color": false,\n\t"use-bold-color": false,\n\t"use-cursor-color": false,\n\t"use-highlight-color": false,\n\t"use-theme-colors": false\n}'
echo -e "${TILIXCOLORS}" > "${scratchdir}/${PROFILE_NAME}.json"
# Note: Tilix does not store color scheme name in dconf
# so we have to update color palette for the current profile in order to switch to the new theme
# but only set the palette on the last loop to avoid a flashing terminal
if ((LOOP == OPTLENGTH)); then
cp -f ${scratchdir}/* "$HOME/.config/tilix/schemes/"
rm -rf "${scratchdir}"
read -r -p "All done - apply new theme? [y/N] " -n 1 TILIX_RES
if [[ ${TILIX_RES::1} =~ ^(y|Y)$ ]]; then
PROFILE_KEY="${BASE_DIR}${DEFAULT_SLUG}"
PROFILE_NAME="$(${DCONF} read ${PROFILE_KEY}/visible-name | tr -d \')"
set_theme
dset palette "['${COLOR_01}', '${COLOR_02}', '${COLOR_03}', '${COLOR_04}', '${COLOR_05}', '${COLOR_06}', '${COLOR_07}', '${COLOR_08}', '${COLOR_09}', '${COLOR_10}', '${COLOR_11}', '${COLOR_12}', '${COLOR_13}', '${COLOR_14}', '${COLOR_15}', '${COLOR_16}']"
fi
fi
unset PROFILE_NAME
unset PROFILE_SLUG
unset TILIXCOLORS
exit 0
fi
}
apply_xfce4-terminal() {
# XFCE4 terminal has no profiles, instead it uses color presets
SCHEMEDIR="${HOME}/.local/share/xfce4/terminal/colorschemes"
CONFFILE="${HOME}/.config/xfce4/terminal/terminalrc"
if [[ ! (-w "${CONFFILE}") ]]; then
if [[ -r "${XDG_CONFIG_DIRS%%:*}/Terminal/terminalrc" ]]; then
cp "${XDG_CONFIG_DIRS%%:*}/Terminal/terminalrc" ${CONFFILE}
else
echo "ERROR: config file not present or not writable!"
exit 1
fi
fi
[[ -d "${SCHEMEDIR}" ]] || mkdir -p "${SCHEMEDIR}"
F_NAME=${PROFILE_NAME// /-}
F_NAME=$(echo ${F_NAME} | tr -d ":()")
F_NAME=$(echo "${F_NAME}" | awk '{print tolower($0)}')
FF_NAME="${SCHEMEDIR}/${F_NAME}.theme"
touch "${FF_NAME}"
L_COLORCURSOR="ColorCursor=${CURSOR_COLOR}"
L_COLORPALETTE="ColorPalette=${COLOR_01};${COLOR_02};${COLOR_03};${COLOR_04};${COLOR_05};${COLOR_06};${COLOR_07};${COLOR_08};${COLOR_09};${COLOR_10};${COLOR_11};${COLOR_12};${COLOR_13};${COLOR_14};${COLOR_15};${COLOR_16}"
printf '%s\n' \
"; Generated by Gogh" \
"; https://Gogh-Co.github.io/Gogh" \
"[Scheme]" \
"Name=${PROFILE_NAME}" \
"ColorForeground=${FOREGROUND_COLOR}" \
"ColorBackground=${BACKGROUND_COLOR}" \
"${L_COLORCURSOR}" \
"${L_COLORPALETTE}" \
"ColorCursorUseDefault=FALSE" > ${FF_NAME}
# apply last theme in queue
# xfce4-terminal monitors its rc file and doesn't reference
# any of the themes in there. The color settings need to
# be written there directly.
if ((LOOP == OPTLENGTH)); then
read -r -p "All done - apply new theme? [y/N] " -n 1 XFCE4_APPLY_CURR_THEME
if [[ ${XFCE4_APPLY_CURR_THEME::1} =~ ^(y|Y)$ ]]; then
if grep -q "^ColorPalette=" "${CONFFILE}"; then
sed -i -r -e "s/^ColorPalette=.*/${L_COLORPALETTE}/" "${CONFFILE}"
else
echo "${L_COLORPALETTE}" >> "${CONFFILE}"
fi
if grep -q "^ColorCursor=" "${CONFFILE}"; then
sed -i -r -e "s/^ColorCursor=.*/${L_COLORCURSOR}/" "${CONFFILE}"
else
echo "${L_COLORCURSOR}" >> "${CONFFILE}"
fi
if grep -q "^ColorForeground=" "${CONFFILE}"; then
sed -i -r -e "s/^ColorForeground=.*/ColorForeground=${FOREGROUND_COLOR}/" "${CONFFILE}"
else
echo "ColorForeground=${FOREGROUND_COLOR}" >> "${CONFFILE}"
fi
if grep -q "^ColorBackground=" "${CONFFILE}"; then
sed -i -r -e "s/^ColorBackground=.*/ColorBackground=${BACKGROUND_COLOR}/" "${CONFFILE}"
else
echo "ColorBackground=${BACKGROUND_COLOR}" >> "${CONFFILE}"
fi
if grep -q "^ColorCursorUseDefault=FALSE" "${CONFFILE}"; then
true
else
echo "ColorCursorUseDefault=FALSE" >> "${CONFFILE}"
fi
fi
fi
unset SCHEMEDIR
unset CONFFILE
unset PROFILE_NAME
unset F_NAME
unset FF_NAME
unset L_COLORCURSOR
unset L_COLORPALETTE
exit 0
}
[[ -n "${UUIDGEN}" ]] && PROFILE_SLUG="$(uuidgen)"
case "${TERMINAL}" in
pantheon-terminal|io.elementary.t* )
if [[ "${TERMINAL}" == "pantheon-terminal" ]]; then
PROFILE_KEY="org.pantheon.terminal.settings"
else
PROFILE_KEY="io.elementary.terminal.settings"
fi
apply_elementary
;;
iTerm.app )
apply_darwin
;;
mintty )
apply_cygwin
;;
guake )
if [[ -n "$(${DCONF} list /apps/guake/style/)" ]]; then
apply_guake
else
apply_guake legacy
fi
;;
gnome-terminal* )
if [[ -n "$(${DCONF} list /org/gnome/terminal/)" ]]; then
BASE_DIR="/org/gnome/terminal/legacy/profiles:/:"
PROFILE_LIST_KEY="${BASE_DIR%:}list"
PROFILE_SLUG="${PROFILE_SLUG}"
# Note -- ${BASE_DIR%s} is a workaround to avoid doing additional conditional testing for existing profiles
# if terminal is set to gnome-terminal
: ${DEFAULT_SLUG:="$(${DCONF} read ${BASE_DIR%:}default | tr -d \')"}
LEFT_WRAPPER="["
RIGHT_WRAPPER="]"
PALETTE_DELIM="', '"
apply_gtk
else
BASE_DIR="/apps/gnome-terminal/profiles/"
PROFILE_LIST_KEY="${BASE_DIR/profiles/global}profile_list"
LEGACY_BOLD=true
: ${DEFAULT_SLUG:="$(${GCONF} read ${BASE_DIR}default_profile)"}
apply_gtk legacy
fi
;;
mate-terminal )
BASE_DIR="/org/mate/terminal/profiles/"
PROFILE_LIST_KEY="${BASE_DIR/profiles/global}profile-list"
LEGACY_BOLD=true
: ${DEFAULT_SLUG:="$(${DCONF} read ${BASE_DIR/profiles/global}default-profile | tr -d \')"}
PALETTE_DELIM=":"
apply_gtk
;;
tilix )
BASE_DIR="/com/gexperts/Tilix/profiles/"
PROFILE_LIST_KEY="${BASE_DIR}list"
: ${DEFAULT_SLUG:="$(${DCONF} read ${BASE_DIR}default | tr -d \')"}
LEFT_WRAPPER="["
RIGHT_WRAPPER="]"
PALETTE_DELIM="', '"
appy_tilixschemes
apply_gtk
;;
xfce4-terminal )
apply_xfce4-terminal
;;
alacritty )
apply_alacritty
;;
foot )
apply_foot
;;
kitty )
apply_kitty
;;
konsole )
apply_konsole
;;
* )
printf '%s\n' \
"Unsupported terminal!" \
"" \
"Supported terminals:" \
" mintty and deriviates" \
" guake" \
" iTerm2" \
" elementary terminal (pantheon/elementary)" \
" mate-terminal" \
" gnome-terminal" \
" tilix" \
" xfce4-terminal" \
" foot" \
" kitty" \
" konsole" \
"" \
"If you believe you have received this message in error," \
"try manually setting \`TERMINAL', hint: ps -h -o comm -p \$PPID"
exit 1
;;
esac
unset PROFILE_NAME
unset PROFILE_SLUG
unset DEFAULT_SLUG