# Baddcafe - Oh My Zsh Theme A custom Oh My Zsh theme that shows live system information alongside a Git-aware prompt. The status line refreshes once a second without blocking the shell: all data collection happens in a detached background process, so the prompt itself does no work. ## Features - **System Information**: - CPU usage - Memory usage - Battery level - Local and global IP addresses - **Dynamic Prompt**: - Current time - Current working directory - Success (`green ➜`) or failure (`red ➜`) of the last command - **Git Status** (powerlevel10k-style): - Branch name, tag, or short sha for a detached HEAD - Commits ahead of / behind the upstream branch - Counts of conflicted, staged, unstaged and untracked files - Stash count - The operation in progress: merge, rebase (with `step/total`), cherry-pick, revert or bisect - Computed off the prompt path, so a slow `git status` in a large repository never blocks the shell - **Auto-Updating**: - Refreshes system information every second while idle - Updates seamlessly without disrupting typing - Zero subprocesses on the prompt path; each metric has its own refresh interval, and network lookups are cached and time-limited ## The git segment ```  main →origin/trunk ⇣2⇡1 *3 ~1 +2 !4 ?5 rebase 1/3 ``` | Symbol | Meaning | | --- | --- | | `` | Branch name. | | `#` / `➦` | Detached HEAD: the tag it points at, or the short sha. | | `→origin/trunk` | Upstream branch, shown only when its name differs from yours. | | `⇣2` / `⇡1` | Commits behind / ahead of the upstream branch. | | `*3` | Stashes. | | `~1` | Unmerged (conflicted) files. | | `+2` | Staged files. | | `!4` | Files changed but not staged. | | `?5` | Untracked files. | | `rebase 1/3` | Operation in progress: `merge`, `rebase`, `cherry-pick`, `revert`, `bisect`. | A file that is both staged and edited again afterwards is counted in `+` *and* in `!` -- that is the distinction those two numbers exist to make. The segment is drawn as a powerline segment of its own, following the path: **green background when there is nothing to commit, red when there is**, dark text throughout, and the closing `` sits at the end of it. Like p10k's rainbow style, the state lives in the background colour and the counts are told apart by their symbols rather than by colours of their own. Everything above comes from a single `git status --porcelain=v2 --branch`, which requires **git 2.11 or newer**. It runs in a child process, and the result is picked up over a pipe as soon as it lands, so the prompt is drawn immediately and the segment appears a moment later rather than the shell waiting on git. Set `BADDCAFE_GIT_ASYNC=0` if you would rather it be synchronous. ## Preview ![icon](icons/example.png) --- ## System Requirements ### **Supported Operating Systems** - **macOS**: Version 10.12 (Sierra) and later, Intel and Apple Silicon - **Linux**: Most modern distributions, including: - Ubuntu (16.04 and later) - Debian (9 and later) - CentOS (7 and later) - Fedora (latest) - Arch Linux (latest) - openSUSE (latest) ### **Required Tools and Dependencies** - **Shell**: Zsh 5.3 or newer (the theme is written specifically for Zsh) - **Linux**: no external tools are needed for CPU, memory or battery -- these are read directly from `/proc` and `/sys`. Optionally: - `hostname` (local IP address) - `curl` (global IP address) - **macOS**: - `ps` (CPU usage) - `vm_stat` and `sysctl` (memory usage) - `pmset` (battery status) - `ifconfig` (local IP address) - `curl` (global IP address) - **Terminal Support**: - Terminal should support **ANSI escape sequences** for color coding and background changes. ### **Optional**: - **Git**: 2.11 or newer, for the git segment. - **figlet**: Draws the ASCII art banner on shell start. ## Installation You can install the theme using the provided installation script. --- ### Prerequisites 1. **Zsh**: Ensure Zsh is your default shell ($ `echo $SHELL`). 2. **Oh My Zsh**: Ensure you have Oh My Zsh installed. You can install it from [Oh My Zsh's official site](https://ohmyz.sh/). 3. [Powerline fonts](https://github.com/powerline/fonts) 4. **figlet**: Used for drawing ascii art on terminal init ### Steps 1. (Optional) * **Linux**: ``` sudo apt-get install figlet ``` * **macOS**: ``` brew install figlet ``` 2. Download and run the installation script: ```bash zsh <(curl -fsSL https://github.com/dimgatz98/Baddcafe_zsh_theme/raw/main/theme-installer.sh) ``` 3. Restart your terminal or reload Zsh (if needed): ```bash source ~/.zshrc ``` That’s it! You are now ready to use the Baddcafe theme! 🎉 The installer edits `~/.zshrc` between two marker comments and prefixes any `ZSH_THEME` line it disables with `#baddcafe-disabled#`. Re-running it is safe, and `uninstall` undoes exactly those edits and nothing else. A timestamped copy of your `~/.zshrc` is kept in `~/.baddcafe/` either way. ### Updating ```bash zsh <(curl -fsSL https://github.com/dimgatz98/Baddcafe_zsh_theme/raw/main/theme-installer.sh) update ``` ### Uninstalling ```bash zsh <(curl -fsSL https://github.com/dimgatz98/Baddcafe_zsh_theme/raw/main/theme-installer.sh) uninstall ``` --- ## Manual Installation If you prefer to install the theme manually: 1. Download the theme file: ```bash curl -fsSL https://raw.githubusercontent.com/dimgatz98/Baddcafe_zsh_theme/main/theme/baddcafe.zsh-theme -o ~/.oh-my-zsh/custom/themes/baddcafe.zsh-theme ``` 2. Update your `.zshrc` file: - Open the file in an editor: ```bash vim ~/.zshrc # or your favourite editor ``` - Set the `ZSH_THEME` to `"baddcafe"`: ```zsh ZSH_THEME="baddcafe" ``` 3. Save the file and reload Zsh: ```bash source ~/.zshrc ``` --- ## Configuration Set any of these in `~/.zshrc` **before** Oh My Zsh loads the theme: | Variable | Default | Meaning | | --- | --- | --- | | `BADDCAFE_TICK` | `1` | Prompt redraw interval, in seconds. Drives the clock. | | `BADDCAFE_POLL` | `1` | How often the background collector wakes up. | | `BADDCAFE_INTERVAL_CPU` | `2` | CPU sampling interval, in seconds. | | `BADDCAFE_INTERVAL_MEM` | `2` | Memory sampling interval. | | `BADDCAFE_INTERVAL_BAT` | `30` | Battery sampling interval. | | `BADDCAFE_INTERVAL_LOCALIP` | `60` | Local IP refresh interval. | | `BADDCAFE_INTERVAL_GLOBALIP` | `3600` | Global IP refresh interval. | | `BADDCAFE_GLOBALIP` | `1` | Set to `0` to never contact an external service. | | `BADDCAFE_GLOBALIP_URL` | `ifconfig.me` | Service used to resolve the public IP. | | `BADDCAFE_GLOBALIP_TIMEOUT` | `3` | Hard timeout, in seconds, for that lookup. | | `BADDCAFE_BANNER` | `1` | Set to `0` to skip the figlet banner. | | `BADDCAFE_SET_BACKGROUND` | `1` | Set to `0` to leave the terminal background alone. | | `BADDCAFE_PROMPT_GAP` | `1` | Blank columns between the end of the prompt and what you type. | | `BADDCAFE_GIT` | `1` | Set to `0` to drop the git segment entirely. | | `BADDCAFE_GIT_ASYNC` | `1` | Set to `0` to run `git status` in `precmd` instead of a child. | | `BADDCAFE_GIT_UNTRACKED` | *(unset)* | `0` skips the untracked scan (`-uno`), `1` forces it on. Unset defers to git's own `status.showUntrackedFiles`. | | `BADDCAFE_GIT_STASH` | `1` | Set to `0` to hide the stash count. | | `BADDCAFE_GIT_TAG` | `1` | Set to `0` to show a bare sha on a detached HEAD instead of looking up a tag. | | `BADDCAFE_GIT_BG_CLEAN` | `071` | Segment background when there is nothing to commit. | | `BADDCAFE_GIT_BG_DIRTY` | `167` | Segment background when there is. | | `BADDCAFE_GIT_FG` | `235` | Text colour inside the segment. | Every symbol is a variable too: `BADDCAFE_GIT_SYM_BRANCH`, `_DETACHED`, `_TAG`, `_UPSTREAM`, `_AHEAD`, `_BEHIND`, `_STASH`, `_CONFLICT`, `_STAGED`, `_UNSTAGED`, `_UNTRACKED`. Colours are 256-colour numbers; symbols must stay one column wide, for the reason given under [Notes on rendering](#notes-on-rendering). Raising the intervals is the first thing to try if you keep many terminal tabs open; each shell runs its own collector. The git segment runs once per command, not once per redraw, and it no longer blocks the prompt while it does. In a repository large enough for `git status` to still be felt, the untracked-file scan is usually what costs the time; turn it off for that repository alone with ```bash git config status.showUntrackedFiles no ``` and leave `BADDCAFE_GIT_UNTRACKED` unset, which is the default, so that git's own setting is the one that decides. `BADDCAFE_GIT_UNTRACKED=0` does the same thing for every repository at once. You can also edit the theme file directly at: ```bash ~/.oh-my-zsh/custom/themes/baddcafe.zsh-theme ``` Feel free to tweak the colors, symbols, or displayed information to suit your preferences. --- ## Notes on rendering Every emoji in the prompt carries an explicit `%2{...%}` width hint. Zsh sizes prompts with `wcwidth()`, which reports one column for the variation-selector sequences (`U+FE0F`) used by the clock and gear emoji, while terminals draw two. Without the hint zsh miscounts the line, the terminal wraps without zsh knowing, and every redraw leaves a stray blank line behind -- most visibly on macOS, whose `wcwidth()` tables are older. If you replace an emoji, keep the hint and make the number match the columns your terminal actually draws. --- ## Notes on redrawing The clock is redrawn from `TRAPALRM`, once a second. Two rules keep that from fighting with the line editor, and both were learned by breaking them: 1. **Do not redraw while the line editor owns the screen below the prompt** -- a completion listing, an incremental search, history navigation. The test has to look at `$LASTWIDGET`, not only `$WIDGET`: `$WIDGET` is set only while a widget is running, and the alarm nearly always arrives between widgets, where it is empty. As a result the clock pauses while a Tab listing is on screen and resumes at your next keystroke. 2. **Call the `zle` builtin from `TRAPALRM` itself**, never from a helper function it calls. Moving that one line a function deeper leaves the line editor out of step: the next keypress discards what you had typed, redraws the whole five-line prompt, and the completion listing you were looking at is gone -- which looks exactly like "the prompt keeps throwing newlines around when I press Tab". ## Contributions Feel free to fork the repo or suggest improvements by creating a pull request. Contributions to enhance the functionality or add new features are welcome. --- ## License This theme is provided under the GNU GENERAL PUBLIC LICENSE. See `LICENSE` for details.