Compare commits

..

10 Commits

Author SHA1 Message Date
David Heinemeier Hansson
ce00b362a7 Use taha approved colors 2025-09-16 21:30:46 +02:00
David Heinemeier Hansson
8b7fa43b31 Add menu to install different terminal 2025-09-16 21:28:32 +02:00
David Heinemeier Hansson
fb8fc11225 Stick with alacritty for system terminals 2025-09-16 21:27:55 +02:00
David Heinemeier Hansson
d697ef22cd Stick to alacritty so we can control font size 2025-09-16 21:26:41 +02:00
David Heinemeier Hansson
f62086f76d Need to keep this alacritty until we have it fully working for other terminals 2025-09-16 21:13:31 +02:00
David Heinemeier Hansson
ce7b22967a Uniformity 2025-09-16 20:26:52 +02:00
David Heinemeier Hansson
7518b62dca Use correct class for ghostty styling 2025-09-16 20:25:17 +02:00
David Heinemeier Hansson
310a5b1d5a Set font for ghostty too if its on the system 2025-09-16 19:10:34 +02:00
David Heinemeier Hansson
85ef1cf1d2 Fix theme name 2025-09-16 18:34:08 +02:00
David Heinemeier Hansson
198ead1231 Themeing for ghostty 2025-09-16 18:27:57 +02:00
486 changed files with 1973 additions and 7460 deletions

View File

@@ -1,9 +0,0 @@
root = true
[*]
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
end_of_line = lf
charset = utf-8

View File

@@ -1,5 +1,5 @@
name: Bug name: Bug
description: Report a validated bug -- NOT FOR SUPPORT REQUESTS description: Report a problem
labels: [bug] labels: [bug]
body: body:
- type: markdown - type: markdown
@@ -19,6 +19,5 @@ body:
id: steps id: steps
attributes: attributes:
label: What's wrong? label: What's wrong?
description: Describe the issue, include steps to recreate it if possible, and attach the output of `omarchy-debug` if possible
validations: validations:
required: true required: true

View File

@@ -1,8 +1 @@
blank_issues_enabled: false blank_issues_enabled: false
contact_links:
- name: Suggestion
url: https://github.com/basecamp/omarchy/discussions/categories/suggestions
about: Suggest a new feature, change to existing feature, or other ideas in Discussions.
- name: Support
url: https://omarchy.org/discord
about: Need help? Join our Discord community for support with any issues. GitHub issues should be used for verified bugs only.

View File

@@ -0,0 +1,15 @@
name: Documentation
description: New pages or changes to existing
labels: [documentation]
body:
- type: markdown
attributes:
value: |
Remember: Omarchy is an open source gift, not a product you bought from a vendor
- type: textarea
id: steps
attributes:
label: What correction or addition do we need?
validations:
required: true

15
.github/ISSUE_TEMPLATE/enhancement.yml vendored Normal file
View File

@@ -0,0 +1,15 @@
name: Enhancement
description: Feature or change
labels: [enhancement]
body:
- type: markdown
attributes:
value: |
Remember: Omarchy is an open source gift, not a product you bought from a vendor
- type: textarea
id: steps
attributes:
label: What do you need?
validations:
required: true

View File

@@ -1,9 +1,10 @@
# Omarchy # Omarchy
Omarchy is a beautiful, modern & opinionated Linux distribution by DHH. Turn a fresh Arch installation into a fully-configured, beautiful, and modern web development system based on Hyprland by running a single command. That's the one-line pitch for Omarchy (like it was for Omakub). No need to write bespoke configs for every essential tool just to get started or to be up on all the latest command-line tools. Omarchy is an opinionated take on what Linux can be at its best.
Read more at [omarchy.org](https://omarchy.org). Read more at [omarchy.org](https://omarchy.org).
## License ## License
Omarchy is released under the [MIT License](https://opensource.org/licenses/MIT). Omarchy is released under the [MIT License](https://opensource.org/licenses/MIT).

View File

@@ -1,2 +0,0 @@
[Desktop Entry]
Hidden=true

View File

@@ -1,2 +0,0 @@
[Desktop Entry]
Hidden=true

View File

@@ -1,2 +0,0 @@
[Desktop Entry]
Hidden=true

View File

@@ -1,2 +0,0 @@
[Desktop Entry]
Hidden=true

View File

@@ -1,2 +0,0 @@
[Desktop Entry]
Hidden=true

View File

@@ -1,2 +0,0 @@
[Desktop Entry]
Hidden=true

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

12
applications/nvim.desktop Normal file
View File

@@ -0,0 +1,12 @@
[Desktop Entry]
Name=Neovim
GenericName=Text Editor
Comment=Edit text files
Exec=$TERMINAL --class=nvim --title=nvim -e nvim -- %F
Terminal=false
Type=Application
Keywords=Text;editor;
Icon=nvim
Categories=Utility;TextEditor;
StartupNotify=false
MimeType=text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-c;text/x-c++;

View File

@@ -1,7 +0,0 @@
[Desktop Entry]
Name=Walker
Comment=Walker Service
Exec=walker --gapplication-service
StartupNotify=false
Terminal=false
Type=Application

View File

@@ -4,20 +4,33 @@
BATTERY_THRESHOLD=10 BATTERY_THRESHOLD=10
NOTIFICATION_FLAG="/run/user/$UID/omarchy_battery_notified" NOTIFICATION_FLAG="/run/user/$UID/omarchy_battery_notified"
BATTERY_LEVEL=$(omarchy-battery-remaining)
BATTERY_STATE=$(upower -i $(upower -e | grep 'BAT') | grep -E "state" | awk '{print $2}') get_battery_percentage() {
upower -i "$(upower -e | grep 'BAT')" \
| awk -F: '/percentage/ {
gsub(/[%[:space:]]/, "", $2);
val=$2;
printf("%d\n", (val+0.5))
exit
}'
}
get_battery_state() {
upower -i $(upower -e | grep 'BAT') | grep -E "state" | awk '{print $2}'
}
send_notification() { send_notification() {
notify-send -u critical "󱐋 Time to recharge!" "Battery is down to ${1}%" -i battery-caution -t 30000 notify-send -u critical "󱐋 Time to recharge!" "Battery is down to ${1}%" -i battery-caution -t 30000
} }
if [[ -n "$BATTERY_LEVEL" && "$BATTERY_LEVEL" =~ ^[0-9]+$ ]]; then BATTERY_LEVEL=$(get_battery_percentage)
if [[ $BATTERY_STATE == "discharging" && $BATTERY_LEVEL -le $BATTERY_THRESHOLD ]]; then BATTERY_STATE=$(get_battery_state)
if [[ ! -f $NOTIFICATION_FLAG ]]; then
send_notification $BATTERY_LEVEL if [[ "$BATTERY_STATE" == "discharging" && "$BATTERY_LEVEL" -le "$BATTERY_THRESHOLD" ]]; then
touch $NOTIFICATION_FLAG if [[ ! -f "$NOTIFICATION_FLAG" ]]; then
fi send_notification "$BATTERY_LEVEL"
else touch "$NOTIFICATION_FLAG"
rm -f $NOTIFICATION_FLAG
fi fi
else
rm -f "$NOTIFICATION_FLAG"
fi fi

View File

@@ -1,11 +0,0 @@
#!/bin/bash
# Returns the battery percentage remaining as an integer.
upower -i $(upower -e | grep BAT) \
| awk -F: '/percentage/ {
gsub(/[%[:space:]]/, "", $2);
val=$2;
printf("%d\n", (val+0.5))
exit
}'

View File

@@ -1,14 +0,0 @@
#!/bin/bash
if (($# == 0)); then
echo "Usage: omarchy-branch-set [master|dev]"
exit 1
else
branch="$1"
fi
case "$branch" in
"master") git -C $OMARCHY_PATH switch master ;;
"dev") git -C $OMARCHY_PATH switch dev ;;
*) echo "Unknown branch: $branch"; exit 1; ;;
esac

View File

@@ -1,17 +0,0 @@
#!/bin/bash
if (($# == 0)); then
echo "Usage: omarchy-channel-set [stable|edge|dev]"
exit 1
else
channel="$1"
fi
case "$channel" in
"stable") omarchy-branch-set "master" && omarchy-refresh-pacman "stable" ;;
"edge") omarchy-branch-set "master" && omarchy-refresh-pacman "edge" ;;
"dev") omarchy-branch-set "dev" && omarchy-refresh-pacman "edge" ;;
*) echo "Unknown channel: $channel"; exit 1; ;;
esac
omarchy-update -y

View File

@@ -3,12 +3,5 @@
if [[ $# -eq 0 ]]; then if [[ $# -eq 0 ]]; then
echo "Adjust Apple Display Brightness by passing +5000 or -5000 (or any range from 0-60000)" echo "Adjust Apple Display Brightness by passing +5000 or -5000 (or any range from 0-60000)"
else else
DEVICE="$(sudo asdcontrol --detect /dev/usb/hiddev* | grep ^/dev/usb/hiddev | cut -d: -f1)" sudo asdcontrol $(sudo asdcontrol --detect /dev/usb/hiddev* | grep ^/dev/usb/hiddev | cut -d: -f1) -- "$1"
sudo asdcontrol "$DEVICE" -- "$1" >/dev/null
VALUE="$(sudo asdcontrol "$DEVICE" | awk -F= '/BRIGHTNESS=/{print $2+0}')"
swayosd-client \
--monitor "$(hyprctl monitors -j | jq -r '.[]|select(.focused==true).name')" \
--custom-icon display-brightness \
--custom-progress "$(awk -v v="$VALUE" 'BEGIN{printf "%.2f", v/60000}')" \
--custom-progress-text "$(( VALUE * 100 / 60000 ))%"
fi fi

View File

@@ -23,13 +23,7 @@ fi
next_sink=$(echo "$sinks" | jq -r ".[$next_sink_index]") next_sink=$(echo "$sinks" | jq -r ".[$next_sink_index]")
next_sink_name=$(echo "$next_sink" | jq -r '.name') next_sink_name=$(echo "$next_sink" | jq -r '.name')
next_sink_description=$(echo "$next_sink" | jq -r '.description') next_sink_description=$(echo "$next_sink" | jq -r '.description')
if [ "$next_sink_description" = "(null)" ] || [ "$next_sink_description" = "null" ] || [ -z "$next_sink_description" ]; then
sink_id=$(echo "$next_sink" | jq -r '.properties."object.id"')
next_sink_description=$(wpctl status | grep -E "\s+\*?\s+${sink_id}\." | sed -E 's/^.*[0-9]+\.\s+//' | sed -E 's/\s+\[.*$//')
fi
next_sink_volume=$(echo "$next_sink" | jq -r \ next_sink_volume=$(echo "$next_sink" | jq -r \
'.volume | to_entries[0].value.value_percent | sub("%"; "")') '.volume | to_entries[0].value.value_percent | sub("%"; "")')
next_sink_is_muted=$(echo "$next_sink" | jq -r '.mute') next_sink_is_muted=$(echo "$next_sink" | jq -r '.mute')

View File

@@ -8,13 +8,10 @@ if [[ -f "$FIRST_RUN_MODE" ]]; then
rm -f "$FIRST_RUN_MODE" rm -f "$FIRST_RUN_MODE"
bash "$OMARCHY_PATH/install/first-run/battery-monitor.sh" bash "$OMARCHY_PATH/install/first-run/battery-monitor.sh"
bash "$OMARCHY_PATH/install/first-run/cleanup-reboot-sudoers.sh"
bash "$OMARCHY_PATH/install/first-run/firewall.sh" bash "$OMARCHY_PATH/install/first-run/firewall.sh"
bash "$OMARCHY_PATH/install/first-run/dns-resolver.sh"
bash "$OMARCHY_PATH/install/first-run/gnome-theme.sh" bash "$OMARCHY_PATH/install/first-run/gnome-theme.sh"
bash "$OMARCHY_PATH/install/first-run/elephant.sh"
sudo rm -f /etc/sudoers.d/first-run sudo rm -f /etc/sudoers.d/first-run
bash "$OMARCHY_PATH/install/first-run/welcome.sh"
bash "$OMARCHY_PATH/install/first-run/wifi.sh" bash "$OMARCHY_PATH/install/first-run/wifi.sh"
bash "$OMARCHY_PATH/install/first-run/welcome.sh"
fi fi

View File

@@ -1,6 +0,0 @@
#!/bin/bash
omarchy-state clear re*-required
omarchy-hyprland-window-close-all
sleep 1 # Allow apps like Chrome to shutdown correctly
systemctl reboot --no-wall

View File

@@ -8,92 +8,31 @@ if [[ ! -d "$OUTPUT_DIR" ]]; then
exit 1 exit 1
fi fi
DESKTOP_AUDIO="false" # Selects region or output
MICROPHONE_AUDIO="false" SCOPE="$1"
WEBCAM="false"
STOP_RECORDING="false"
for arg in "$@"; do # Selects audio inclusion or not
case "$arg" in AUDIO=$([[ $2 == "audio" ]] && echo "--audio")
--with-desktop-audio) DESKTOP_AUDIO="true" ;;
--with-microphone-audio) MICROPHONE_AUDIO="true" ;;
--with-webcam) WEBCAM="true" ;;
--stop-recording) STOP_RECORDING="true"
esac
done
cleanup_webcam() {
pkill -f "WebcamOverlay" 2>/dev/null
}
start_webcam_overlay() {
cleanup_webcam
# Get monitor scale
local scale=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | .scale')
# Target width (base 360px, scaled to monitor)
local target_width=$(awk "BEGIN {printf \"%.0f\", 360 * $scale}")
# Try preferred 16:9 resolutions in order, use first available
local preferred_resolutions=("640x360" "1280x720" "1920x1080")
local video_size_arg=""
local available_formats=$(v4l2-ctl --list-formats-ext -d /dev/video0 2>/dev/null)
for resolution in "${preferred_resolutions[@]}"; do
if echo "$available_formats" | grep -q "$resolution"; then
video_size_arg="-video_size $resolution"
break
fi
done
ffplay -f v4l2 $video_size_arg -framerate 30 /dev/video0 \
-vf "scale=${target_width}:-1" \
-window_title "WebcamOverlay" \
-noborder \
-fflags nobuffer -flags low_delay \
-probesize 32 -analyzeduration 0 \
-loglevel quiet &
sleep 1
}
start_screenrecording() { start_screenrecording() {
local filename="$OUTPUT_DIR/screenrecording-$(date +'%Y-%m-%d_%H-%M-%S').mp4" filename="$OUTPUT_DIR/screenrecording-$(date +'%Y-%m-%d_%H-%M-%S').mp4"
local audio_devices=""
local audio_args=""
[[ "$DESKTOP_AUDIO" == "true" ]] && audio_devices+="default_output" if lspci | grep -qi 'nvidia'; then
wf-recorder $AUDIO -f "$filename" -c libx264 -p crf=23 -p preset=medium -p movflags=+faststart "$@" &
if [[ "$MICROPHONE_AUDIO" == "true" ]]; then else
# Merge audio tracks into one - separate tracks only play one at a time in most players wl-screenrec $AUDIO -f "$filename" --ffmpeg-encoder-options="-c:v libx264 -crf 23 -preset medium -movflags +faststart" "$@" &
[[ -n "$audio_devices" ]] && audio_devices+="|"
audio_devices+="default_input"
fi fi
[[ -n "$audio_devices" ]] && audio_args+="-a $audio_devices"
gpu-screen-recorder -w portal -f 60 -fallback-cpu-encoding yes -o "$filename" $audio_args -ac aac &
toggle_screenrecording_indicator toggle_screenrecording_indicator
} }
stop_screenrecording() { stop_screenrecording() {
pkill -SIGINT -f "^gpu-screen-recorder" # SIGINT required to save video properly pkill -x wl-screenrec
pkill -x wf-recorder
# Wait a maximum of 5 seconds to finish before hard killing
local count=0
while pgrep -f "^gpu-screen-recorder" >/dev/null && [ $count -lt 50 ]; do
sleep 0.1
count=$((count + 1))
done
if pgrep -f "^gpu-screen-recorder" >/dev/null; then
pkill -9 -f "^gpu-screen-recorder"
cleanup_webcam
notify-send "Screen recording error" "Recording process had to be force-killed. Video may be corrupted." -u critical -t 5000
else
cleanup_webcam
notify-send "Screen recording saved to $OUTPUT_DIR" -t 2000 notify-send "Screen recording saved to $OUTPUT_DIR" -t 2000
fi
sleep 0.2 # ensures the process is actually dead before we check
toggle_screenrecording_indicator toggle_screenrecording_indicator
} }
@@ -102,19 +41,14 @@ toggle_screenrecording_indicator() {
} }
screenrecording_active() { screenrecording_active() {
pgrep -f "^gpu-screen-recorder" >/dev/null || pgrep -f "WebcamOverlay" >/dev/null pgrep -x wl-screenrec >/dev/null || pgrep -x wf-recorder >/dev/null
} }
if screenrecording_active; then if screenrecording_active; then
if pgrep -f "WebcamOverlay" >/dev/null && ! pgrep -f "^gpu-screen-recorder" >/dev/null; then
cleanup_webcam
else
stop_screenrecording stop_screenrecording
fi elif [[ "$SCOPE" == "output" ]]; then
elif [[ "$STOP_RECORDING" == "false" ]]; then start_screenrecording
[[ "$WEBCAM" == "true" ]] && start_webcam_overlay
start_screenrecording || cleanup_webcam
else else
exit 1 region=$(slurp) || exit 1
start_screenrecording -g "$region"
fi fi

