diff options
| -rw-r--r-- | Sources/bar/bar.docc/bar.md | 1 | ||||
| -rw-r--r-- | Sources/bar/bar.docc/examples.md | 15 | ||||
| -rw-r--r-- | Sources/bar/bar.docc/examples/example-aerospace.md | 42 | ||||
| -rw-r--r-- | Sources/bar/bar.docc/examples/example-clock.md | 9 | ||||
| -rw-r--r-- | Sources/bar/bar.docc/examples/example-cpu.md | 21 | ||||
| -rw-r--r-- | Sources/bar/bar.docc/examples/example-focused-app.md | 71 | ||||
| -rw-r--r-- | Sources/bar/bar.docc/examples/example-kitty.md | 66 | ||||
| -rw-r--r-- | Sources/bar/bar.docc/examples/example-mail.md | 28 | ||||
| -rw-r--r-- | Sources/bar/bar.docc/examples/example-memory.md | 24 | ||||
| -rw-r--r-- | Sources/bar/bar.docc/examples/example-mpd.md | 30 | ||||
| -rw-r--r-- | Sources/bar/bar.docc/examples/example-volume.md | 47 |
11 files changed, 354 insertions, 0 deletions
diff --git a/Sources/bar/bar.docc/bar.md b/Sources/bar/bar.docc/bar.md index e49e402..61fee5b 100644 --- a/Sources/bar/bar.docc/bar.md +++ b/Sources/bar/bar.docc/bar.md @@ -44,6 +44,7 @@ If you specify the interval, the block will re-run the command with such frequen - <doc:refresh> - <doc:highlighting> - <doc:gestures> +- <doc:examples> - ``Block`` - ``Cell`` diff --git a/Sources/bar/bar.docc/examples.md b/Sources/bar/bar.docc/examples.md new file mode 100644 index 0000000..e4e4b2e --- /dev/null +++ b/Sources/bar/bar.docc/examples.md @@ -0,0 +1,15 @@ +# Examples + +A few examples you can use as starting point for your commands. + +## Topics + +- <doc:example-aerospace> +- <doc:example-clock> +- <doc:example-cpu> +- <doc:example-focused-app> +- <doc:example-kitty> +- <doc:example-mail> +- <doc:example-memory> +- <doc:example-mpd> +- <doc:example-volume> diff --git a/Sources/bar/bar.docc/examples/example-aerospace.md b/Sources/bar/bar.docc/examples/example-aerospace.md new file mode 100644 index 0000000..18726eb --- /dev/null +++ b/Sources/bar/bar.docc/examples/example-aerospace.md @@ -0,0 +1,42 @@ +# Aerospace + +A script that prints the active Aerospace workspaces. + +```shell +#!/bin/zsh + +# Get all available workspaces +workspaces=() +while IFS= read -r line; do + workspaces+=("$line") +done < <(aerospace list-workspaces --monitor 1) + +# Get all active workspaces (with at least one window). +typeset -A used_workspaces +while IFS= read -r line; do + used_workspaces[$line]=1 +done < <(aerospace list-windows --monitor 1 --format "%{workspace}") + +# Get the current workspace +focused_workspace=$(aerospace list-workspaces --focused) + +for workspace in "${workspaces[@]}"; do + if [[ $workspace == $focused_workspace ]]; then + echo "&!2 $workspace " + elif [[ -n ${used_workspaces[$workspace]} ]]; then + echo "&!1 $workspace " + fi +done +``` + +## Usage + +Instead of relaying on ``Block/interval``, you might want to setup a Aerospace [callback](https://nikitabobko.github.io/AeroSpace/guide#on-focus-changed-callbacks) to update the block in real-time: + +```toml +# ~/.config/aerospace/aerospace.toml + +on-focus-changed = [ + "exec-and-forget notifyutil -p bar.touch.spaces" +] +``` diff --git a/Sources/bar/bar.docc/examples/example-clock.md b/Sources/bar/bar.docc/examples/example-clock.md new file mode 100644 index 0000000..9705143 --- /dev/null +++ b/Sources/bar/bar.docc/examples/example-clock.md @@ -0,0 +1,9 @@ +# Clock + +A script that prints the current date and time. + +```shell +#!/bin/zsh + +date '+%a %d, %H:%M:%S' +``` diff --git a/Sources/bar/bar.docc/examples/example-cpu.md b/Sources/bar/bar.docc/examples/example-cpu.md new file mode 100644 index 0000000..63a6582 --- /dev/null +++ b/Sources/bar/bar.docc/examples/example-cpu.md @@ -0,0 +1,21 @@ +# CPU + +A script that prints the current CPU usage. + +```shell +#!/bin/zsh + +core_count=$(sysctl -n machdep.cpu.thread_count) +user=$(whoami) +cpu_info=$(ps -eo pcpu,user) + +# Split CPU usage into system (other users) vs. current user, normalised by core count +cpu_sys=$(echo "$cpu_info" | grep -v "$user" | sed 's/[^ 0-9.]//g' | awk "{sum+=\$1} END {print sum/(100.0 * $core_count)}") +cpu_user=$(echo "$cpu_info" | grep "$user" | sed 's/[^ 0-9.]//g' | awk "{sum+=\$1} END {print sum/(100.0 * $core_count)}") + +percentage=$(awk -v sys="$cpu_sys" -v user="$cpu_user" 'BEGIN { printf "%.0f", (sys + user) * 100 }') + +(( percentage > 10 )) && echo " $percentage% " || exit 0 +``` + +> Note: The block becomes visible only if usage exceeds 10%. diff --git a/Sources/bar/bar.docc/examples/example-focused-app.md b/Sources/bar/bar.docc/examples/example-focused-app.md new file mode 100644 index 0000000..29a6f18 --- /dev/null +++ b/Sources/bar/bar.docc/examples/example-focused-app.md @@ -0,0 +1,71 @@ +# Focused app + +A script that prints the currently focused app with a custom icon. + +> Important: This script uses Aerospace CLI to get the currently focused window. +If you don't use Aerospace, please adapt the script accordingly. + +```shell +#!/bin/zsh + +# Default to a UTF-8 locale when launched with a minimal environment +# (aerospace/launchd set neither LANG nor LC_*), otherwise zsh rejects +# multibyte chars like the U+200E prefix in WhatsApp's app-name. +: ${LANG:=en_US.UTF-8}; export LANG + +# Icon used when the focused app isn't recognised below +fallback_icon="" + +# Get currently focused app +app=$(aerospace list-windows --focused --format "%{app-name}") + +# Hide app on an empty workspace +if [[ -z $app ]]; then + echo "" + exit 0 +fi + +# Map each favourite app to its SF Symbol icon, grouped by icon. +typeset -A icons +map() { + local icon=$1; shift + for name in "$@"; do icons[$name]=$icon + done +} + +map Finder Transmit +map kitty Xcode "SF Symbols" Terminal TablePro RapidAPI +map qutebrowser "Brave Browser" Safari +map "Brewer X" "App Store" +map Messages WhatsApp $'\u200eWhatsApp' # WhatsApp ships a leading U+200E (invisible LRM) +map Whereby FaceTime "Final Cut Pro" HandBrake Compressor Infuse TV mpv +map BusyCal Calendar +map BusyContacts +map Sketch +map "Pixelmator Pro" Affinity Aseprite +map Calculator +map Numbers +map Keynote "iA Presenter" +map Pages "iA Writer" +map Blender +map Music "Mp3tag" +map Podcasts +map "Logic Pro" +map Mail +map Preview + +# Set icon (fallback to $fallback_icon for unknown apps) + label in one call, then show +echo " ${icons[$app]:-$fallback_icon} $app " +``` + +## Usage + +Instead of relaying on ``Block/interval``, you might want to setup a Aerospace [callback](https://nikitabobko.github.io/AeroSpace/guide#on-focus-changed-callbacks) to update the block in real-time: + +```toml +# ~/.config/aerospace/aerospace.toml + +on-focus-changed = [ + "exec-and-forget notifyutil -p bar.touch.app" +] +``` diff --git a/Sources/bar/bar.docc/examples/example-kitty.md b/Sources/bar/bar.docc/examples/example-kitty.md new file mode 100644 index 0000000..2193f25 --- /dev/null +++ b/Sources/bar/bar.docc/examples/example-kitty.md @@ -0,0 +1,66 @@ +# Kitty sessions + +A script that prints the current Kitty session. + +> Important: This script uses Aerospace CLI to get the currently focused window. +If you don't use Aerospace, please adapt the script accordingly. + +```shell +#!/bin/zsh + +# Get currently focused app +app=$(aerospace list-windows --focused --format "%{app-name}") + +if [[ $app == kitty ]]; then + # Get current kitty session + socket=$(ls -t /tmp/kitty-* 2>/dev/null | head -1) + [[ -z $socket ]] && exit 0 + session=$(kitty @ --to "unix:$socket" ls | jq -r '.[0].tabs[] | select(.is_active).windows[] | select(.is_active).session_name') + + if [[ -n $session ]]; then + echo " $session " + else + exit 0 + fi +else + exit 0 +fi +``` + +## Usage + +Instead of relaying on ``Block/interval``, you might want to setup a Kitty [watcher](https://sw.kovidgoyal.net/kitty/launch/#watchers) to update the block in real-time: + +```python +# ~/.config/kitty/watchers/session_watcher.py + +import subprocess +from typing import Any + +from kitty.boss import Boss +from kitty.window import Window + +def _touch_bar() -> None: + subprocess.Popen( + ["notifyutil", "-p", "bar.touch.session"], + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + ) + +def on_focus_change(boss: Boss, window: Window, data: dict[str, Any]) -> None: + _touch_bar() + +def on_tab_bar_dirty(boss: Boss, window: Window, data: dict[str, Any]) -> None: + _touch_bar() +``` + +Also, you might want to refresh the block on workspace/app change. +You can do that by setting an Aerospace [callback](https://nikitabobko.github.io/AeroSpace/guide#on-focus-changed-callbacks): + +```toml +# ~/.config/aerospace/aerospace.toml + +on-focus-changed = [ + "exec-and-forget notifyutil -p bar.touch.session" +] +``` diff --git a/Sources/bar/bar.docc/examples/example-mail.md b/Sources/bar/bar.docc/examples/example-mail.md new file mode 100644 index 0000000..73b15ed --- /dev/null +++ b/Sources/bar/bar.docc/examples/example-mail.md @@ -0,0 +1,28 @@ +# Unread emails + +A script that prints the number of unread emails. + +```shell +#!/bin/zsh + +# Maildir roots to check for unread mail +maildirs=( + "$HOME/.local/share/email/first-email@example.com" + "$HOME/.local/share/email/second-email@example.com" + "$HOME/.local/share/email/third-email@example.com" +) + +# Count unread messages (files under */new/ at depth 2) +# +# Drop the -mindepth/-maxdepth constraints to recurse +# into nested mailboxes. +total_unread=0 +for maildir in "${maildirs[@]}"; do + total_unread=$(( total_unread + $(find "$maildir" -mindepth 3 -maxdepth 3 -type f -path "*/new/*" 2>/dev/null | wc -l) )) +done + +# Conditionally display the block based on unread messages +(( total_unread > 0 )) && echo " $total_unread " || exit 0 +``` + +> Note: This script is only useful if you're using a tool like [isync](https://isync.sourceforge.io/) to locally synchronise emails. diff --git a/Sources/bar/bar.docc/examples/example-memory.md b/Sources/bar/bar.docc/examples/example-memory.md new file mode 100644 index 0000000..299a703 --- /dev/null +++ b/Sources/bar/bar.docc/examples/example-memory.md @@ -0,0 +1,24 @@ +# Memory + +A script that prints the current memory usage. + +```shell +#!/bin/zsh + +# Query vm_stat once (the previous version called it 5 times) +total_memory=$(sysctl -n hw.memsize) +vm=$(vm_stat) +page_size=$(echo "$vm" | awk 'NR==1 {print $8}') + +active=$(echo "$vm" | awk '/Pages active/ {sub("\\.","",$3); print $3}') +inactive=$(echo "$vm" | awk '/Pages inactive/ {sub("\\.","",$3); print $3}') +speculative=$(echo "$vm" | awk '/Pages speculative/{sub("\\.","",$3); print $3}') +wired=$(echo "$vm" | awk '/Pages wired down/{sub("\\.","",$4); print $4}') + +used_mem_bytes=$(( (active + inactive + speculative + wired) * page_size )) +percentage=$(awk -v used="$used_mem_bytes" -v total="$total_memory" 'BEGIN { printf "%.0f", (used/total)*100 }') + +(( percentage > 80 )) && echo " $percentage% " || exit 0 +``` + +> Note: The block becomes visible only if usage exceeds 80%. diff --git a/Sources/bar/bar.docc/examples/example-mpd.md b/Sources/bar/bar.docc/examples/example-mpd.md new file mode 100644 index 0000000..2803ca0 --- /dev/null +++ b/Sources/bar/bar.docc/examples/example-mpd.md @@ -0,0 +1,30 @@ +# MPD + +A script that prints the current artist and song from MPD. + +```shell +#!/bin/zsh + +case $BUTTON in + (0) mpc toggle >/dev/null ;; + (2) mpc stop >/dev/null ;; +esac + +artist=$(mpc current -f %artist% 2>/dev/null) +song=$(mpc current -f %title% 2>/dev/null) + +# Nothing playing → hide block +if (( $(mpc status 2>/dev/null | wc -l) == 1 )); then + exit 0 +elif mpc status 2>/dev/null | awk 'NR==2 {print; exit}' | grep -q playing; then + echo " $artist • $song " +else + echo " $artist • $song " +fi +``` + +> Note: The block will play/pause the song on left mouse click and stop the player on scroll-wheel click. + +## Usage + +Instead of relaying on ``Block/interval``, you might want to use the <doc:daemon-mpd> daemon to update the block in real-time. diff --git a/Sources/bar/bar.docc/examples/example-volume.md b/Sources/bar/bar.docc/examples/example-volume.md new file mode 100644 index 0000000..60603e1 --- /dev/null +++ b/Sources/bar/bar.docc/examples/example-volume.md @@ -0,0 +1,47 @@ +# Volume + +A script that prints the current volume level. + +```shell +#!/bin/zsh + +increaseVolume() { osascript -e "set volume output volume (output volume of (get volume settings) + 5)" } +decreaseVolume() { osascript -e "set volume output volume (output volume of (get volume settings) - 5)" } +toggleMuted() { + case $(osascript -e "output muted of (get volume settings)") in + (true) osascript -e "set volume output muted false" ;; + (false) osascript -e "set volume output muted true" ;; + esac +} + +case $BUTTON in + (2) toggleMuted ;; +esac + +case $SCROLL in + (UP) increaseVolume ;; + (DOWN) decreaseVolume ;; +esac + +volume=$(osascript -e "output volume of (get volume settings)") +muted=$(osascript -e "output muted of (get volume settings)") + +if [[ $muted == true ]]; then + icon="" +else + case $volume in + [6-9][0-9]|100) icon="" ;; + [3-5][0-9]) icon="" ;; + [1-9]|[1-2][0-9]) icon="" ;; + *) icon="" ;; + esac +fi + +echo " $icon $volume% " +``` + +> Note: The block will increase/decrease the volume on scroll and mute/un-mute on scroll-wheel click. + +## Usage + +Instead of relaying on ``Block/interval``, you might want to use the <doc:daemon-volumed> daemon to update the block in real-time. |
