Skip to content

Commit

Permalink
Make themes user-customizable (jimeh#30)
Browse files Browse the repository at this point in the history
Make themes user-customizable
  • Loading branch information
jimeh authored Dec 22, 2019
2 parents 7fc71ae + c7d7a17 commit bb24b39
Show file tree
Hide file tree
Showing 90 changed files with 4,638 additions and 1,835 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,6 @@ jobs:
./configure && make && sudo make install
cd ..
- name: Run all tests
env:
TMUX_VERSION: ${{ matrix.tmux_version }}
run: make test
28 changes: 25 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,31 @@
default: test
BUILDER := bin/build-theme
THEME_SRC := $(shell find src -name '*.tmuxtheme')
INCLUDES := $(shell find src -name '*.tmuxsh')
THEMES := $(patsubst src/%,%,$(THEME_SRC))
TESTS := $(addsuffix .test,$(THEMES))

.PHONY: build
build: $(THEMES)

.PHONY: clean
clean:
rm $(shell find * -name "*.tmuxtheme" -not -path "src/*")

.PHONY: lint
lint:
cd test && golangci-lint run -v

.PHONY: test
test:
cd test && go test -v
test: needs-build
cd test && go test -count=1 -v ./...

.PHONY: needs-build
needs-build:
$(foreach file,$(THEMES), \
$(BUILDER) "src/$(file)" | diff -q "$(file)" - && \
) true

$(THEMES): %.tmuxtheme: src/%.tmuxtheme $(INCLUDES)
$(BUILDER) "src/$@" "$@"

$(TESTS): %.test: src/%.test
29 changes: 17 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# Tmux Themepack

A pack of various themes for Tmux.

A pack of various themes for Tmux for 2.6 or later.

## Installation

Expand Down Expand Up @@ -177,23 +176,29 @@ left side.

![powerline-double-yellow](https://github.com/jimeh/tmux-themepack-previews/raw/1.0.0/powerline/double/yellow-preview.png)

## Customizing

## Tips
All themes are built with overridable custom @-prefixed Tmux options, which
means that any part of a theme can be easily customized.

- Use different themes/colors on different machines by using some sort of
wrapper around launching Tmux.
To customize a theme, simply look at the source to see the list of Tmux options
with names beginning with a `@`, and simply set the desired option in your
`tmux.conf` before the theme is loaded.

## Development / Contributing

## Contributing
If you want to contribute a theme, please have them use custom @-prefixed Tmux
options like existing themes, so they can be customized the same way.

If you decide to contribute your own tmux themes, please try to base it on the
`default.tmuxtheme` theme. This ensures that switching between themes works as
it should and completely overwrites all settings from previous themes.
New themes should be created under the `src` folder with a `.tmuxtheme`
extension. Please have a look at existing themes to see how files can be
included and shared between themes.

If it's not possible to base your theme on my default one, something is probably
missing from it. So please contribute a fix to the default theme too in that
case :)
To build all themes, just run `make build` from the root of the project.

All themes also have unit tests which can be found under the `test`
directory. They are written in [Go](https://golang.org/), but hopefully easy to
understand. To run all tests, just run `make test` from the root of the project.

## License

Expand Down
145 changes: 95 additions & 50 deletions basic.tmuxtheme
Original file line number Diff line number Diff line change
@@ -1,54 +1,99 @@
# Status update interval
set -g status-interval 1
#
# Basic theme
#

# Basic status bar colors
set -g status-style bg=black,fg=cyan
# Themepack format options - Overrideable
set -goq @themepack-status-left-area-left-format "#S"
set -goq @themepack-status-left-area-left-prefix ""
set -goq @themepack-status-left-area-left-suffix ""
set -goq @themepack-status-left-area-middle-format "#I"
set -goq @themepack-status-left-area-middle-prefix ""
set -goq @themepack-status-left-area-middle-suffix ""
set -goq @themepack-status-left-area-right-format "#P"
set -goq @themepack-status-left-area-right-prefix ""
set -goq @themepack-status-left-area-right-suffix ""
set -goq @themepack-status-right-area-left-format "#H"
set -goq @themepack-status-right-area-left-prefix ""
set -goq @themepack-status-right-area-left-suffix ""
set -goq @themepack-status-right-area-middle-format "%H:%M:%S"
set -goq @themepack-status-right-area-middle-prefix ""
set -goq @themepack-status-right-area-middle-suffix ""
set -goq @themepack-status-right-area-right-format "%d-%b-%y"
set -goq @themepack-status-right-area-right-prefix ""
set -goq @themepack-status-right-area-right-suffix ""
set -goq @themepack-window-status-current-format "#I:#W#F"
set -goq @themepack-window-status-current-prefix ""
set -goq @themepack-window-status-current-suffix ""
set -goq @themepack-window-status-format "#I:#W#F"
set -goq @themepack-window-status-prefix ""
set -goq @themepack-window-status-suffix ""

# Left side of status bar
set -g status-left-style bg=black,fg=green
set -g status-left-length 40
set -g status-left "#S #[fg=white]» #[fg=yellow]#I #[fg=cyan]#P"
# Themepack format options - combine prefixes, formats, and suffixes
set -gqF @themepack-status-left-area-left-format "#{@themepack-status-left-area-left-prefix}#{@themepack-status-left-area-left-format}#{@themepack-status-left-area-left-suffix}"
set -gqF @themepack-status-left-area-middle-format "#{@themepack-status-left-area-middle-prefix}#{@themepack-status-left-area-middle-format}#{@themepack-status-left-area-middle-suffix}"
set -gqF @themepack-status-left-area-right-format "#{@themepack-status-left-area-right-prefix}#{@themepack-status-left-area-right-format}#{@themepack-status-left-area-right-suffix}"
set -gqF @themepack-status-right-area-left-format "#{@themepack-status-right-area-left-prefix}#{@themepack-status-right-area-left-format}#{@themepack-status-right-area-left-suffix}"
set -gqF @themepack-status-right-area-middle-format "#{@themepack-status-right-area-middle-prefix}#{@themepack-status-right-area-middle-format}#{@themepack-status-right-area-middle-suffix}"
set -gqF @themepack-status-right-area-right-format "#{@themepack-status-right-area-right-prefix}#{@themepack-status-right-area-right-format}#{@themepack-status-right-area-right-suffix}"
set -gqF @themepack-window-status-current-format "#{@themepack-window-status-current-prefix}#{@themepack-window-status-current-format}#{@themepack-window-status-current-suffix}"
set -gqF @themepack-window-status-format "#{@themepack-window-status-prefix}#{@themepack-window-status-format}#{@themepack-window-status-suffix}"

# Right side of status bar
set -g status-right-style bg=black,fg=cyan
set -g status-right-length 40
set -g status-right "#H #[fg=white]« #[fg=yellow]%H:%M:%S #[fg=green]%d-%b-%y"
# Theme options
set -goq @theme-clock-mode-colour red
set -goq @theme-clock-mode-style 24
set -goq @theme-display-panes-active-colour default
set -goq @theme-display-panes-colour default
set -goq @theme-message-bg default
set -goq @theme-message-command-bg default
set -goq @theme-message-command-fg default
set -goq @theme-message-fg default
set -goq @theme-mode-bg red
set -goq @theme-mode-fg default
set -goq @theme-pane-active-border-bg default
set -goq @theme-pane-active-border-fg green
set -goq @theme-pane-border-bg default
set -goq @theme-pane-border-fg default
set -goq @theme-status-bg black
set -goq @theme-status-fg cyan
set -goq @theme-status-interval 1
set -goq @theme-status-justify centre
set -goqF @theme-status-left "#{@themepack-status-left-area-left-format} #[fg=white]» #[fg=yellow]#{@themepack-status-left-area-middle-format} #[fg=cyan]#{@themepack-status-left-area-right-format}"
set -goq @theme-status-left-bg black
set -goq @theme-status-left-fg green
set -goq @theme-status-left-length 40
set -goqF @theme-status-right "#{@themepack-status-right-area-left-format} #[fg=white]« #[fg=yellow]#{@themepack-status-right-area-middle-format} #[fg=green]#{@themepack-status-right-area-right-format}"
set -goq @theme-status-right-bg black
set -goq @theme-status-right-fg cyan
set -goq @theme-status-right-length 40
set -goq @theme-window-status-activity-bg black
set -goq @theme-window-status-activity-fg yellow
set -goq @theme-window-status-current-bg red
set -goq @theme-window-status-current-fg black
set -goqF @theme-window-status-current-format " #{@themepack-window-status-current-format} "
set -goqF @theme-window-status-format " #{@themepack-window-status-format} "
set -goq @theme-window-status-separator ""

# Window status
set -g window-status-format " #I:#W#F "
set -g window-status-current-format " #I:#W#F "

# Current window status
set -g window-status-current-style bg=red,fg=black

# Window with activity status
set -g window-status-activity-style bg=black,fg=yellow

# Window separator
set -g window-status-separator ""

# Window status alignment
set -g status-justify centre

# Pane border
set -g pane-border-style bg=default,fg=default

# Active pane border
set -g pane-active-border-style bg=default,fg=green

# Pane number indicator
set -g display-panes-colour default
set -g display-panes-active-colour default

# Clock mode
set -g clock-mode-colour red
set -g clock-mode-style 24

# Message
set -g message-style bg=default,fg=default

# Command message
set -g message-command-style bg=default,fg=default

# Mode
set -g mode-style bg=red,fg=default
# Apply theme options
set -gF display-panes-active-colour "#{@theme-display-panes-active-colour}"
set -gF display-panes-colour "#{@theme-display-panes-colour}"
set -gF message-command-style "fg=#{@theme-message-command-fg},bg=#{@theme-message-command-bg}"
set -gF message-style "fg=#{@theme-message-fg},bg=#{@theme-message-bg}"
set -gF status-interval "#{@theme-status-interval}"
set -gF status-justify "#{@theme-status-justify}"
set -gF status-left "#{@theme-status-left}"
set -gF status-left-length "#{@theme-status-left-length}"
set -gF status-left-style "fg=#{@theme-status-left-fg},bg=#{@theme-status-left-bg}"
set -gF status-right "#{@theme-status-right}"
set -gF status-right-length "#{@theme-status-right-length}"
set -gF status-right-style "fg=#{@theme-status-right-fg},bg=#{@theme-status-right-bg}"
set -gF status-style "fg=#{@theme-status-fg},bg=#{@theme-status-bg}"
set -gwF clock-mode-colour "#{@theme-clock-mode-colour}"
set -gwF clock-mode-style "#{@theme-clock-mode-style}"
set -gwF mode-style "fg=#{@theme-mode-fg},bg=#{@theme-mode-bg}"
set -gwF pane-active-border-style "fg=#{@theme-pane-active-border-fg},bg=#{@theme-pane-active-border-bg}"
set -gwF pane-border-style "fg=#{@theme-pane-border-fg},bg=#{@theme-pane-border-bg}"
set -gwF window-status-activity-style "fg=#{@theme-window-status-activity-fg},bg=#{@theme-window-status-activity-bg}"
set -gwF window-status-current-format "#{@theme-window-status-current-format}"
set -gwF window-status-current-style "fg=#{@theme-window-status-current-fg},bg=#{@theme-window-status-current-bg}"
set -gwF window-status-format "#{@theme-window-status-format}"
set -gwF window-status-separator "#{@theme-window-status-separator}"
107 changes: 107 additions & 0 deletions bin/build-theme
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#! /usr/bin/env bash
#set -e
shopt -s extglob
[ -n "$BUILD_THEME_DEBUG" ] && set -x

trim() {
local string="$*"
string="${string#"${string%%[![:space:]]*}"}"
string="${string%"${string##*[![:space:]]}"}"
echo -n "$string"
}

find-included() {
local needle source dir found
needle="$1"
source="$2"
dir="$(dirname "$source")"
found=""

if [[ "${needle:0:1}" == "/" ]]; then
echo "$needle"
return 0
fi

while [ -z "$found" ] && [[ ! "$dir" =~ ^(\/|\.|\.\.)$ ]]; do
if [ -f "${dir}/${needle}" ]; then
found="${dir}/${needle}"
elif [ -f "${dir}/${needle}.tmuxsh" ]; then
found="${dir}/${needle}.tmuxsh"
elif [ -f "${dir}/${needle}.tmuxtheme" ]; then
found="${dir}/${needle}.tmuxtheme"
else
dir="$(dirname "$dir")"
fi
done

if [ -z "$found" ]; then
echo "ERROR: Could not find \"$needle\" to include in \"$source\"" 1>&2
return 1
else
# echo "INFO: Found \"$needle\" to include in \"$source\"" 1>&2
echo "$found"
return 0
fi
}

build-theme() {
local source target output file line included err
source="$1"
target="$2"
output=""
err="0"

while IFS= read -r line; do
if [[ "$line" =~ ^#=\ *include\ \"(.+)\".*$ ]]; then
if file="$(find-included "${BASH_REMATCH[1]}" "$source")"; then
if included="$(build-theme "${file}")"; then
output="${output}${included}
"
else
err="1"
fi
else
err="1"
fi
else
output="${output}${line}
"
fi
done < "$source"

if [ "$err" != "0" ]; then
return "$err"
elif [ -z "$target" ]; then
echo "$(trim "$output")"
else
mkdir -p "$(dirname "$target")"
echo "$(trim "$output")" > "$target"
fi
}

help() {
echo "usage: build-theme <source-file> [<target-file>]"
echo ""
echo "Arguments:"
echo " <source-file> - The theme file to build."
echo " <target-file> - Write output to specified file. If not given, print"
echo " output to STDOUT."
}

main() {
local source="$1"
local target="$2"

if [ -z "$source" ]; then
help
exit 1
elif [[ " $* " =~ ^.*\ (-h|--help)\ .*$ ]]; then
help
else
build-theme "$source" "$target"
return "$?"
fi
}

main "$@"
exit "$?"
Loading

0 comments on commit bb24b39

Please sign in to comment.