View File

@@ -1,35 +1,28 @@
#!/bin/bash #!/bin/bash
screensaver_in_focus() { screensaver_in_focus() {
hyprctl activewindow -j | jq -e '.class == "org.omarchy.screensaver"' >/dev/null 2>&1 hyprctl activewindow -j | jq -e '.class == "Screensaver"' >/dev/null 2>&1
} }
exit_screensaver() { exit_screensaver() {
hyprctl keyword cursor:invisible false hyprctl keyword cursor:invisible false
pkill -x tte 2>/dev/null pkill -x tte 2>/dev/null
pkill -f org.omarchy.screensaver 2>/dev/null pkill -f "alacritty --class Screensaver" 2>/dev/null
exit 0 exit 0
} }
# Exit the screensaver on signals and input from keyboard and mouse
trap exit_screensaver SIGINT SIGTERM SIGHUP SIGQUIT trap exit_screensaver SIGINT SIGTERM SIGHUP SIGQUIT
printf '\e[?1000h\e[?1003h' # Enable mouse tracking (clicks: 1000, movement: 1003)
while read -rsn1 -t 0.1; do :; done # Flush any pending input
printf '\033]11;rgb:00/00/00\007' # Set background color to black hyprctl keyword cursor:invisible true
hyprctl keyword cursor:invisible true &>/dev/null
tty=$(tty 2>/dev/null)
while true; do while true; do
effect=$(tte 2>&1 | grep -oP '{\K[^}]+' | tr ',' ' ' | tr ' ' '\n' | sed -n '/^beams$/,$p' | sort -u | shuf -n1)
tte -i ~/.config/omarchy/branding/screensaver.txt \ tte -i ~/.config/omarchy/branding/screensaver.txt \
--frame-rate 120 --canvas-width 0 --canvas-height 0 --reuse-canvas --anchor-canvas c --anchor-text c\ --frame-rate 240 --canvas-width 0 --canvas-height $(($(tput lines) - 2)) --anchor-canvas c --anchor-text c \
--random-effect --exclude-effects dev_worm \ "$effect" &
--no-eol --no-restore-cursor &
while pgrep -t "${tty#/dev/}" -x tte >/dev/null; do while pgrep -x tte >/dev/null; do
if read -rsn1 -t 1 || ! screensaver_in_focus; then if read -n 1 -t 3 || ! screensaver_in_focus; then
exit_screensaver exit_screensaver
fi fi
done done

View File

@@ -8,76 +8,10 @@ if [[ ! -d "$OUTPUT_DIR" ]]; then
exit 1 exit 1
fi fi
pkill slurp && exit 0 pkill slurp || hyprshot -m ${1:-region} --raw |
MODE="${1:-smart}"
PROCESSING="${2:-slurp}"
get_rectangles() {
local active_workspace=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | .activeWorkspace.id')
hyprctl monitors -j | jq -r --arg ws "$active_workspace" '.[] | select(.activeWorkspace.id == ($ws | tonumber)) | "\(.x),\(.y) \((.width / .scale) | floor)x\((.height / .scale) | floor)"'
hyprctl clients -j | jq -r --arg ws "$active_workspace" '.[] | select(.workspace.id == ($ws | tonumber)) | "\(.at[0]),\(.at[1]) \(.size[0])x\(.size[1])"'
}
# Select based on mode
case "$MODE" in
region)
wayfreeze & PID=$!
sleep .1
SELECTION=$(slurp 2>/dev/null)
kill $PID 2>/dev/null
;;
windows)
wayfreeze & PID=$!
sleep .1
SELECTION=$(get_rectangles | slurp -r 2>/dev/null)
kill $PID 2>/dev/null
;;
fullscreen)
SELECTION=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | "\(.x),\(.y) \((.width / .scale) | floor)x\((.height / .scale) | floor)"')
;;
smart|*)
RECTS=$(get_rectangles)
wayfreeze & PID=$!
sleep .1
SELECTION=$(echo "$RECTS" | slurp 2>/dev/null)
kill $PID 2>/dev/null
# If the selction area is L * W < 20, we'll assume you were trying to select whichever
# window or output it was inside of to prevent accidental 2px snapshots
if [[ "$SELECTION" =~ ^([0-9]+),([0-9]+)[[:space:]]([0-9]+)x([0-9]+)$ ]]; then
if (( ${BASH_REMATCH[3]} * ${BASH_REMATCH[4]} < 20 )); then
click_x="${BASH_REMATCH[1]}"
click_y="${BASH_REMATCH[2]}"
while IFS= read -r rect; do
if [[ "$rect" =~ ^([0-9]+),([0-9]+)[[:space:]]([0-9]+)x([0-9]+) ]]; then
rect_x="${BASH_REMATCH[1]}"
rect_y="${BASH_REMATCH[2]}"
rect_width="${BASH_REMATCH[3]}"
rect_height="${BASH_REMATCH[4]}"
if (( click_x >= rect_x && click_x < rect_x+rect_width && click_y >= rect_y && click_y < rect_y+rect_height )); then
SELECTION="${rect_x},${rect_y} ${rect_width}x${rect_height}"
break
fi
fi
done <<< "$RECTS"
fi
fi
;;
esac
[ -z "$SELECTION" ] && exit 0
if [[ $PROCESSING == "slurp" ]]; then
grim -g "$SELECTION" - |
satty --filename - \ satty --filename - \
--output-filename "$OUTPUT_DIR/screenshot-$(date +'%Y-%m-%d_%H-%M-%S').png" \ --output-filename "$OUTPUT_DIR/screenshot-$(date +'%Y-%m-%d_%H-%M-%S').png" \
--early-exit \ --early-exit \
--actions-on-enter save-to-clipboard \ --actions-on-enter save-to-clipboard \
--save-after-copy \ --save-after-copy \
--copy-command 'wl-copy' --copy-command 'wl-copy'
else
grim -g "$SELECTION" - | wl-copy
fi

View File

@@ -1,6 +0,0 @@
#!/bin/bash
omarchy-state clear re*-required
omarchy-hyprland-window-close-all
sleep 1 # Allow apps like Chrome to shutdown correctly
systemctl poweroff --no-wall

View File

@@ -2,18 +2,10 @@
# Go from current active terminal to its child shell process and run cwd there # Go from current active terminal to its child shell process and run cwd there
terminal_pid=$(hyprctl activewindow | awk '/pid:/ {print $2}') terminal_pid=$(hyprctl activewindow | awk '/pid:/ {print $2}')
shell_pid=$(pgrep -P "$terminal_pid" | tail -n1) shell_pid=$(pgrep -P "$terminal_pid" | head -n1)
if [[ -n $shell_pid ]]; then if [[ -n $shell_pid ]]; then
cwd=$(readlink -f "/proc/$shell_pid/cwd" 2>/dev/null) readlink -f "/proc/$shell_pid/cwd" 2>/dev/null || echo "$HOME"
shell=$(readlink -f "/proc/$shell_pid/exe" 2>/dev/null)
# Check if $shell is a valid shell and $cwd is a directory.
if grep -qs "$shell" /etc/shells && [[ -d $cwd ]]; then
echo "$cwd"
else
echo "$HOME"
fi
else else
echo "$HOME" echo "$HOME"
fi fi

8
bin/omarchy-cmd-tzupdate Executable file
View File

@@ -0,0 +1,8 @@
#!/bin/bash
notify-send " Updating time and timezone..."
sudo systemctl restart systemd-timesyncd
sudo tzupdate
new_timezone=$(timedatectl show -p Timezone --value)
omarchy-restart-waybar
notify-send " Time updated and timezone set to $new_timezone"

View File

@@ -1,61 +0,0 @@
#!/bin/bash
LOG_FILE="/tmp/omarchy-debug.log"
cat > "$LOG_FILE" <<EOF
Date: $(date)
Hostname: $(hostname)
Omarchy Branch: $(git -C "$OMARCHY_PATH" branch --show-current 2>/dev/null || echo "unknown")
=========================================
SYSTEM INFORMATION
=========================================
$(inxi -Farz)
=========================================
DMESG
=========================================
$(sudo dmesg)
=========================================
JOURNALCTL (CURRENT BOOT, ERRORS ONLY)
=========================================
$(journalctl -b -p 4..1)
=========================================
INSTALLED PACKAGES
=========================================
$({ expac -S '%n %v (%r)' $(pacman -Qqe) 2>/dev/null; comm -13 <(pacman -Sql | sort) <(pacman -Qqe | sort) | xargs -r expac -Q '%n %v (AUR)'; } | sort)
EOF
OPTIONS=("View log" "Save in current directory")
if ping -c 1 8.8.8.8 >/dev/null 2>&1; then
OPTIONS=("Upload log" "${OPTIONS[@]}")
fi
ACTION=$(gum choose "${OPTIONS[@]}")
case "$ACTION" in
"Upload log")
echo "Uploading debug log to 0x0.st..."
URL=$(curl -sF "file=@$LOG_FILE" -Fexpires=24 https://0x0.st)
if [ $? -eq 0 ] && [ -n "$URL" ]; then
echo "✓ Log uploaded successfully!"
echo "Share this URL:"
echo ""
echo " $URL"
echo ""
echo "This link will expire in 24 hours."
else
echo "Error: Failed to upload log file"
exit 1
fi
;;
"View log")
less "$LOG_FILE"
;;
"Save in current directory")
cp "$LOG_FILE" "./omarchy-debug.log"
echo "✓ Log saved to $(pwd)/omarchy-debug.log"
;;
esac

View File

@@ -18,7 +18,6 @@ if [[ -n "$font_name" && "$font_name" != "CNCLD" ]]; then
pkill -SIGUSR2 ghostty pkill -SIGUSR2 ghostty
fi fi
sed -i "s/font_family = .*/font_family = $font_name/g" ~/.config/hypr/hyprlock.conf
sed -i "s/font-family: .*/font-family: '$font_name';/g" ~/.config/waybar/style.css sed -i "s/font-family: .*/font-family: '$font_name';/g" ~/.config/waybar/style.css
sed -i "s/font-family: .*/font-family: '$font_name';/g" ~/.config/swayosd/style.css sed -i "s/font-family: .*/font-family: '$font_name';/g" ~/.config/swayosd/style.css
xmlstarlet ed -L \ xmlstarlet ed -L \
@@ -28,12 +27,7 @@ if [[ -n "$font_name" && "$font_name" != "CNCLD" ]]; then
omarchy-restart-waybar omarchy-restart-waybar
omarchy-restart-swayosd omarchy-restart-swayosd
omarchy-restart-walker
if pgrep -x ghostty; then
notify-send " You must restart Ghostty to see font change"
fi
omarchy-hook font-set "$font_name"
else else
echo "Font '$font_name' not found." echo "Font '$font_name' not found."
exit 1 exit 1

View File

@@ -1,16 +0,0 @@
#!/bin/bash
set -e
if [[ $# -lt 1 ]]; then
echo "Usage: omarchy-hook [name] [args...]"
exit 1
fi
HOOK=$1
HOOK_PATH="$HOME/.config/omarchy/hooks/$1"
shift
if [[ -f $HOOK_PATH ]]; then
bash "$HOOK_PATH" "$@"
fi

View File

@@ -1,46 +0,0 @@
#!/bin/bash
# Toggle to pop-out a tile to stay fixed on a display basis.
# Usage:
# omarchy-hyprland-window-pop [width height [x y]]
#
# Arguments:
# width Optional. Width of the floating window. Default: 1300
# height Optional. Height of the floating window. Default: 900
# x Optional. X position of the window. Must provide both X and Y to take effect.
# y Optional. Y position of the window. Must provide both X and Y to take effect.
#
# Behavior:
# - If the window is already pinned, it will be unpinned and removed from the pop layer.
# - If the window is not pinned, it will be floated, resized, moved/centered, pinned, brought to top, and popped.
width=${1:-1300}
height=${2:-900}
x=${3:-}
y=${4:-}
active=$(hyprctl activewindow -j)
pinned=$(echo "$active" | jq ".pinned")
addr=$(echo "$active" | jq -r ".address")
if [[ $pinned == "true" ]]; then
hyprctl -q --batch \
"dispatch pin address:$addr;" \
"dispatch togglefloating address:$addr;" \
"dispatch tagwindow -pop address:$addr;"
elif [[ -n $addr ]]; then
hyprctl dispatch togglefloating address:$addr
hyprctl dispatch resizeactive exact $width $height address:$addr
if [[ -n $x && -n $y ]]; then
hyprctl dispatch moveactive $x $y address:$addr
else
hyprctl dispatch centerwindow address:$addr
fi
hyprctl -q --batch \
"dispatch pin address:$addr;" \
"dispatch alterzorder top address:$addr;" \
"dispatch tagwindow +pop address:$addr;"
fi

View File

@@ -1,10 +0,0 @@
#!/bin/bash
workspace_id=$(hyprctl activeworkspace -j | jq -r .id)
gaps=$(hyprctl workspacerules -j | jq -r ".[] | select(.workspaceString==\"$workspace_id\") | .gapsOut[0] // 0")
if [[ $gaps == "0" ]]; then
hyprctl keyword "workspace $workspace_id, gapsout:10, gapsin:5, bordersize:2"
else \
hyprctl keyword "workspace $workspace_id, gapsout:0, gapsin:0, bordersize:0"
fi

View File

@@ -1,13 +0,0 @@
#!/bin/bash
if [[ -f ~/.config/chromium-flags.conf ]]; then
CONF=~/.config/chromium-flags.conf
grep -qxF -- "--oauth2-client-id=77185425430.apps.googleusercontent.com" "$CONF" ||
echo "--oauth2-client-id=77185425430.apps.googleusercontent.com" >>"$CONF"
grep -qxF -- "--oauth2-client-secret=OTJgUOQcT7lO7GsGZq2G4IlT" "$CONF" ||
echo "--oauth2-client-secret=OTJgUOQcT7lO7GsGZq2G4IlT" >>"$CONF"
echo "Now you can login to your Google Account in Chromium."
fi

View File

@@ -47,10 +47,8 @@ install_node() {
case "$1" in case "$1" in
ruby) ruby)
echo -e "Installing Ruby on Rails...\n" echo -e "Installing Ruby on Rails...\n"
omarchy-pkg-add libyaml
mise use --global ruby@latest mise use --global ruby@latest
mise settings add idiomatic_version_file_enable_tools ruby mise settings add idiomatic_version_file_enable_tools ruby
echo "gem: --no-document" > ~/.gemrc
mise x ruby -- gem install rails --no-document mise x ruby -- gem install rails --no-document
echo -e "\nYou can now run: rails new myproject" echo -e "\nYou can now run: rails new myproject"
;; ;;
@@ -121,7 +119,6 @@ java)
zig) zig)
echo -e "Installing Zig...\n" echo -e "Installing Zig...\n"
mise use --global zig@latest mise use --global zig@latest
mise use -g zls@latest
;; ;;
ocaml) ocaml)
echo -e "Installing OCaml...\n" echo -e "Installing OCaml...\n"

View File

