diff --git a/CHANGELOG.md b/CHANGELOG.md index c94c9ff..5540452 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Added editorconfig - Added code linters for shellcheck & shfmt [#33](https://github.com/egel/tmux-gruvbox/issues/33) - Added tests (for linux) [#39](https://github.com/egel/tmux-gruvbox/issues/39) +- Added customizable statusbar [#31](https://github.com/egel/tmux-gruvbox/issues/31) ### Changed diff --git a/README.md b/README.md index ff5426d..eb2da52 100644 --- a/README.md +++ b/README.md @@ -25,60 +25,126 @@ Theme with 'retro groove' flavor for [Tmux][github-tmux], based on Pavel Pertsev ## Installation -**Available Themes** +### Install via [TPM][github-tpm] (recommended) -- [`dark`](./docs/assets/img/gruvbox-dark-theme.png) -- [`light`](./docs/assets/img/gruvbox-light-theme.png) -- `dark-transparent` (experimental) -- `light-transparent` (experimental) +Add plugin at the top list of TPM plugins in `.tmux.conf` and select desired theme. + +```bash +# ~/.tmux.conf +set -g @plugin 'egel/tmux-gruvbox' +# set desired options... +set -g @tmux-gruvbox 'dark' # or 'light' +``` + +Hit `prefix + I` to fetch the plugin and source it. Your Tmux should be updated with the theme at this point. ### Install manually -The simplest way is just: +1. Clone the project to desired location + + > ![TIP] If you do not have github account [download](https://github.com/egel/tmux-gruvbox/archive/refs/heads/main.zip) it and unzip. + + ```bash + cd ~/projects/ + git clone ... + ``` -> [!TIP] -> Always make a backup of your config files before any action. +1. Add theme at to top of your `~/.tmux.conf` config. + + ```bash + # ~/.tmux.conf + run ~/projects/tmux-gruvbox/tmux-gruvbox.tmux + # set desired options... + set -g @tmux-gruvbox 'dark' # or light + ``` + +## Configuration options + +### Theme + +- default value: `dark256` +- available themes: + - [`dark256`](./docs/assets/img/gruvbox-dark-theme.png) + - [`light256`](./docs/assets/img/gruvbox-light-theme.png) ```bash -cat tmux-gruvbox-dark.conf >> ~/.tmux.conf +set -g @tmux-gruvbox 'dark256' ``` -### Install through [Tmux Plugin Manager](https://github.com/tmux-plugins/tpm) +### Transparent status-bar -Add plugin to the list of TPM plugins in `.tmux.conf` and select desired theme. +- default value: `'false'` +- tmux >= 3.2 (experimental) ```bash -set -g @plugin 'egel/tmux-gruvbox' -set -g @tmux-gruvbox 'dark' # or 'light', 'dark-transparent', 'light-transparent' +set -g @tmux-gruvbox-statusbar-alpha 'true' ``` -Hit `prefix + I` to fetch the plugin and source it. Your Tmux should be updated with the theme at this point. +### Left Status (Section A) + +- default value: `'#S'` + +```bash +set -g @tmux-gruvbox-left-status-a +``` + +### Right Status (Section X) + +- default value: `'%Y-%m-%d'` + +This section is customizable for user, and by default contains current date. + +```bash +set -g @tmux-gruvbox-right-status-x +``` + +### Right Status (Section Y) + +- default value: `'%H:%M'` + +This section is customizable for user, and by default contains current time. + +```bash +# set different time format +set -g @tmux-gruvbox-right-status-y '%H:%M' +``` + +### Right Status (Section Z) + +- default value: `'#h'` + +This section is customizable for user, and by default contains hostname. + +```bash +# enhance this section with other plugin +set -g @tmux-gruvbox-right-status-z '#h #{tmux_mode_indicator} ' +``` ## Development To run project locally: -1. clone the repo to desired place +1. clone the repository to desired place ```bash cd $HOME/projects/ git clone ... ``` -1. create symlink in plugin dir to the cloned repo: +1. create a symlink to the cloned repository (best in the standard [TPM][github-tpm] plugin directory): ```bash # cd to tmux plugin directory cd ~/.tmux/plugins/ - # create simlink to cloned repo + # create symlink to cloned repo ln -sf $HOME/projects/tmux-gruvbox/ tmux-gruvbox ``` 1. and in `~/.tmux.conf` set ```bash - # add plugin + # ~/.tmux.conf set -g @plugin 'egel/tmux-gruvbox' # set desired options... set -g @tmux-gruvbox 'dark' @@ -101,6 +167,7 @@ GPLv3 - Maciej Sypień [github-hack]: https://github.com/chrissimpkins/Hack [github-nerd-fonts]: https://github.com/ryanoasis/nerd-fonts [github-alacritty]: https://github.com/alacritty/alacritty +[github-tpm]: https://github.com/tmux-plugins/tpm [tmux-color-solarized]: https://github.com/seebi/tmux-colors-solarized [pexcel-1]: https://www.pexels.com/photo/urban-photo-of-an-alley-2411688/ [pexcel-2]: https://www.pexels.com/photo/lights-hanging-above-the-alley-in-a-city-at-night-27044195/ diff --git a/src/gruvbox-main.sh b/src/gruvbox-main.sh index 0773393..7bb1c20 100755 --- a/src/gruvbox-main.sh +++ b/src/gruvbox-main.sh @@ -5,37 +5,79 @@ readonly CURRENT_DIR readonly THEME_OPTION="@tmux-gruvbox" readonly DEFAULT_THEME="dark" -get_theme() { - local option="$1" - local default_value="$2" - local option_value - option_value=$(tmux show-option -gqv "$option") - if [ -z "$option_value" ]; then - echo "$default_value" - else - echo "$option_value" - fi -} +# hold the array of all command to configure tmux theme +declate -a TMUX_CMDS + +# load libraries +# shellcheck disable=1091 +source "${CURRENT_DIR}/src/helper_methods.sh" +# shellcheck disable=1091 +source "${CURRENT_DIR}/src/tmux_utils.sh" + +readonly TMUX_GRUVBOX="@tmux-gruvbox" +readonly TMUX_GRUVBOX_STATUSBAR_ALPHA="@tmux-gruvbox-statusbar-alpha" +readonly TMUX_GRUVBOX_LEFT_STATUS_A="@tmux-gruvbox-left-status-a" +readonly TMUX_GRUVBOX_RIGHT_STAUTS_X="@tmux-gruvbox-right-status-x" +readonly TMUX_GRUVBOX_RIGHT_STAUTS_Y="@tmux-gruvbox-right-status-y" +readonly TMUX_GRUVBOX_RIGHT_STAUTS_Z="@tmux-gruvbox-right-status-z" + +# define simple theme options (no color interpolation required) +DEFAULT_THEME="dark" +DEFAULT_STATUSBAR_ALPHA=false +# defaults for theme option (with color interpolation) +DEFAULT_LEFT_STATUS_A='#S' +DEFAULT_RIGHT_STATUS_X='%Y-%m-%d' +DEFAULT_RIGHT_STATUS_Y='%H:%M' +DEFAULT_RIGHT_STATUS_Z='#h' main() { - local _theme _path - _theme=$(get_theme "$THEME_OPTION" "$DEFAULT_THEME") + TMUX_CMDS=() # clear + + # load proper palette for the theme asap to avoid additional variable interpolation + local _theme + _theme=$(tmux_get_option "${TMUX_GRUVBOX}" "${DEFAULT_THEME}") + _statusbar_alpha=$(tmux_get_option "${TMUX_GRUVBOX_STATUSBAR_ALPHA}" "${DEFAULT_STATUSBAR_ALPHA}") + case "$_theme" in - light-transparent) - _theme="light-transparent" + light | light256) + # shellcheck disable=1091 + source "${CURRENT_DIR}/src/palette_gruvbox_light256.sh" + # shellcheck disable=1091 + source "${CURRENT_DIR}/src/theme_gruvbox_light.sh" ;; - dark-transparent) - _theme="dark-transparent" + dark | dark256 | *) + # shellcheck disable=1091 + source "${CURRENT_DIR}/src/palette_gruvbox_dark256.sh" + # shellcheck disable=1091 + source "${CURRENT_DIR}/src/theme_gruvbox_dark.sh" ;; + esac + + local _status_left _status_right _window_status_current_format _window_status_format + _status_left_a=$(tmux_get_option "$TMUX_GRUVBOX_LEFT_STATUS_A" "$DEFAULT_LEFT_STATUS_A") + _status_right_x=$(tmux_get_option "$TMUX_GRUVBOX_RIGHT_STAUTS_X" "$DEFAULT_RIGHT_STATUS_X") + _status_right_y=$(tmux_get_option "$TMUX_GRUVBOX_RIGHT_STAUTS_Y" "$DEFAULT_RIGHT_STATUS_Y") + _status_right_z=$(tmux_get_option "$TMUX_GRUVBOX_RIGHT_STAUTS_Z" "$DEFAULT_RIGHT_STATUS_Z") + + theme_args=( + "$_status_left_a" + "$_status_right_x" + "$_status_right_y" + "$_status_right_z" + "$_statusbar_alpha" + ) + + case $_theme in light | light256) - _theme="light" + theme_set_light "${theme_args[@]}" ;; dark | dark256 | *) - _theme="dark" + theme_set_dark "${theme_args[@]}" ;; esac - tmux source-file "${CURRENT_DIR}/tmux-gruvbox-${_theme}.conf" + # execute commands with tmux as array of options + tmux "${TMUX_CMDS[@]}" } main "$@" diff --git a/src/helper_methods.sh b/src/helper_methods.sh new file mode 100644 index 0000000..175a5a3 --- /dev/null +++ b/src/helper_methods.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +# simply print passed array +# +# example +# +# myarray=() +# print_array myarray +# +print_array() { + local -n arr # -n available over bash 4.3 + arr=$1 + + echo "" + echo "begin >>>" + printf "%s\n" "${arr[@]}" + echo "<<< end" + echo "" +} diff --git a/src/palette_gruvbox_dark256.sh b/src/palette_gruvbox_dark256.sh new file mode 100644 index 0000000..5470ee8 --- /dev/null +++ b/src/palette_gruvbox_dark256.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +########################## +# gruvbox dark pallete +########################## + +#### +# When using 'colour124' you are using the color default in terminal pallete. +# This could be important for people which terminals support only 256 colors +# and does not support HEX values. +# +# The names of colors used from https://github.com/morhetz/gruvbox + +# shellcheck disable=2034 # ignored as this file only contains var definitions +col_bg=colour235 +col_bg0_h=colour234 +col_bg0=colour235 +col_bg1=colour237 +col_bg2=colour239 +col_bg3=colour241 +col_bg4=colour243 +col_gray0=colour246 +col_gray1=colour245 +col_gray2=colour245 +col_bg0_s=colour236 +col_fg=colour223 +col_fg4=colour246 +col_fg3=colour248 +col_fg2=colour250 +col_fg1=colour223 +col_fg0=colour229 + +col_red=colour124 +col_red2=colour167 +col_green=colour106 +col_green2=colour142 +col_yellow=colour172 +col_yellow2=colour214 +col_blue=colour66 +col_blue2=colour109 +col_purple=colour132 +col_purple2=colour175 +col_aqua=colour72 +col_aqua2=colour108 +col_orange=colour166 +col_orange2=colour208 diff --git a/src/palette_gruvbox_light256.sh b/src/palette_gruvbox_light256.sh new file mode 100644 index 0000000..3949472 --- /dev/null +++ b/src/palette_gruvbox_light256.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +########################## +# gruvbox dark pallete +########################## + +#### +# When using 'colour124' you are using the color default in terminal pallete. +# This could be important for people which terminals support only 256 colors +# and does not support HEX values. +# +# The names of colors used from https://github.com/morhetz/gruvbox + +# shellcheck disable=2034 # ignored as this file only contains var definitions +col_bg=colour229 +col_bg0_h=colour230 +col_bg0=colour229 +col_bg1=colour223 +col_bg2=colour250 +col_bg3=colour248 +col_bg4=colour246 +col_gray0=colour246 +col_gray1=colour245 +col_gray2=colour244 +col_bg0_s=colour228 +col_fg=colour223 +col_fg4=colour243 +col_fg3=colour241 +col_fg2=colour239 +col_fg1=colour237 +col_fg0=colour235 + +col_red=colour124 +col_red2=colour88 +col_green=colour106 +col_green2=colour100 +col_yellow=colour172 +col_yellow2=colour136 +col_blue=colour66 +col_blue2=colour24 +col_purple=colour132 +col_purple2=colour96 +col_aqua=colour72 +col_aqua2=colour66 +col_orange=colour166 +col_orange2=colour130 diff --git a/src/theme_gruvbox_dark.sh b/src/theme_gruvbox_dark.sh new file mode 100644 index 0000000..3ee9e88 --- /dev/null +++ b/src/theme_gruvbox_dark.sh @@ -0,0 +1,79 @@ +#!/bin/bash + +# Themes may use different colors in sets therefore we setup dark and light +# separately. +# +# shellcheck disable=SC2154 +theme_set_dark() { + local _left_status_a _right_status_x _right_status_y _right_status_z _statusbar_alpha + _left_status_a=$1 + _right_status_x=$2 + _right_status_y=$3 + _right_status_z=$4 + _statusbar_alpha=$5 + + tmux_append_seto "status" "on" + + # default statusbar bg color + local _statusbar_bg="${col_bg1}" + if [[ "$_statusbar_alpha" == "true" ]]; then _statusbar_bg="default"; fi + tmux_append_seto "status-style" "bg=${_statusbar_bg},fg=${col_fg1}" + + # default window title colors + local _window_title_bg=${col_yellow2} + if [[ "$_statusbar_alpha" == "true" ]]; then _window_title_bg="default"; fi + tmux_append_setwo "window-status-style" "bg=${_window_title_bg},fg=${col_bg1}" + + # default window with an activity alert + tmux_append_setwo "window-status-activity-style" "bg=${col_bg1},fg=${col_fg3}" + + # active window title colors + local active_window_title_bg=${col_yellow2} + if [[ "$_statusbar_alpha" == "true" ]]; then active_window_title_bg="default"; fi + tmux_append_setwo "window-status-current-style" "bg=${active_window_title_bg},fg=${col_bg1}" # TODO cosider removing red! + + # pane border + tmux_append_seto "pane-active-border-style" "fg=${col_fg2}" + tmux_append_seto "pane-border-style" "fg=${col_bg1}" + + # message infos + tmux_append_seto "message-style" "bg=${col_bg2},fg=${col_fg1}" + + # writing commands inactive + tmux_append_seto "message-command-style" "bg=${col_fg3},fg=${col_bg1}" + + # pane number display + tmux_append_seto "display-panes-active-colour" "${col_fg2}" + tmux_append_seto "display-panes-colour" "${col_bg1}" + + # clock + tmux_append_setwo "clock-mode-colour" "${col_blue2}" + + # bell + tmux_append_setwo "window-status-bell-style" "bg=${col_red2},fg=${col_bg}" + + ## Theme settings mixed with colors (unfortunately, but there is no cleaner way) + tmux_append_seto "status-justify" "left" + tmux_append_seto "status-left-style" none + tmux_append_seto "status-left-length" "80" + tmux_append_seto "status-right-style" none + tmux_append_seto "status-right-length" "80" + tmux_append_setwo "window-status-separator" "" + + tmux_append_seto "status-left" "#[bg=${col_bg3},fg=${col_fg3}] ${_left_status_a} #[bg=${col_bg1},fg=${col_bg3},nobold,noitalics,nounderscore]" + + # right status + local _status_right_bg=${col_bg1} + if [[ "$_statusbar_alpha" == "true" ]]; then _status_right_bg="default"; fi + tmux_append_seto "status-right" "#[bg=${_status_right_bg},fg=${col_bg2},nobold,nounderscore,noitalics]#[bg=${col_bg2},fg=${col_fg4}] ${_right_status_x}  ${_right_status_y} #[bg=${col_bg2},fg=${col_fg3},nobold,noitalics,nounderscore]#[bg=${col_fg3},fg=${col_bg1}] ${_right_status_z}" + + # current window + local _current_window_status_format_bg=${col_bg1} + if [[ "$_statusbar_alpha" == "true" ]]; then _current_window_status_format_bg="default"; fi + tmux_append_setwo "window-status-current-format" "#[bg=${col_yellow2},fg=${col_bg1},nobold,noitalics,nounderscore]#[bg=${col_yellow2},fg=${col_bg2}] #I #[bg=${col_yellow2},fg=${col_bg2},bold] #W#{?window_zoomed_flag,*Z,} #{?window_end_flag,#[bg=${_current_window_status_format_bg}],#[bg=${col_bg1}]}#[fg=${col_yellow2},nobold,noitalics,nounderscore]" + + # default window + local _default_window_status_format_bg=${col_bg1} + if [[ "$_statusbar_alpha" == "true" ]]; then _default_window_status_format_bg="default"; fi + tmux_append_setwo "window-status-format" "#[bg=${col_bg2},fg=${col_bg1},noitalics]#[bg=${col_bg2},fg=${col_fg1}] #I #[bg=${col_bg2},fg=${col_fg1}] #W #{?window_end_flag,#[bg=${_default_window_status_format_bg}],#[bg=${col_bg1}]}#[fg=${col_bg2},noitalics]" +} diff --git a/src/theme_gruvbox_light.sh b/src/theme_gruvbox_light.sh new file mode 100644 index 0000000..f5c21fd --- /dev/null +++ b/src/theme_gruvbox_light.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +# Themes may use different colors in sets therefore we setup dark and light +# separately. +# +# shellcheck disable=SC2154 +theme_set_light() { + local _left_status_value _right_status_value _window_status_current_format _window_status_format + _left_status_a=$1 + _right_status_x=$2 + _right_status_y=$3 + _right_status_z=$4 + + tmux_append_seto "status" "on" + + # default statusbar color + tmux_append_seto "status-style" "bg=${col_bg1},fg=${col_fg1}" + + # default window title colors + tmux_append_setwo "window-status-style" "bg=${col_yellow2},fg=${col_bg1}" + + # default window with an activity alert + tmux_append_setwo "window-status-activity-style" "bg=${col_bg1},fg=${col_fg3}" + + # active window title colors + tmux_append_setwo "window-status-current-style" "bg=default,fg=${col_bg1}" # TODO cosider removing red! + + # pane border + tmux_append_seto "pane-active-border-style" "fg=${col_fg2}" + tmux_append_seto "pane-border-style" "fg=${col_bg1}" + + # message infos + tmux_append_seto "message-style" "bg=${col_bg2},fg=${col_fg1}" + + # writing commands inactive + tmux_append_seto "message-command-style" "bg=${col_fg3},fg=${col_bg1}" + + # pane number display + tmux_append_seto "display-panes-active-colour" "${col_fg2}" + tmux_append_seto "display-panes-colour" "${col_bg1}" + + # clock + tmux_append_setwo "clock-mode-colour" "${col_blue2}" + + # bell + tmux_append_setwo "window-status-bell-style" "bg=${col_red2},fg=${col_bg}" + + ## Theme settings mixed with colors (unfortunately, but there is no cleaner way) + tmux_append_seto "status-justify" "left" + tmux_append_seto "status-left-style" none + tmux_append_seto "status-left-length" "80" + tmux_append_seto "status-right-style" none + tmux_append_seto "status-right-length" "80" + tmux_append_setwo "window-status-separator" "" + + tmux_append_seto "status-left" "#[bg=${col_bg3},fg=${col_fg3}] ${_left_status_a} #[bg=${col_bg1},fg=${col_bg3},nobold,noitalics,nounderscore]" + tmux_append_seto "status-right" "#[bg=${col_bg1},fg=${col_bg2},nobold,nounderscore,noitalics]#[bg=${col_bg2},fg=${col_fg4}] ${_right_status_x}  ${_right_status_y} #[bg=${col_bg2},fg=${col_fg3},nobold,noitalics,nounderscore]#[bg=${col_fg3},fg=${col_bg1}] ${_right_status_z}" + + tmux_append_setwo "window-status-current-format" "#[bg=${col_yellow2},fg=${col_bg1},nobold,noitalics,nounderscore]#[bg=${col_yellow2},fg=${col_bg2}] #I #[bg=${col_yellow2},fg=${col_bg2},bold] #W#{?window_zoomed_flag,*Z,} #[bg=${col_bg1},fg=${col_yellow2},nobold,noitalics,nounderscore]" + tmux_append_setwo "window-status-format" "#[bg=${col_bg2},fg=${col_bg1},noitalics]#[bg=${col_bg2},fg=${col_fg1}] #I #[bg=${col_bg2},fg=${col_fg1}] #W #[bg=${col_bg1},fg=${col_bg2},noitalics]" +} diff --git a/src/tmux-gruvbox-dark.conf b/src/tmux-gruvbox-dark.conf index 8d86699..93700c5 100644 --- a/src/tmux-gruvbox-dark.conf +++ b/src/tmux-gruvbox-dark.conf @@ -42,7 +42,7 @@ set-option -g status-right-length "80" set-window-option -g window-status-separator "" set-option -g status-left "#[bg=colour241,fg=colour248] #S #[bg=colour237,fg=colour241,nobold,noitalics,nounderscore]" -set-option -g status-right "#[bg=colour237,fg=colour239 nobold, nounderscore, noitalics]#[bg=colour239,fg=colour246] %Y-%m-%d  %H:%M #[bg=colour239,fg=colour248,nobold,noitalics,nounderscore]#[bg=colour248,fg=colour237] #h " +set-option -g status-right "#[bg=colour237,fg=colour239 nobold, nounderscore, noitalics]#[bg=colour239,fg=colour246] %Y-%m-%d  %H:%M #[bg=colour239,fg=colour248,nobold,noitalics,nounderscore]#[bg=colour248,fg=colour237] #h #{tmux_mode_indicator}" set-window-option -g window-status-current-format "#[bg=colour214,fg=colour237,nobold,noitalics,nounderscore]#[bg=colour214,fg=colour239] #I #[bg=colour214,fg=colour239,bold] #W#{?window_zoomed_flag,*Z,} #[bg=colour237,fg=colour214,nobold,noitalics,nounderscore]" set-window-option -g window-status-format "#[bg=colour239,fg=colour237,noitalics]#[bg=colour239,fg=colour223] #I #[bg=colour239,fg=colour223] #W #[bg=colour237,fg=colour239,noitalics]" diff --git a/src/tmux_utils.sh b/src/tmux_utils.sh new file mode 100644 index 0000000..cc235b3 --- /dev/null +++ b/src/tmux_utils.sh @@ -0,0 +1,78 @@ +#!/bin/bash + +# get desired option from tmux or default +tmux_get_option_or_default() { + local _option_name _default_value + _option_name="$1" + _default_value="$2" + + local _current_option_value + _current_option_value=$(tmux show-option -gqv "$_option_name") + if [[ -n "$_current_option_value" ]]; then + echo "$_current_option_value" + else + echo "$_default_value" + fi +} + +# get desired tmux option or use given default value +tmux_get_option() { + local _option_name _default_value + _option_name="$1" + _default_value="$2" + + local _current_option_value + _current_option_value=$(tmux show-option -gqv "$_option_name") + if [[ -n "$_current_option_value" ]]; then + echo "$_current_option_value" + else + echo "$_default_value" + fi +} + +# get desired window-option from tmux or default +tmux_get_window_option() { + local _option_name _default_value + _option_name="$1" + _default_value="$2" + + local _current_option_value + _current_option_value=$(tmux show-window-option -gqv "$_option_name") + if [[ -n "$_current_option_value" ]]; then + echo "$_current_option_value" + else + echo "$_default_value" + fi +} + +# append preconfigured tmux set-option to global array +tmux_append_seto() { + local _option _value _result + _option="$1" + _value="$2" + TMUX_CMDS+=("set-option" "-gq" "${_option}" "${_value}" ";") +} + +# append preconfigured tmux set-window-option to global array +tmux_append_setwo() { + local _option _value _result + _option="$1" + _value="$2" + TMUX_CMDS+=("set-window-option" "-gq" "${_option}" "${_value}" ";") +} + +# imediately execute tmux option +tmux_set_option_now() { + local _option_name _value + _option_name="$1" + _value="$2" + tmux set-option -gq "$_option_name" "$_value" +} + +# imediately execute tmux option +tmux_set_window_option_now() { + local _option_name _value + _option_name="$1" + _value="$2" + tmux set-window-option -gq "$_option_name" "$_value" +}