feat: add customizable statusbar (#31)

* feat: define dark and light color palettes

* feat: add customization of status-right & status-left sections

* feat: rename to gruvbox_dark256 and implement alpha option

* fix: transparency for tabs in left status bar

* fix: shellcheck errors

* fix: files according to shfmt

* feat: remove unnecessary modeline

* feat: save palettes as 256 color

* feat: update information about dark256 & light256 themes

* chore: add changelog entry
This commit is contained in:
Maciej Sypien 2024-09-16 00:43:06 +02:00 committed by Maciej Sypien
parent f01574b318
commit 4f8b69ab8b
No known key found for this signature in database
GPG key ID: 10BC01EDA6827DC8
10 changed files with 487 additions and 48 deletions

View file

@ -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

117
README.md
View file

@ -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)
### Install manually
The simplest way is just:
> [!TIP]
> Always make a backup of your config files before any action.
```bash
cat tmux-gruvbox-dark.conf >> ~/.tmux.conf
```
### Install through [Tmux Plugin Manager](https://github.com/tmux-plugins/tpm)
Add plugin to the list of TPM plugins in `.tmux.conf` and select desired theme.
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 -g @tmux-gruvbox 'dark' # or 'light', 'dark-transparent', 'light-transparent'
# 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
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 ...
```
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
set -g @tmux-gruvbox 'dark256'
```
### Transparent status-bar
- default value: `'false'`
- tmux >= 3.2 (experimental)
```bash
set -g @tmux-gruvbox-statusbar-alpha 'true'
```
### 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/

View file

@ -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"
;;
dark-transparent)
_theme="dark-transparent"
;;
light | light256)
_theme="light"
# shellcheck disable=1091
source "${CURRENT_DIR}/src/palette_gruvbox_light256.sh"
# shellcheck disable=1091
source "${CURRENT_DIR}/src/theme_gruvbox_light.sh"
;;
dark | dark256 | *)
_theme="dark"
# shellcheck disable=1091
source "${CURRENT_DIR}/src/palette_gruvbox_dark256.sh"
# shellcheck disable=1091
source "${CURRENT_DIR}/src/theme_gruvbox_dark.sh"
;;
esac
tmux source-file "${CURRENT_DIR}/tmux-gruvbox-${_theme}.conf"
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_set_light "${theme_args[@]}"
;;
dark | dark256 | *)
theme_set_dark "${theme_args[@]}"
;;
esac
# execute commands with tmux as array of options
tmux "${TMUX_CMDS[@]}"
}
main "$@"

19
src/helper_methods.sh Normal file
View file

@ -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 ""
}

View file

@ -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

View file

@ -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

79
src/theme_gruvbox_dark.sh Normal file
View file

@ -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]"
}

View file

@ -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]"
}

View file

@ -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]"

78
src/tmux_utils.sh Normal file
View file

@ -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"
}