@@ -1,9 +1,9 @@
#!/bin/bash #!/bin/bash
options=("MySQL" "PostgreSQL" "Redis" "MongoDB" "MariaDB" "MSSQL") options=("MySQL" "PostgreSQL" "Redis" "MongoDB" "MariaDB")
if [[ "$#" -eq 0 ]]; then if [[ "$#" -eq 0 ]]; then
choices=$(printf "%s\n" "${options[@]}" | gum choose --header "Select database (return to install, esc to cancel)") || main_menu choices=$(printf "%s\n" "${options[@]}" | gum choose --header "Select databases (space to select, return to install, esc to cancel)") || main_menu
else else
choices="$@" choices="$@"
fi fi
@@ -16,7 +16,6 @@ if [[ -n "$choices" ]]; then
MariaDB) sudo docker run -d --restart unless-stopped -p "127.0.0.1:3306:3306" --name=mariadb11 -e MARIADB_ROOT_PASSWORD= -e MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=true mariadb:11.8 ;; MariaDB) sudo docker run -d --restart unless-stopped -p "127.0.0.1:3306:3306" --name=mariadb11 -e MARIADB_ROOT_PASSWORD= -e MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=true mariadb:11.8 ;;
Redis) sudo docker run -d --restart unless-stopped -p "127.0.0.1:6379:6379" --name=redis redis:7 ;; Redis) sudo docker run -d --restart unless-stopped -p "127.0.0.1:6379:6379" --name=redis redis:7 ;;
MongoDB) sudo docker run -d --restart unless-stopped -p "127.0.0.1:27017:27017" --name mongodb -e MONGO_INITDB_ROOT_USERNAME=admin -e MONGO_INITDB_ROOT_PASSWORD=admin123 mongo:noble ;; MongoDB) sudo docker run -d --restart unless-stopped -p "127.0.0.1:27017:27017" --name mongodb -e MONGO_INITDB_ROOT_USERNAME=admin -e MONGO_INITDB_ROOT_PASSWORD=admin123 mongo:noble ;;
MSSQL) sudo docker run -d --restart unless-stopped -p "127.0.0.1:1433:1433" --name mssql -e MSSQL_PID=Developer -e ACCEPT_EULA=Y -e "MSSQL_SA_PASSWORD=@dmin123" mcr.microsoft.com/mssql/server:2022-CU12-ubuntu-22.04 ;;
esac esac
done done
else else

View File

@@ -4,5 +4,5 @@ echo "Installing all dependencies..."
omarchy-pkg-add dropbox dropbox-cli libappindicator-gtk3 python-gpgme nautilus-dropbox omarchy-pkg-add dropbox dropbox-cli libappindicator-gtk3 python-gpgme nautilus-dropbox
echo "Starting Dropbox..." echo "Starting Dropbox..."
uwsm-app -- dropbox-cli start &>/dev/null & uwsm app -- dropbox-cli start &>/dev/null &
echo "See Dropbox icon behind hover tray in top right and right-click for setup." echo "See Dropbox icon behind hover tray in top right and right-click for setup."

View File

@@ -1,7 +1,5 @@
#!/bin/bash #!/bin/bash
set -e
echo "Now pick dependencies matching your graphics card" echo "Now pick dependencies matching your graphics card"
sudo pacman -S steam sudo pacman -Syu --noconfirm steam
setsid gtk-launch steam >/dev/null 2>&1 & setsid gtk-launch steam >/dev/null 2>&1 &

View File

@@ -7,53 +7,13 @@ fi
package="$1" package="$1"
# Map package name to desktop entry ID
case "$package" in
alacritty) desktop_id="Alacritty.desktop" ;;
ghostty) desktop_id="com.mitchellh.ghostty.desktop" ;;
kitty) desktop_id="kitty.desktop" ;;
*)
echo "Unknown terminal: $package"
exit 1
;;
esac
# Install package # Install package
if omarchy-pkg-add $package; then omarchy-pkg-add $package
# Copy custom desktop entry for alacritty with X-TerminalArg* keys
if [[ $package == "alacritty" ]]; then
mkdir -p ~/.local/share/applications
cat > ~/.local/share/applications/Alacritty.desktop << EOF
[Desktop Entry]
Type=Application
TryExec=alacritty
Exec=alacritty
Icon=Alacritty
Terminal=false
Categories=System;TerminalEmulator;
Name=Alacritty
GenericName=Terminal
Comment=A fast, cross-platform, OpenGL terminal emulator
StartupNotify=true
StartupWMClass=Alacritty
Actions=New;
X-TerminalArgExec=-e
X-TerminalArgAppId=--class=
X-TerminalArgTitle=--title=
X-TerminalArgDir=--working-directory=
[Desktop Action New] # Set as default terminal
Name=New Terminal echo "Setting $package as new default terminal..."
Exec=alacritty sed -i "/export TERMINAL=/ c\export TERMINAL=$package" ~/.config/uwsm/default
EOF
fi
# Update xdg-terminals.list to prioritize the proper terminal # Relaunch is needed for new default to take effect
cat > ~/.config/xdg-terminals.list << EOF echo
# Terminal emulator preference order for xdg-terminal-exec gum confirm "Relaunch Hyprland to use new terminal?" && uwsm stop
# The first found and valid terminal will be used
$desktop_id
EOF
else
echo "Failed to install $package"
fi

View File

@@ -1,27 +0,0 @@
#!/bin/bash
echo "Installing VSCode..."
omarchy-pkg-add visual-studio-code-bin
mkdir -p ~/.vscode ~/.config/Code/User
cat > ~/.vscode/argv.json << 'EOF'
// This configuration file allows you to pass permanent command line arguments to VS Code.
// Only a subset of arguments is currently supported to reduce the likelihood of breaking
// the installation.
//
// PLEASE DO NOT CHANGE WITHOUT UNDERSTANDING THE IMPACT
//
// NOTE: Changing this file requires a restart of VS Code.
{
"password-store":"gnome-libsecret"
}
EOF
# Ensure VSC's own auto-update feature is turned off
printf '{\n "update.mode": "none"\n}\n' > ~/.config/Code/User/settings.json
# Apply Omarchy theme to VSCode
omarchy-theme-set-vscode
setsid gtk-launch code

View File

@@ -1,17 +0,0 @@
#!/bin/bash
set -e
# Install xpadneo to ensure controllers work out of the box
sudo pacman -S --noconfirm --needed linux-headers
yay -S --noconfirm xpadneo-dkms
# Prevent xpad/xpadneo driver conflict
echo blacklist xpad | sudo tee /etc/modprobe.d/blacklist-xpad.conf >/dev/null
echo hid_xpadneo | sudo tee /etc/modules-load.d/xpadneo.conf >/dev/null
# Give user access to game controllers
sudo usermod -a -G input $USER
# Modules need to be loaded
gum confirm "Install requires reboot. Ready?" && sudo reboot now

View File

@@ -1,3 +1,3 @@
#!/bin/bash #!/bin/bash
exec omarchy-launch-or-focus-tui "bash -c 'fastfetch; read -n 1 -s'" exec setsid uwsm app -- alacritty --class=Omarchy -o font.size=9 -e bash -c 'fastfetch; read -n 1 -s'

View File

@@ -1,4 +0,0 @@
#!/bin/bash
rfkill unblock bluetooth
exec omarchy-launch-or-focus-tui bluetui

View File

@@ -3,12 +3,10 @@
default_browser=$(xdg-settings get default-web-browser) default_browser=$(xdg-settings get default-web-browser)
browser_exec=$(sed -n 's/^Exec=\([^ ]*\).*/\1/p' {~/.local,~/.nix-profile,/usr}/share/applications/$default_browser 2>/dev/null | head -1) browser_exec=$(sed -n 's/^Exec=\([^ ]*\).*/\1/p' {~/.local,~/.nix-profile,/usr}/share/applications/$default_browser 2>/dev/null | head -1)
if [[ $browser_exec =~ (firefox|zen|librewolf|mullvad) ]]; then if [[ $browser_exec =~ (firefox|zen|librewolf) ]]; then
private_flag="--private-window" private_flag="--private-window"
elif [[ $browser_exec =~ edge ]]; then
private_flag="--inprivate"
else else
private_flag="--incognito" private_flag="--incognito"
fi fi
exec setsid uwsm-app -- "$browser_exec" "${@/--private/$private_flag}" exec setsid uwsm app -- "$browser_exec" "${@/--private/$private_flag}"

View File

@@ -1,12 +1,13 @@
#!/bin/bash #!/bin/bash
omarchy-cmd-present "$EDITOR" || EDITOR=nvim
case "$EDITOR" in case "$EDITOR" in
nvim | vim | nano | micro | hx | helix) nvim | vim | nano | micro | hx)
exec omarchy-launch-tui "$EDITOR" "$@" exec setsid uwsm app -- "$TERMINAL" -e "$EDITOR" "$@"
;;
code | codium | subl | gedit | kate | zeditor)
exec setsid uwsm app -- "$EDITOR" "$@"
;; ;;
*) *)
exec setsid uwsm-app -- "$EDITOR" "$@" exec setsid uwsm app -- "$TERMINAL" -e nvim "$@"
;; ;;
esac esac

View File

@@ -1,4 +1,4 @@
#!/bin/bash #!/bin/bash
cmd="$*" cmd="$*"
exec setsid uwsm-app -- xdg-terminal-exec --app-id=org.omarchy.terminal --title=Omarchy -e bash -c "omarchy-show-logo; $cmd; omarchy-show-done" exec setsid uwsm app -- alacritty --class=Omarchy --title=Omarchy -e bash -c "omarchy-show-logo; $cmd; omarchy-show-done"

View File

@@ -6,11 +6,11 @@ if (($# == 0)); then
fi fi
WINDOW_PATTERN="$1" WINDOW_PATTERN="$1"
LAUNCH_COMMAND="${2:-"uwsm-app -- $WINDOW_PATTERN"}" LAUNCH_COMMAND="${2:-"uwsm app -- $WINDOW_PATTERN"}"
WINDOW_ADDRESS=$(hyprctl clients -j | jq -r --arg p "$WINDOW_PATTERN" '.[]|select((.class|test("\\b" + $p + "\\b";"i")) or (.title|test("\\b" + $p + "\\b";"i")))|.address' | head -n1) WINDOW_ADDRESS=$(hyprctl clients -j | jq -r --arg p "$WINDOW_PATTERN" '.[]|select((.class+" "+.title)|test($p;"i"))|.address' | head -n1)
if [[ -n $WINDOW_ADDRESS ]]; then if [[ -n $WINDOW_ADDRESS ]]; then
hyprctl dispatch focuswindow "address:$WINDOW_ADDRESS" hyprctl dispatch focuswindow "address:$WINDOW_ADDRESS"
else else
eval exec setsid $LAUNCH_COMMAND eval exec $LAUNCH_COMMAND
fi fi

View File

@@ -1,6 +0,0 @@
#!/bin/bash
APP_ID="org.omarchy.$(basename $1)"
LAUNCH_COMMAND="omarchy-launch-tui $@"
exec omarchy-launch-or-focus "$APP_ID" "$LAUNCH_COMMAND"

View File

@@ -1,12 +1,8 @@
#!/bin/bash #!/bin/bash
if (($# == 0)); then if (($# == 0)); then
echo "Usage: omarchy-launch-or-focus-webapp [window-pattern] [url-and-flags...]" echo "Usage: omarchy-launch-or-focus-webapp [window-pattern] [url]"
exit 1 exit 1
fi fi
WINDOW_PATTERN="$1" exec omarchy-launch-or-focus "$1" "omarchy-launch-webapp '$2'"
shift
LAUNCH_COMMAND="omarchy-launch-webapp $@"
exec omarchy-launch-or-focus "$WINDOW_PATTERN" "$LAUNCH_COMMAND"

View File

@@ -6,47 +6,23 @@ if ! command -v tte &>/dev/null; then
fi fi
# Exit early if screensave is already running # Exit early if screensave is already running
pgrep -f org.omarchy.screensaver && exit 0 pgrep -f "alacritty --class Screensaver" && exit 0
# Allow screensaver to be turned off but also force started # Allow screensaver to be turned off but also force started
if [[ -f ~/.local/state/omarchy/toggles/screensaver-off ]] && [[ $1 != "force" ]]; then if [[ -f ~/.local/state/omarchy/toggles/screensaver-off ]] && [[ $1 != "force" ]]; then
exit 1 exit 1
fi fi
# Silently quit Walker on overlay
walker -q
focused=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true).name') focused=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true).name')
terminal=$(xdg-terminal-exec --print-id)
for m in $(hyprctl monitors -j | jq -r '.[] | .name'); do for m in $(hyprctl monitors -j | jq -r '.[] | .name'); do
hyprctl dispatch focusmonitor $m hyprctl dispatch focusmonitor $m
case $terminal in # FIXME: Find a way to make this generic where we it can work for kitty + ghostty
*Alacritty*)
hyprctl dispatch exec -- \ hyprctl dispatch exec -- \
alacritty --class=org.omarchy.screensaver \ alacritty --class Screensaver \
--config-file ~/.local/share/omarchy/default/alacritty/screensaver.toml \ --config-file ~/.local/share/omarchy/default/alacritty/screensaver.toml \
-e omarchy-cmd-screensaver -e omarchy-cmd-screensaver
;;
*ghostty*)
hyprctl dispatch exec -- \
ghostty --class=org.omarchy.screensaver \
--config-file=~/.local/share/omarchy/default/ghostty/screensaver \
--font-size=18 \
-e omarchy-cmd-screensaver
;;
*kitty*)
hyprctl dispatch exec -- \
kitty --class=org.omarchy.screensaver \
--override font_size=18 \
--override window_padding_width=0 \
-e omarchy-cmd-screensaver
;;
*)
notify-send "✋ Screensaver only runs in Alacritty, Ghostty, or Kitty"
;;
esac
done done
hyprctl dispatch focusmonitor $focused hyprctl dispatch focusmonitor $focused

View File

@@ -1,3 +0,0 @@
#!/bin/bash
exec setsid uwsm-app -- xdg-terminal-exec --app-id=org.omarchy.$(basename $1) -e "$1" "${@:2}"

View File

@@ -1,13 +0,0 @@
#!/bin/bash
# Ensure elephant is running before launching walker
if ! pgrep -x elephant > /dev/null; then
setsid uwsm-app -- elephant &
fi
# Ensure walker service is running
if ! pgrep -f "walker --gapplication-service" > /dev/null; then
setsid uwsm-app -- walker --gapplication-service &
fi
exec walker --width 644 --maxheight 300 --minheight 300 "$@"

View File

@@ -3,8 +3,8 @@
browser=$(xdg-settings get default-web-browser) browser=$(xdg-settings get default-web-browser)
case $browser in case $browser in
google-chrome* | brave-browser* | microsoft-edge* | opera* | vivaldi* | helium*) ;; google-chrome* | brave-browser* | microsoft-edge* | opera* | vivaldi*) ;;
*) browser="chromium.desktop" ;; *) browser="chromium.desktop" ;;
esac esac
exec setsid uwsm-app -- $(sed -n 's/^Exec=\([^ ]*\).*/\1/p' {~/.local,~/.nix-profile,/usr}/share/applications/$browser 2>/dev/null | head -1) --app="$1" "${@:2}" exec setsid uwsm app -- $(sed -n 's/^Exec=\([^ ]*\).*/\1/p' {~/.local,~/.nix-profile,/usr}/share/applications/$browser 2>/dev/null | head -1) --app="$1" "${@:2}"

View File

@@ -1,4 +1,3 @@
#!/bin/bash #!/bin/bash
rfkill unblock wifi exec setsid uwsm app -- "$TERMINAL" --class=Impala -e impala "$@"
omarchy-launch-or-focus-tui impala

View File

@@ -3,13 +3,10 @@
# Lock the screen # Lock the screen
pidof hyprlock || hyprlock & pidof hyprlock || hyprlock &
# Set keyboard layout to default (first layout)
hyprctl switchxkblayout all 0 > /dev/null 2>&1
# Ensure 1password is locked # Ensure 1password is locked
if pgrep -x "1password" >/dev/null; then if pgrep -x "1password" >/dev/null; then
1password --lock & 1password --lock &
fi fi
# Avoid running screensaver when locked # Avoid running screensaver when locked
pkill -f org.omarchy.screensaver pkill -f "$TERMINAL --class Screensaver"

View File

