Browse Source

Improve style-gnome-terminal.sh.

Configurations are now parsed from very simple files, instead of
being defined inline in the script (however cleverly).

Config file and profile manipulation is now encapsulated in tiny
libraries. This should allow implementation of other subcommands
without too much effort.
main
Titouan Rigoudy 4 years ago
parent
commit
30fe1d6e14
3 changed files with 244 additions and 120 deletions
  1. +3
    -1
      README.md
  2. +220
    -119
      style-gnome-terminal.sh
  3. +21
    -0
      styles/gruvbox8.conf

+ 3
- 1
README.md View File

@ -39,8 +39,10 @@ $ ln -s ~/dotfiles/tmux.conf ~/.tmux.conf
## Configure gnome-terminal
Install the [Hack font](https://github.com/source-foundry/Hack).
Run the following command:
```sh
$ ~/dotfiles/style-gnome-terminal.sh gruvbox8
$ ~/dotfiles/style-gnome-terminal.sh styles/gruvbox8.conf
```

+ 220
- 119
style-gnome-terminal.sh View File

@ -3,106 +3,246 @@
set -eu
# CONSTANTS
# =========
# DConf directory in which gnome-terminal profile configuration is stored.
ROOT_DCONF_DIR='/org/gnome/terminal/legacy/profiles:/'
# ansi_colors COLOR1 ... COLOR16
function ansi_colors() {
echo -n "['$1'"
for i in {2..16}; do
echo -n ",'${!i}'"
# The names of ANSI color properties in config files.
# Order matters. These correspond to the ANSI color codes.
ANSI_COLOR_PROPERTIES=(
"ansi-colors-black"
"ansi-colors-red"
"ansi-colors-green"
"ansi-colors-yellow"
"ansi-colors-blue"
"ansi-colors-purple"
"ansi-colors-cyan"
"ansi-colors-white"
"ansi-colors-bright-black"
"ansi-colors-bright-red"
"ansi-colors-bright-green"
"ansi-colors-bright-yellow"
"ansi-colors-bright-blue"
"ansi-colors-bright-purple"
"ansi-colors-bright-cyan"
"ansi-colors-bright-white"
)
# LOGGING
# =======
# log ARGS...
# echo for stderr
function log() {
echo 1>&2 "$@"
}
# die ARGS...
# log then exit with an error code
function die() {
log "$@"
exit 1
}
# CONFIG
# ======
#
# Configuration files have a very basic grammar:
#
# PROPERTY_NAME = VALUE
#
# The functions below allow reading config file contents.
# config_get_property FILE PROPERTY
# Echoes the given property from the given config file.
function config_get_property() {
FILE="$1"
PROPERTY="$2"
sed -n "s:^${PROPERTY} *= *\(\.*\):\1:p" < "${FILE}"
}
# config_get_property_or_die FILE PROPERTY
# config_get_property, except dies if the property is not found.
function config_get_property_or_die() {
FILE="$1"
PROPERTY="$2"
RESULT=$(config_get_property "${FILE}" "${PROPERTY}")
if [ -z "$RESULT" ]; then
die "Error: cannot find property '${PROPERTY}' in file '${FILE}'."
fi
echo "${RESULT}"
}
# config_get_font FILE
function config_get_font() {
FILE="$1"
config_get_property "${FILE}" "font"
}
# config_get_foreground_color FILE
function config_get_foreground_color() {
FILE="$1"
config_get_property "${FILE}" "foreground-color"
}
# config_get_background_color FILE
function config_get_background_color() {
FILE="$1"
config_get_property "${FILE}" "background-color"
}
# join_ansi_colors COLOR1 ... COLOR16
# Echoes "[${COLOR1}, ..., ${COLOR16}]".
function join_ansi_colors () {
echo -n "[$1"
for i in {2..16}; do
echo -n ", ${!i}" # Get the i-th argument to this function.
done
echo "]"
}
# colorscheme NAME FG_COLOR BG_COLOR ANSI_COLORS
function colorscheme() {
NAME="$1"
FG_COLOR="$2"
BG_COLOR="$3"
ANSI_COLORS="$4"
# config_get_ansi_colors FILE
function config_get_ansi_colors() {
FILE="$1"
ANSI_COLORS=()
for PROPERTY in "${ANSI_COLOR_PROPERTIES[@]}"; do
COLOR=$(config_get_property_or_die "${FILE}" "${PROPERTY}")
ANSI_COLORS+=("${COLOR}")
done
echo "${NAME};${FG_COLOR};${BG_COLOR};${ANSI_COLORS}"
join_ansi_colors "${ANSI_COLORS[@]}"
}
function unpack_colorscheme_field(){
PACKED="$1"
FIELD="$2"
echo "${PACKED}" | cut -d ';' -f "${FIELD}"
# PROFILE
# =======
#
# Gnome-terminal profile preferences are read and written through dconf.
#
# In the following functions, profiles are referenced by their dconf directory
# paths (ending in a '/' character).
# profile_get_property PROFILE PROPERTY
# Echoes the given property from the given gnome-terminal profile.
function profile_get_property() {
PROFILE="$1"
PROPERTY="$2"
dconf read "${PROFILE}${PROPERTY}"
}
# colorscheme_name COLORSCHEME
function colorscheme_name() {
unpack_colorscheme_field "$1" 1
# profile_set_property PROFILE PROPERTY VALUE
# Sets the given profile's given property to the given value.
function profile_set_property() {
PROFILE="$1"
PROPERTY="$2"
VALUE="$3"
dconf write "${PROFILE}${PROPERTY}" "${VALUE}"
}
# colorscheme_fg_color COLORSCHEME
function colorscheme_fg_color() {
unpack_colorscheme_field "$1" 2
# profile_get_name PROFILE
# Echoes the human-readable name for the given gnome-terminal profile.
function profile_get_name() {
PROFILE="$1"
profile_get_property "${PROFILE}" "visible-name"
}
# colorscheme_bg_color COLORSCHEME
function colorscheme_bg_color() {
unpack_colorscheme_field "$1" 3
# profile_set_name PROFILE VALUE
# Sets the human-readable name for the given gnome-terminal profile.
function profile_set_name() {
PROFILE="$1"
VALUE="$2"
profile_set_property "${PROFILE}" "visible-name" "${VALUE}"
}
# colorscheme_ansi_colors COLORSCHEME
function colorscheme_ansi_colors() {
unpack_colorscheme_field "$1" 4
# profile_get_font PROFILE
# Echoes the font for the given gnome-terminal profile.
function profile_get_font() {
PROFILE="$1"
profile_get_property "${PROFILE}" "font"
}
GRUVBOX8_COLORSCHEME=$(colorscheme "gruvbox8" \
"#ebdbb2" \
"#1d2021" \
$(ansi_colors \
"#1d2021" \
"#cc241d" \
"#98971a" \
"#d79921" \
"#458588" \
"#b16286" \
"#689d6a" \
"#a89984" \
"#928374" \
"#fb4934" \
"#b8bb26" \
"#fabd2f" \
"#83a598" \
"#d3869b" \
"#8ec07c" \
"#ebdbb2"
)
)
# profile_set_font PROFILE VALUE
# Sets the font for the given gnome-terminal profile.
function profile_set_font() {
PROFILE="$1"
VALUE="$2"
profile_set_property "${PROFILE}" "font" "${VALUE}"
}
COLORSCHEMES=(
"${GRUVBOX8_COLORSCHEME}"
)
# profile_get_foreground_color PROFILE
# Echoes the foreground color for the given gnome-terminal profile.
function profile_get_foreground_color() {
PROFILE="$1"
profile_get_property "${PROFILE}" "foreground-color"
}
# log ARGS...
# echo for stderr
function log() {
echo 1>&2 "$@"
# profile_set_foreground_color PROFILE VALUE
# Sets the foreground color for the given gnome-terminal profile.
function profile_set_foreground_color() {
PROFILE="$1"
VALUE="$2"
profile_set_property "${PROFILE}" "foreground-color" "${VALUE}"
}
# die ARGS...
# log then exit with an error code
function die() {
log "$@"
exit 1
# profile_get_background_color PROFILE
# Echoes the background color for the given gnome-terminal profile.
function profile_get_background_color() {
PROFILE="$1"
profile_get_property "${PROFILE}" "background_color"
}
function get_profile_property() {
# profile_set_background_color PROFILE VALUE
# Sets the background color for the given gnome-terminal profile.
function profile_set_background_color() {
PROFILE="$1"
PROPERTY="$2"
VALUE="$2"
profile_set_property "${PROFILE}" "background-color" "${VALUE}"
}
dconf read "${PROFILE}${PROPERTY}"
# profile_get_ansi_colors PROFILE
# Echoes the ANSI color palette for the given gnome-terminal profile.
function profile_get_ansi_colors() {
PROFILE="$1"
profile_get_property "${PROFILE}" "palette"
}
# get_profile_name PROFILE
# Echoes the human-readable name for a gnome-terminal profile subdirectory.
function get_profile_name() {
get_profile_property "$1" "visible-name"
# profile_set_ansi_colors PROFILE VALUE
# Sets the ANSI color palette for the given gnome-terminal profile.
function profile_set_ansi_colors() {
PROFILE="$1"
VALUE="$2"
profile_set_property "${PROFILE}" "palette" "${VALUE}"
}
# profile_apply_config PROFILE CONFIG_FILE
# Applies the given configuration to the given gnome-terminal profile.
function profile_apply_config() {
PROFILE="$1"
CONFIG_FILE="$2"
FONT=$(config_get_font "${CONFIG_FILE}")
FOREGROUND_COLOR=$(config_get_foreground_color "${CONFIG_FILE}")
BACKGROUND_COLOR=$(config_get_background_color "${CONFIG_FILE}")
ANSI_COLORS=$(config_get_ansi_colors "${CONFIG_FILE}")
profile_set_font "${PROFILE}" "${FONT}"
profile_set_foreground_color "${PROFILE}" "${FOREGROUND_COLOR}"
profile_set_background_color "${PROFILE}" "${BACKGROUND_COLOR}"
profile_set_ansi_colors "${PROFILE}" "${ANSI_COLORS}"
}
# INTERACTIVE USE
# ===============
# choose_number BASE_PROMPT MIN MAX
# Asks the user to choose a number between MIN and MAX, inclusive.
# BASE_PROMPT should not end in a newline.
@ -110,6 +250,7 @@ function choose_number() {
PROMPT="$1"
MIN_NUMBER="$2"
MAX_NUMBER="$3"
while true; do
read -p "$1 [${MIN_NUMBER} to ${MAX_NUMBER}]: " CHOSEN_NUMBER
if [ "${CHOSEN_NUMBER}" -lt "${MIN_NUMBER}" ]; then
@ -133,81 +274,42 @@ function choose_profile() {
PROFILES+=("${ROOT_DCONF_DIR}${PROFILE_SUBDIR}")
done
NUM_PROFILES="${#PROFILES[@]}"
if [ "${NUM_PROFILES}" -eq 0 ]; then
die "Error: found no gnome-terminal profiles to style."
fi
if [ "${NUM_PROFILES}" -eq 1 ]; then
PROFILE="${PROFILES[0]}"
PROFILE_NAME=$(get_profile_name "${PROFILE}")
PROFILE_NAME=$(profile_get_name "${PROFILE}")
log "Found single gnome-terminal profile ${PROFILE_NAME}, using it."
echo "${PROFILE}"
return
fi
log "Available gnome-terminal profiles:"
for i in $(seq 1 "${NUM_PROFILES}"); do
PROFILE="${PROFILES[$(($i - 1))]}"
PROFILE_NAME=$(get_profile_name "${PROFILE}")
PROFILE_NAME=$(profile_get_name "${PROFILE}")
log " #$i: ${PROFILE_NAME}"
done
choose_number "Choose a profile" 1 "${NUM_PROFILES}"
}
# find_colorscheme COLORSCHEME_NAME
# Echoes the colorscheme if it exists.
# Dies otherwise with a useful message.
function find_colorscheme() {
COLORSCHEME_NAME="$1"
NAMES=()
for COLORSCHEME in "${COLORSCHEMES[@]}"; do
NAME=$(colorscheme_name ${COLORSCHEME})
NAMES+=("${NAME}")
if [ "${NAME,,}" == "${NAME,,}" ]; then
echo "${COLORSCHEME}"
return
fi
done
log "Error: no such colorscheme '${COLORSCHEME_NAME}'. Options are:"
for NAME in "${NAMES[@]}"; do
log " - ${NAME}"
done
exit 1
}
# apply_colorscheme PROFILE COLORSCHEME
# Applies the given packed colorscheme to the given gnome-terminal profile.
function apply_colorscheme() {
PROFILE="$1"
COLORSCHEME="$2"
FG_COLOR=$(colorscheme_fg_color "${COLORSCHEME}")
BG_COLOR=$(colorscheme_bg_color "${COLORSCHEME}")
ANSI_COLORS=$(colorscheme_ansi_colors "${COLORSCHEME}")
dconf write "${PROFILE}foreground-color" "'${FG_COLOR}'"
dconf write "${PROFILE}background-color" "'${BG_COLOR}'"
dconf write "${PROFILE}palette" "${ANSI_COLORS}"
}
function main() {
if [ "$#" -le 0 ]; then
die "USAGE: style-gnome-terminal COLORSCHEME_NAME"
die "USAGE: style-gnome-terminal CONFIG_FILE"
fi
# TODO: Subcommands:
#
#
# Profiles:
#
#
# - profile list
# - profile show NAME_OR_ID
#
#
# Styling:
#
# These all take an optional [profile NAME_OR_ID] clause to specify a profile
@ -233,10 +335,9 @@ function main() {
# arbitrary code (rules our source-ing .sh files containing variables), that
# does not require onerous dependencies to parse.
COLORSCHEME_NAME="$1"
COLORSCHEME=$(find_colorscheme "${COLORSCHEME_NAME}")
CONFIG_FILE="$1"
PROFILE=$(choose_profile)
apply_colorscheme "${PROFILE}" "${COLORSCHEME}"
profile_apply_config "${PROFILE}" "${CONFIG_FILE}"
}
main "$@"

+ 21
- 0
styles/gruvbox8.conf View File

@ -0,0 +1,21 @@
font = "Hack Regular 12"
foreground-color = "#ebdbb2"
background-color = "#1d2021"
ansi-colors-black = "#1d2021"
ansi-colors-red = "#cc241d"
ansi-colors-green = "#98971a"
ansi-colors-yellow = "#d79921"
ansi-colors-blue = "#458588"
ansi-colors-purple = "#b16286"
ansi-colors-cyan = "#689d6a"
ansi-colors-white = "#a89984"
ansi-colors-bright-black = "#928374"
ansi-colors-bright-red = "#fb4934"
ansi-colors-bright-green = "#b8bb26"
ansi-colors-bright-yellow = "#fabd2f"
ansi-colors-bright-blue = "#83a598"
ansi-colors-bright-purple = "#d3869b"
ansi-colors-bright-cyan = "#8ec07c"
ansi-colors-bright-white = "#ebdbb2"

Loading…
Cancel
Save