@@ -29,15 +29,15 @@ menu() {
local index local index
index=$(echo -e "$options" | grep -nxF "$preselect" | cut -d: -f1) index=$(echo -e "$options" | grep -nxF "$preselect" | cut -d: -f1)
if [[ -n "$index" ]]; then if [[ -n "$index" ]]; then
args+=("-c" "$index") args+=("-a" "$index")
fi fi
fi fi
echo -e "$options" | omarchy-launch-walker --dmenu --width 295 --minheight 1 --maxheight 630 -p "$prompt…" "${args[@]}" 2>/dev/null echo -e "$options" | walker --dmenu --theme dmenu_250 -p "$prompt…" "${args[@]}"
} }
terminal() { terminal() {
xdg-terminal-exec --app-id=org.omarchy.terminal "$@" alacritty --class=Omarchy -e "$@"
} }
present_terminal() { present_terminal() {
@@ -104,27 +104,27 @@ show_capture_menu() {
} }
show_screenshot_menu() { show_screenshot_menu() {
case $(menu "Screenshot" " Snap with Editing\n Straight to Clipboard") in case $(menu "Screenshot" " Region\n Window\n Display") in
*Editing*) omarchy-cmd-screenshot smart ;; *Region*) omarchy-cmd-screenshot ;;
*Clipboard*) omarchy-cmd-screenshot smart clipboard ;; *Window*) omarchy-cmd-screenshot window ;;
*Display*) omarchy-cmd-screenshot output ;;
*) show_capture_menu ;; *) show_capture_menu ;;
esac esac
} }
show_screenrecord_menu() { show_screenrecord_menu() {
omarchy-cmd-screenrecord --stop-recording && exit 0 case $(menu "Screenrecord" " Region\n Region + Audio\n Display\n Display + Audio") in
*"Region + Audio"*) omarchy-cmd-screenrecord region audio ;;
case $(menu "Screenrecord" " With desktop audio\n With desktop + microphone audio\n With desktop + microphone audio + webcam") in *Region*) omarchy-cmd-screenrecord ;;
*"With desktop audio") omarchy-cmd-screenrecord --with-desktop-audio ;; *"Display + Audio"*) omarchy-cmd-screenrecord output audio ;;
*"With desktop + microphone audio") omarchy-cmd-screenrecord --with-desktop-audio --with-microphone-audio ;; *Display*) omarchy-cmd-screenrecord output ;;
*"With desktop + microphone audio + webcam") omarchy-cmd-screenrecord --with-desktop-audio --with-microphone-audio --with-webcam ;; *) show_capture_menu ;;
*) back_to show_capture_menu ;;
esac esac
} }
show_share_menu() { show_share_menu() {
case $(menu "Share" " Clipboard\n File \n Folder") in case $(menu "Share" " Clipboard\n File \n Folder") in
*Clipboard*) omarchy-cmd-share clipboard ;; *Clipboard*) terminal bash -c "omarchy-cmd-share clipboard" ;;
*File*) terminal bash -c "omarchy-cmd-share file" ;; *File*) terminal bash -c "omarchy-cmd-share file" ;;
*Folder*) terminal bash -c "omarchy-cmd-share folder" ;; *Folder*) terminal bash -c "omarchy-cmd-share folder" ;;
*) back_to show_trigger_menu ;; *) back_to show_trigger_menu ;;
@@ -154,11 +154,16 @@ show_style_menu() {
} }
show_theme_menu() { show_theme_menu() {
omarchy-launch-walker -m menus:omarchythemes --width 800 --minheight 400 theme=$(menu "Theme" "$(omarchy-theme-list)" "" "$(omarchy-theme-current)")
if [[ "$theme" == "CNCLD" || -z "$theme" ]]; then
back_to show_style_menu
else
omarchy-theme-set "$theme"
fi
} }
show_font_menu() { show_font_menu() {
theme=$(menu "Font" "$(omarchy-font-list)" "--width 350" "$(omarchy-font-current)") theme=$(menu "Font" "$(omarchy-font-list)" "-w 350" "$(omarchy-font-current)")
if [[ "$theme" == "CNCLD" || -z "$theme" ]]; then if [[ "$theme" == "CNCLD" || -z "$theme" ]]; then
back_to show_style_menu back_to show_style_menu
else else
@@ -173,9 +178,15 @@ show_setup_menu() {
options="$options\n Defaults\n󰱔 DNS\n Security\n Config" options="$options\n Defaults\n󰱔 DNS\n Security\n Config"
case $(menu "Setup" "$options") in case $(menu "Setup" "$options") in
*Audio*) omarchy-launch-or-focus-tui wiremix ;; *Audio*) $TERMINAL --class=Wiremix -e wiremix ;;
*Wifi*) omarchy-launch-wifi ;; *Wifi*)
*Bluetooth*) omarchy-launch-bluetooth ;; rfkill unblock wifi
omarchy-launch-wifi
;;
*Bluetooth*)
rfkill unblock bluetooth
blueberry
;;
*Power*) show_setup_power_menu ;; *Power*) show_setup_power_menu ;;
*Monitors*) open_in_editor ~/.config/hypr/monitors.conf ;; *Monitors*) open_in_editor ~/.config/hypr/monitors.conf ;;
*Keybindings*) open_in_editor ~/.config/hypr/bindings.conf ;; *Keybindings*) open_in_editor ~/.config/hypr/bindings.conf ;;
@@ -221,7 +232,7 @@ show_setup_security_menu() {
} }
show_install_menu() { show_install_menu() {
case $(menu "Install" "󰣇 Package\n󰣇 AUR\n Web App\n TUI\n Service\n Style\n󰵮 Development\n Editor\n Terminal\n󱚤 AI\n󰍲 Windows\n Gaming") in case $(menu "Install" "󰣇 Package\n󰣇 AUR\n Web App\n TUI\n Service\n Style\n󰵮 Development\n Editor\n Terminal\n󱚤 AI\n Gaming") in
*Package*) terminal omarchy-pkg-install ;; *Package*) terminal omarchy-pkg-install ;;
*AUR*) terminal omarchy-pkg-aur-install ;; *AUR*) terminal omarchy-pkg-aur-install ;;
*Web*) present_terminal omarchy-webapp-install ;; *Web*) present_terminal omarchy-webapp-install ;;
@@ -232,28 +243,26 @@ show_install_menu() {
*Editor*) show_install_editor_menu ;; *Editor*) show_install_editor_menu ;;
*Terminal*) show_install_terminal_menu ;; *Terminal*) show_install_terminal_menu ;;
*AI*) show_install_ai_menu ;; *AI*) show_install_ai_menu ;;
*Windows*) present_terminal "omarchy-windows-vm install" ;;
*Gaming*) show_install_gaming_menu ;; *Gaming*) show_install_gaming_menu ;;
*) show_main_menu ;; *) show_main_menu ;;
esac esac
} }
show_install_service_menu() { show_install_service_menu() {
case $(menu "Install" " Dropbox\n Tailscale\n󰟵 Bitwarden\n Chromium Account") in case $(menu "Install" " Dropbox\n Tailscale\n󰟵 Bitwarden") in
*Dropbox*) present_terminal omarchy-install-dropbox ;; *Dropbox*) present_terminal omarchy-install-dropbox ;;
*Tailscale*) present_terminal omarchy-install-tailscale ;; *Tailscale*) present_terminal omarchy-install-tailscale ;;
*Bitwarden*) install_and_launch "Bitwarden" "bitwarden bitwarden-cli" "bitwarden" ;; *Bitwarden*) install_and_launch "Bitwarden" "bitwarden bitwarden-cli" "bitwarden" ;;
*Chromium*) present_terminal omarchy-install-chromium-google-account ;;
*) show_install_menu ;; *) show_install_menu ;;
esac esac
} }
show_install_editor_menu() { show_install_editor_menu() {
case $(menu "Install" " VSCode\n Cursor\n Zed\n Sublime Text\n Helix\n Emacs") in case $(menu "Install" " VSCode\n Cursor\n Zed\n Sublime Text\n Helix\n Emacs") in
*VSCode*) present_terminal omarchy-install-vscode ;; *VSCode*) install_and_launch "VSCode" "visual-studio-code-bin" "code" ;;
*Cursor*) install_and_launch "Cursor" "cursor-bin" "cursor" ;; *Cursor*) install_and_launch "Cursor" "cursor-bin" "cursor" ;;
*Zed*) present_terminal "echo 'Installing Zed...'; sudo pacman -S zed && setsid gtk-launch dev.zed.Zed" ;; *Zed*) install_and_launch "Zed" "zed" "dev.zed.Zed" ;;
*Sublime*) install_and_launch "Sublime Text" "sublime-text-4" "sublime_text" ;; *Sublime*) aur_install_and_launch "Sublime Text" "sublime-text-4" "sublime_text" ;;
*Helix*) install "Helix" "helix" ;; *Helix*) install "Helix" "helix" ;;
*Emacs*) install "Emacs" "emacs-wayland" && systemctl --user enable --now emacs.service ;; *Emacs*) install "Emacs" "emacs-wayland" && systemctl --user enable --now emacs.service ;;
*) show_install_menu ;; *) show_install_menu ;;
@@ -276,11 +285,10 @@ show_install_ai_menu() {
echo ollama echo ollama
) )
case $(menu "Install" "󱚤 Claude Code\n󱚤 Cursor CLI\n󱚤 Gemini\n󱚤 OpenAI Codex\n󱚤 LM Studio\n󱚤 Ollama\n󱚤 Crush\n󱚤 opencode") in case $(menu "Install" "󱚤 Claude Code\n󱚤 Gemini [AUR]\n󱚤 OpenAI Codex [AUR]\n󱚤 LM Studio\n󱚤 Ollama\n󱚤 Crush\n󱚤 opencode") in
*Claude*) install "Claude Code" "claude-code" ;; *Claude*) install "Claude Code" "claude-code" ;;
*Cursor*) install "Cursor CLI" "cursor-cli" ;; *OpenAI*) aur_install "OpenAI Codex" "openai-codex-bin" ;;
*OpenAI*) install "OpenAI Codex" "openai-codex-bin" ;; *Gemini*) aur_install "Gemini" "gemini-cli" ;;
*Gemini*) install "Gemini" "gemini-cli" ;;
*Studio*) install "LM Studio" "lmstudio" ;; *Studio*) install "LM Studio" "lmstudio" ;;
*Ollama*) install "Ollama" $ollama_pkg ;; *Ollama*) install "Ollama" $ollama_pkg ;;
*Crush*) install "Crush" "crush-bin" ;; *Crush*) install "Crush" "crush-bin" ;;
@@ -290,11 +298,10 @@ show_install_ai_menu() {
} }
show_install_gaming_menu() { show_install_gaming_menu() {
case $(menu "Install" " Steam\n RetroArch [AUR]\n󰍳 Minecraft\n󰖺 Xbox Controller [AUR]") in case $(menu "Install" " Steam\n RetroArch [AUR]\n󰍳 Minecraft") in
*Steam*) present_terminal omarchy-install-steam ;; *Steam*) present_terminal omarchy-install-steam ;;
*RetroArch*) aur_install_and_launch "RetroArch" "retroarch retroarch-assets libretro libretro-fbneo" "com.libretro.RetroArch.desktop" ;; *RetroArch*) aur_install_and_launch "RetroArch" "retroarch retroarch-assets libretro libretro-fbneo" "com.libretro.RetroArch.desktop" ;;
*Minecraft*) install_and_launch "Minecraft" "minecraft-launcher" "minecraft-launcher" ;; *Minecraft*) aur_install_and_launch "Minecraft [AUR]" "minecraft-launcher" "minecraft-launcher" ;;
*Xbox*) present_terminal omarchy-install-xbox-controllers ;;
*) show_install_menu ;; *) show_install_menu ;;
esac esac
} }
@@ -309,12 +316,11 @@ show_install_style_menu() {
} }
show_install_font_menu() { show_install_font_menu() {
case $(menu "Install" " Meslo LG Mono\n Fira Code\n Victor Code\n Bistream Vera Mono\n Iosevka" "--width 350") in case $(menu "Install" " Meslo LG Mono\n Fira Code\n Victor Code\n Bistream Vera Mono" "-w 350") in
*Meslo*) install_font "Meslo LG Mono" "ttf-meslo-nerd" "MesloLGL Nerd Font" ;; *Meslo*) install_font "Meslo LG Mono" "ttf-meslo-nerd" "MesloLGL Nerd Font" ;;
*Fira*) install_font "Fira Code" "ttf-firacode-nerd" "FiraCode Nerd Font" ;; *Fira*) install_font "Fira Code" "ttf-firacode-nerd" "FiraCode Nerd Font" ;;
*Victor*) install_font "Victor Code" "ttf-victor-mono-nerd" "VictorMono Nerd Font" ;; *Victor*) install_font "Victor Code" "ttf-victor-mono-nerd" "VictorMono Nerd Font" ;;
*Bistream*) install_font "Bistream Vera Code" "ttf-bitstream-vera-mono-nerd" "BitstromWera Nerd Font" ;; *Bistream*) install_font "Bistream Vera Code" "ttf-bitstream-vera-mono-nerd" "BitstromWera Nerd Font" ;;
*Iosevka*) install_font "Iosevka" "ttf-iosevka-nerd" "Iosevka Nerd Font Mono" ;;
*) show_install_menu ;; *) show_install_menu ;;
esac esac
} }
@@ -365,12 +371,11 @@ show_install_elixir_menu() {
} }
show_remove_menu() { show_remove_menu() {
case $(menu "Remove" "󰣇 Package\n Web App\n TUI\n󰸌 Theme\n󰍲 Windows\n󰈷 Fingerprint\n Fido2") in case $(menu "Remove" "󰣇 Package\n Web App\n TUI\n󰸌 Theme\n󰈷 Fingerprint\n Fido2") in
*Package*) terminal omarchy-pkg-remove ;; *Package*) terminal omarchy-pkg-remove ;;
*Web*) present_terminal omarchy-webapp-remove ;; *Web*) present_terminal omarchy-webapp-remove ;;
*TUI*) present_terminal omarchy-tui-remove ;; *TUI*) present_terminal omarchy-tui-remove ;;
*Theme*) present_terminal omarchy-theme-remove ;; *Theme*) present_terminal omarchy-theme-remove ;;
*Windows*) present_terminal "omarchy-windows-vm remove" ;;
*Fingerprint*) present_terminal "omarchy-setup-fingerprint --remove" ;; *Fingerprint*) present_terminal "omarchy-setup-fingerprint --remove" ;;
*Fido2*) present_terminal "omarchy-setup-fido2 --remove" ;; *Fido2*) present_terminal "omarchy-setup-fido2 --remove" ;;
*) show_main_menu ;; *) show_main_menu ;;
@@ -378,29 +383,18 @@ show_remove_menu() {
} }
show_update_menu() { show_update_menu() {
case $(menu "Update" " Omarchy\n󰔫 Channel\n Config\n󰸌 Extra Themes\n Process\n󰇅 Hardware\n Firmware\n Password\n Timezone\n Time") in case $(menu "Update" " Omarchy\n Config\n󰸌 Extra Themes\n Process\n󰇅 Hardware\n Password\n Timezone") in
*Omarchy*) present_terminal omarchy-update ;; *Omarchy*) present_terminal omarchy-update ;;
*Channel*) show_update_channel_menu ;;
*Config*) show_update_config_menu ;; *Config*) show_update_config_menu ;;
*Themes*) present_terminal omarchy-theme-update ;; *Themes*) present_terminal omarchy-theme-update ;;
*Process*) show_update_process_menu ;; *Process*) show_update_process_menu ;;
*Hardware*) show_update_hardware_menu ;; *Hardware*) show_update_hardware_menu ;;
*Firmware*) present_terminal omarchy-update-firmware ;; *Timezone*) omarchy-cmd-tzupdate ;;
*Timezone*) present_terminal omarchy-tz-select ;;
*Time*) present_terminal omarchy-update-time ;;
*Password*) show_update_password_menu ;; *Password*) show_update_password_menu ;;
*) show_main_menu ;; *) show_main_menu ;;
esac esac
} }
show_update_channel_menu() {
case $(menu "Update channel" "🟢 Stable\n🟡 Edge\n🔴 Dev") in
*Stable*) present_terminal "omarchy-channel-set stable" ;;
*Edge*) present_terminal "omarchy-channel-set edge" ;;
*Dev*) present_terminal "omarchy-channel-set dev" ;;
*) show_update_menu ;;
esac
}
show_update_process_menu() { show_update_process_menu() {
case $(menu "Restart" " Hypridle\n Hyprsunset\n Swayosd\n󰌧 Walker\n󰍜 Waybar") in case $(menu "Restart" " Hypridle\n Hyprsunset\n Swayosd\n󰌧 Walker\n󰍜 Waybar") in
*Hypridle*) omarchy-restart-hypridle ;; *Hypridle*) omarchy-restart-hypridle ;;
@@ -427,8 +421,7 @@ show_update_config_menu() {
} }
show_update_hardware_menu() { show_update_hardware_menu() {
case $(menu "Restart" " Audio\n󱚾 Wi-Fi\n󰂯 Bluetooth") in case $(menu "Restart" "󱚾 Wi-Fi\n󰂯 Bluetooth") in
*Audio*) present_terminal omarchy-restart-pipewire ;;
*Wi-Fi*) present_terminal omarchy-restart-wifi ;; *Wi-Fi*) present_terminal omarchy-restart-wifi ;;
*Bluetooth*) present_terminal omarchy-restart-bluetooth ;; *Bluetooth*) present_terminal omarchy-restart-bluetooth ;;
*) show_update_menu ;; *) show_update_menu ;;
@@ -444,23 +437,24 @@ show_update_password_menu() {
} }
show_system_menu() { show_system_menu() {
case $(menu "System" " Lock\n󱄄 Screensaver\n󰜉 Restart\n󰐥 Shutdown") in case $(menu "System" " Lock\n󱄄 Screensaver\n󰤄 Suspend\n Relaunch\n󰜉 Restart\n󰐥 Shutdown") in
*Lock*) omarchy-lock-screen ;; *Lock*) omarchy-lock-screen ;;
*Screensaver*) omarchy-launch-screensaver force ;; *Screensaver*) omarchy-launch-screensaver force ;;
*Restart*) omarchy-cmd-reboot ;; *Suspend*) systemctl suspend ;;
*Shutdown*) omarchy-cmd-shutdown ;; *Relaunch*) uwsm stop ;;
*Restart*) systemctl reboot ;;
*Shutdown*) systemctl poweroff ;;
*) back_to show_main_menu ;; *) back_to show_main_menu ;;
esac esac
} }
show_main_menu() { show_main_menu() {
go_to_menu "$(menu "Go" "󰀻 Apps\n󰧑 Learn\n󱓞 Trigger\n Style\n Setup\n󰉉 Install\n󰭌 Remove\n Update\n About\n System")" go_to_menu "$(menu "Go" "󰀻 Apps\n󱓞 Trigger\n Style\n Setup\n󰉉 Install\n󰭌 Remove\n Update\n󰧑 Learn\n About\n System")"
} }
go_to_menu() { go_to_menu() {
case "${1,,}" in case "${1,,}" in
*apps*) walker -p "Launch…" ;; *apps*) walker -p "Launch…" ;;
*learn*) show_learn_menu ;;
*trigger*) show_trigger_menu ;; *trigger*) show_trigger_menu ;;
*share*) show_share_menu ;; *share*) show_share_menu ;;
*style*) show_style_menu ;; *style*) show_style_menu ;;
@@ -472,6 +466,7 @@ go_to_menu() {
*install*) show_install_menu ;; *install*) show_install_menu ;;
*remove*) show_remove_menu ;; *remove*) show_remove_menu ;;
*update*) show_update_menu ;; *update*) show_update_menu ;;
*learn*) show_learn_menu ;;
*about*) omarchy-launch-about ;; *about*) omarchy-launch-about ;;
*system*) show_system_menu ;; *system*) show_system_menu ;;
esac esac

View File

@@ -3,80 +3,6 @@
# A script to display Hyprland keybindings defined in your configuration # A script to display Hyprland keybindings defined in your configuration
# using walker for an interactive search menu. # using walker for an interactive search menu.
declare -A KEYCODE_SYM_MAP
build_keymap_cache() {
local keymap
keymap="$(xkbcli compile-keymap)" || {
echo "Failed to compile keymap" >&2
return 1
}
while IFS=, read -r code sym; do
[[ -z "$code" || -z "$sym" ]] && continue
KEYCODE_SYM_MAP["$code"]="$sym"
done < <(
awk '
BEGIN { sec = "" }
/xkb_keycodes/ { sec = "codes"; next }
/xkb_symbols/ { sec = "syms"; next }
sec == "codes" {
if (match($0, /<([A-Za-z0-9_]+)>\s*=\s*([0-9]+)\s*;/, m)) code_by_name[m[1]] = m[2]
}
sec == "syms" {
if (match($0, /key\s*<([A-Za-z0-9_]+)>\s*\{\s*\[\s*([^, \]]+)/, m)) sym_by_name[m[1]] = m[2]
}
END {
for (k in code_by_name) {
c = code_by_name[k]
s = sym_by_name[k]
if (c != "" && s != "" && s != "NoSymbol") print c "," s
}
}
' <<<"$keymap"
)
}
lookup_keycode_cached() {
printf '%s\n' "${KEYCODE_SYM_MAP[$1]}"
}
parse_keycodes() {
local start end elapsed
[[ "${DEBUG:-0}" == "1" ]] && start=$(date +%s.%N)
while IFS= read -r line; do
if [[ "$line" =~ code:([0-9]+) ]]; then
code="${BASH_REMATCH[1]}"
symbol=$(lookup_keycode_cached "$code" "$XKB_KEYMAP_CACHE")
echo "${line/code:${code}/$symbol}"
elif [[ "$line" =~ mouse:([0-9]+) ]]; then
code="${BASH_REMATCH[1]}"
case "$code" in
272) symbol="LEFT MOUSE BUTTON" ;;
273) symbol="RIGHT MOUSE BUTTON" ;;
274) symbol="MIDDLE MOUSE BUTTON" ;;
*) symbol="mouse:${code}" ;;
esac
echo "${line/mouse:${code}/$symbol}"
else
echo "$line"
fi
done
if [[ "$DEBUG" == "1" ]]; then
end=$(date +%s.%N)
# fall back to awk if bc is missing
if command -v bc >/dev/null 2>&1; then
elapsed=$(echo "$end - $start" | bc)
else
elapsed=$(awk -v s="$start" -v e="$end" 'BEGIN{printf "%.6f", (e - s)}')
fi
echo "[DEBUG] parse_keycodes elapsed: ${elapsed}s" >&2
fi
}
# Fetch dynamic keybindings from Hyprland # Fetch dynamic keybindings from Hyprland
# #
# Also do some pre-processing: # Also do some pre-processing:
@@ -85,13 +11,12 @@ parse_keycodes() {
# - Map numeric modifier key mask to a textual rendition # - Map numeric modifier key mask to a textual rendition
# - Output comma-separated values that the parser can understand # - Output comma-separated values that the parser can understand
dynamic_bindings() { dynamic_bindings() {
hyprctl -j binds | hyprctl -j binds | \
jq -r '.[] | {modmask, key, keycode, description, dispatcher, arg} | "\(.modmask),\(.key)@\(.keycode),\(.description),\(.dispatcher),\(.arg)"' | jq -r '.[] | {modmask, key, keycode, description, dispatcher, arg} | "\(.modmask),\(.key)@\(.keycode),\(.description),\(.dispatcher),\(.arg)"' | \
sed -r \ sed -r \
-e 's/null//' \ -e 's/null//' \
-e 's,~/.local/share/omarchy/bin/,,' \ -e 's,~/.local/share/omarchy/bin/,,' \
-e 's,uwsm app -- ,,' \ -e 's,uwsm app -- ,,' \
-e 's,uwsm-app -- ,,' \
-e 's/@0//' \ -e 's/@0//' \
-e 's/,@/,code:/' \ -e 's/,@/,code:/' \
-e 's/^0,/,/' \ -e 's/^0,/,/' \
@@ -112,11 +37,6 @@ dynamic_bindings() {
-e 's/^77,/SUPER SHIFT CTRL ALT,/' -e 's/^77,/SUPER SHIFT CTRL ALT,/'
} }
# Hardcoded bindings, like the copy-url extension and such
static_bindings() {
echo "SHIFT ALT,L,Copy URL from Web App,extension,copy-url"
}
# Parse and format keybindings # Parse and format keybindings
# #
# `awk` does the heavy lifting: # `awk` does the heavy lifting:
@@ -163,67 +83,11 @@ parse_bindings() {
}' }'
} }
prioritize_entries() {
awk '
{
line = $0
prio = 50
if (match(line, /Terminal/)) prio = 0
if (match(line, /Browser/) && !match(line, /Browser[[:space:]]*\(/)) prio = 1
if (match(line, /File manager/)) prio = 2
if (match(line, /Launch apps/)) prio = 3
if (match(line, /Omarchy menu/)) prio = 4
if (match(line, /System menu/)) prio = 5
if (match(line, /Theme menu/)) prio = 6
if (match(line, /Full screen/)) prio = 7
if (match(line, /Close window/)) prio = 8
if (match(line, /Toggle window floating/)) prio = 9
if (match(line, /Toggle window split/)) prio = 10
if (match(line, /Universal/)) prio = 11
if (match(line, /Clipboard/)) prio = 12
if (match(line, /Emoji picker/)) prio = 13
if (match(line, /Color picker/)) prio = 14
if (match(line, /Screenshot/)) prio = 15
if (match(line, /Screenrecording/)) prio = 16
if (match(line, /(Switch|Next|Former|Previous).*workspace/)) prio = 17
if (match(line, /Move window to workspace/)) prio = 18
if (match(line, /Swap window/)) prio = 19
if (match(line, /Move window focus/)) prio = 20
if (match(line, /Move window$/)) prio = 21
if (match(line, /Resize window/)) prio = 22
if (match(line, /Expand window/)) prio = 23
if (match(line, /Shrink window/)) prio = 24
if (match(line, /scratchpad/)) prio = 25
if (match(line, /notification/)) prio = 26
if (match(line, /Toggle window transparency/)) prio = 27
if (match(line, /Toggle workspace gaps/)) prio = 28
if (match(line, /Toggle nightlight/)) prio = 29
if (match(line, /group/)) prio = 94
if (match(line, /Scroll active workspace/)) prio = 95
if (match(line, /Cycle to/)) prio = 96
if (match(line, /Reveal active/)) prio = 97
if (match(line, /Apple Display/)) prio = 98
if (match(line, /XF86/)) prio = 99
# print "priority<TAB>line"
printf "%d\t%s\n", prio, line
}' |
sort -k1,1n -k2,2 |
cut -f2-
}
monitor_height=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | .height') monitor_height=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | .height')
menu_height=$((monitor_height * 40 / 100)) menu_height=$((monitor_height * 40 / 100))
build_keymap_cache dynamic_bindings | \
sort -u | \
{ parse_bindings | \
dynamic_bindings walker --dmenu --theme keybindings -p 'Keybindings' -w 800 -h "$menu_height"
static_bindings
} |
sort -u |
parse_keycodes |
parse_bindings |
prioritize_entries |
walker --dmenu -p 'Keybindings' --width 800 --height "$menu_height"

View File

@@ -1,14 +1,8 @@
#!/bin/bash #!/bin/bash
if omarchy-pkg-missing "$@"; then
sudo pacman -S --noconfirm --needed "$@" || exit 1
fi
for pkg in "$@"; do for pkg in "$@"; do
# Secondary check to handle states where pacman doesn't actually register an error
if ! pacman -Q "$pkg" &>/dev/null; then if ! pacman -Q "$pkg" &>/dev/null; then
echo -e "\033[31mError: Package '$pkg' did not install\033[0m" >&2 sudo pacman -S --noconfirm "$pkg" || exit 1
exit 1
fi fi
done done

View File

@@ -3,7 +3,7 @@
fzf_args=( fzf_args=(
--multi --multi
--preview 'yay -Siia {1}' --preview 'yay -Siia {1}'
--preview-label='alt-p: toggle description, alt-b/B: toggle PKGBUILD, alt-j/k: scroll, tab: multi-select' --preview-label='alt-p: toggle description, alt-b/B: toggle PKGBUILD, alt-j/k: scroll, tab: multi-select, F11: maximize'
--preview-label-pos='bottom' --preview-label-pos='bottom'
--preview-window 'down:65%:wrap' --preview-window 'down:65%:wrap'
--bind 'alt-p:toggle-preview' --bind 'alt-p:toggle-preview'

7
bin/omarchy-pkg-ignored Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/bash
IGNORED_PACKAGES_FILE="$OMARCHY_PATH/install/packages.ignored"
if [[ -f $IGNORED_PACKAGES_FILE ]]; then
tr '\r\n' ',' <"$IGNORED_PACKAGES_FILE" | sed 's/,$//'
fi

View File

@@ -3,7 +3,7 @@
fzf_args=( fzf_args=(
--multi --multi
--preview 'pacman -Sii {1}' --preview 'pacman -Sii {1}'
--preview-label='alt-p: toggle description, alt-j/k: scroll, tab: multi-select' --preview-label='alt-p: toggle description, alt-j/k: scroll, tab: multi-select, F11: maximize'
--preview-label-pos='bottom' --preview-label-pos='bottom'
--preview-window 'down:65%:wrap' --preview-window 'down:65%:wrap'
--bind 'alt-p:toggle-preview' --bind 'alt-p:toggle-preview'

View File

@@ -3,7 +3,7 @@
fzf_args=( fzf_args=(
--multi --multi
--preview 'yay -Qi {1}' --preview 'yay -Qi {1}'
--preview-label='alt-p: toggle description, alt-j/k: scroll, tab: multi-select' --preview-label='alt-p: toggle description, alt-j/k: scroll, tab: multi-select, F11: maximize'
--preview-label-pos='bottom' --preview-label-pos='bottom'
--preview-window 'down:65%:wrap' --preview-window 'down:65%:wrap'
--bind 'alt-p:toggle-preview' --bind 'alt-p:toggle-preview'

View File

@@ -10,8 +10,4 @@ mkdir -p ~/.local/share/applications
cp ~/.local/share/omarchy/applications/*.desktop ~/.local/share/applications/ cp ~/.local/share/omarchy/applications/*.desktop ~/.local/share/applications/
cp ~/.local/share/omarchy/applications/hidden/*.desktop ~/.local/share/applications/ cp ~/.local/share/omarchy/applications/hidden/*.desktop ~/.local/share/applications/
# Refresh the webapps
bash $OMARCHY_PATH/install/packaging/icons.sh
bash $OMARCHY_PATH/install/packaging/webapps.sh
update-desktop-database ~/.local/share/applications update-desktop-database ~/.local/share/applications

View File

@@ -2,6 +2,6 @@
omarchy-refresh-config hypr/autostart.conf omarchy-refresh-config hypr/autostart.conf
omarchy-refresh-config hypr/bindings.conf omarchy-refresh-config hypr/bindings.conf
omarchy-refresh-config hypr/envs.conf
omarchy-refresh-config hypr/input.conf omarchy-refresh-config hypr/input.conf
omarchy-refresh-config hypr/looknfeel.conf
omarchy-refresh-config hypr/hyprland.conf omarchy-refresh-config hypr/hyprland.conf

View File

@@ -1,34 +0,0 @@
#!/bin/bash
if [[ -f /boot/EFI/Linux/omarchy_linux.efi ]] && [[ -f /boot/EFI/Linux/$(cat /etc/machine-id)_linux.efi ]]; then
echo "Cleanup extra UKI"
sudo rm -f /boot/EFI/Linux/$(cat /etc/machine-id)_linux.efi
fi
echo "Resetting limine config"
sudo mv /boot/limine.conf /boot/limine.conf.bak
sudo tee /boot/limine.conf <<EOF >/dev/null
### Read more at config document: https://github.com/limine-bootloader/limine/blob/trunk/CONFIG.md
#timeout: 3
default_entry: 2
interface_branding: Omarchy Bootloader
interface_branding_color: 2
hash_mismatch_panic: no
term_background: 1a1b26
backdrop: 1a1b26
# Terminal colors (Tokyo Night palette)
term_palette: 15161e;f7768e;9ece6a;e0af68;7aa2f7;bb9af7;7dcfff;a9b1d6
term_palette_bright: 414868;f7768e;9ece6a;e0af68;7aa2f7;bb9af7;7dcfff;c0caf5
# Text colors
term_foreground: c0caf5
term_foreground_bright: c0caf5
term_background_bright: 24283b
EOF
sudo limine-update
sudo limine-snapper-sync

View File

@@ -1,22 +0,0 @@
#!/bin/bash
# Take backup of existing files
sudo cp -f /etc/pacman.conf /etc/pacman.conf.bak
sudo cp -f /etc/pacman.d/mirrorlist /etc/pacman.d/mirrorlist.bak
sudo cp -f ~/.local/share/omarchy/default/pacman/pacman.conf /etc/pacman.conf
if [[ $1 == "edge" ]]; then
sudo cp -f ~/.local/share/omarchy/default/pacman/mirrorlist-edge /etc/pacman.d/mirrorlist
sudo sed -i 's|https://pkgs.omarchy.org/.*$arch|https://pkgs.omarchy.org/edge/$arch|' /etc/pacman.conf
echo "Setting channel to edge"
else
sudo cp -f ~/.local/share/omarchy/default/pacman/mirrorlist-stable /etc/pacman.d/mirrorlist
sudo sed -i 's|https://pkgs.omarchy.org/.*$arch|https://pkgs.omarchy.org/stable/$arch|' /etc/pacman.conf
echo "Setting channel to stable"
fi
echo
# Reset all package DBs and then update
sudo pacman -Syyu --noconfirm

View File

@@ -0,0 +1,3 @@
#!/bin/bash
sudo cp -f ~/.local/share/omarchy/default/pacman/mirrorlist /etc/pacman.d/mirrorlist

View File

@@ -1,11 +1,4 @@
#!/bin/bash #!/bin/bash
# Ensure walker is set to autostart
mkdir -p ~/.config/autostart/
cp $OMARCHY_PATH/autostart/walker.desktop ~/.config/autostart/
systemctl --user daemon-reload
omarchy-refresh-config walker/config.toml omarchy-refresh-config walker/config.toml
omarchy-refresh-config elephant/calc.toml
omarchy-refresh-config elephant/desktopapplications.toml
omarchy-restart-walker omarchy-restart-walker

View File

@@ -1,33 +0,0 @@
#!/bin/bash
set -e
if [ "$EUID" -eq 0 ]; then
echo "Error: This script should not be run as root"
exit 1
fi
echo -e "This will reinstall all the default Omarchy packages and reset all default configs.\nWarning: All changes to configs will be lost.\n"
if gum confirm "Are you sure you want to reinstall and lose all config changes?"; then
echo "Resetting Omarchy repository"
git clone "https://github.com/basecamp/omarchy.git" ~/.local/share/omarchy-new >/dev/null
rm -rf $OMARCHY_PATH
mv ~/.local/share/omarchy-new $OMARCHY_PATH
echo "Reinstalling missing Omarchy packages"
mapfile -t packages < <(grep -v '^#' "$OMARCHY_PATH/install/omarchy-base.packages" | grep -v '^$')
sudo pacman -Syu --noconfirm --needed "${packages[@]}"
echo "Resetting all Omarchy configs"
cp -R ~/.local/share/omarchy/config/* ~/.config/
cp ~/.local/share/omarchy/default/bashrc ~/.bashrc
echo '[[ -f ~/.bashrc ]] && . ~/.bashrc' | tee ~/.bash_profile >/dev/null
$(bash $OMARCHY_PATH/install/config/theme.sh)
$(bash $OMARCHY_PATH/install/config/git.sh)
omarchy-refresh-limine
omarchy-refresh-plymouth
omarchy-nvim-setup
fi

View File

@@ -1,4 +1,4 @@
#!/bin/bash #!/bin/bash
pkill -x $1 pkill -x $1
setsid uwsm-app -- $1 >/dev/null 2>&1 & setsid uwsm app -- $1 >/dev/null 2>&1 &

View File

@@ -1,5 +1,4 @@
#!/bin/bash #!/bin/bash
echo -e "Unblocking bluetooth...\n"
rfkill unblock bluetooth rfkill unblock bluetooth
rfkill list bluetooth rfkill list bluetooth

View File

@@ -1,4 +0,0 @@
#!/bin/bash
echo -e "Restarting pipewire audio service...\n"
systemctl --user restart pipewire.service

View File

@@ -1,13 +0,0 @@
#!/bin/bash
if [[ -f ~/.config/alacritty/alacritty.toml ]]; then
touch ~/.config/alacritty/alacritty.toml
fi
if pgrep -x kitty; then
killall -SIGUSR1 kitty
fi
if pgrep -x ghostty; then
killall -SIGUSR2 ghostty
fi

View File

@@ -1,18 +1,7 @@
#!/bin/bash #!/bin/bash
# Detect if we're running as root (from pacman hook) pkill walker
if [[ $EUID -eq 0 ]]; then # FIXME: Reenable the walker service once the memory leak has been fixed
# Get the owner of this script to determine which user to run as # See https://github.com/basecamp/omarchy/issues/698
SCRIPT_OWNER=$(stat -c '%U' "$0") # setsid uwsm app -- walker --gapplication-service &
USER_UID=$(id -u "$SCRIPT_OWNER") echo # Always end in success so we don't terminate further running
# Restart services as the script owner
systemd-run --uid="$SCRIPT_OWNER" --setenv=XDG_RUNTIME_DIR="/run/user/$USER_UID" \
bash -c "
systemctl --user restart elephant.service
systemctl --user restart app-walker@autostart.service
"
else
systemctl --user restart elephant.service
systemctl --user restart app-walker@autostart.service
fi

View File

@@ -1,5 +1,4 @@
#!/bin/bash #!/bin/bash
echo -e "Unblocking wifi...\n"
rfkill unblock wifi rfkill unblock wifi
rfkill list wifi rfkill list wifi

View File

@@ -20,7 +20,7 @@ print_info() {
} }
check_fingerprint_hardware() { check_fingerprint_hardware() {
if ! lsusb | grep -Eiq 'fingerprint|synaptics|goodix|elan|validity|FPC'; then if ! lsusb | grep -Eiq 'fingerprint|synaptics|goodix|elan|validity'; then
print_error "\nNo fingerprint sensor detected." print_error "\nNo fingerprint sensor detected."
return 1 return 1
fi fi
@@ -51,16 +51,6 @@ EOF
fi fi
} }
add_hyprlock_fingerprint_icon() {
print_info "Adding fingerprint icon to hyprlock placeholder text..."
sed -i 's/placeholder_text = .*/placeholder_text = <span> Enter Password 󰈷 <\/span>/' ~/.config/hypr/hyprlock.conf
}
remove_hyprlock_fingerprint_icon() {
print_info "Removing fingerprint icon from hyprlock placeholder text..."
sed -i 's/placeholder_text = .*/placeholder_text = Enter Password/' ~/.config/hypr/hyprlock.conf
}
remove_pam_config() { remove_pam_config() {
# Remove from sudo # Remove from sudo
if grep -q pam_fprintd.so /etc/pam.d/sudo; then if grep -q pam_fprintd.so /etc/pam.d/sudo; then
@@ -81,9 +71,6 @@ if [[ "--remove" == "$1" ]]; then
# Remove PAM configuration # Remove PAM configuration
remove_pam_config remove_pam_config
# Remove fingerprint icon from hyprlock placeholder text
remove_hyprlock_fingerprint_icon
# Uninstall packages # Uninstall packages
print_info "Removing fingerprint packages..." print_info "Removing fingerprint packages..."
sudo pacman -Rns --noconfirm fprintd sudo pacman -Rns --noconfirm fprintd
@@ -103,9 +90,6 @@ else
# Configure PAM # Configure PAM
setup_pam_config setup_pam_config
# Add fingerprint icon to hyprlock placeholder text
add_hyprlock_fingerprint_icon
# Enroll first fingerprint # Enroll first fingerprint
print_success "\nLet's setup your right index finger as the first fingerprint." print_success "\nLet's setup your right index finger as the first fingerprint."
print_info "Keep moving the finger around on sensor until the process completes.\n" print_info "Keep moving the finger around on sensor until the process completes.\n"

View File

@@ -1,7 +1,5 @@
#!/bin/bash #!/bin/bash
set -e
COMMAND="$1" COMMAND="$1"
OMARCHY_PATH=${OMARCHY_PATH:-$HOME/.local/share/omarchy} OMARCHY_PATH=${OMARCHY_PATH:-$HOME/.local/share/omarchy}

View File

@@ -5,13 +5,13 @@
BACKGROUNDS_DIR="$HOME/.config/omarchy/current/theme/backgrounds/" BACKGROUNDS_DIR="$HOME/.config/omarchy/current/theme/backgrounds/"
CURRENT_BACKGROUND_LINK="$HOME/.config/omarchy/current/background" CURRENT_BACKGROUND_LINK="$HOME/.config/omarchy/current/background"
mapfile -d '' -t BACKGROUNDS < <(find -L "$BACKGROUNDS_DIR" -type f -print0 | sort -z) mapfile -d '' -t BACKGROUNDS < <(find "$BACKGROUNDS_DIR" -type f -print0 | sort -z)
TOTAL=${#BACKGROUNDS[@]} TOTAL=${#BACKGROUNDS[@]}
if [[ $TOTAL -eq 0 ]]; then if [[ $TOTAL -eq 0 ]]; then
notify-send "No background was found for theme" -t 2000 notify-send "No background was found for theme" -t 2000
pkill -x swaybg pkill -x swaybg
setsid uwsm-app -- swaybg --color '#000000' >/dev/null 2>&1 & setsid uwsm app -- swaybg --color '#000000' >/dev/null 2>&1 &
else else
# Get current background from symlink # Get current background from symlink
if [[ -L "$CURRENT_BACKGROUND_LINK" ]]; then if [[ -L "$CURRENT_BACKGROUND_LINK" ]]; then
@@ -44,5 +44,5 @@ else
# Relaunch swaybg # Relaunch swaybg
pkill -x swaybg pkill -x swaybg
setsid uwsm-app -- swaybg -i "$CURRENT_BACKGROUND_LINK" -m fill >/dev/null 2>&1 & setsid uwsm app -- swaybg -i "$CURRENT_BACKGROUND_LINK" -m fill >/dev/null 2>&1 &
fi fi

View File

@@ -7,7 +7,7 @@ if [ -z "$1" ]; then
mapfile -t extra_themes < <(find ~/.config/omarchy/themes -mindepth 1 -maxdepth 1 -type d ! -xtype l -printf '%f\n') mapfile -t extra_themes < <(find ~/.config/omarchy/themes -mindepth 1 -maxdepth 1 -type d ! -xtype l -printf '%f\n')
if [[ ${#extra_themes[@]} -gt 0 ]]; then if [[ ${#extra_themes[@]} -gt 0 ]]; then
THEME_NAME=$(printf '%s\n' "${extra_themes[@]}" | sort | gum choose --header="Remove extra theme") THEME_NAME=$(gum choose --header="Remove extra theme" "${extra_themes[@]}")
else else
echo "No extra themes installed." echo "No extra themes installed."
exit 1 exit 1

View File

@@ -24,21 +24,15 @@ ln -nsf "$THEME_PATH" "$CURRENT_THEME_DIR"
omarchy-theme-bg-next omarchy-theme-bg-next
# Restart components to apply new theme # Restart components to apply new theme
if pgrep -x waybar >/dev/null; then omarchy-restart-waybar
omarchy-restart-waybar
fi
omarchy-restart-swayosd omarchy-restart-swayosd
omarchy-restart-terminal
hyprctl reload hyprctl reload
pkill -SIGUSR2 btop pkill -SIGUSR2 btop
makoctl reload makoctl reload
# Change gnome, browser, vscode, cursor themes # Change gnome, browser, vscode themes
omarchy-theme-set-terminal
omarchy-theme-set-gnome omarchy-theme-set-gnome
omarchy-theme-set-eza
omarchy-theme-set-browser omarchy-theme-set-browser
omarchy-theme-set-vscode omarchy-theme-set-vscode
omarchy-theme-set-cursor
omarchy-theme-set-obsidian
# Call hook on theme set
omarchy-hook theme-set "$THEME_NAME"

View File

@@ -2,25 +2,18 @@
CHROMIUM_THEME=~/.config/omarchy/current/theme/chromium.theme CHROMIUM_THEME=~/.config/omarchy/current/theme/chromium.theme
if omarchy-cmd-present chromium || omarchy-cmd-present helium-browser || omarchy-cmd-present brave; then if omarchy-cmd-present chromium || omarchy-cmd-present brave; then
if [[ -f $CHROMIUM_THEME ]]; then if [[ -f $CHROMIUM_THEME ]]; then
THEME_RGB_COLOR=$(<$CHROMIUM_THEME) rgb=$(<$CHROMIUM_THEME)
THEME_HEX_COLOR=$(printf '#%02x%02x%02x' ${THEME_RGB_COLOR//,/ }) THEME_HEX_COLOR=$(printf '#%02x%02x%02x' ${rgb//,/ })
else else
# Use a default, neutral grey if theme doesn't have a color # Use a default, neutral grey if theme doesn't have a color
THEME_RGB_COLOR="28,32,39"
THEME_HEX_COLOR="#1c2027" THEME_HEX_COLOR="#1c2027"
fi fi
if omarchy-cmd-present chromium; then if omarchy-cmd-present chromium; then
rm -f /etc/chromium/policies/managed/color.json echo "{\"BrowserThemeColor\": \"$THEME_HEX_COLOR\"}" | tee "/etc/chromium/policies/managed/color.json" >/dev/null
chromium --no-startup-window --set-theme-color="$THEME_RGB_COLOR" chromium --refresh-platform-policy --no-startup-window
if [[ -f ~/.config/omarchy/current/theme/light.mode ]]; then
chromium --no-startup-window --set-color-scheme="light"
else
chromium --no-startup-window --set-color-scheme="dark"
fi
fi fi
if omarchy-cmd-present brave; then if omarchy-cmd-present brave; then

View File

@@ -1,4 +0,0 @@
#!/bin/bash
# Call the VSCode theme setter with Cursor-specific parameters
omarchy-theme-set-vscode cursor "$HOME/.config/Cursor/User/settings.json" "$HOME/.local/state/omarchy/toggles/skip-cursor-theme-changes" Cursor

7
bin/omarchy-theme-set-eza Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/bash
if [ -f ~/.config/omarchy/current/theme/eza.yml ]; then
ln -snf ~/.config/omarchy/current/theme/eza.yml ~/.config/eza/theme.yml
else
rm -f ~/.config/eza/theme.yml
fi

View File

@@ -1,684 +0,0 @@
#!/bin/bash
# omarchy-theme-set-obsidian: Bootstrap and update Omarchy theme for Obsidian
#
# - Ensures registry at ~/.local/state/omarchy/obsidian-vaults
# - Populates by extracting vault paths from ~/.config/obsidian/obsidian.json
# - For each valid vault:
# - Ensures .obsidian/themes/Omarchy/{manifest.json, theme.css}
# - Updates theme.css (uses current themes obsidian.css if present; otherwise generates -- see below)
# Theme automagic generation logic:
#
# - Background/foreground: read from ~/.config/omarchy/current/theme/alacritty.toml [colors.primary]
# (background/foreground). Fallbacks: bg=#1a1b26, fg=#a9b1d6. Compute bg brightness for light/dark handling.
# - Palette extraction: collect colors from Alacritty (primary/normal/bright/dim/selection), Waybar (@define-color),
# and Hyprland (col.*_border; rgba->hex). Normalize, dedupe, and count frequencies.
# - Slot ordering: remove bg/fg, sort remaining colors by frequency, then fill 13 slots by cycling. Map slots to:
# h1h6, links, inline code, marks, interactive accent, blockquote border; muted/faint use border color.
# - Code colors: code background = closest color to bg (Euclidean RGB); if none, make a subtle bg variant (+/ RGB).
# code foreground = closest color to fg; fallback #e0e0e0.
# - Border color: from btop.theme theme[div_line]; else blended mix biased toward bg (≈ (bg+fg)/3).
# - Selection: from Alacritty [colors.selection] (background/text), honoring CellForeground/Background.
# If missing, background = 75% bg + 25% fg; text chosen for contrast vs selection background.
# - Fonts: monospace from Alacritty [font] or fontconfig monospace; UI font from fontconfig sans-serif.
VAULTS_FILE="$HOME/.local/state/omarchy/obsidian-vaults"
CURRENT_THEME_DIR="$HOME/.config/omarchy/current/theme"
ensure_vaults_file() {
mkdir -p "$(dirname "$VAULTS_FILE")"
local tmpfile
tmpfile="$(mktemp)"
# Extract the Obsidian vault location from config file <base>/<vault>/.obsidian
jq -r '.vaults | values[].path' ~/.config/obsidian/obsidian.json 2>/dev/null >>"$tmpfile"
if [ -s "$tmpfile" ]; then
sort -u "$tmpfile" >"$VAULTS_FILE"
else
: >"$VAULTS_FILE"
fi
rm "$tmpfile"
}
# Ensure theme directory and minimal manifest exist in a vault
ensure_theme_scaffold() {
local vault_path="$1"
local theme_dir="$vault_path/.obsidian/themes/Omarchy"
mkdir -p "$theme_dir"
if [ ! -f "$theme_dir/manifest.json" ]; then
cat >"$theme_dir/manifest.json" <<'EOF'
{
"name": "Omarchy",
"version": "1.0.0",
"minAppVersion": "0.16.0",
"description": "Automatically syncs with your current Omarchy system theme colors and fonts",
"author": "Omarchy",
"authorUrl": "https://omarchy.org"
}
EOF
fi
[ -f "$theme_dir/theme.css" ] || : >"$theme_dir/theme.css"
}
# Function to extract hex color from string
extract_hex_color() {
echo "$1" | grep -oE '#[0-9a-fA-F]{6}' | head -1
}
# Function to convert RGB/RGBA to hex
rgb_to_hex() {
local rgb_string="$1"
if [[ $rgb_string =~ rgba?\(([0-9]+),\s*([0-9]+),\s*([0-9]+) ]]; then
printf "#%02x%02x%02x\n" "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}" "${BASH_REMATCH[3]}"
fi
}
# Convert hex to RGB components
hex_to_rgb() {
local hex="${1#\#}"
printf "%d %d %d\n" "0x${hex:0:2}" "0x${hex:2:2}" "0x${hex:4:2}"
}
# Calculate perceived brightness (0-255)
calculate_brightness() {
local hex="$1"
read -r r g b <<<"$(hex_to_rgb "$hex")"
# Use perceived brightness formula
echo $(((r * 299 + g * 587 + b * 114) / 1000))
}
# Calculate approximate contrast ratio between two colors
# Returns ratio scaled by 100 (e.g., 450 = 4.5:1 ratio)
# (this is due to bash not supporting decimal math)
calculate_contrast_ratio() {
local hex1="$1" hex2="$2"
local br1=$(calculate_brightness "$hex1") # 0-255 range
local br2=$(calculate_brightness "$hex2") # 0-255 range
# Ensure br1 is the lighter color (higher brightness)
if [ $br1 -lt $br2 ]; then
local temp=$br1
br1=$br2
br2=$temp
fi
# Approximate contrast ratio scaled by 100
# Add offset to avoid division by zero and approximate WCAG +0.05 behavior
echo $(((br1 + 13) * 100 / (br2 + 13)))
}
# Check if two colors meet minimum contrast threshold
# Usage: meets_contrast_threshold <ratio> <threshold>
# Both ratio and threshold should be scaled by 100 (e.g., 300 = 3:1)
meets_contrast_threshold() {
local ratio="$1" # Ratio scaled by 100 (from calculate_contrast_ratio)
local threshold="$2" # Threshold scaled by 100 (300=3:1, 450=4.5:1, 700=7:1)
[ $ratio -ge $threshold ]
}
# Calculate color distance (euclidean in RGB space)
color_distance() {
local hex1="$1"
local hex2="$2"
read -r r1 g1 b1 <<<"$(hex_to_rgb "$hex1")"
read -r r2 g2 b2 <<<"$(hex_to_rgb "$hex2")"
echo $(((r1 - r2) * (r1 - r2) + (g1 - g2) * (g1 - g2) + (b1 - b2) * (b1 - b2)))
}
# Extract all colors with frequency count
extract_all_colors_with_count() {
local -A color_counts
local color
# Extract from Alacritty config
if [ -f "$CURRENT_THEME_DIR/alacritty.toml" ]; then
# Primary colors
while IFS= read -r color; do
color=$(echo "$color" | tr '[:upper:]' '[:lower:]') # Lowercase for consistency
[ -n "$color" ] && ((color_counts["$color"]++))
done < <(grep -E "(background|foreground|cursor|text)" "$CURRENT_THEME_DIR/alacritty.toml" | sed "s/.*[\"']0x/#/;s/.*[\"']#/#/;s/[\"'].*//;s/.*#\([0-9a-fA-F]\{6\}\).*/\#\1/" | grep "^#")
# Normal colors
while IFS= read -r color; do
color=$(echo "$color" | tr '[:upper:]' '[:lower:]') # Lowercase for consistency
[ -n "$color" ] && ((color_counts["$color"]++))
done < <(grep -A 20 "\[colors.normal\]" "$CURRENT_THEME_DIR/alacritty.toml" | grep -E "(black|red|green|yellow|blue|magenta|cyan|white)" | sed "s/.*[\"']0x/#/;s/.*[\"']#/#/;s/[\"'].*//;s/.*#\([0-9a-fA-F]\{6\}\).*/\#\1/" | grep "^#")
# Bright colors
while IFS= read -r color; do
# Add # if missing
[[ "$color" =~ ^[0-9a-fA-F]{6}$ ]] && color="#$color"
color=$(echo "$color" | tr '[:upper:]' '[:lower:]') # Lowercase for consistency
[[ "$color" =~ ^#[0-9a-f]{6}$ ]] && ((color_counts["$color"]++))
done < <(grep -A 20 "\[colors.bright\]" "$CURRENT_THEME_DIR/alacritty.toml" | grep -E "(black|red|green|yellow|blue|magenta|cyan|white)" | sed "s/.*[\"']//;s/[\"'].*//")
# Dim colors if present
while IFS= read -r color; do
# Add # if missing
[[ "$color" =~ ^[0-9a-fA-F]{6}$ ]] && color="#$color"
color=$(echo "$color" | tr '[:upper:]' '[:lower:]') # Lowercase for consistency
[[ "$color" =~ ^#[0-9a-f]{6}$ ]] && ((color_counts["$color"]++))
done < <(grep -A 20 "\[colors.dim\]" "$CURRENT_THEME_DIR/alacritty.toml" 2>/dev/null | grep -E "(black|red|green|yellow|blue|magenta|cyan|white)" | sed "s/.*[\"']//;s/[\"'].*//")
# Selection colors
while IFS= read -r color; do
color=$(echo "$color" | tr '[:upper:]' '[:lower:]') # Lowercase for consistency
[ -n "$color" ] && ((color_counts["$color"]++))
done < <(grep -A 5 "\[colors.selection\]" "$CURRENT_THEME_DIR/alacritty.toml" 2>/dev/null | grep -E "(background|text)" | sed "s/.*[\"']0x/#/;s/.*[\"']#/#/;s/[\"'].*//;s/.*#\([0-9a-fA-F]\{6\}\).*/\#\1/" | grep "^#")
fi
# Extract from Waybar CSS
if [ -f "$CURRENT_THEME_DIR/waybar.css" ]; then
while IFS= read -r color; do
color=$(echo "$color" | tr '[:upper:]' '[:lower:]') # Lowercase for consistency
[ -n "$color" ] && ((color_counts["$color"]++))
done < <(grep -oE '@define-color [a-z_-]+ #[0-9a-fA-F]{6}' "$CURRENT_THEME_DIR/waybar.css" | grep -oE '#[0-9a-fA-F]{6}')
fi
# Extract from Hyprland config
if [ -f "$CURRENT_THEME_DIR/hyprland.conf" ]; then
while IFS= read -r color; do
if [[ $color == rgba* ]] || [[ $color == rgb* ]]; then
color=$(rgb_to_hex "$color")
fi
color=$(echo "$color" | tr '[:upper:]' '[:lower:]') # Lowercase for consistency
[ -n "$color" ] && ((color_counts["$color"]++))
done < <(grep -E "col\.(active|inactive)_border" "$CURRENT_THEME_DIR/hyprland.conf" | grep -oE 'rgba?\([^)]+\)|#[0-9a-fA-F]{6,8}' | sed 's/ff$//')
fi
# Output colors with their counts
for color in "${!color_counts[@]}"; do
echo "${color_counts[$color]} $color"
done
}
# Sort colors by frequency
sort_colors_by_frequency() {
# Input is already "count color" format
sort -rn | cut -d' ' -f2
}
# Fill color slots with cycling if needed
fill_color_slots() {
local -a colors=("$@")
local -a slots
local num_colors=${#colors[@]}
# Need 13 slots total (code colors are handled separately)
local slots_needed=13
if [ $num_colors -eq 0 ]; then
# No colors available, use defaults
colors=("#3d3d3d" "#5d5d5d" "#7d7d7d" "#9d9d9d" "#bd93f9" "#50fa7b")
num_colors=6
fi
# Fill slots, cycling if necessary
for ((i = 0; i < slots_needed; i++)); do
slots[$i]="${colors[$((i % num_colors))]}"
done
echo "${slots[@]}"
}
# Main color extraction and theme generation
extract_theme_data() {
# Get primary colors from Alacritty
local bg_color="#1a1b26"
local fg_color="#a9b1d6"
if [ -f "$CURRENT_THEME_DIR/alacritty.toml" ]; then
local extracted_bg=$(grep -A 5 "\[colors.primary\]" "$CURRENT_THEME_DIR/alacritty.toml" | grep "^background = " | sed "s/.*[\"']0x/#/;s/.*[\"']#/#/;s/[\"'].*//;s/.*#\([0-9a-fA-F]\{6\}\).*/\#\1/" | head -1 | tr '[:upper:]' '[:lower:]')
local extracted_fg=$(grep -A 5 "\[colors.primary\]" "$CURRENT_THEME_DIR/alacritty.toml" | grep "^foreground = " | sed "s/.*[\"']0x/#/;s/.*[\"']#/#/;s/[\"'].*//;s/.*#\([0-9a-fA-F]\{6\}\).*/\#\1/" | head -1 | tr '[:upper:]' '[:lower:]')
[ -n "$extracted_bg" ] && bg_color="$extracted_bg"
[ -n "$extracted_fg" ] && fg_color="$extracted_fg"
fi
# Determine if light or dark theme
local bg_brightness=$(calculate_brightness "$bg_color")
local is_light_theme=false
[ $bg_brightness -gt 127 ] && is_light_theme=true
# Extract all colors with counts
local color_data=$(extract_all_colors_with_count)
# Filter out background and foreground colors for the main array
local filtered_data=$(echo "$color_data" | grep -v "$bg_color" | grep -v "$fg_color")
# Get all unique colors (including bg/fg) for distance calculations
local -a all_unique_colors
readarray -t all_unique_colors < <(echo "$color_data" | cut -d' ' -f2 | sort -u)
# Find the 3 closest colors to background for background variations
local -a bg_distances
for color in "${all_unique_colors[@]}"; do
if [ "$color" != "$bg_color" ]; then
distance=$(color_distance "$color" "$bg_color")
bg_distances+=("$distance:$color")
fi
done
# All background variations use the same as primary background
local bg_primary_alt="$bg_color"
local bg_secondary="$bg_color"
local bg_secondary_alt="$bg_color"
# Generate code background color that will contrast with foreground text
read -r r g b <<<"$(hex_to_rgb "$bg_color")"
if [ $bg_brightness -gt 127 ]; then
r=$((r - 10))
g=$((g - 10))
b=$((b - 10))
else
r=$((r + 15))
g=$((g + 15))
b=$((b + 15))
fi
[ $r -lt 0 ] && r=0
[ $r -gt 255 ] && r=255
[ $g -lt 0 ] && g=0
[ $g -gt 255 ] && g=255
[ $b -lt 0 ] && b=0
[ $b -gt 255 ] && b=255
code_bg=$(printf "#%02x%02x%02x" "$r" "$g" "$b")
# Find closest color to foreground for code block text
local code_fg=""
min_distance=999999999
for color in "${all_unique_colors[@]}"; do
if [ "$color" != "$fg_color" ]; then
distance=$(color_distance "$color" "$fg_color")
if [ $distance -lt $min_distance ]; then
min_distance=$distance
code_fg="$color"
fi
fi
done
[ -z "$code_fg" ] && code_fg="#e0e0e0" # Fallback
# Extract text selection colors from Alacritty
local selection_bg=""
local selection_fg=""
if [ -f "$CURRENT_THEME_DIR/alacritty.toml" ]; then
selection_bg=$(grep -A 5 "\[colors.selection\]" "$CURRENT_THEME_DIR/alacritty.toml" | grep "^background = " | sed "s/.*[\"']0x/#/;s/.*[\"']#/#/;s/[\"'].*//;s/.*#\([0-9a-fA-F]\{6\}\).*/\#\1/" | head -1 | tr '[:upper:]' '[:lower:]')
local selection_text=$(grep -A 5 "\[colors.selection\]" "$CURRENT_THEME_DIR/alacritty.toml" | grep "^text = " | sed "s/.*[\"']0x/#/;s/.*[\"']#/#/;s/[\"'].*//;s/.*#\([0-9a-fA-F]\{6\}\).*/\#\1/" | head -1 | tr '[:upper:]' '[:lower:]')
# If text is set to CellForeground/CellBackground, use the appropriate color
if [ -z "$selection_text" ] || [[ "$(grep -A 5 "\[colors.selection\]" "$CURRENT_THEME_DIR/alacritty.toml" | grep "^text = ")" == *"CellForeground"* ]]; then
selection_fg="$fg_color"
elif [[ "$(grep -A 5 "\[colors.selection\]" "$CURRENT_THEME_DIR/alacritty.toml" | grep "^text = ")" == *"CellBackground"* ]]; then
selection_fg="$bg_color"
else
selection_fg="$selection_text"
fi
fi
# Fallback if no selection colors found
if [ -z "$selection_bg" ]; then
read -r r1 g1 b1 <<<"$(hex_to_rgb "$bg_color")"
read -r r2 g2 b2 <<<"$(hex_to_rgb "$fg_color")"
local r=$(((r1 * 3 + r2) / 4)) # 75% background, 25% foreground
local g=$(((g1 * 3 + g2) / 4))
local b=$(((b1 * 3 + b2) / 4))
selection_bg=$(printf "#%02x%02x%02x" "$r" "$g" "$b")
fi
# Use contrasting color for selection text if not defined
if [ -z "$selection_fg" ]; then
# Calculate brightness of selection background
local sel_brightness=$(calculate_brightness "$selection_bg")
if [ $sel_brightness -gt 127 ]; then
selection_fg="$bg_color" # Dark text on light selection
else
selection_fg="$fg_color" # Light text on dark selection
fi
fi
# Extract border color from btop theme
local border_color=""
if [ -f "$CURRENT_THEME_DIR/btop.theme" ]; then
# Look for theme[div_line] in btop theme
local btop_divline=$(grep 'theme\[div_line\]' "$CURRENT_THEME_DIR/btop.theme" | head -1)
if [ -n "$btop_divline" ]; then
# Extract the color value after the = sign
local extracted=$(echo "$btop_divline" | sed 's/.*=//' | xargs)
# Check if it's a hex color and lowercase it
if [[ $extracted =~ ^#[0-9a-fA-F]{6}$ ]]; then
border_color=$(echo "$extracted" | tr '[:upper:]' '[:lower:]')
elif [[ $extracted =~ ^[0-9a-fA-F]{6}$ ]]; then
# Add # if missing and lowercase
border_color=$(echo "#$extracted" | tr '[:upper:]' '[:lower:]')
fi
fi
fi
# Fallback if no border color found
if [ -z "$border_color" ]; then
# Use a color between bg and fg
read -r r1 g1 b1 <<<"$(hex_to_rgb "$bg_color")"
read -r r2 g2 b2 <<<"$(hex_to_rgb "$fg_color")"
local r=$(((r1 + r2) / 3)) # Closer to background
local g=$(((g1 + g2) / 3))
local b=$(((b1 + b2) / 3))
border_color=$(printf "#%02x%02x%02x" "$r" "$g" "$b")
fi
# Set text colors for muted/faint based on contrast
local text_muted_color="$border_color"
local text_faint_color="$border_color"
# Validate border color contrast against background
# Represents a 3:1 WCAG contrast ratio
local ideal_contrast_ratio=300
local border_contrast=$(calculate_contrast_ratio "$border_color" "$bg_color")
if ! meets_contrast_threshold "$border_contrast" "$ideal_contrast_ratio"; then
# Override text colors for readability, keep border color for visibility
text_muted_color="$fg_color"
text_faint_color="$fg_color"
fi
# Get unique colors array (without bg/fg) sorted by frequency
local -a unique_colors
readarray -t unique_colors < <(echo "$filtered_data" | sort_colors_by_frequency)
# Fill the 13 color slots (code colors handled separately)
local -a color_slots
readarray -t color_slots < <(fill_color_slots "${unique_colors[@]}" | tr ' ' '\n')
# Extract fonts
local monospace_font="JetBrainsMono Nerd Font"
local ui_font="Liberation Sans"
if [ -f "$CURRENT_THEME_DIR/alacritty.toml" ]; then
local alacritty_font=$(grep -A 5 "\[font\]" "$CURRENT_THEME_DIR/alacritty.toml" | grep 'family = ' | head -1 | cut -d'"' -f2)
[ -n "$alacritty_font" ] && monospace_font="$alacritty_font"
fi
if [ -f "$HOME/.config/fontconfig/fonts.conf" ]; then
local fontconfig_mono=$(xmlstarlet sel -t -v '//match[@target="pattern"][test/string="monospace"]/edit[@name="family"]/string' "$HOME/.config/fontconfig/fonts.conf" 2>/dev/null || true)
[ -n "$fontconfig_mono" ] && monospace_font="$fontconfig_mono"
local fontconfig_sans=$(xmlstarlet sel -t -v '//match[@target="pattern"][test/string="sans-serif"]/edit[@name="family"]/string' "$HOME/.config/fontconfig/fonts.conf" 2>/dev/null || true)
[ -n "$fontconfig_sans" ] && ui_font="$fontconfig_sans"
fi
# Generate CSS with 14-slot system
cat <<EOF
/* Omarchy Theme for Obsidian */
/* Generated on $(date) from theme: $(basename "$(readlink "$CURRENT_THEME_DIR" 2>/dev/null || echo "unknown")") */
/* Colors sorted by frequency, backgrounds by distance */
.theme-dark, .theme-light {
/* Core colors */
--background-primary: $bg_color;
--text-normal: $fg_color;
/* Background variations (always distance-based) */
--background-primary-alt: $bg_primary_alt;
--background-secondary: $bg_secondary;
--background-secondary-alt: $bg_secondary_alt;
/* Code block colors (always distance-based) */
--code-background: $code_bg;
--code-foreground: $code_fg;
/* Border color from btop theme */
--border-color: $border_color;
/* Selection colors from Alacritty */
--text-selection: $selection_bg;
--text-selection-fg: $selection_fg;
/* 13-slot color system for remaining elements */
--text-title-h1: ${color_slots[0]};
--text-title-h2: ${color_slots[1]};
--text-title-h3: ${color_slots[2]};
--text-title-h4: ${color_slots[3]};
--text-title-h5: ${color_slots[4]};
--text-title-h6: ${color_slots[4]}; /* Same as h5 */
--text-link: ${color_slots[5]};
--markup-code: ${color_slots[6]};
--text-mark: ${color_slots[7]};
--interactive-accent: ${color_slots[8]};
--blockquote-border: ${color_slots[9]};
--text-muted: $text_muted_color; /* Use text-specific color for muted text */
--text-faint: $text_faint_color; /* Use text-specific color for faint text */
/* Additional mappings */
--text-accent: var(--interactive-accent);
--text-accent-hover: var(--interactive-accent);
--text-error: var(--text-title-h1);
--text-error-hover: var(--text-title-h1);
--text-highlight-bg: $fg_color; /* Use text color as highlight background */
--text-on-accent: $bg_color;
--interactive-normal: var(--code-background);
--interactive-hover: var(--interactive-accent);
--interactive-accent-hover: var(--interactive-accent);
--interactive-success: var(--text-title-h2);
--scrollbar-bg: var(--background-primary);
--scrollbar-thumb-bg: var(--code-background);
--scrollbar-active-thumb-bg: var(--interactive-accent);
--background-modifier-border: var(--border-color);
--background-modifier-form-field: var(--code-background);
--background-modifier-form-field-highlighted: var(--code-background);
--background-modifier-box-shadow: rgba(0, 0, 0, 0.3);
--background-modifier-success: var(--interactive-success);
--background-modifier-error: var(--text-error);
--background-modifier-error-hover: var(--text-error);
--background-modifier-cover: rgba(0, 0, 0, 0.8);
--link-color: var(--text-link);
--link-color-hover: var(--text-link);
--link-unresolved-color: var(--text-muted);
--link-unresolved-opacity: 0.7;
--tag-color: var(--text-title-h3);
--tag-background: var(--code-background);
--graph-line: var(--text-muted);
--graph-node: var(--interactive-accent);
--graph-node-unresolved: var(--text-muted);
--graph-node-focused: var(--text-link);
--graph-node-tag: var(--text-title-h3);
--graph-node-attachment: var(--text-title-h2);
/* Fonts */
--font-interface-theme: "$ui_font";
--font-text-theme: "$ui_font";
--font-monospace-theme: "$monospace_font";
}
/* Headers */
.cm-header-1, .markdown-rendered h1 { color: var(--text-title-h1); }
.cm-header-2, .markdown-rendered h2 { color: var(--text-title-h2); }
.cm-header-3, .markdown-rendered h3 { color: var(--text-title-h3); }
.cm-header-4, .markdown-rendered h4 { color: var(--text-title-h4); }
.cm-header-5, .markdown-rendered h5 { color: var(--text-title-h5); }
.cm-header-6, .markdown-rendered h6 { color: var(--text-title-h6); }
/* Code blocks */
.markdown-rendered code {
font-family: var(--font-monospace-theme);
background-color: var(--code-background);
color: var(--markup-code);
padding: 2px 4px;
border-radius: 3px;
}
.markdown-rendered pre {
background-color: var(--code-background);
border: 1px solid var(--background-modifier-border);
border-radius: 5px;
}
.markdown-rendered pre code {
background-color: transparent;
color: var(--code-foreground);
}
/* Syntax highlighting */
.cm-s-obsidian span.cm-keyword { color: var(--text-title-h1); }
.cm-s-obsidian span.cm-string { color: var(--text-title-h2); }
.cm-s-obsidian span.cm-number { color: var(--text-title-h3); }
.cm-s-obsidian span.cm-comment { color: var(--text-muted); }
.cm-s-obsidian span.cm-operator { color: var(--text-link); }
.cm-s-obsidian span.cm-variable { color: var(--text-normal); }
.cm-s-obsidian span.cm-def { color: var(--text-link); }
/* Highlighted text */
.markdown-rendered mark,
.cm-s-obsidian span.cm-highlight,
mark {
background-color: var(--text-highlight-bg) !important;
color: var(--code-background) !important;
}
/* Links */
.markdown-rendered a {
color: var(--text-link);
}
/* Blockquotes */
.markdown-rendered blockquote {
border-left: 4px solid var(--blockquote-border);
padding-left: 1em;
}
/* Status bar */
.status-bar {
background-color: var(--code-background);
border-top: 1px solid var(--background-modifier-border);
}
/* Active file */
.workspace-leaf.mod-active .workspace-leaf-header-title {
color: var(--interactive-accent);
}
.nav-file-title.is-active {
background-color: var(--code-background);
color: var(--interactive-accent);
}
/* Text selection */
::selection {
background-color: var(--text-selection);
color: var(--text-selection-fg);
}
/* Search results */
.search-result-file-title {
color: var(--interactive-accent);
}
.search-result-file-match {
background-color: var(--code-background);
color: var(--text-normal);
border-left: 3px solid var(--interactive-accent);
}
.search-result-file-matched-text {
color: var(--code-background);
}
/* Tables */
.markdown-rendered table {
border: 1px solid var(--background-modifier-border);
}
.markdown-rendered th {
background-color: var(--code-background);
color: var(--text-accent);
}
.markdown-rendered td {
border: 1px solid var(--background-modifier-border);
}
/* Callouts */
.callout {
border-left: 4px solid var(--interactive-accent);
background-color: var(--code-background);
}
.callout * {
color: var(--text-normal);
}
/* Modal dialogs */
.modal {
background-color: var(--background-primary);
border: 2px solid var(--background-modifier-border);
}
/* Settings */
.vertical-tab-header-group-title {
color: var(--interactive-accent);
}
.vertical-tab-nav-item.is-active {
background-color: var(--code-background);
color: var(--interactive-accent);
}
EOF
}
# Option handling
if [ "${1:-}" = "--reset" ]; then
echo "♻️ Resetting Omarchy themes and registry..."
if [ -f "$VAULTS_FILE" ] && [ -s "$VAULTS_FILE" ]; then
while IFS= read -r vault_path || [ -n "$vault_path" ]; do
case "$vault_path" in ""|\#*) continue ;; esac
vault_path="${vault_path%/}"
vault_name=$(basename "$vault_path")
theme_dir="$vault_path/.obsidian/themes/Omarchy"
if [ -d "$theme_dir" ]; then
rm -rf "$theme_dir"
echo " ✅ $vault_name (theme removed)"
else
echo " $vault_name (no theme present)"
fi
done <"$VAULTS_FILE"
fi
rm -f "$VAULTS_FILE"
echo "✅ Registry removed"
exit 0
fi
# Main update logic
echo "🔄 Updating Obsidian vaults..."
# Step 1: ensure registry exists (bootstrap if needed)
ensure_vaults_file
while IFS= read -r vault_path || [ -n "$vault_path" ]; do
case "$vault_path" in "" | \#*) continue ;; esac
vault_path="${vault_path%/}"
vault_name=$(basename "$vault_path")
# Step 2: verify path exists; log/skip gracefully if invalid
if [ ! -d "$vault_path" ] || [ ! -d "$vault_path/.obsidian" ]; then
echo " ❌ $vault_name (invalid entry: missing directory or .obsidian)"
continue
fi
# Ensure theme files exist for this vault
ensure_theme_scaffold "$vault_path"
THEME_DIR="$vault_path/.obsidian/themes/Omarchy"
# Step 3: update theme.css
if [ -f "$CURRENT_THEME_DIR/obsidian.css" ]; then
cp "$CURRENT_THEME_DIR/obsidian.css" "$THEME_DIR/theme.css"
echo " ✅ $vault_name (custom theme)"
else
extract_theme_data >"$THEME_DIR/theme.css"
echo " ✅ $vault_name (generated theme)"
fi
done <"$VAULTS_FILE"

7
bin/omarchy-theme-set-terminal Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/bash
case "$TERMINAL" in
"alacritty") touch ~/.config/alacritty/alacritty.toml ;;
"kitty") pkill -USRSIG1 kitty ;;
"ghostty") pkill -USRSIG2 ghostty ;;
esac

View File

@@ -1,47 +1,25 @@
#!/bin/bash #!/bin/bash
# Note: We cannot use `jq` to update settings.json because its JSONC (allows comments),
# which jq doesnt support.
# Parameters: EDITOR_CMD SETTINGS_PATH SKIP_FLAG EDITOR_NAME
EDITOR_CMD="${1:-code}"
SETTINGS_PATH="${2:-$HOME/.config/Code/User/settings.json}"
SKIP_FLAG="${3:-$HOME/.local/state/omarchy/toggles/skip-vscode-theme-changes}"
EDITOR_NAME="${4:-VS Code}"
VS_CODE_THEME="$HOME/.config/omarchy/current/theme/vscode.json" VS_CODE_THEME="$HOME/.config/omarchy/current/theme/vscode.json"
VS_CODE_SETTINGS="$HOME/.config/Code/User/settings.json"
VS_CODE_SKIP_FLAG="$HOME/.local/state/omarchy/toggles/skip-vscode-theme-changes"
if omarchy-cmd-present "$EDITOR_CMD" && [[ ! -f "$SKIP_FLAG" ]]; then if omarchy-cmd-present code && [[ ! -f "$VS_CODE_SKIP_FLAG" ]]; then
if [[ -f "$VS_CODE_THEME" ]]; then if [[ -f "$VS_CODE_THEME" ]]; then
theme_name=$(jq -r '.name' "$VS_CODE_THEME") # Install VS Code theme extension
extension=$(jq -r '.extension' "$VS_CODE_THEME") extension=$(jq -r '.extension' "$VS_CODE_THEME")
if [[ -n "$extension" ]] && ! code --list-extensions | grep -Fxq "$extension"; then
# Install $EDITOR_NAME theme extension notify-send " Installing VS Code theme for $THEME_NAME"
if [[ -n "$extension" ]] && ! "$EDITOR_CMD" --list-extensions | grep -Fxq "$extension"; then code --install-extension "$extension" >/dev/null
"$EDITOR_CMD" --install-extension "$extension" >/dev/null
fi fi
# Create config file if there isn't already one # Update theme in settings.json
mkdir -p "$(dirname "$SETTINGS_PATH")" theme_name=$(jq -r '.name' "$VS_CODE_THEME")
if [[ ! -f "$SETTINGS_PATH" ]]; then jq -n --arg t "$theme_name" '(input? // {}) | .["workbench.colorTheme"] = $t' "$VS_CODE_SETTINGS" >"${VS_CODE_SETTINGS}.new"
printf '{\n}\n' >"$SETTINGS_PATH"
fi
# Create a `workbench.colorTheme` entry in settings.
if ! grep -q '"workbench.colorTheme"' "$SETTINGS_PATH"; then
# Insert `"workbench.colorTheme": "",` immediately after the first `{`
# Use sed's first-match range (0,/{/) to only replace the first `{`
sed -i --follow-symlinks -E '0,/\{/{s/\{/{\ "workbench.colorTheme": "",/}' "$SETTINGS_PATH"
fi
# Update theme
sed -i --follow-symlinks -E \
"s/(\"workbench.colorTheme\"[[:space:]]*:[[:space:]]*\")[^\"]*(\")/\1$theme_name\2/" \
"$SETTINGS_PATH"
else else
# Remove theme from settings.json when the theme doesn't have $EDITOR_NAME support # Remove theme from settings.json when the theme doesn't have vscode support
if [[ -f "$SETTINGS_PATH" ]]; then jq 'del(.["workbench.colorTheme"])' "$VS_CODE_SETTINGS" >"${VS_CODE_SETTINGS}.new"
sed -i --follow-symlinks -E 's/\"workbench\.colorTheme\"[[:space:]]*:[^,}]*,?//' "$SETTINGS_PATH"
fi
fi fi
mv "${VS_CODE_SETTINGS}.new" "$VS_CODE_SETTINGS"
fi fi

View File

@@ -1,8 +1,5 @@
#!/bin/bash #!/bin/bash
for dir in ~/.config/omarchy/themes/*/; do for dir in ~/.config/omarchy/themes/*/; do
if [[ -d $dir ]] && [[ ! -L "${dir%/}" ]] && [[ -d "$dir/.git" ]]; then [ -d "$dir" ] && [ ! -L "${dir%/}" ] && echo "Updating: $(basename "$dir")" && git -C "$dir" pull
echo "Updating: $(basename "$dir")"
git -C "$dir" pull
fi
done done

View File

@@ -4,6 +4,6 @@ if pgrep -x hypridle >/dev/null; then
pkill -x hypridle pkill -x hypridle
notify-send "Stop locking computer when idle" notify-send "Stop locking computer when idle"
else else
uwsm-app -- hypridle >/dev/null 2>&1 & uwsm app -- hypridle >/dev/null 2>&1 &
notify-send "Now locking computer when idle" notify-send "Now locking computer when idle"
fi fi

View File

@@ -6,7 +6,7 @@ OFF_TEMP=6000
# Ensure hyprsunset is running # Ensure hyprsunset is running
if ! pgrep -x hyprsunset; then if ! pgrep -x hyprsunset; then
setsid uwsm-app -- hyprsunset & setsid uwsm app -- hyprsunset &
sleep 1 # Give it time to register sleep 1 # Give it time to register
fi fi

View File

@@ -3,5 +3,5 @@
if pgrep -x waybar >/dev/null; then if pgrep -x waybar >/dev/null; then
pkill -x waybar pkill -x waybar
else else
uwsm-app -- waybar >/dev/null 2>&1 & uwsm app -- waybar >/dev/null 2>&1 &
fi fi

View File

@@ -5,7 +5,7 @@ if [ "$#" -ne 4 ]; then
APP_NAME=$(gum input --prompt "Name> " --placeholder "My TUI") APP_NAME=$(gum input --prompt "Name> " --placeholder "My TUI")
APP_EXEC=$(gum input --prompt "Launch Command> " --placeholder "lazydocker or bash -c 'dust; read -n 1 -s'") APP_EXEC=$(gum input --prompt "Launch Command> " --placeholder "lazydocker or bash -c 'dust; read -n 1 -s'")
WINDOW_STYLE=$(gum choose --header "Window style" float tile) WINDOW_STYLE=$(gum choose --header "Window style" float tile)
ICON_URL=$(gum input --prompt "Icon URL> " --placeholder "See https://dashboardicons.com (must use PNG or SVG!)") ICON_URL=$(gum input --prompt "Icon URL> " --placeholder "See https://dashboardicons.com (must use PNG!)")
else else
APP_NAME="$1" APP_NAME="$1"
APP_EXEC="$2" APP_EXEC="$2"
@@ -43,7 +43,7 @@ cat >"$DESKTOP_FILE" <<EOF
Version=1.0 Version=1.0
Name=$APP_NAME Name=$APP_NAME
Comment=$APP_NAME Comment=$APP_NAME
Exec=xdg-terminal-exec --app-id=$APP_CLASS -e $APP_EXEC Exec=$TERMINAL --class $APP_CLASS -e $APP_EXEC
Terminal=false Terminal=false
Type=Application Type=Application
Icon=$ICON_PATH Icon=$ICON_PATH

View File

@@ -6,7 +6,7 @@ DESKTOP_DIR="$HOME/.local/share/applications/"
if [ "$#" -eq 0 ]; then if [ "$#" -eq 0 ]; then
# Find all TUIs # Find all TUIs
while IFS= read -r -d '' file; do while IFS= read -r -d '' file; do
if grep -qE '^Exec=.*(\$TERMINAL|xdg-terminal-exec).*-e' "$file"; then if grep -q '^Exec=.*$TERMINAL.*-e' "$file"; then
TUIS+=("$(basename "${file%.desktop}")") TUIS+=("$(basename "${file%.desktop}")")
fi fi
done < <(find "$DESKTOP_DIR" -name '*.desktop' -print0) done < <(find "$DESKTOP_DIR" -name '*.desktop' -print0)

View File

@@ -1,6 +0,0 @@
#!/bin/bash
timezone=$(timedatectl list-timezones | gum filter --height 20 --header "Set timezone") || exit 1
sudo timedatectl set-timezone "$timezone"
echo "Timezone is now set to $timezone"
omarchy-restart-waybar

View File

@@ -2,11 +2,6 @@
set -e set -e
trap 'echo ""; echo -e "\033[0;31mSomething went wrong during the update!\n\nPlease review the output above carefully, correct the error, and retry the update.\n\nIf you need assistance, get help from the community at https://omarchy.org/discord\033[0m"' ERR omarchy-snapshot create || [ $? -eq 127 ]
omarchy-update-git
if [[ $1 == "-y" ]] || omarchy-update-confirm; then omarchy-update-perform
omarchy-update-without-idle
omarchy-snapshot create || [ $? -eq 127 ]
omarchy-update-git
omarchy-update-perform
fi

Some files were not shown because too many files have changed in this diff Show More