Compare commits

..
170 Commits
Author SHA1 Message Date
Ryan Hughes d63fdd2a23 Avoid transient Hyprland binding module errors 2026-06-16 01:27:43 -04:00
Ryan Hughes 2fdc6f0573 Move stock Hyprland bindings into defaults 2026-06-16 01:25:04 -04:00
Ryan Hughes fd5063dc30 Fix notification popup placement 2026-06-16 01:25:04 -04:00
Ryan Hughes 2a7602a084 Complete upgrade-to-4 update flow 2026-06-15 11:27:54 -04:00
Ryan Hughes 227240d280 Collapse inactive indicator spacing 2026-06-14 21:12:42 -04:00
Ryan Hughes 8d490d525e Select Codex icon by surface background 2026-06-14 20:14:09 -04:00
Ryan Hughes e0eaf8eea8 Use light Codex icon on light themes 2026-06-14 20:09:29 -04:00
Ryan Hughes d8cff94711 Fix model usage layout on vertical bar 2026-06-14 17:40:00 -04:00
Ryan Hughes 4bfa5a6949 Switch default editor to tensaku so we can move things 2026-06-12 22:27:20 -04:00
Ryan Hughes c582e7133a Unify Omarchy migrations 2026-06-12 13:49:46 -04:00
Ryan Hughes 04b0fab64d Remove old test repo 2026-06-12 02:16:01 -04:00
Ryan Hughes fec52e53d2 Cleanup hyprland conf 2026-06-12 02:15:51 -04:00
Ryan Hughes b1e585fec5 Fix nvim theme location 2026-06-12 02:15:22 -04:00
Ryan Hughes 221fb296fc Simplify theme palette tokens 2026-06-11 02:08:02 -04:00
Ryan Hughes 4b2a15b6ea Avoid polkit prompts from shell network status 2026-06-10 13:10:03 -04:00
Ryan Hughes cd0b78cd0f Restore lock surface after shell restart 2026-06-10 12:17:35 -04:00
Ryan Hughes 15614cd4d3 Rename live dev channel to edge 2026-06-10 11:18:36 -04:00
Ryan Hughes c1b9788506 Fix channels 2026-06-09 23:55:58 -04:00
Ryan Hughes 0f5e81143e Move current theme state to local state 2026-06-09 19:48:37 -04:00
Ryan Hughes 29c4a20a86 Fix Claude weekly usage display 2026-06-09 18:11:47 -04:00
Ryan Hughes 7d30407a23 Namespace Discord icon 2026-06-09 15:21:52 -04:00
Ryan Hughes bce9fef4e3 Streamline Hyprland reload guard 2026-06-09 15:13:23 -04:00
Ryan Hughes f79a231cc7 Pause Hyprland reloads during settings updates 2026-06-09 14:20:36 -04:00
Ryan Hughes 9b8c9fd537 Update Omarchy channel switcher 2026-06-09 13:05:30 -04:00
Ryan Hughes 22a42e073a Infer edge channel on --dev 2026-06-09 10:22:55 -04:00
Ryan Hughes 64581ec289 Remove hot link / unlink bits 2026-06-08 12:03:40 -04:00
David Heinemeier Hansson 38bb61b685 Overly defensive 2026-06-08 17:48:09 +02:00
David Heinemeier Hansson 73d47390c4 Improve Bluetooth panel connected devices 2026-06-08 17:20:59 +02:00
David Heinemeier Hansson 42a0b25e01 Merge branch 'omarchy-shell' into quattro 2026-06-08 16:56:51 +02:00
David Heinemeier Hansson 8e65151fb8 Show the whole disk 2026-06-08 16:44:17 +02:00
David Heinemeier Hansson baff7f8080 Make user for now 2026-06-08 16:41:56 +02:00
David Heinemeier Hansson 01bdd06e10 No more elephant 2026-06-08 16:40:54 +02:00
David Heinemeier Hansson cbc7c8f30a Use dua 2026-06-08 16:38:17 +02:00
David Heinemeier Hansson 8807a9c889 Merge branch 'dev' into quattro 2026-06-08 16:36:51 +02:00
Carmine PaolinoandGitHub 9cf1852525 Use dua for disk usage (#6052) 2026-06-08 16:36:05 +02:00
David Heinemeier Hansson 6cec42d97d Merge branch 'omarchy-4' into quattro 2026-06-08 16:28:52 +02:00
David Heinemeier Hansson 3d4bb9ab81 Add splitters to all panels... for now 2026-06-07 20:58:02 +02:00
David Heinemeier Hansson ae7365f937 Fix repeated fingerprint setup 2026-05-27 21:20:39 +02:00
Jason ZimdarsandGitHub 8075b8b0dc Update Basecamp logo asset for version 5 release (#5769)
* Update Basecamp logo asset for version 5 release

* Final Basecamp 5 logo asset
2026-05-25 23:36:54 +02:00
David Heinemeier Hansson 9a5e80f2be Fix compatibility of old tiling.conf with HL 0.55+
Closes #5973
2026-05-25 14:50:56 +02:00
Ryan Hughes f9e41548c1 Bump version 2026-05-23 18:27:38 -04:00
961d4241f0 Install mpv MPRIS support (#5937)
* Install mpv MPRIS support

* omarchy-pkg-add already checks if installed

---------

Co-authored-by: David Heinemeier Hansson <david@hey.com>
2026-05-23 20:49:00 +02:00
David Heinemeier Hansson ea25179b7c Fix HL 0.55 compatible unified clipboard hotkeys 2026-05-23 20:05:46 +02:00
Ryan Hughes b4939c8ccb Fail hard if we don't get the right branch 2026-05-23 02:04:14 -04:00
Ryan Hughes 703581cee2 Fix logs uploading 2026-05-22 12:04:45 -04:00
JisnuandGitHub 9c8f6cf2cb fix: remove pseudotile and fix -1 gradient colors for Hyprland 0.55.x (#5922) 2026-05-21 08:21:42 +02:00
Ryan HughesandGitHub 82f99928d0 Bump version from 3.8.0 to 3.8.1 2026-05-14 13:23:48 -04:00
Ryan HughesandGitHub 6b5baf06ad Merge pull request #5816 from basecamp/fix-reinstall-git-default-branch
Pin omarchy-reinstall-git to master branch
2026-05-14 13:22:35 -04:00
Ryan Hughes 32a82dd15b Pin omarchy-reinstall-git to master branch
GitHub's default branch on basecamp/omarchy is no longer master, so
a plain clone pulls the development branch. Pass --branch master so
reinstalls always land on stable regardless of repo default.
2026-05-14 13:18:46 -04:00
David Heinemeier Hansson b2d95ee24b libretro-vice is now an explosion of minor pkgs 2026-05-10 16:47:29 +02:00
David Heinemeier HanssonandGitHub 7f6abcd743 Merge pull request #5628 from basecamp/rc
Omarchy 3.8.0
2026-05-09 17:20:48 +02:00
David Heinemeier Hansson 44a0123058 Merge branch 'dev' into rc 2026-05-09 16:21:52 +02:00
David Heinemeier Hansson dde76059a8 Merge branch 'dev' into rc 2026-05-09 08:30:09 +02:00
David Heinemeier Hansson 8f43960b8f Merge branch 'dev' into rc 2026-05-08 22:31:44 +02:00
David Heinemeier Hansson 27b598a6e5 Fix guidance 2026-05-08 22:07:38 +02:00
David Heinemeier Hansson 6f281d888f Merge branch 'dev' into rc 2026-05-08 22:06:23 +02:00
David Heinemeier Hansson a865ecc875 Merge branch 'dev' into rc 2026-05-08 22:04:46 +02:00
David Heinemeier Hansson b2ffc1ffa9 Merge branch 'dev' into rc 2026-05-08 21:53:15 +02:00
David Heinemeier Hansson 2a1c1980b4 Merge branch 'dev' into rc 2026-05-08 21:44:27 +02:00
David Heinemeier Hansson d0000ea8cf Merge branch 'dev' into rc 2026-05-08 21:34:52 +02:00
David Heinemeier Hansson cff80ff699 Merge branch 'dev' into rc 2026-05-08 21:16:50 +02:00
David Heinemeier Hansson c8c395b231 Merge branch 'dev' into rc 2026-05-08 21:09:42 +02:00
David Heinemeier Hansson f2f65fdfb2 Merge branch 'dev' into rc 2026-05-07 17:02:13 +02:00
David Heinemeier Hansson 74f319bb6f Merge branch 'dev' into rc 2026-05-07 16:18:28 +02:00
David Heinemeier Hansson 98e9bc6d05 Merge branch 'dev' into rc 2026-05-07 16:16:06 +02:00
David Heinemeier Hansson 121a1e088a Merge branch 'dev' into rc 2026-05-07 16:15:15 +02:00
David Heinemeier Hansson 71e303d2aa Merge branch 'dev' into rc 2026-05-07 15:12:31 +02:00
David Heinemeier Hansson 3a240c7838 Add note about correct perms for migrations 2026-05-07 15:09:53 +02:00
David Heinemeier Hansson c9d1cdce76 Merge branch 'dev' into rc 2026-05-07 15:04:15 +02:00
David Heinemeier Hansson d8a9186326 Merge branch 'dev' into rc 2026-05-07 15:02:25 +02:00
David Heinemeier Hansson 38326c77fc Merge branch 'dev' into rc 2026-05-07 14:54:53 +02:00
David Heinemeier Hansson 66492e57a7 Merge branch 'dev' into rc 2026-05-07 11:23:17 +02:00
David Heinemeier Hansson b6ad01a0fc Merge branch 'dev' into rc 2026-05-07 09:06:25 +02:00
David Heinemeier Hansson cd4fadd502 Merge branch 'dev' into rc 2026-05-06 21:05:41 +02:00
David Heinemeier Hansson d4ffa9e39d Just focus on the window rules 2026-05-06 21:05:24 +02:00
David Heinemeier Hansson dc8ad1dace Use proper .desktop files 2026-05-06 21:03:43 +02:00
David Heinemeier Hansson c80d060321 Merge branch 'dev' into rc 2026-05-06 20:37:36 +02:00
David Heinemeier HanssonandGitHub d827b90a4d Merge branch 'master' into rc 2026-05-06 17:16:10 +02:00
David Heinemeier Hansson e22b70f380 Merge branch 'dev' into rc 2026-05-06 16:52:49 +02:00
David Heinemeier Hansson d59ad099a9 Merge branch 'dev' into rc 2026-05-06 16:52:16 +02:00
Ryan Hughes a3aedb0c4d Version bump 2026-05-04 19:46:42 -04:00
Ryan Hughes 0a5cd43aac Add migration to handle lingering panel_replay addition 2026-05-04 19:46:00 -04:00
David Heinemeier HanssonandGitHub 9aa3858794 Merge pull request #5467 from basecamp/rc
Omarchy 3.7.0
2026-05-04 15:44:57 +02:00
David Heinemeier Hansson 648d8339d2 Merge branch 'dev' into rc 2026-05-04 15:42:37 +02:00
David Heinemeier Hansson 7138044bd2 Merge branch 'dev' into rc 2026-05-04 15:33:23 +02:00
David Heinemeier Hansson 86a38c4a98 Merge branch 'dev' into rc 2026-05-04 14:43:07 +02:00
David Heinemeier Hansson 516882a43c Merge branch 'dev' into rc 2026-05-04 13:57:18 +02:00
David Heinemeier Hansson e3d3ee4044 Merge branch 'dev' into rc 2026-05-04 13:23:37 +02:00
David Heinemeier Hansson 48a771bdac Merge branch 'dev' into rc 2026-05-04 12:38:16 +02:00
David Heinemeier Hansson 03750b31c1 Merge branch 'dev' into rc 2026-05-04 12:23:41 +02:00
David Heinemeier Hansson a6280eed26 Merge branch 'dev' into rc 2026-05-04 11:36:24 +02:00
David Heinemeier Hansson f4a0249ff3 Merge branch 'dev' into rc 2026-05-04 11:18:30 +02:00
David Heinemeier Hansson 011243f4fa Merge branch 'dev' into rc 2026-05-04 10:52:16 +02:00
David Heinemeier Hansson e7f45386d4 Merge branch 'dev' into rc 2026-05-04 10:38:50 +02:00
David Heinemeier Hansson cb3fcf4f60 Merge branch 'dev' into rc 2026-05-04 07:55:06 +02:00
David Heinemeier Hansson d7e3c0dcde Merge branch 'dev' into rc 2026-05-03 22:53:51 +02:00
David Heinemeier Hansson 0edff316da Merge branch 'dev' into rc 2026-05-03 22:02:43 +02:00
David Heinemeier Hansson 774acbf5af Merge branch 'dev' into rc 2026-05-03 19:38:02 +02:00
David Heinemeier Hansson fddaa5e869 Merge branch 'dev' into rc 2026-05-03 13:42:26 +02:00
David Heinemeier Hansson f1a4e9f6e8 Merge branch 'dev' into rc 2026-05-03 13:38:42 +02:00
David Heinemeier Hansson 5cf34963d7 Merge branch 'dev' into rc 2026-05-03 12:47:41 +02:00
David Heinemeier Hansson d40e314d4f Merge branch 'dev' into rc 2026-05-03 12:05:52 +02:00
David Heinemeier Hansson dc249dba95 Merge branch 'dev' into rc 2026-05-03 11:57:19 +02:00
David Heinemeier Hansson 4a7ade9c52 Merge branch 'dev' into rc 2026-05-02 16:43:10 +02:00
David Heinemeier Hansson 06fd369318 Merge branch 'dev' into rc 2026-05-02 14:47:48 +02:00
David Heinemeier Hansson ea7979a057 No quoting needed for bash 5 2026-05-02 13:47:55 +02:00
David Heinemeier Hansson 60966d4553 Merge branch 'dev' into rc 2026-05-02 13:34:38 +02:00
David Heinemeier Hansson 211acd6f9f Merge branch 'dev' into rc 2026-05-02 12:13:33 +02:00
David Heinemeier Hansson 1351cc6442 Merge branch 'dev' into rc 2026-05-02 11:47:54 +02:00
Ryan HughesandGitHub 59b16e7f0f Merge pull request #5541 from dotsilva/dev
fix: "Bistream" typo to "Bitstream"
2026-05-01 23:30:20 -04:00
Bruno da Silva ff23d01fce FIX: Bistream typo to Bitstream in three places 2026-05-01 21:24:41 -03:00
David Heinemeier Hansson a4ab555516 Merge branch 'dev' into rc 2026-05-01 18:33:06 +02:00
David Heinemeier Hansson 1eaddf97ea Quiet down so we don't get useless output spam 2026-05-01 18:27:20 +02:00
David Heinemeier Hansson 8537f41a9d Merge branch 'dev' into rc 2026-05-01 18:22:57 +02:00
David Heinemeier Hansson cf16a6a1a6 Merge branch 'dev' into rc 2026-05-01 14:15:08 +02:00
David Heinemeier Hansson 3d9a875104 Merge branch 'dev' into rc 2026-05-01 11:27:23 +02:00
David Heinemeier Hansson 0b35365f6b Merge branch 'dev' into rc 2026-05-01 11:24:23 +02:00
David Heinemeier Hansson 58c350c171 Merge branch 'dev' into rc 2026-04-30 22:23:48 +02:00
David Heinemeier Hansson efd34a2eea Merge branch 'dev' into rc 2026-04-30 21:45:16 +02:00
David Heinemeier Hansson 0c972657c2 Merge branch 'dev' into rc 2026-04-30 18:32:37 +02:00
David Heinemeier Hansson fa5d054173 Merge branch 'dev' into rc 2026-04-30 18:07:02 +02:00
David Heinemeier Hansson cd7c38c8aa Merge branch 'dev' into rc 2026-04-30 09:40:17 +02:00
David Heinemeier Hansson 9eb0f0e805 Merge branch 'dev' into rc 2026-04-29 20:19:48 +02:00
David Heinemeier Hansson b77f900420 Merge branch 'dev' into rc 2026-04-29 15:49:48 +02:00
David Heinemeier Hansson 1770494fa2 Merge branch 'dev' into rc 2026-04-29 11:23:41 +02:00
David Heinemeier Hansson 53d073da7c Merge branch 'dev' into rc 2026-04-28 09:37:27 +02:00
David Heinemeier Hansson 2fab15c0a7 Merge branch 'dev' into rc 2026-04-27 15:00:25 +02:00
David Heinemeier Hansson 4127c749fb Proper fix for using device dark mode in Chrome 2026-04-24 10:16:31 +02:00
David Heinemeier HanssonandGitHub bc9777c0b8 Merge pull request #5388 from basecamp/rc
Omarchy 3.6.0
2026-04-23 15:12:57 +02:00
David Heinemeier Hansson add6a3c506 Merge branch 'dev' into rc 2026-04-23 14:39:27 +02:00
David Heinemeier Hansson 7dc086bb47 Merge branch 'dev' into rc 2026-04-23 13:03:33 +02:00
David Heinemeier Hansson 8346eea614 Merge branch 'dev' into rc 2026-04-23 12:48:31 +02:00
David Heinemeier Hansson 1abc92aadd Merge branch 'dev' into rc 2026-04-23 11:57:26 +02:00
141edc262f Quote OMARCHY_PATH in migration source command
Agent-Logs-Url: https://github.com/basecamp/omarchy/sessions/36fb96d5-70fd-4365-9550-e7ff5f8735d1

Co-authored-by: dhh <2741+dhh@users.noreply.github.com>
2026-04-22 20:31:31 +00:00
David Heinemeier Hansson 12494bcd8f Merge branch 'dev' into rc 2026-04-22 22:18:40 +02:00
David Heinemeier Hansson 577cd1e8ab Merge branch 'dev' into rc 2026-04-22 21:28:28 +02:00
David Heinemeier Hansson 2f5be43407 Merge branch 'dev' into rc 2026-04-22 20:11:29 +02:00
David Heinemeier Hansson 77c9bca045 Merge branch 'dev' into rc 2026-04-22 16:33:50 +02:00
David Heinemeier Hansson 2537edb1e6 Merge branch 'dev' into rc 2026-04-22 16:31:09 +02:00
David Heinemeier HanssonandGitHub 236a34b23c Merge pull request #5280 from basecamp/rc
Omarchy 3.5.1
2026-04-16 16:12:03 +02:00
David Heinemeier Hansson 2c4b4488c0 Merge branch 'dev' into rc 2026-04-16 16:03:49 +02:00
David Heinemeier Hansson 8f7d64ba78 Merge branch 'dev' into rc 2026-04-16 15:34:24 +02:00
David Heinemeier Hansson 9ece3318ec Merge branch 'dev' into rc 2026-04-16 15:24:11 +02:00
David Heinemeier Hansson d51a3f6b37 Merge branch 'dev' into rc 2026-04-15 18:16:27 +02:00
David Heinemeier Hansson cdb8628502 Merge branch 'dev' into rc 2026-04-15 16:21:03 +02:00
David Heinemeier Hansson b919a5541a Merge branch 'dev' into rc 2026-04-15 16:17:19 +02:00
David Heinemeier Hansson 4ee44c36a6 Merge branch 'dev' into rc 2026-04-15 15:55:55 +02:00
David Heinemeier Hansson d71ddf022a Merge branch 'dev' into rc 2026-04-15 15:02:11 +02:00
David Heinemeier Hansson cd511f77b9 Merge branch 'dev' into rc 2026-04-15 14:36:44 +02:00
David Heinemeier Hansson e6b105d0b2 Merge branch 'dev' into rc 2026-04-15 13:52:05 +02:00
David Heinemeier Hansson 2554fe8555 Merge branch 'dev' into rc 2026-04-15 12:34:23 +02:00
David Heinemeier Hansson feda8b7231 Merge branch 'dev' into rc 2026-04-15 12:11:18 +02:00
David Heinemeier Hansson 46eb5568d9 Merge branch 'dev' into rc 2026-04-15 11:56:00 +02:00
David Heinemeier Hansson 33c92f554b Merge branch 'dev' into rc 2026-04-15 11:49:29 +02:00
David Heinemeier Hansson 997011e985 Merge branch 'dev' into rc 2026-04-13 16:00:11 -07:00
David Heinemeier Hansson 0e126b7916 Merge branch 'dev' into rc 2026-04-13 15:59:23 -07:00
David Heinemeier Hansson f81b3c842d Merge branch 'dev' into rc 2026-04-11 20:48:42 -04:00
David Heinemeier Hansson ecbd912b09 Merge branch 'dev' into rc 2026-04-11 18:02:01 -04:00
David Heinemeier HanssonandGitHub 76d09b29b7 Merge pull request #5192 from basecamp/rc
Omarchy 3.5.0
2026-04-03 19:16:29 +02:00
David Heinemeier Hansson f18dfdd101 Merge branch 'dev' into rc 2026-04-03 11:36:14 +02:00
David Heinemeier Hansson e4757abb80 Merge branch 'dev' into rc 2026-04-03 10:57:18 +02:00
David Heinemeier Hansson fc1cb1a751 Merge branch 'dev' into rc 2026-04-02 18:06:32 +02:00
David Heinemeier Hansson 50d3579d66 Don't use the names here since they break the all-themes setup in omarchy-nvim 2026-04-02 18:04:55 +02:00
David Heinemeier Hansson b72a831bf5 Merge branch 'dev' into rc 2026-04-02 17:39:10 +02:00
David Heinemeier Hansson e2b6b5ed5a Merge branch 'dev' into rc 2026-04-02 17:23:41 +02:00
David Heinemeier Hansson e5bcec53d1 Merge branch 'dev' into rc 2026-04-02 16:07:23 +02:00
David Heinemeier Hansson 1b07638732 Merge branch 'dev' into rc 2026-04-02 16:06:29 +02:00
David Heinemeier Hansson 4a3355e767 Merge branch 'dev' into rc 2026-04-01 18:16:31 +02:00
David Heinemeier Hansson 3b8ab81781 Merge branch 'dev' into rc 2026-03-08 18:29:04 +01:00
David Heinemeier Hansson da0bb37a19 Merge branch 'dev' into rc 2026-03-08 17:54:04 +01:00
166 changed files with 3703 additions and 1990 deletions
+3 -6
View File
@@ -105,7 +105,7 @@ Exceptions are allowed for migration and package-helper scripts where the helper
- `config/` - default configs copied to `~/.config/`
- `default/themed/*.tpl` - templates with `{{ variable }}` placeholders for theme colors
- `themes/*/colors.toml` - theme color definitions (accent, background, foreground, red/green/yellow/blue/magenta/cyan and bright_* variants)
- `themes/*/colors.toml` - theme color definitions (accent, bg, fg, red/green/yellow/blue/magenta/cyan and bright_* variants)
# Tests
@@ -177,12 +177,9 @@ This copies `/etc/skel/.config/hypr/hyprlock.conf` to `~/.config/hypr/hyprlock.c
Read `docs/migrations.md` before creating or changing migrations.
Migrations are split by execution scope:
Migrations are per-user and run through `omarchy-migrate` during `omarchy update` or from the migration notification. Put migrations directly under `migrations/<timestamp>.sh`. Pending state is per-user under `~/.local/state/omarchy/migrations/`, so every user gets a chance to run every migration. Migrations run as the user; privileged work should invoke the appropriate helper or privilege prompt, and no-op when another user already applied it.
- `migrations/system/<timestamp>.sh` — root, noninteractive, safe to run from pacman via `omarchy-migrate-system` (`omarchy` `post_upgrade` calls it). Use for `/etc`, `/usr`, `/boot`, services, hardware quirks, and other system state. Do not prompt.
- `migrations/user/<timestamp>.sh` — current user/session, may touch `~/.config`, `~/.local`, user systemd, browser prefs, DBus/session state, and may prompt if necessary. Runs through `omarchy-migrate` / `omarchy-migrate-user`; pending state is per-user based on missing files under `~/.local/state/omarchy/migrations/user/`.
To create a new migration, run `omarchy-dev-add-migration system --no-edit` or `omarchy-dev-add-migration user --no-edit` based on scope.
To create a new migration, run `omarchy-dev-add-migration --no-edit`.
New migration format:
- File permissions must be `0644` (`-rw-r--r--`); migration runners execute them with `bash -euo pipefail`, not through executable bits
+1 -1
View File
@@ -4,5 +4,5 @@ Name=Discord
Exec=omarchy-launch-webapp https://discord.com/channels/@me
Terminal=false
Type=Application
Icon=discord
Icon=omarchy-discord
StartupNotify=true
+1 -1
View File
@@ -1,7 +1,7 @@
[Desktop Entry]
Version=1.0
Name=Disk Usage
Exec=xdg-terminal-exec --app-id=TUI.float -e bash -c "dust -r; read -n 1 -s"
Exec=xdg-terminal-exec --app-id=TUI.float -e bash -c "dua i /"
Terminal=false
Type=Application
Icon=disk-usage
Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 147 KiB

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

+2 -10
View File
@@ -16,7 +16,7 @@ fi
pkill slurp && exit 0
SCREENSHOT_EDITOR="${OMARCHY_SCREENSHOT_EDITOR:-satty}"
SCREENSHOT_EDITOR="${OMARCHY_SCREENSHOT_EDITOR:-tensaku-edit}"
# Parse --editor flag from any position
ARGS=()
@@ -31,15 +31,7 @@ set -- "${ARGS[@]}"
open_editor() {
local filepath="$1"
if [[ $SCREENSHOT_EDITOR == "satty" ]]; then
satty --filename "$filepath" \
--output-filename "$filepath" \
--actions-on-enter save-to-clipboard \
--save-after-copy \
--copy-command 'wl-copy --type image/png'
else
$SCREENSHOT_EDITOR "$filepath"
fi
"$SCREENSHOT_EDITOR" "$filepath"
}
MODE="${1:-smart}"
+33
View File
@@ -0,0 +1,33 @@
#!/bin/bash
# omarchy:summary=Print the active Omarchy package channel
set -euo pipefail
conf=${OMARCHY_CONFIG_FILE:-/etc/omarchy.conf}
omarchy_path=${OMARCHY_PATH:-/usr/share/omarchy}
if [[ -r $conf ]]; then
configured_path=$(bash -c 'source "$1"; printf "%s\n" "${OMARCHY_PATH:-}"' bash "$conf" 2>/dev/null || true)
[[ -n $configured_path ]] && omarchy_path="$configured_path"
fi
channel=$(omarchy-version-channel 2>/dev/null | awk '{ print $1 }')
if pacman -Q omarchy-dev omarchy-settings-dev >/dev/null 2>&1; then
case "$channel" in
rc) echo rc ;;
edge)
if [[ $omarchy_path == "/usr/share/omarchy" ]]; then
echo dev
else
echo edge
fi
;;
*) echo unknown ;;
esac
elif pacman -Q omarchy omarchy-settings >/dev/null 2>&1 && [[ $channel == "stable" ]]; then
echo stable
else
echo unknown
fi
+111 -9
View File
@@ -1,21 +1,123 @@
#!/bin/bash
# omarchy:summary=Set the Omarchy package channel.
# omarchy:args=<stable|rc|edge|dev>
# omarchy:args=<stable|rc|dev|edge>
# omarchy:requires-sudo=true
set -e
set -euo pipefail
if (($# == 0)); then
echo "Usage: omarchy-channel-set [stable|rc|edge|dev]"
exit 1
fi
usage() { echo "Usage: omarchy-channel-set [stable|rc|dev|edge]"; }
fail() { echo "Error: $*" >&2; exit 1; }
confirm_edge() {
cat <<'WARNING'
Edge links Omarchy directly to a mutable source checkout.
This disables package-based protections for the Omarchy code path, including
normal package updates and package-backed snapshot restores. You'll be
responsible for pulling, fixing, and restoring that checkout yourself.
WARNING
if omarchy-cmd-present gum; then
gum confirm --default=false "Enable Edge anyway?"
else
local answer=""
read -r -p "Enable Edge anyway? [y/N] " answer
[[ $answer == "y" || $answer == "Y" || $answer == "yes" || $answer == "YES" ]]
fi
}
choose_edge_checkout() {
local default_path="$HOME/Work/omarchy"
local path="${OMARCHY_EDGE_PATH:-}"
if [[ -z $path ]]; then
if omarchy-cmd-present gum; then
path=$(gum input --value "$default_path" --placeholder "$default_path" --header "Where should Edge checkout live? Existing non-checkout paths will not be overwritten.") || exit 1
else
read -r -p "Edge checkout path [$default_path]: " path
fi
fi
path="${path:-$default_path}"
case "$path" in
"~") path="$HOME" ;;
"~/"*) path="$HOME/${path#~/}" ;;
/*) ;;
*) path="$PWD/$path" ;;
esac
if [[ -e $path && ! -d $path/.git ]]; then
fail "$path already exists and is not a git checkout. Choose an empty path or an existing Omarchy checkout."
fi
if [[ -d $path/.git && ( ! -d $path/bin || ! -d $path/default || ! -d $path/shell ) ]]; then
fail "$path is a git checkout, but it does not look like Omarchy."
fi
printf '%s\n' "$path"
}
sync_edge_checkout() {
local checkout="$1"
if [[ -d $checkout/.git ]]; then
echo "Updating Edge checkout at $checkout"
git -C "$checkout" fetch origin quattro
git -C "$checkout" checkout quattro 2>/dev/null || git -C "$checkout" checkout --track origin/quattro
git -C "$checkout" pull --ff-only origin quattro
else
mkdir -p "$(dirname -- "$checkout")"
git clone --branch quattro --single-branch https://github.com/basecamp/omarchy.git "$checkout"
fi
omarchy-dev-link "$checkout"
}
(( $# > 0 )) || { usage; exit 1; }
edge_checkout=""
channel="$1"
case "$channel" in
stable|rc|edge) omarchy-refresh-pacman "$channel" ;;
dev) omarchy-refresh-pacman edge ;;
*) echo "Unknown channel: $channel"; exit 1 ;;
stable)
pacman_channel=stable
packages=(omarchy omarchy-settings)
;;
rc)
pacman_channel=rc
packages=(omarchy-dev omarchy-settings-dev)
;;
dev)
pacman_channel=edge
packages=(omarchy-dev omarchy-settings-dev)
;;
edge|source)
confirm_edge || { echo "Cancelled."; exit 0; }
edge_checkout=$(choose_edge_checkout)
pacman_channel=edge
packages=(omarchy-dev omarchy-settings-dev)
;;
*)
echo "Unknown channel: $channel" >&2
usage >&2
exit 1
;;
esac
omarchy-refresh-pacman "$pacman_channel"
# --ask 4 accepts omarchy <-> omarchy-dev replacement prompts without file overwrites.
sudo env OMARCHY_UPDATE_PACMAN=1 pacman -S --needed --noconfirm --ask 4 "${packages[@]}"
if [[ -z $edge_checkout ]] && omarchy-cmd-present omarchy-dev-unlink; then
omarchy-dev-unlink
export OMARCHY_PATH=/usr/share/omarchy
fi
omarchy-update -y
if [[ -n $edge_checkout ]]; then
sync_edge_checkout "$edge_checkout"
fi
+1 -1
View File
@@ -29,7 +29,7 @@ open_image() {
local path="$1"
[[ -r $path ]] || exit 1
exec satty --filename "$path" --output-filename "$path"
exec tensaku-edit "$path"
}
open_text() {
+27 -19
View File
@@ -1,32 +1,40 @@
#!/bin/bash
# omarchy:summary=Create a new Omarchy migration in the current source tree.
# omarchy:args=<system|user> [--no-edit]
# omarchy:args=[--no-edit]
set -euo pipefail
scope="${1:-}"
case "$scope" in
system|user)
shift
;;
-h|--help|"")
echo "Usage: omarchy-dev-add-migration <system|user> [--no-edit]"
exit 0
;;
*)
echo "Unknown migration scope: $scope" >&2
echo "Usage: omarchy-dev-add-migration <system|user> [--no-edit]" >&2
exit 1
;;
esac
no_edit=0
while (($#)); do
case "$1" in
--no-edit)
no_edit=1
shift
;;
system|user)
echo "omarchy-dev-add-migration: migration scopes are no longer used; creating a regular migration." >&2
shift
;;
-h|--help)
echo "Usage: omarchy-dev-add-migration [--no-edit]"
exit 0
;;
*)
echo "Unknown option: $1" >&2
echo "Usage: omarchy-dev-add-migration [--no-edit]" >&2
exit 1
;;
esac
done
cd "${OMARCHY_PATH:-$(pwd)}"
mkdir -p "migrations/$scope"
migration_file="migrations/$scope/$(git log -1 --format=%cd --date=unix).sh"
mkdir -p migrations
migration_file="migrations/$(git log -1 --format=%cd --date=unix).sh"
touch "$migration_file"
if [[ ${1:-} != "--no-edit" ]]; then
if (( ! no_edit )); then
nvim "$migration_file"
fi
+23 -42
View File
@@ -1,26 +1,24 @@
#!/bin/bash
# omarchy:summary=Point Omarchy at a local checkout for live editing
# omarchy:summary=Point Omarchy at a local checkout after reboot
# omarchy:group=dev
# omarchy:args=<path-to-checkout>
# omarchy:examples=omarchy dev link ~/Work/omarchy/omarchy-installer
set -euo pipefail
# Sudo wipes HYPRLAND_INSTANCE_SIGNATURE, so the live-session refresh below
# can't reach hyprctl. Run as user; we sudo internally for the conf write.
if [[ $EUID -eq 0 ]]; then
if (( EUID == 0 )); then
echo "Error: run omarchy-dev-link as your user, not under sudo." >&2
exit 1
fi
if [[ $# -ne 1 || $1 == "-h" || $1 == "--help" ]]; then
if (( $# != 1 )) || [[ $1 == "-h" || $1 == "--help" ]]; then
cat <<USAGE
Usage: omarchy dev link <path-to-checkout>
Writes /etc/omarchy.conf so OMARCHY_PATH resolves to <path-to-checkout>
in all new shells, the Hyprland session, and Quickshell. Restarts
omarchy-shell and reloads hyprctl so changes take effect immediately.
after reboot. This intentionally does not rewrite the running Hyprland,
systemd, shell, or app-launcher environment; reboot to make every layer agree.
Affects only \$OMARCHY_PATH-resolved trees: bin/, default/, shell/,
themes/, applications/, config/. Files installed at fixed system paths
@@ -31,50 +29,33 @@ USAGE
exit 0
fi
omarchy_conf_quote() {
local value="$1"
value=${value//\\/\\\\}
value=${value//\"/\\\"}
value=${value//\$/\\\$}
value=${value//\`/\\\`}
printf '"%s"' "$value"
}
target=$(realpath -e "$1" 2>/dev/null) || {
echo "Error: path does not exist: $1" >&2
exit 1
}
for required in bin default shell; do
if [[ ! -d "$target/$required" ]]; then
if [[ ! -d $target/$required ]]; then
echo "Warning: $target/$required not found — does this look like an Omarchy source checkout?" >&2
fi
done
# Strip any previous dev-link's bin/ from PATH before adding the new one,
# so repeated link calls don't accumulate stale entries.
prior_target=""
if [[ -f /etc/omarchy.conf ]]; then
prior_target=$(sed -n 's/^[[:space:]]*export[[:space:]]\+OMARCHY_PATH="\?\([^"]*\)"\?/\1/p' /etc/omarchy.conf | tail -1)
fi
echo "Pointing Omarchy at $target"
printf 'export OMARCHY_PATH="%s"\n' "$target" | sudo tee /etc/omarchy.conf >/dev/null
export OMARCHY_PATH="$target"
if [[ -n $prior_target && $prior_target != "$target" ]]; then
PATH=$(printf '%s' "$PATH" | tr ':' '\n' | grep -vFx "$prior_target/bin" | paste -sd:)
fi
export PATH="$target/bin:$PATH"
if command -v hyprctl >/dev/null 2>&1 && hyprctl version &>/dev/null; then
hyprctl setenv OMARCHY_PATH "$target" >/dev/null
hyprctl setenv PATH "$PATH" >/dev/null
echo " Updated Hyprland session env."
systemctl --user import-environment OMARCHY_PATH PATH 2>/dev/null || true
echo " Updated systemd --user env."
if pgrep -x quickshell >/dev/null 2>&1; then
omarchy-restart-shell
echo " Restarted omarchy-shell."
fi
hyprctl reload >/dev/null
echo " Reloaded Hyprland config."
fi
{
printf 'export OMARCHY_PATH='
omarchy_conf_quote "$target"
printf '\n'
} | sudo tee /etc/omarchy.conf >/dev/null
echo "Pointed Omarchy at $target"
echo
echo "Done. Open a new shell (or restart existing ones) to pick up the new"
echo "OMARCHY_PATH. Run 'omarchy dev unlink' to restore the package install."
echo "Reboot to activate the linked checkout in Hyprland, app launchers, and new shells."
echo "Run 'omarchy dev unlink' and reboot to restore the package install."
+6 -15
View File
@@ -3,6 +3,8 @@
# omarchy:summary=Show the current Omarchy dev-link state
# omarchy:group=dev
set -euo pipefail
default_target="/usr/share/omarchy"
configured="$default_target"
conf_present=0
@@ -22,8 +24,9 @@ if [[ -f /etc/omarchy.conf ]]; then
fi
if (( linked )); then
echo "dev-link: ACTIVE"
echo "dev-link: configured"
echo " /etc/omarchy.conf -> OMARCHY_PATH=$configured"
echo " status: reboot required before all session layers use this checkout"
else
echo "dev-link: inactive"
if (( conf_present )); then
@@ -33,19 +36,7 @@ fi
echo " current shell: OMARCHY_PATH=${OMARCHY_PATH:-<unset>}"
if (( linked )) && [[ ${OMARCHY_PATH:-} != "$configured" ]]; then
if [[ ${OMARCHY_PATH:-$default_target} != "$configured" ]]; then
echo
echo "Note: this shell predates dev-link. Open a new shell to pick up the change,"
echo "or 'export OMARCHY_PATH=$configured' to update just this shell."
elif (( ! linked )) && [[ ${OMARCHY_PATH:-$default_target} != "$default_target" ]]; then
echo
echo "Note: no dev-link is configured, but this shell still has a stale OMARCHY_PATH."
echo "Open a new shell or run 'export OMARCHY_PATH=$default_target'."
fi
if command -v hyprctl >/dev/null 2>&1 && hyprctl version &>/dev/null; then
hypr_path=$(hyprctl getoption -j env 2>/dev/null | sed -n 's/.*OMARCHY_PATH=\([^"]*\).*/\1/p' | head -1)
if [[ -n "$hypr_path" ]]; then
echo " hyprland session: OMARCHY_PATH=$hypr_path"
fi
echo "Note: the running session does not match /etc/omarchy.conf. Reboot to settle it."
fi
+453
View File
@@ -0,0 +1,453 @@
#!/bin/bash
# omarchy:summary=Preview an Omarchy theme palette in the terminal
# omarchy:args=[theme-name|theme-dir|colors.toml] [--no-color] [--no-osc|--osc]
# omarchy:examples=omarchy dev theme-preview | omarchy dev theme-preview tokyo-night | omarchy dev theme-preview themes/gruvbox/colors.toml --no-color --no-osc
set -o pipefail
CURRENT_THEME_PATH="$HOME/.local/state/omarchy/current/theme"
USER_THEMES_PATH="$HOME/.config/omarchy/themes"
OMARCHY_THEMES_PATH="$OMARCHY_PATH/themes"
COLOR_OUTPUT=1
APPLY_OSC="auto"
THEME_REF=""
declare -A COLORS
usage() {
cat <<'USAGE'
Usage: omarchy-dev-theme-preview [theme-name|theme-dir|colors.toml] [--no-color] [--no-osc]
Preview a theme palette in the terminal. Without an argument, previews the
current theme from ~/.local/state/omarchy/current/theme/colors.toml.
When stdout is a terminal and color output is enabled, the preview also applies
that theme's OSC palette to the current terminal only. Use --no-osc to suppress
that, or --osc to force it even when stdout is not detected as a terminal.
USAGE
}
for arg in "$@"; do
case "$arg" in
--no-color | --plain)
COLOR_OUTPUT=0
APPLY_OSC="never"
;;
--no-osc)
APPLY_OSC="never"
;;
--osc | --apply-osc | --terminal)
APPLY_OSC="always"
;;
-h | --help)
usage
exit 0
;;
*)
if [[ -n $THEME_REF ]]; then
usage >&2
exit 1
fi
THEME_REF="$arg"
;;
esac
done
if [[ -n ${NO_COLOR:-} ]]; then
COLOR_OUTPUT=0
fi
normalize_theme_name() {
printf '%s' "$1" | sed -E 's/<[^>]+>//g' | tr '[:upper:]' '[:lower:]' | tr ' ' '-'
}
resolve_colors_file() {
local ref="$1"
local theme_name
if [[ -z $ref ]]; then
printf '%s/colors.toml' "$CURRENT_THEME_PATH"
elif [[ -f $ref ]]; then
printf '%s' "$ref"
elif [[ -d $ref && -f $ref/colors.toml ]]; then
printf '%s/colors.toml' "$ref"
else
theme_name=$(normalize_theme_name "$ref")
if [[ -f $USER_THEMES_PATH/$theme_name/colors.toml ]]; then
printf '%s/colors.toml' "$USER_THEMES_PATH/$theme_name"
elif [[ -f $OMARCHY_THEMES_PATH/$theme_name/colors.toml ]]; then
printf '%s/colors.toml' "$OMARCHY_THEMES_PATH/$theme_name"
else
return 1
fi
fi
}
clean_toml_value() {
local value="$1"
value="${value#*[\"\']}"
value="${value%%[\"\']*}"
printf '%s' "$value"
}
load_colors() {
local colors_file="$1"
local key value
while IFS='=' read -r key value; do
key="${key//[\"\' ]/}"
[[ $key && $key != \#* ]] || continue
value=$(clean_toml_value "$value")
COLORS[$key]="$value"
done <"$colors_file"
# Legacy semantic names win when present so older themes keep their intended
# primary text/background colors even if they also had dimmer fg/bg slots.
[[ ${COLORS[background]} ]] && COLORS[bg]="${COLORS[background]}"
[[ ${COLORS[foreground]} ]] && COLORS[fg]="${COLORS[foreground]}"
[[ ${COLORS[bg]} ]] || COLORS[bg]="${COLORS[color0]}"
[[ ${COLORS[fg]} ]] || COLORS[fg]="${COLORS[color7]}"
[[ ${COLORS[light_fg]} ]] || COLORS[light_fg]="${COLORS[color7]:-${COLORS[fg]}}"
[[ ${COLORS[bright_fg]} ]] || COLORS[bright_fg]="${COLORS[color15]:-${COLORS[fg]}}"
[[ ${COLORS[selection_background]} ]] || COLORS[selection_background]="${COLORS[selection]}"
[[ ${COLORS[selection_foreground]} ]] || COLORS[selection_foreground]="${COLORS[bright_fg]}"
if hex_valid "${COLORS[bg]}"; then
[[ ${COLORS[dark_bg]} ]] || COLORS[dark_bg]=$(mix_hex "${COLORS[bg]}" "#000000" 1 4)
[[ ${COLORS[darker_bg]} ]] || COLORS[darker_bg]=$(mix_hex "${COLORS[bg]}" "#000000" 1 2)
fi
}
hex_parts() {
local hex="${1#\#}"
printf '%d %d %d' "0x${hex:0:2}" "0x${hex:2:2}" "0x${hex:4:2}"
}
hex_valid() {
[[ $1 =~ ^#[0-9A-Fa-f]{6}$ ]]
}
luma_sum() {
local r g b
read -r r g b < <(hex_parts "$1")
printf '%d' $((r * 2126 + g * 7152 + b * 722))
}
contrast_ratio() {
local fg="$1"
local bg="$2"
awk -v fg="${fg#\#}" -v bg="${bg#\#}" '
function hex_value(char) { return index("0123456789abcdef", tolower(char)) - 1 }
function hex_pair(hex, idx) { return hex_value(substr(hex, idx, 1)) * 16 + hex_value(substr(hex, idx + 1, 1)) }
function channel(hex, idx) { return hex_pair(hex, idx) / 255 }
function linear(c) { return c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ^ 2.4 }
function lum(hex) {
return 0.2126 * linear(channel(hex, 1)) + 0.7152 * linear(channel(hex, 3)) + 0.0722 * linear(channel(hex, 5))
}
BEGIN {
a = lum(fg)
b = lum(bg)
if (a < b) { tmp = a; a = b; b = tmp }
printf "%.2f", (a + 0.05) / (b + 0.05)
}
'
}
ansi_bg() {
local r g b
read -r r g b < <(hex_parts "$1")
printf '\033[48;2;%d;%d;%dm' "$r" "$g" "$b"
}
ansi_fg() {
local r g b
read -r r g b < <(hex_parts "$1")
printf '\033[38;2;%d;%d;%dm' "$r" "$g" "$b"
}
reset_ansi() {
printf '\033[0m'
}
apply_terminal_osc() {
case "$APPLY_OSC" in
never)
return
;;
auto)
[[ -t 1 ]] && (( COLOR_OUTPUT )) || return
;;
always)
;;
esac
if [[ -x $OMARCHY_PATH/bin/omarchy-theme-osc ]]; then
"$OMARCHY_PATH/bin/omarchy-theme-osc" "$colors_file" || true
else
omarchy-theme-osc "$colors_file" || true
fi
}
swatch() {
local hex="$1"
local width="${2:-18}"
local i
if (( COLOR_OUTPUT )) && hex_valid "$hex"; then
ansi_bg "$hex"
for (( i = 0; i < width; i++ )); do
printf ' '
done
reset_ansi
else
for (( i = 0; i < width; i++ )); do
printf '#'
done
fi
}
print_color_row() {
local key="$1"
local hex="${COLORS[$key]}"
[[ -n $hex ]] || return
printf ' %-22s %-9s ' "$key" "$hex"
swatch "$hex" 20
printf '\n'
}
paint_segment() {
local text="$1"
local fg="$2"
local bg="${3:-${COLORS[bg]}}"
if (( COLOR_OUTPUT )) && hex_valid "$fg" && hex_valid "$bg"; then
ansi_bg "$bg"
ansi_fg "$fg"
printf '%s' "$text"
reset_ansi
else
printf '%s' "$text"
fi
}
print_group() {
local title="$1"
shift
local key
printf '\n%s\n' "$title"
for key in "$@"; do
print_color_row "$key"
done
}
print_selection_sample() {
local bg="${COLORS[bg]}"
local fg="${COLORS[fg]}"
local selection_bg="${COLORS[selection_background]}"
local selection_fg="${COLORS[selection_foreground]}"
[[ -n $bg && -n $fg && -n $selection_bg && -n $selection_fg ]] || return
printf '\nSelection sample\n '
if (( COLOR_OUTPUT )) && hex_valid "$bg" && hex_valid "$fg" && hex_valid "$selection_bg" && hex_valid "$selection_fg"; then
ansi_bg "$bg"
ansi_fg "$fg"
printf ' This is some '
ansi_bg "$selection_bg"
ansi_fg "$selection_fg"
printf 'selected text'
ansi_bg "$bg"
ansi_fg "$fg"
printf ' in a sentence '
reset_ansi
printf '\n'
else
printf 'This is some [selected text] in a sentence\n'
fi
}
print_practical_samples() {
printf '\nTerminal/UI samples\n'
printf ' '
paint_segment ' normal text ' "${COLORS[fg]}"
paint_segment ' muted/comment ' "${COLORS[muted]}"
paint_segment ' accent/link ' "${COLORS[accent]}"
paint_segment ' error ' "${COLORS[red]}"
paint_segment ' warning ' "${COLORS[yellow]}"
paint_segment ' success ' "${COLORS[green]}"
printf '\n '
paint_segment ' $ omarchy theme-preview ' "${COLORS[green]}"
paint_segment ' # comment ' "${COLORS[muted]}"
paint_segment ' "string" ' "${COLORS[green]}"
paint_segment ' function() ' "${COLORS[blue]}"
paint_segment ' --flag ' "${COLORS[magenta]}"
printf '\n '
paint_segment ' unselected menu row ' "${COLORS[fg]}"
printf '\n '
paint_segment ' selected menu row ' "${COLORS[selection_foreground]}" "${COLORS[selection_background]}"
printf '\n '
paint_segment ' status/inverse ' "${COLORS[bg]}" "${COLORS[fg]}"
paint_segment ' inactive surface ' "${COLORS[fg]}" "${COLORS[lighter_bg]}"
paint_segment ' urgent ' "${COLORS[bg]}" "${COLORS[red]}"
printf '\n'
}
print_palette_strip() {
local title="$1"
shift
local key hex
printf ' %-12s ' "$title"
for key in "$@"; do
hex="${COLORS[$key]}"
if [[ -n $hex ]]; then
swatch "$hex" 4
printf ' '
fi
done
printf '\n'
}
print_ansi_palette() {
printf '\nANSI palette strips\n'
print_palette_strip normal bg red green yellow blue magenta cyan fg
print_palette_strip bright muted bright_red bright_green bright_yellow bright_blue bright_magenta bright_cyan bright_fg
}
mix_hex() {
local start="$1"
local end="$2"
local index="$3"
local max_index="$4"
local sr sg sb er eg eb r g b
read -r sr sg sb < <(hex_parts "$start")
read -r er eg eb < <(hex_parts "$end")
if (( max_index == 0 )); then
printf '%s' "$start"
return
fi
r=$(((sr * (max_index - index) + er * index + max_index / 2) / max_index))
g=$(((sg * (max_index - index) + eg * index + max_index / 2) / max_index))
b=$(((sb * (max_index - index) + eb * index + max_index / 2) / max_index))
printf '#%02x%02x%02x' "$r" "$g" "$b"
}
print_gradient() {
local start_key="$1"
local end_key="$2"
local start="${COLORS[$start_key]}"
local end="${COLORS[$end_key]}"
local steps=24
local i hex
[[ -n $start && -n $end ]] || return
hex_valid "$start" && hex_valid "$end" || return
printf '\n%s -> %s gradient\n' "$start_key" "$end_key"
printf ' %s ' "$start"
for (( i = 0; i < steps; i++ )); do
hex=$(mix_hex "$start" "$end" "$i" "$((steps - 1))")
if (( COLOR_OUTPUT )); then
ansi_bg "$hex"
printf ' '
reset_ansi
else
printf '%s ' "$hex"
fi
done
printf ' %s\n' "$end"
}
print_neutral_ramp() {
local mode="$1"
local direction sort_flag key hex score entry
local -a keys entries sorted
keys=(darker_bg dark_bg bg lighter_bg selection muted dark_fg fg light_fg bright_fg)
if [[ $mode == "light" ]]; then
direction="lightest -> darkest"
sort_flag="-rn"
else
direction="darkest -> lightest"
sort_flag="-n"
fi
for key in "${keys[@]}"; do
hex="${COLORS[$key]}"
[[ -n $hex ]] || continue
hex_valid "$hex" || continue
score=$(luma_sum "$hex")
entries+=("$score $key")
done
(( ${#entries[@]} > 0 )) || return
mapfile -t sorted < <(printf '%s\n' "${entries[@]}" | sort "$sort_flag")
printf '\nNeutral ramp (%s)\n' "$direction"
for entry in "${sorted[@]}"; do
key="${entry#* }"
print_color_row "$key"
done
}
colors_file=$(resolve_colors_file "$THEME_REF") || {
echo "Theme not found: $THEME_REF" >&2
exit 1
}
if [[ ! -f $colors_file ]]; then
echo "Missing colors.toml: $colors_file" >&2
exit 1
fi
load_colors "$colors_file"
mode="${COLORS[mode]}"
if [[ -z $mode && ${COLORS[bg]} =~ ^#[0-9A-Fa-f]{6}$ ]]; then
if (( $(luma_sum "${COLORS[bg]}") > 1275000 )); then
mode="light"
else
mode="dark"
fi
fi
[[ -n $mode ]] || mode="dark"
theme_label="$THEME_REF"
if [[ -z $theme_label ]]; then
if [[ -f $HOME/.local/state/omarchy/current/theme.name ]]; then
theme_label=$(<"$HOME/.local/state/omarchy/current/theme.name")
else
theme_label="current"
fi
fi
apply_terminal_osc
printf 'Theme: %s\n' "$theme_label"
printf 'File: %s\n' "$colors_file"
printf 'Mode: %s\n' "$mode"
if [[ ${COLORS[fg]} =~ ^#[0-9A-Fa-f]{6}$ && ${COLORS[bg]} =~ ^#[0-9A-Fa-f]{6}$ ]]; then
printf 'fg/bg contrast: %s:1\n' "$(contrast_ratio "${COLORS[fg]}" "${COLORS[bg]}")"
fi
print_gradient bg bright_fg
print_neutral_ramp "$mode"
print_group "Foundation" bg fg accent selection
print_selection_sample
print_practical_samples
print_ansi_palette
print_group "Normal colors" red yellow orange green cyan blue magenta brown
print_group "Bright colors" bright_red bright_yellow bright_green bright_cyan bright_blue bright_magenta bright_fg
+7 -59
View File
@@ -1,11 +1,11 @@
#!/bin/bash
# omarchy:summary=Restore Omarchy to the package install (undo omarchy-dev-link)
# omarchy:summary=Restore Omarchy to the package install after reboot
# omarchy:group=dev
set -euo pipefail
if [[ $EUID -eq 0 ]]; then
if (( EUID == 0 )); then
echo "Error: run omarchy-dev-unlink as your user, not under sudo." >&2
exit 1
fi
@@ -14,69 +14,17 @@ if [[ ${1:-} == "-h" || ${1:-} == "--help" ]]; then
cat <<USAGE
Usage: omarchy dev unlink
Writes /etc/omarchy.conf defensively so OMARCHY_PATH resolves to
/usr/share/omarchy (the package install), even from stale session env.
Updates Hyprland/systemd session env and restarts omarchy-shell so live
state matches.
Writes /etc/omarchy.conf so OMARCHY_PATH resolves to /usr/share/omarchy
after reboot. This intentionally does not rewrite the running Hyprland,
systemd, shell, or app-launcher environment; reboot to make every layer agree.
USAGE
exit 0
fi
default_target="/usr/share/omarchy"
linked=0
prior_target=""
if [[ -f /etc/omarchy.conf ]]; then
# Capture the path dev-link wrote BEFORE we reset the conf, so we know
# which bin/ to strip from PATH.
prior_target=$(sed -n 's/^[[:space:]]*export[[:space:]]\+OMARCHY_PATH="\?\([^"]*\)"\?/\1/p' /etc/omarchy.conf | tail -1)
if [[ $prior_target != "$default_target" ]]; then
linked=1
echo "Unlinking Omarchy from ${prior_target:-<empty>}"
else
echo "/etc/omarchy.conf already points at $default_target."
fi
elif [[ ${OMARCHY_PATH:-$default_target} != "$default_target" ]]; then
prior_target="$OMARCHY_PATH"
echo "Not currently linked: /etc/omarchy.conf is absent."
echo "This shell still has OMARCHY_PATH=$OMARCHY_PATH; writing the default guard."
else
echo "Not currently linked. Writing the default OMARCHY_PATH guard."
fi
printf 'export OMARCHY_PATH="%s"\n' "$default_target" | sudo tee /etc/omarchy.conf >/dev/null
echo "Set /etc/omarchy.conf -> OMARCHY_PATH=$default_target"
export OMARCHY_PATH="$default_target"
if [[ -n $prior_target && $prior_target != "$default_target" ]]; then
PATH=$(printf '%s' "$PATH" | tr ':' '\n' | awk -v drop="$prior_target/bin" '$0 != drop' | paste -sd:)
export PATH
fi
if command -v systemctl >/dev/null 2>&1; then
if systemctl --user import-environment OMARCHY_PATH PATH 2>/dev/null; then
echo " Updated systemd --user env."
fi
fi
if command -v hyprctl >/dev/null 2>&1 && hyprctl version &>/dev/null; then
hyprctl setenv OMARCHY_PATH "$default_target" >/dev/null
hyprctl setenv PATH "$PATH" >/dev/null
echo " Updated Hyprland session env."
if pgrep -x quickshell >/dev/null 2>&1; then
omarchy-restart-shell
echo " Restarted omarchy-shell."
fi
hyprctl reload >/dev/null
echo " Reloaded Hyprland config."
fi
echo
if (( linked )) || [[ -n $prior_target ]]; then
echo "Done. Existing shells still have the old OMARCHY_PATH until restarted."
echo "For this shell, run: export OMARCHY_PATH=$default_target"
else
echo "Done."
fi
echo "Reboot to restore the package install in Hyprland, app launchers, and new shells."
+5 -21
View File
@@ -12,13 +12,13 @@ Usage: omarchy finalize user [--force] [--first-install]
Runs the per-user setup steps that /etc/skel can't seed:
dev-aware skill symlinks, xdg-user-dirs + gtk bookmarks (need \$HOME),
vconsole→hypr keyboard sync, default browser/mailto, and install/user/all.sh.
default browser/mailto, and install/user/all.sh.
For shipped configs see /etc/skel (new users) and omarchy-reinstall-configs
(existing users explicitly resyncing).
--first-install is used by the ISO in the target chroot. It marks shipped
user migrations complete for the freshly-created user.
migrations complete for the freshly-created user.
Idempotency marker: ~/.local/state/omarchy/finalize-user.done
USAGE
@@ -100,22 +100,6 @@ for dir in Downloads Projects Pictures Videos; do
grep -qxF "$bookmark" ~/.config/gtk-3.0/bookmarks || echo "$bookmark" >>~/.config/gtk-3.0/bookmarks
done
conf=/etc/vconsole.conf
hyprlua="$HOME/.config/hypr/input.lua"
if [[ -f $conf && -f $hyprlua ]]; then
sed -i '/^[[:space:]]*kb_layout[[:space:]]*=/d' "$hyprlua"
sed -i '/^[[:space:]]*kb_variant[[:space:]]*=/d' "$hyprlua"
if grep -q '^XKBLAYOUT=' "$conf"; then
layout=$(grep '^XKBLAYOUT=' "$conf" | cut -d= -f2 | tr -d '"')
sed -i "/^[[:space:]]*kb_options *=/i\ kb_layout = \"$layout\"," "$hyprlua"
fi
if grep -q '^XKBVARIANT=' "$conf"; then
variant=$(grep '^XKBVARIANT=' "$conf" | cut -d= -f2 | tr -d '"')
sed -i "/^[[:space:]]*kb_options *=/i\ kb_variant = \"$variant\"," "$hyprlua"
fi
fi
source "$OMARCHY_INSTALL/user/all.sh"
omarchy-refresh-applications
@@ -123,9 +107,9 @@ xdg-settings set default-web-browser chromium.desktop
xdg-mime default HEY.desktop x-scheme-handler/mailto
if (( first_install )); then
mkdir -p "$state_dir/migrations/user"
for migration in "$OMARCHY_PATH"/migrations/user/*.sh; do
[[ -f $migration ]] && touch "$state_dir/migrations/user/$(basename "$migration")"
mkdir -p "$state_dir/migrations"
for migration in "$OMARCHY_PATH"/migrations/*.sh; do
[[ -f $migration ]] && touch "$state_dir/migrations/$(basename "$migration")"
done
fi
+1 -1
View File
@@ -101,7 +101,7 @@ if [[ ! -f $MIGRATION_NOTIFY_WATCH_MARKER || $force -eq 1 ]]; then
fi
fi
run_first_run_step "notify about pending user migrations" omarchy-migrate-notify
run_first_run_step "notify about pending migrations" omarchy-migrate-notify
USER_MARKER="$state_dir/first-run-user.done"
if [[ ! -f $USER_MARKER || $force -eq 1 ]]; then
+110
View File
@@ -0,0 +1,110 @@
#!/bin/bash
# omarchy:summary=Pause or resume Hyprland config auto-reload around package transactions.
# omarchy:hidden=true
set -euo pipefail
command="${1:-}"
case "$command" in
pause | resume) ;;
*)
echo "Usage: omarchy-hyprland-reload-guard pause|resume" >&2
exit 1
;;
esac
run_root="${OMARCHY_HYPRLAND_RELOAD_GUARD_RUN_ROOT:-/run/user}"
state_dir="${OMARCHY_HYPRLAND_RELOAD_GUARD_STATE_DIR:-/run/omarchy/hyprland-reload-guard}"
hyprctl_bin="${HYPRCTL:-/usr/bin/hyprctl}"
hyprctl_instance() {
local runtime_dir="$1"
local signature="$2"
shift 2
XDG_RUNTIME_DIR="$runtime_dir" "$hyprctl_bin" --instance "$signature" "$@"
}
option_bool() {
local runtime_dir="$1"
local signature="$2"
local option="$3"
hyprctl_instance "$runtime_dir" "$signature" -j getoption "$option" 2>/dev/null | jq -r '.bool'
}
instances() {
local instance_dir signature hypr_dir runtime_dir uid
[[ -d $run_root ]] || return 0
for instance_dir in "$run_root"/*/hypr/*; do
[[ -d $instance_dir ]] || continue
signature="${instance_dir##*/}"
hypr_dir="${instance_dir%/*}"
runtime_dir="${hypr_dir%/*}"
uid="${runtime_dir##*/}"
[[ $uid =~ ^[0-9]+$ ]] || continue
printf '%s\t%s\n' "$runtime_dir" "$signature"
done
}
pause_instance() {
local runtime_dir="$1"
local signature="$2"
local disable_autoreload suppress_errors state_file="$state_dir/$signature"
mkdir -p "$state_dir"
if [[ ! -f $state_file ]]; then
disable_autoreload=$(option_bool "$runtime_dir" "$signature" misc.disable_autoreload) || return 0
suppress_errors=$(option_bool "$runtime_dir" "$signature" debug.suppress_errors) || return 0
printf '%s\t%s\t%s\n' "$runtime_dir" "$disable_autoreload" "$suppress_errors" >"$state_file"
fi
hyprctl_instance "$runtime_dir" "$signature" eval \
'hl.config({ misc = { disable_autoreload = true }, debug = { suppress_errors = true } })' \
>/dev/null 2>&1 || true
}
resume_instance() {
local state_file="$1"
local signature="${state_file##*/}"
local runtime_dir disable_autoreload suppress_errors
IFS=$'\t' read -r runtime_dir disable_autoreload suppress_errors <"$state_file" || return 0
if [[ -d $runtime_dir ]]; then
hyprctl_instance "$runtime_dir" "$signature" eval \
"hl.config({ debug = { suppress_errors = $suppress_errors } })" \
>/dev/null 2>&1 || true
hyprctl_instance "$runtime_dir" "$signature" reload >/dev/null 2>&1 || true
hyprctl_instance "$runtime_dir" "$signature" eval \
"hl.config({ misc = { disable_autoreload = $disable_autoreload }, debug = { suppress_errors = $suppress_errors } })" \
>/dev/null 2>&1 || true
fi
rm -f "$state_file"
}
case "$command" in
pause)
while IFS=$'\t' read -r runtime_dir signature; do
pause_instance "$runtime_dir" "$signature"
done < <(instances)
;;
resume)
[[ -d $state_dir ]] || exit 0
for state_file in "$state_dir"/*; do
[[ -f $state_file ]] || continue
resume_instance "$state_file"
done
rmdir "$state_dir" 2>/dev/null || true
;;
esac
+2 -2
View File
@@ -8,7 +8,7 @@ omarchy-pkg-add helix
mkdir -p ~/.config/helix/themes
# Symlink the rendered Omarchy theme so Helix tracks the active theme
ln -sf ~/.config/omarchy/current/theme/helix.toml ~/.config/helix/themes/omarchy.toml
ln -sf "$HOME/.local/state/omarchy/current/theme/helix.toml" ~/.config/helix/themes/omarchy.toml
# Only seed a config.toml if the user does not already have one
if [[ ! -f ~/.config/helix/config.toml ]]; then
@@ -18,7 +18,7 @@ EOF
fi
# Ensure the symlink target exists for users whose current theme predates this template
if [[ ! -e ~/.config/omarchy/current/theme/helix.toml ]]; then
if [[ ! -e $HOME/.local/state/omarchy/current/theme/helix.toml ]]; then
omarchy-theme-refresh
fi
+41 -41
View File
@@ -1,15 +1,14 @@
#!/bin/bash
# omarchy:summary=Run pending Omarchy system and user migrations.
# omarchy:args=[--pending [all|system|user]]
# omarchy:summary=Run pending Omarchy migrations.
# omarchy:args=[--pending]
set -euo pipefail
mode="run"
pending_scope="all"
usage() {
echo "Usage: omarchy-migrate [--pending [all|system|user]]"
echo "Usage: omarchy-migrate [--pending]"
}
while (($#)); do
@@ -17,15 +16,6 @@ while (($#)); do
--pending|--check)
mode="pending"
shift
if [[ ${1:-} == "all" || ${1:-} == "system" || ${1:-} == "user" ]]; then
pending_scope="$1"
shift
fi
;;
--pending=all|--pending=system|--pending=user)
mode="pending"
pending_scope="${1#--pending=}"
shift
;;
-h|--help)
usage
@@ -38,38 +28,37 @@ while (($#)); do
esac
done
pending_output=""
OMARCHY_PATH="${OMARCHY_PATH:-/usr/share/omarchy}"
STATE_DIR="${OMARCHY_MIGRATION_STATE:-$HOME/.local/state/omarchy/migrations}"
MIGRATIONS_DIR="$OMARCHY_PATH/migrations"
append_pending() {
local scope="$1"
local command="$2"
local output=""
local migration=""
migration_entries() {
[[ -d $MIGRATIONS_DIR ]] || return 0
if output=$("$command" --pending 2>/dev/null); then
while IFS= read -r migration; do
[[ -n $migration ]] || continue
pending_output+="$scope/$migration"$'\n'
done <<<"$output"
fi
local file filename
for file in "$MIGRATIONS_DIR"/*.sh; do
[[ -f $file ]] || continue
filename=$(basename "$file")
printf '%s\t%s\t%s\n' "$filename" "$file" "$STATE_DIR/$filename"
done
}
pending_migrations() {
local name file marker
while IFS=$'\t' read -r name file marker; do
[[ -n $name ]] || continue
if [[ ! -f $marker ]]; then
printf '%s\n' "$name"
fi
done < <(migration_entries)
}
if [[ $mode == "pending" ]]; then
case "$pending_scope" in
all)
append_pending system omarchy-migrate-system
append_pending user omarchy-migrate-user
;;
system)
append_pending system omarchy-migrate-system
;;
user)
append_pending user omarchy-migrate-user
;;
esac
pending_output=$(pending_migrations)
if [[ -n $pending_output ]]; then
printf '%s' "$pending_output"
printf '%s\n' "$pending_output"
exit 0
else
exit 1
@@ -93,5 +82,16 @@ wait_for_pacman_transaction() {
wait_for_pacman_transaction
omarchy-migrate-system
omarchy-migrate-user
mkdir -p "$STATE_DIR"
[[ -d $MIGRATIONS_DIR ]] || exit 0
while IFS=$'\t' read -r name file marker; do
[[ -n $name ]] || continue
if [[ ! -f $marker ]]; then
echo -e "\e[32m\nRunning migration (${name%.sh})\e[0m"
OMARCHY_PATH="$OMARCHY_PATH" bash -euo pipefail "$file"
mkdir -p "$(dirname "$marker")"
touch "$marker"
fi
done < <(migration_entries)
+5 -5
View File
@@ -1,16 +1,16 @@
#!/bin/bash
# omarchy:summary=Notify the user when Omarchy has pending user migrations
# omarchy:summary=Notify the user when Omarchy has pending migrations
set -euo pipefail
pending_migrations=$(omarchy-migrate --pending user 2>/dev/null) || exit 0
pending_migrations=$(omarchy-migrate --pending 2>/dev/null) || exit 0
pending_count=$(printf '%s\n' "$pending_migrations" | sed '/^[[:space:]]*$/d' | wc -l)
if (( pending_count == 1 )); then
message="1 new Omarchy user migration is available. Click to run it in a terminal."
message="1 new Omarchy migration is available. Click to run it in a terminal."
else
message="$pending_count new Omarchy user migrations are available. Click to run them in a terminal."
message="$pending_count new Omarchy migrations are available. Click to run them in a terminal."
fi
notify_command=$(printf 'if [[ -n $(omarchy-notification-send -u critical -g  "Run Omarchy Migrations" %q -a) ]]; then omarchy-launch-floating-terminal-with-presentation omarchy-migrate; fi' "$message")
@@ -21,7 +21,7 @@ if command -v systemd-run >/dev/null 2>&1; then
fi
print_pending_migrations() {
echo "Omarchy has pending user migrations. Run omarchy-migrate in a terminal to apply them:"
echo "Omarchy has pending migrations. Run omarchy-migrate in a terminal to apply them:"
while IFS= read -r migration; do
[[ -n $migration ]] || continue
printf ' %s\n' "$migration"
-74
View File
@@ -1,74 +0,0 @@
#!/bin/bash
# omarchy:summary=Run pending Omarchy system migrations as root.
# omarchy:args=[--pending]
# omarchy:requires-sudo=true
set -euo pipefail
mode="run"
while (($#)); do
case "$1" in
--pending|--check)
mode="pending"
shift
;;
-h|--help)
echo "Usage: omarchy-migrate-system [--pending]"
exit 0
;;
*)
echo "Unknown option: $1" >&2
exit 1
;;
esac
done
OMARCHY_PATH="${OMARCHY_PATH:-/usr/share/omarchy}"
STATE_DIR="${OMARCHY_SYSTEM_MIGRATION_STATE:-/var/lib/omarchy/migrations/system}"
MIGRATIONS_DIR="$OMARCHY_PATH/migrations/system"
pending_migrations() {
[[ -d $MIGRATIONS_DIR ]] || return 0
for file in "$MIGRATIONS_DIR"/*.sh; do
[[ -f $file ]] || continue
filename=$(basename "$file")
if [[ ! -f $STATE_DIR/$filename ]]; then
printf '%s\n' "$filename"
fi
done
}
if [[ $mode == "pending" ]]; then
pending_output=$(pending_migrations)
if [[ -n $pending_output ]]; then
printf '%s\n' "$pending_output"
exit 0
else
exit 1
fi
fi
if (( EUID != 0 )) && [[ -z ${OMARCHY_SYSTEM_MIGRATION_STATE:-} ]]; then
if ! "$0" --pending >/dev/null; then
exit 0
fi
exec sudo --preserve-env=OMARCHY_PATH "$0" "$@"
fi
mkdir -p "$STATE_DIR"
[[ -d $MIGRATIONS_DIR ]] || exit 0
for file in "$MIGRATIONS_DIR"/*.sh; do
[[ -f $file ]] || continue
filename=$(basename "$file")
if [[ ! -f $STATE_DIR/$filename ]]; then
echo -e "\e[32m\nRunning system migration (${filename%.sh})\e[0m"
OMARCHY_PATH="$OMARCHY_PATH" bash -euo pipefail "$file"
touch "$STATE_DIR/$filename"
fi
done
-65
View File
@@ -1,65 +0,0 @@
#!/bin/bash
# omarchy:summary=Run pending Omarchy migrations for the current user.
# omarchy:args=[--pending]
set -euo pipefail
mode="run"
while (($#)); do
case "$1" in
--pending|--check)
mode="pending"
shift
;;
-h|--help)
echo "Usage: omarchy-migrate-user [--pending]"
exit 0
;;
*)
echo "Unknown option: $1" >&2
exit 1
;;
esac
done
OMARCHY_PATH="${OMARCHY_PATH:-/usr/share/omarchy}"
STATE_DIR="${OMARCHY_USER_MIGRATION_STATE:-$HOME/.local/state/omarchy/migrations/user}"
MIGRATIONS_DIR="$OMARCHY_PATH/migrations/user"
pending_migrations() {
[[ -d $MIGRATIONS_DIR ]] || return 0
for file in "$MIGRATIONS_DIR"/*.sh; do
[[ -f $file ]] || continue
filename=$(basename "$file")
if [[ ! -f $STATE_DIR/$filename ]]; then
printf '%s\n' "$filename"
fi
done
}
if [[ $mode == "pending" ]]; then
pending_output=$(pending_migrations)
if [[ -n $pending_output ]]; then
printf '%s\n' "$pending_output"
exit 0
else
exit 1
fi
fi
mkdir -p "$STATE_DIR"
[[ -d $MIGRATIONS_DIR ]] || exit 0
for file in "$MIGRATIONS_DIR"/*.sh; do
[[ -f $file ]] || continue
filename=$(basename "$file")
if [[ ! -f $STATE_DIR/$filename ]]; then
echo -e "\e[32m\nRunning user migration (${filename%.sh})\e[0m"
OMARCHY_PATH="$OMARCHY_PATH" bash -euo pipefail "$file"
touch "$STATE_DIR/$filename"
fi
done
+1 -1
View File
@@ -37,7 +37,7 @@ print_status() {
nm=$(nmcli -t -f GENERAL.STATE,GENERAL.CONNECTION dev show "$device" 2>/dev/null)
state=$(awk -F: '$1 == "GENERAL.STATE" { print $2; exit }' <<<"$nm")
ssid=$(awk -F: '$1 == "GENERAL.CONNECTION" { print $2; exit }' <<<"$nm")
signal=$(nmcli -t -f IN-USE,SIGNAL dev wifi list ifname "$device" 2>/dev/null | awk -F: '$1 == "*" { print $2; exit }')
signal=$(nmcli -t -f IN-USE,SIGNAL dev wifi list ifname "$device" --rescan no 2>/dev/null | awk -F: '$1 == "*" { print $2; exit }')
freq=$(iw dev "$device" link 2>/dev/null | awk '/freq:/ { print $2; exit }')
if [[ $state != 100* ]]; then
+1 -1
View File
@@ -2,7 +2,7 @@
# omarchy:summary=Preview a Plymouth boot screen with custom colors and logo
# omarchy:args=<background-hex> <text-hex> <path-to-logo.png> <output-path>
# omarchy:examples=omarchy plymouth preview '#1d2021' '#ebdbb2' ~/.config/omarchy/current/theme/plymouth/logo.png /tmp/plymouth-preview.png
# omarchy:examples=omarchy plymouth preview '#1d2021' '#ebdbb2' ~/.local/state/omarchy/current/theme/plymouth/logo.png /tmp/plymouth-preview.png
# Render a Plymouth login-screen preview PNG by compositing the staged omarchy
# theme assets (recolored with the given text color) onto the background.
+1 -1
View File
@@ -2,7 +2,7 @@
# omarchy:summary=Set the Plymouth boot theme colors and logo
# omarchy:args=<background-hex> <text-hex> <path-to-logo.png>
# omarchy:examples=omarchy plymouth set '#1d2021' '#ebdbb2' ~/.config/omarchy/current/theme/plymouth/logo.png
# omarchy:examples=omarchy plymouth set '#1d2021' '#ebdbb2' ~/.local/state/omarchy/current/theme/plymouth/logo.png
# omarchy:requires-sudo=true
# Configure the Plymouth boot theme with a custom background color, text color, and logo.
+33 -2
View File
@@ -20,7 +20,38 @@ else
theme_dir="$OMARCHY_PATH/themes/$theme"
fi
bg=$(awk -F'"' '/^background/{print $2}' "$theme_dir/colors.toml")
text=$(awk -F'"' '/^foreground/{print $2}' "$theme_dir/colors.toml")
theme_color() {
local key="$1"
local fallback="$2"
awk -F= -v key="$key" -v fallback="$fallback" '
function clean(raw) {
gsub(/^[[:space:]]+|[[:space:]]+$/, "", raw)
if (raw ~ /^"/) {
sub(/^"/, "", raw)
sub(/".*$/, "", raw)
}
return raw
}
{
field = $1
gsub(/^[[:space:]]+|[[:space:]]+$/, "", field)
if (field == key) {
print clean($2)
found = 1
exit
}
if (field == fallback) fallback_value = clean($2)
}
END {
if (!found && fallback_value != "") print fallback_value
}
' "$theme_dir/colors.toml"
}
bg=$(theme_color background bg)
text=$(theme_color foreground fg)
exec omarchy-plymouth-set "$bg" "$text" "$theme_dir/unlock.png"
-17
View File
@@ -12,20 +12,3 @@ omarchy-refresh-config hypr/monitors.lua
mkdir -p ~/.local/state/omarchy/toggles/hypr
cp "$OMARCHY_PATH/default/hypr/toggles/flags.lua" ~/.local/state/omarchy/toggles/hypr/
conf=/etc/vconsole.conf
hyprlua="$HOME/.config/hypr/input.lua"
if [[ -f $conf && -f $hyprlua ]]; then
sed -i '/^[[:space:]]*kb_layout[[:space:]]*=/d' "$hyprlua"
sed -i '/^[[:space:]]*kb_variant[[:space:]]*=/d' "$hyprlua"
if grep -q '^XKBLAYOUT=' "$conf"; then
layout=$(grep '^XKBLAYOUT=' "$conf" | cut -d= -f2 | tr -d '"')
sed -i "/^[[:space:]]*kb_options *=/i\ kb_layout = \"$layout\"," "$hyprlua"
fi
if grep -q '^XKBVARIANT=' "$conf"; then
variant=$(grep '^XKBVARIANT=' "$conf" | cut -d= -f2 | tr -d '"')
sed -i "/^[[:space:]]*kb_options *=/i\ kb_variant = \"$variant\"," "$hyprlua"
fi
fi
+2 -2
View File
@@ -8,8 +8,8 @@ if gum confirm "Are you sure you want to remove all preinstalled web apps, TUI w
omarchy-webapp-remove-all
omarchy-tui-remove-all
[[ -f ~/.config/hypr/bindings.lua ]] && cp ~/.config/hypr/bindings.lua ~/.config/hypr/bindings.lua.bak
cp "$OMARCHY_PATH/default/hypr/plain-bindings.lua" ~/.config/hypr/bindings.lua
mkdir -p ~/.local/state/omarchy
touch ~/.local/state/omarchy/preinstalls-removed
hyprctl reload
# Remove mise stubs
+154 -1
View File
@@ -17,6 +17,155 @@ export PATH="$omarchy_root/bin:/usr/local/bin:/usr/bin:/bin:$PATH"
omarchy_shell_bin=/usr/bin/omarchy-shell
[[ -x $omarchy_shell_bin ]] || omarchy_shell_bin=omarchy-shell
import_env_from_pid() {
local pid=$1 entry key
[[ -r /proc/$pid/environ ]] || return 1
while IFS= read -r -d '' entry; do
key=${entry%%=*}
case $key in
DBUS_SESSION_BUS_ADDRESS | DISPLAY | HYPRLAND_INSTANCE_SIGNATURE | LANG | LC_ALL | LC_CTYPE | QT_QPA_PLATFORM | WAYLAND_DISPLAY | XDG_CURRENT_DESKTOP | XDG_RUNTIME_DIR | XDG_SESSION_TYPE)
[[ -n ${!key:-} ]] || export "$entry"
;;
esac
done <"/proc/$pid/environ"
}
import_graphical_session_env() {
local current_user hypr_dir pid wayland_socket x11_socket
current_user=${USER:-$(id -un)}
for pid in $(pgrep -xu "$current_user" quickshell 2>/dev/null || true); do
import_env_from_pid "$pid" || true
done
for pid in $(pgrep -u "$UID" -f '/omarchy-hyprland-monitor-watch($| )' 2>/dev/null || true); do
import_env_from_pid "$pid" || true
done
if [[ -z ${XDG_RUNTIME_DIR:-} && -d /run/user/$UID ]]; then
export XDG_RUNTIME_DIR="/run/user/$UID"
fi
if [[ -z ${WAYLAND_DISPLAY:-} && -n ${XDG_RUNTIME_DIR:-} ]]; then
for wayland_socket in "$XDG_RUNTIME_DIR"/wayland-*; do
[[ -S $wayland_socket ]] || continue
export WAYLAND_DISPLAY=${wayland_socket##*/}
break
done
fi
if [[ -z ${DISPLAY:-} ]]; then
for x11_socket in /tmp/.X11-unix/X*; do
[[ -S $x11_socket ]] || continue
export DISPLAY=:${x11_socket##*X}
break
done
fi
if [[ -z ${HYPRLAND_INSTANCE_SIGNATURE:-} && -n ${XDG_RUNTIME_DIR:-} && -d $XDG_RUNTIME_DIR/hypr ]]; then
hypr_dir=$(find "$XDG_RUNTIME_DIR/hypr" -mindepth 1 -maxdepth 1 -type d -printf '%T@ %p\n' 2>/dev/null | sort -n | tail -n 1 | cut -d' ' -f2-)
[[ -n $hypr_dir ]] && export HYPRLAND_INSTANCE_SIGNATURE=${hypr_dir##*/}
fi
if [[ -z ${LANG:-} || $LANG == "C" || $LANG == "POSIX" ]]; then
if locale -a 2>/dev/null | grep -qxF "C.utf8"; then
export LANG="C.utf8"
else
export LANG="C.UTF-8"
fi
fi
if [[ -z ${QT_QPA_PLATFORM:-} ]]; then
export QT_QPA_PLATFORM="wayland;xcb"
fi
if [[ -z ${DBUS_SESSION_BUS_ADDRESS:-} && -n ${XDG_RUNTIME_DIR:-} && -S $XDG_RUNTIME_DIR/bus ]]; then
export DBUS_SESSION_BUS_ADDRESS="unix:path=$XDG_RUNTIME_DIR/bus"
fi
}
require_graphical_session_env() {
local missing=()
[[ -n ${XDG_RUNTIME_DIR:-} ]] || missing+=(XDG_RUNTIME_DIR)
[[ -n ${WAYLAND_DISPLAY:-} || -n ${DISPLAY:-} ]] || missing+=(WAYLAND_DISPLAY)
if [[ -n ${XDG_RUNTIME_DIR:-} && -d $XDG_RUNTIME_DIR/hypr && -z ${HYPRLAND_INSTANCE_SIGNATURE:-} ]]; then
missing+=(HYPRLAND_INSTANCE_SIGNATURE)
fi
if (( ${#missing[@]} > 0 )); then
printf 'Refusing to restart Omarchy shell; missing graphical session environment: %s\n' "${missing[*]}" >&2
exit 1
fi
}
hyprland_session_locked() {
local monitors
if monitors=$(hyprctl -j monitors 2>/dev/null); then
[[ $monitors == *'"LOCK"'* ]] && return 0
fi
monitors=$(hyprctl monitors 2>/dev/null) || return 1
[[ $monitors == *"session lock"* ]]
}
shell_quote() {
printf "'"
printf "%s" "$1" | sed "s/'/'\\\\''/g"
printf "'"
}
lua_quote() {
local value=$1
value=${value//\\/\\\\}
value=${value//\"/\\\"}
value=${value//$'\n'/\\n}
printf '"%s"' "$value"
}
launch_shell() {
local launch_command
launch_command="env OMARCHY_PATH=$(shell_quote "$omarchy_root") PATH=$(shell_quote "$PATH") quickshell -n -p $(shell_quote "$CONFIG_DIR")"
if [[ -n ${HYPRLAND_INSTANCE_SIGNATURE:-} ]] && omarchy-cmd-present hyprctl; then
if hyprctl dispatch "hl.dsp.exec_cmd($(lua_quote "$launch_command"))" >/dev/null 2>&1; then
return 0
fi
if hyprctl dispatch exec "$launch_command" >/dev/null 2>&1; then
return 0
fi
fi
setsid quickshell -n -p "$CONFIG_DIR" >/dev/null 2>&1 &
}
restore_hyprland_session_lock() {
local attempt
for (( attempt = 0; attempt < 50; attempt++ )); do
if "$omarchy_shell_bin" shell ping >/dev/null 2>&1; then
"$omarchy_shell_bin" lock lock >/dev/null 2>&1 || true
return 0
fi
sleep 0.1
done
echo "Omarchy shell restarted while Hyprland was session-locked, but lock IPC did not become ready." >&2
}
import_graphical_session_env
require_graphical_session_env
hyprland_was_session_locked=0
hyprland_session_locked && hyprland_was_session_locked=1
if [[ $("$omarchy_shell_bin" lock isLocked 2>/dev/null || true) == "true" ]]; then
echo "Refusing to restart Omarchy shell while the session is locked." >&2
exit 1
@@ -24,4 +173,8 @@ fi
pkill -x quickshell 2>/dev/null || true
sleep 0.2
setsid quickshell -n -p "$CONFIG_DIR" >/dev/null 2>&1 &
launch_shell
if (( hyprland_was_session_locked )); then
restore_hyprland_session_lock
fi
+5 -5
View File
@@ -57,12 +57,12 @@ echo -e "\e[32mSetting up fingerprint scanner for authentication.\n\e[0m"
# Install required packages
echo "Installing required packages..."
installed_libfprint=$(pacman -Qq libfprint 2>/dev/null || true)
# libfprint-git provides+conflicts libfprint; pacman -S --noconfirm
# defaults the conflict prompt to N and aborts. Pre-remove libfprint
# with -Rdd so the install goes silent. -Rdd (not omarchy-pkg-drop's
# -Rns) is required because fprintd requires libfprint; the dep is
# re-satisfied immediately by libfprint-git's provides=libfprint.
if omarchy-pkg-present libfprint; then
# defaults the conflict prompt to N and aborts. Pre-remove the exact
# libfprint package, but not an installed provider like libfprint-git.
if [[ $installed_libfprint == "libfprint" ]]; then
sudo pacman -Rdd --noconfirm libfprint
fi
+1 -1
View File
@@ -75,7 +75,7 @@ valid_hex "$background_color" || fallback
omarchy-cmd-present magick || fallback
if [[ -z $background_path ]]; then
background_path=$(readlink -f "$HOME/.config/omarchy/current/background" 2>/dev/null || true)
background_path=$(readlink -f "$HOME/.local/state/omarchy/current/background" 2>/dev/null || true)
fi
[[ -f $background_path ]] || fallback
+2 -2
View File
@@ -2,9 +2,9 @@
# omarchy:summary=Cache background switcher thumbnails for the current theme
theme_name=$(cat "$HOME/.config/omarchy/current/theme.name" 2>/dev/null)
theme_name=$(cat "$HOME/.local/state/omarchy/current/theme.name" 2>/dev/null)
omarchy-menu-images \
--cache-only \
"$HOME/.config/omarchy/current/theme/backgrounds" \
"$HOME/.local/state/omarchy/current/theme/backgrounds" \
"$HOME/.config/omarchy/backgrounds/$theme_name"
+1 -1
View File
@@ -3,7 +3,7 @@
# omarchy:summary=Show current background
# omarchy:examples=omarchy theme bg current
BACKGROUND_PATH=$(readlink -f "$HOME/.config/omarchy/current/background" 2>/dev/null)
BACKGROUND_PATH=$(readlink -f "$HOME/.local/state/omarchy/current/background" 2>/dev/null)
if [[ -n $BACKGROUND_PATH ]]; then
basename -- "$BACKGROUND_PATH" | perl -pe 's/\.[^.]+$//; s/^\d+-//; s/-/ /g; s/\b(\w)/\U$1/g'
+1 -1
View File
@@ -2,7 +2,7 @@
# omarchy:summary=Open the current theme's user background folder
CURRENT_THEME_NAME=$(cat "$HOME/.config/omarchy/current/theme.name")
CURRENT_THEME_NAME=$(cat "$HOME/.local/state/omarchy/current/theme.name")
THEME_USER_BACKGROUNDS="$HOME/.config/omarchy/backgrounds/$CURRENT_THEME_NAME"
mkdir -p "$THEME_USER_BACKGROUNDS"
+3 -3
View File
@@ -3,10 +3,10 @@
# omarchy:summary=Cycle to the next background for the current theme
# omarchy:examples=omarchy theme bg next
THEME_NAME=$(cat "$HOME/.config/omarchy/current/theme.name" 2>/dev/null)
THEME_BACKGROUNDS_PATH="$HOME/.config/omarchy/current/theme/backgrounds/"
THEME_NAME=$(cat "$HOME/.local/state/omarchy/current/theme.name" 2>/dev/null)
THEME_BACKGROUNDS_PATH="$HOME/.local/state/omarchy/current/theme/backgrounds/"
USER_BACKGROUNDS_PATH="$HOME/.config/omarchy/backgrounds/$THEME_NAME/"
CURRENT_BACKGROUND_LINK="$HOME/.config/omarchy/current/background"
CURRENT_BACKGROUND_LINK="$HOME/.local/state/omarchy/current/background"
mapfile -d '' -t BACKGROUNDS < <(
find -L "$USER_BACKGROUNDS_PATH" "$THEME_BACKGROUNDS_PATH" -maxdepth 1 -type f \
+1 -1
View File
@@ -10,7 +10,7 @@ if [[ -z $1 ]]; then
fi
BACKGROUND="$(realpath "$1")"
CURRENT_BACKGROUND_LINK="$HOME/.config/omarchy/current/background"
CURRENT_BACKGROUND_LINK="$HOME/.local/state/omarchy/current/background"
if [[ ! -f $BACKGROUND ]]; then
echo "File does not exist: $BACKGROUND" >&2
+3 -3
View File
@@ -5,10 +5,10 @@
# omarchy:name=bg-switcher
# omarchy:aliases=omarchy background
theme_name=$(cat "$HOME/.config/omarchy/current/theme.name" 2>/dev/null)
current_background=$(readlink -f "$HOME/.config/omarchy/current/background" 2>/dev/null)
theme_name=$(cat "$HOME/.local/state/omarchy/current/theme.name" 2>/dev/null)
current_background=$(readlink -f "$HOME/.local/state/omarchy/current/background" 2>/dev/null)
omarchy-menu-images \
--selected "$current_background" \
"$HOME/.config/omarchy/current/theme/backgrounds" \
"$HOME/.local/state/omarchy/current/theme/backgrounds" \
"$HOME/.config/omarchy/backgrounds/$theme_name"
+6 -20
View File
@@ -154,13 +154,6 @@ if [[ -z $foreground ]]; then
foreground=$(extract_color_in_section "colors" "primary.foreground")
fi
# Extract cursor color (from [colors.cursor] section)
cursor=$(extract_color_in_section "colors.cursor" "cursor")
if [[ -z $cursor ]]; then
cursor=$(extract_color_in_section "colors" "cursor.cursor")
fi
# Extract selection colors
selection_background=$(extract_color_in_section "colors.selection" "background")
@@ -168,29 +161,22 @@ if [[ -z $selection_background ]]; then
selection_background=$(extract_color_in_section "colors" "selection.background")
fi
selection_foreground=$(extract_color_in_section "colors.selection" "text")
if [[ -z $selection_foreground ]]; then
selection_foreground=$(extract_color_in_section "colors" "selection.text")
fi
# Apply defaults
background=${background:-$color0}
foreground=${foreground:-$color7}
cursor=${cursor:-$foreground}
color0=$background
color7=$foreground
selection_background=${selection_background:-$foreground}
selection_foreground=${selection_foreground:-$background}
accent=$color4
mkdir -p "$THEME_SOURCE"
cat > "$COLORS_OUTPUT" <<EOF
accent = "$accent"
cursor = "$cursor"
foreground = "$foreground"
background = "$background"
selection_foreground = "$selection_foreground"
selection_background = "$selection_background"
selection = "$selection_background"
bg = "$background"
fg = "$foreground"
color0 = "$color0"
color1 = "$color1"
+1 -1
View File
@@ -3,7 +3,7 @@
# omarchy:summary=Show current theme
# omarchy:examples=omarchy theme current
THEME_NAME_PATH="$HOME/.config/omarchy/current/theme.name"
THEME_NAME_PATH="$HOME/.local/state/omarchy/current/theme.name"
if [[ -f $THEME_NAME_PATH ]]; then
cat $THEME_NAME_PATH | sed -E 's/(^|-)([a-z])/\1\u\2/g; s/-/ /g'
+16 -1
View File
@@ -3,7 +3,7 @@
# omarchy:summary=Print OSC sequences for an Omarchy color theme
# omarchy:hidden=true
theme="${1:-$HOME/.config/omarchy/current/theme/colors.toml}"
theme="${1:-$HOME/.local/state/omarchy/current/theme/colors.toml}"
[[ -f $theme ]] || exit 0
@@ -33,6 +33,13 @@ awk -F= '
}
END {
if (colors["background"] != "") colors["bg"] = colors["background"]
if (colors["foreground"] != "") colors["fg"] = colors["foreground"]
if (colors["bg"] != "") colors["background"] = colors["bg"]
if (colors["fg"] != "") colors["foreground"] = colors["fg"]
if (colors["bg"] != "") colors["color0"] = colors["bg"]
if (colors["fg"] != "") colors["color7"] = colors["fg"]
alias_color("color0", "bg")
alias_color("color0", "background")
alias_color("color1", "red")
@@ -63,6 +70,14 @@ awk -F= '
alias_color("color14", "cyan")
alias_color("color15", "bright_fg")
alias_color("color15", "foreground")
alias_color("light_fg", "color7")
alias_color("light_fg", "fg")
alias_color("bright_fg", "color15")
alias_color("bright_fg", "fg")
if (colors["bright_fg"] != "") colors["cursor"] = colors["bright_fg"]
if (colors["selection_background"] == "" && colors["selection"] != "") colors["selection_background"] = colors["selection"]
if (colors["selection_foreground"] == "") colors["selection_foreground"] = colors["bright_fg"]
if (colors["foreground"] != "") printf "\033]10;%s\007", colors["foreground"]
if (colors["background"] != "") printf "\033]11;%s\007", colors["background"]
+1 -1
View File
@@ -2,7 +2,7 @@
# omarchy:summary=Refresh the current theme from its templates.
THEME_NAME_PATH="$HOME/.config/omarchy/current/theme.name"
THEME_NAME_PATH="$HOME/.local/state/omarchy/current/theme.name"
if [[ -f $THEME_NAME_PATH ]]; then
OMARCHY_THEME_SKIP_BACKGROUND=1 omarchy-theme-set "$(cat $THEME_NAME_PATH)"
-1
View File
@@ -19,7 +19,6 @@ else
fi
THEMES_DIR="$HOME/.config/omarchy/themes"
CURRENT_DIR="$HOME/.config/omarchy/current"
THEME_PATH="$THEMES_DIR/$THEME_NAME"
# Ensure a theme was set
+4 -4
View File
@@ -9,9 +9,9 @@ if [[ -z $1 ]]; then
exit 1
fi
CURRENT_THEME_PATH="$HOME/.config/omarchy/current/theme"
NEXT_THEME_PATH="$HOME/.config/omarchy/current/next-theme"
CURRENT_BACKGROUND_LINK="$HOME/.config/omarchy/current/background"
CURRENT_THEME_PATH="$HOME/.local/state/omarchy/current/theme"
NEXT_THEME_PATH="$HOME/.local/state/omarchy/current/next-theme"
CURRENT_BACKGROUND_LINK="$HOME/.local/state/omarchy/current/background"
BACKGROUND_TRANSITION_CACHE="$HOME/.cache/omarchy/background-transitions"
THEME_SET_LOCK="${XDG_RUNTIME_DIR:-/tmp}/omarchy-theme-set.lock"
USER_THEMES_PATH="$HOME/.config/omarchy/themes"
@@ -165,7 +165,7 @@ rm -rf "$CURRENT_THEME_PATH"
mv "$NEXT_THEME_PATH" "$CURRENT_THEME_PATH"
# Store theme name for reference
echo "$THEME_NAME" >"$HOME/.config/omarchy/current/theme.name"
echo "$THEME_NAME" >"$HOME/.local/state/omarchy/current/theme.name"
# Make the running shell pick up the new palette immediately while the rest of
# the theme hooks run.
+1 -1
View File
@@ -3,7 +3,7 @@
# omarchy:summary=Apply the current theme color to Chromium, Chrome, Edge, and Brave
# omarchy:hidden=true
CHROMIUM_THEME=~/.config/omarchy/current/theme/chromium.theme
CHROMIUM_THEME=$HOME/.local/state/omarchy/current/theme/chromium.theme
if [[ -f $CHROMIUM_THEME ]]; then
THEME_RGB_COLOR=$(<$CHROMIUM_THEME)
+1 -1
View File
@@ -3,7 +3,7 @@
# omarchy:summary=Apply current Omarchy theme colors to running Foot terminals
# omarchy:hidden=true
colors_toml=~/.config/omarchy/current/theme/colors.toml
colors_toml=$HOME/.local/state/omarchy/current/theme/colors.toml
if [[ ! -f $colors_toml ]] || ! pgrep -x foot >/dev/null; then
exit 0
+2 -2
View File
@@ -10,7 +10,7 @@ if [[ -z ${DBUS_SESSION_BUS_ADDRESS:-} ]]; then
exit 0
fi
THEME_DIR=~/.config/omarchy/current/theme
THEME_DIR=$HOME/.local/state/omarchy/current/theme
COLORS_FILE="$THEME_DIR/colors.toml"
# In-tree light themes now declare `mode = "light"` in colors.toml instead of
@@ -50,7 +50,7 @@ else
fi
# Change gnome icon theme color
GNOME_ICONS_THEME=~/.config/omarchy/current/theme/icons.theme
GNOME_ICONS_THEME=$HOME/.local/state/omarchy/current/theme/icons.theme
if [[ -f $GNOME_ICONS_THEME ]]; then
gsettings set org.gnome.desktop.interface icon-theme "$(<$GNOME_ICONS_THEME)"
else
+1 -1
View File
@@ -3,7 +3,7 @@
# omarchy:summary=Apply the current theme keyboard color to ASUS ROG keyboards
# omarchy:hidden=true
ASUSCTL_THEME=~/.config/omarchy/current/theme/keyboard.rgb
ASUSCTL_THEME=$HOME/.local/state/omarchy/current/theme/keyboard.rgb
if omarchy-cmd-present asusctl; then
asusctl aura effect static -c $(sed 's/^#//' $ASUSCTL_THEME)
+1 -1
View File
@@ -3,7 +3,7 @@
# omarchy:summary=Apply the current theme keyboard color to Framework Laptop 16 keyboards
# omarchy:hidden=true
FRAMEWORK16_THEME=~/.config/omarchy/current/theme/keyboard.rgb
FRAMEWORK16_THEME=$HOME/.local/state/omarchy/current/theme/keyboard.rgb
if omarchy-cmd-present qmk_hid && [[ -f $FRAMEWORK16_THEME ]]; then
hex=$(cat "$FRAMEWORK16_THEME")
+1 -1
View File
@@ -3,7 +3,7 @@
# omarchy:summary=Sync Omarchy theme to all Obsidian vaults
# omarchy:hidden=true
CURRENT_THEME_DIR="$HOME/.config/omarchy/current/theme"
CURRENT_THEME_DIR="$HOME/.local/state/omarchy/current/theme"
[[ -f $CURRENT_THEME_DIR/obsidian.css ]] || exit 0
+1 -1
View File
@@ -6,7 +6,7 @@
set -euo pipefail
CURRENT_THEME_PATH="$HOME/.config/omarchy/current/theme"
CURRENT_THEME_PATH="$HOME/.local/state/omarchy/current/theme"
PI_SOURCE_PATH="$CURRENT_THEME_PATH/pi.json"
PI_AGENT_DIR="$HOME/.pi/agent"
PI_THEME_DIR="$PI_AGENT_DIR/themes"
+27 -14
View File
@@ -5,7 +5,7 @@
TEMPLATES_DIR="$OMARCHY_PATH/default/themed"
USER_TEMPLATES_DIR="$HOME/.config/omarchy/themed"
NEXT_THEME_DIR="$HOME/.config/omarchy/current/next-theme"
NEXT_THEME_DIR="$HOME/.local/state/omarchy/current/next-theme"
COLORS_FILE="$NEXT_THEME_DIR/colors.toml"
declare -A THEME_COLORS
@@ -382,8 +382,8 @@ resolve_theme_mode() {
if [[ -f $NEXT_THEME_DIR/light.mode ]]; then
THEME_COLORS[mode]="light"
elif [[ ${THEME_COLORS[background]} =~ ^#[0-9A-Fa-f]{6}$ ]]; then
bg_hex="${THEME_COLORS[background]#\#}"
elif [[ ${THEME_COLORS[bg]} =~ ^#[0-9A-Fa-f]{6}$ ]]; then
bg_hex="${THEME_COLORS[bg]#\#}"
lum=$(( $(printf "%d" "0x${bg_hex:0:2}") + $(printf "%d" "0x${bg_hex:2:2}") + $(printf "%d" "0x${bg_hex:4:2}") ))
(( lum > 382 )) && THEME_COLORS[mode]="light" || THEME_COLORS[mode]="dark"
else
@@ -407,10 +407,20 @@ if [[ -f $COLORS_FILE ]]; then
THEME_COLORS[$key]="$value"
done <"$COLORS_FILE"
# Legacy compatibility: map ANSI color0..color15 and raw bg/fg to semantic names
# Canonical palette keys are bg/fg. Preserve older themes that still define
# background/foreground by treating those semantic values as the source of
# truth, then expose the old names as template aliases for user templates.
[[ ${THEME_COLORS[background]} ]] && THEME_COLORS[bg]="${THEME_COLORS[background]}"
[[ ${THEME_COLORS[foreground]} ]] && THEME_COLORS[fg]="${THEME_COLORS[foreground]}"
[[ ${THEME_COLORS[bg]} ]] || THEME_COLORS[bg]="${THEME_COLORS[color0]}"
[[ ${THEME_COLORS[fg]} ]] || THEME_COLORS[fg]="${THEME_COLORS[color7]}"
[[ ${THEME_COLORS[bg]} ]] && THEME_COLORS[background]="${THEME_COLORS[bg]}"
[[ ${THEME_COLORS[fg]} ]] && THEME_COLORS[foreground]="${THEME_COLORS[fg]}"
[[ ${THEME_COLORS[bg]} ]] && THEME_COLORS[color0]="${THEME_COLORS[bg]}"
[[ ${THEME_COLORS[fg]} ]] && THEME_COLORS[color7]="${THEME_COLORS[fg]}"
# Legacy compatibility: map ANSI color0..color15 to semantic names.
declare -A legacy_alias=(
[bg]=background
[fg]=foreground
[red]=color1
[green]=color2
[yellow]=color3
@@ -430,18 +440,21 @@ if [[ -f $COLORS_FILE ]]; then
alias_theme_color magenta purple
alias_theme_color bright_magenta bright_purple
[[ ${THEME_COLORS[light_fg]} ]] || THEME_COLORS[light_fg]="${THEME_COLORS[color7]:-${THEME_COLORS[foreground]}}"
[[ ${THEME_COLORS[bright_fg]} ]] || THEME_COLORS[bright_fg]="${THEME_COLORS[color15]:-${THEME_COLORS[foreground]}}"
[[ ${THEME_COLORS[lighter_bg]} ]] || THEME_COLORS[lighter_bg]="${THEME_COLORS[color0]:-${THEME_COLORS[background]}}"
[[ ${THEME_COLORS[dark_fg]} ]] || THEME_COLORS[dark_fg]="${THEME_COLORS[color8]:-${THEME_COLORS[foreground]}}"
[[ ${THEME_COLORS[light_fg]} ]] || THEME_COLORS[light_fg]="${THEME_COLORS[color7]:-${THEME_COLORS[fg]}}"
[[ ${THEME_COLORS[bright_fg]} ]] || THEME_COLORS[bright_fg]="${THEME_COLORS[color15]:-${THEME_COLORS[fg]}}"
THEME_COLORS[cursor]="${THEME_COLORS[bright_fg]}"
[[ ${THEME_COLORS[lighter_bg]} ]] || THEME_COLORS[lighter_bg]="${THEME_COLORS[color0]:-${THEME_COLORS[bg]}}"
[[ ${THEME_COLORS[dark_fg]} ]] || THEME_COLORS[dark_fg]="${THEME_COLORS[color8]:-${THEME_COLORS[fg]}}"
[[ ${THEME_COLORS[muted]} ]] || THEME_COLORS[muted]="${THEME_COLORS[color8]:-${THEME_COLORS[dark_fg]}}"
[[ ${THEME_COLORS[selection]} ]] || THEME_COLORS[selection]="${THEME_COLORS[selection_background]:-${THEME_COLORS[color8]:-${THEME_COLORS[color0]}}}"
[[ ${THEME_COLORS[orange]} ]] || THEME_COLORS[orange]="${THEME_COLORS[yellow]}"
[[ ${THEME_COLORS[selection]} ]] || THEME_COLORS[selection]="${THEME_COLORS[selection_background]:-${THEME_COLORS[color8]:-${THEME_COLORS[color0]:-${THEME_COLORS[bg]}}}}"
[[ ${THEME_COLORS[selection_background]} ]] || THEME_COLORS[selection_background]="${THEME_COLORS[selection]}"
[[ ${THEME_COLORS[selection_foreground]} ]] || THEME_COLORS[selection_foreground]="${THEME_COLORS[bright_fg]}"
[[ ${THEME_COLORS[orange]} ]] || THEME_COLORS[orange]="${THEME_COLORS[yellow]}"
[[ ${THEME_COLORS[brown]} ]] || THEME_COLORS[brown]=$(mix_color "${THEME_COLORS[orange]}" "#000000" 50%)
# Auto-derive shades from base accents when not defined and not aliased from colorN
[[ ${THEME_COLORS[dark_bg]} ]] || THEME_COLORS[dark_bg]=$(mix_color "${THEME_COLORS[background]}" "#000000" 25%)
[[ ${THEME_COLORS[darker_bg]} ]] || THEME_COLORS[darker_bg]=$(mix_color "${THEME_COLORS[background]}" "#000000" 50%)
[[ ${THEME_COLORS[dark_bg]} ]] || THEME_COLORS[dark_bg]=$(mix_color "${THEME_COLORS[bg]}" "#000000" 25%)
[[ ${THEME_COLORS[darker_bg]} ]] || THEME_COLORS[darker_bg]=$(mix_color "${THEME_COLORS[bg]}" "#000000" 50%)
[[ ${THEME_COLORS[bright_red]} ]] || THEME_COLORS[bright_red]=$(mix_color "${THEME_COLORS[red]}" "#ffffff" 20%)
[[ ${THEME_COLORS[bright_yellow]} ]] || THEME_COLORS[bright_yellow]=$(mix_color "${THEME_COLORS[yellow]}" "#ffffff" 20%)
[[ ${THEME_COLORS[bright_green]} ]] || THEME_COLORS[bright_green]=$(mix_color "${THEME_COLORS[green]}" "#ffffff" 20%)
+21 -11
View File
@@ -3,7 +3,7 @@
# omarchy:summary=Sync current Omarchy theme environment into tmux
# omarchy:hidden=true
CURRENT_THEME_PATH="$HOME/.config/omarchy/current/theme"
CURRENT_THEME_PATH="$HOME/.local/state/omarchy/current/theme"
GUM_ENV="$CURRENT_THEME_PATH/gum_env.lua"
COLORS_TOML="$CURRENT_THEME_PATH/colors.toml"
@@ -54,21 +54,31 @@ theme_osc_sequences() {
theme_color() {
local key="$1"
local fallback="${2:-}"
awk -F= -v key="$key" -v fallback="$fallback" '
function clean(raw) {
gsub(/^[[:space:]]+|[[:space:]]+$/, "", raw)
if (raw ~ /^"/) {
sub(/^"/, "", raw)
sub(/".*$/, "", raw)
}
return raw
}
awk -F= -v key="$key" '
{
field = $1
gsub(/^[[:space:]]+|[[:space:]]+$/, "", field)
if (field == key) {
value = $2
gsub(/^[[:space:]]+|[[:space:]]+$/, "", value)
if (value ~ /^"/) {
sub(/^"/, "", value)
sub(/".*$/, "", value)
}
print value
print clean($2)
found = 1
exit
}
if (fallback != "" && field == fallback) fallback_value = clean($2)
}
END {
if (!found && fallback_value != "") print fallback_value
}
' "$COLORS_TOML"
}
@@ -78,8 +88,8 @@ sync_tmux_window_style() {
[[ -f $COLORS_TOML ]] || return
foreground=$(theme_color foreground)
background=$(theme_color background)
foreground=$(theme_color foreground fg)
background=$(theme_color background bg)
[[ -n $foreground && -n $background ]] || return
+2 -2
View File
@@ -3,8 +3,8 @@
# omarchy:summary=Sync Omarchy theme to VS Code, VSCodium, and Cursor
# omarchy:hidden=true
VS_CODE_THEME_DESCRIPTOR="$HOME/.config/omarchy/current/theme/vscode.json"
GENERATED_THEME="$HOME/.config/omarchy/current/theme/vscode-theme.json"
VS_CODE_THEME_DESCRIPTOR="$HOME/.local/state/omarchy/current/theme/vscode.json"
GENERATED_THEME="$HOME/.local/state/omarchy/current/theme/vscode-theme.json"
GENERATED_EXTENSION_NAME="omarchy-theme"
GENERATED_EXTENSION_ID="local.$GENERATED_EXTENSION_NAME"
GENERATED_EXTENSION_VERSION="1.0.0"
+1 -1
View File
@@ -102,7 +102,7 @@ if [[ ! -f $fast_signature_file ]] || ! cmp -s "$fast_signature_file" <(printf '
printf '%s' "$fast_signature" >"$fast_signature_file"
fi
current_theme=$(cat "$HOME/.config/omarchy/current/theme.name" 2>/dev/null)
current_theme=$(cat "$HOME/.local/state/omarchy/current/theme.name" 2>/dev/null)
selected_preview=""
for extension in png jpg jpeg webp gif bmp; do
if [[ -e $preview_dir/$current_theme.$extension ]]; then
+213 -118
View File
@@ -18,8 +18,8 @@ in Omarchy 3.8.x or run directly with curl | bash on older systems.
Options:
-y, --yes Do not prompt before upgrading
--reboot Reboot automatically after a successful upgrade
--dev Use stop-gap packages from the [omarchy-dev] repo
--channel stable|rc|edge Override detected Omarchy package channel
--dev Use dev packages [omarchy-dev / omarchy-settings-dev] (uses edge channel)
--channel stable|rc|edge Override the default stable Omarchy package channel
--user USER User account to refresh after package install
-h, --help Show this help
USAGE
@@ -51,7 +51,8 @@ valid_channel() {
normalize_channel "$1" >/dev/null 2>&1
}
channel_override="${OMARCHY_UPGRADE_CHANNEL:-${OMARCHY_CHANNEL:-${OMARCHY_MIRROR:-}}}"
channel_override="${OMARCHY_UPGRADE_CHANNEL:-}"
channel_override_cli=0
target_user="${OMARCHY_INSTALL_USER:-}"
yes=0
auto_reboot=0
@@ -73,6 +74,7 @@ while (($#)); do
;;
--channel)
channel_override="${2:-}"
channel_override_cli=1
shift 2
;;
--user)
@@ -95,6 +97,22 @@ case "$use_dev_packages" in
*) fail "Invalid OMARCHY_UPGRADE_DEV value '$use_dev_packages'. Use 1/0, true/false, or pass --dev." ;;
esac
if (( use_dev_packages )); then
if (( channel_override_cli )); then
if ! valid_channel "$channel_override"; then
fail "Invalid channel '$channel_override'. Use stable, rc, or edge."
fi
if [[ $(normalize_channel "$channel_override") != edge ]]; then
fail "--dev uses the edge channel; remove --channel or pass --channel edge."
fi
fi
channel_override=edge
fi
if { [[ -n $channel_override ]] || (( channel_override_cli )); } && ! valid_channel "$channel_override"; then
fail "Invalid channel '$channel_override'. Use stable, rc, or edge."
fi
if ! command -v pacman >/dev/null 2>&1; then
fail "This upgrade is only supported on Arch/Omarchy systems with pacman."
fi
@@ -247,64 +265,11 @@ discover_hyprland_signature() {
printf '%s\n' "${candidates[0]}"
}
detect_channel() {
local candidate="${channel_override:-}"
if [[ -n $candidate ]] && valid_channel "$candidate"; then
normalize_channel "$candidate"
return 0
fi
if command -v omarchy-version-channel >/dev/null 2>&1; then
candidate=$(omarchy-version-channel 2>/dev/null | awk '{ print $1 }' || true)
if [[ -n $candidate ]] && valid_channel "$candidate"; then
normalize_channel "$candidate"
return 0
fi
fi
if [[ -f /etc/pacman.conf ]]; then
if grep -q 'https://pkgs\.omarchy\.org/rc/' /etc/pacman.conf; then
echo rc
return 0
elif grep -q 'https://pkgs\.omarchy\.org/edge/' /etc/pacman.conf; then
echo edge
return 0
elif grep -q 'https://pkgs\.omarchy\.org/stable/' /etc/pacman.conf; then
echo stable
return 0
fi
fi
if [[ -f /etc/pacman.d/mirrorlist ]]; then
if grep -q 'https://rc-mirror\.omarchy\.org/' /etc/pacman.d/mirrorlist; then
echo rc
return 0
elif grep -q 'https://mirror\.omarchy\.org/' /etc/pacman.d/mirrorlist; then
echo edge
return 0
elif grep -q 'https://stable-mirror\.omarchy\.org/' /etc/pacman.d/mirrorlist; then
echo stable
return 0
fi
fi
if [[ -d $target_home/.local/share/omarchy/.git ]]; then
if (( EUID == 0 )); then
candidate=$(run_as_user git -C "$target_home/.local/share/omarchy" branch --show-current 2>/dev/null || true)
else
candidate=$(git -C "$target_home/.local/share/omarchy" branch --show-current 2>/dev/null || true)
fi
if [[ -n $candidate ]] && valid_channel "$candidate"; then
normalize_channel "$candidate"
return 0
fi
fi
echo stable
resolve_channel() {
normalize_channel "${channel_override:-stable}"
}
channel=$(detect_channel)
channel=$(resolve_channel)
if ! valid_channel "$channel"; then
fail "Invalid channel '$channel'. Use stable, rc, or edge."
fi
@@ -326,7 +291,7 @@ esac
if (( ! yes )); then
package_mode="production Omarchy packages"
(( use_dev_packages )) && package_mode="stop-gap packages from [omarchy-dev]"
(( use_dev_packages )) && package_mode="dev packages [omarchy-dev / omarchy-settings-dev]"
cat <<EOF
@@ -387,48 +352,28 @@ configure_pacman_channel() {
as_root cp -f /etc/pacman.conf "/etc/pacman.conf.omarchy-upgrade-to-4.$backup_suffix.bak"
# Drop any stale [omarchy-dev] block every time. Re-add it only for the
# stop-gap dev package mode so normal upgrades resolve the real tagged
# packages from [omarchy] once they exist.
local dev_server='https://share.heyoodle.com/omarchy/dev/$arch'
# Replace the normal Omarchy package repository. Dev package mode uses the
# edge channel and resolves omarchy-dev / omarchy-settings-dev from [omarchy].
local tmp
tmp=$(mktemp)
awk -v server="$package_server" -v dev_server="$dev_server" -v use_dev="$use_dev_packages" '
BEGIN { in_omarchy = 0; in_dev = 0; wrote = 0; use_dev += 0 }
/^\[omarchy-dev\]$/ {
in_dev = 1
in_omarchy = 0
next
}
/^\[omarchy\]$/ {
awk -v server="$package_server" '
BEGIN { in_omarchy = 0; wrote = 0 }
/^[[:space:]]*\[omarchy\][[:space:]]*$/ {
if (!wrote) {
if (use_dev) {
print "[omarchy-dev]"
print "SigLevel = Never"
print "Server = " dev_server
print ""
}
print "[omarchy]"
print "SigLevel = Optional TrustAll"
print "Server = " server
wrote = 1
}
in_omarchy = 1
in_dev = 0
next
}
/^\[/ { in_omarchy = 0; in_dev = 0 }
!in_omarchy && !in_dev { print }
/^[[:space:]]*\[/ { in_omarchy = 0 }
!in_omarchy { print }
END {
if (!wrote) {
print ""
if (use_dev) {
print "[omarchy-dev]"
print "SigLevel = Never"
print "Server = " dev_server
print ""
}
print "[omarchy]"
print "SigLevel = Optional TrustAll"
print "Server = " server
@@ -553,9 +498,6 @@ migrate_1password_beta_package() {
}
install_omarchy_4_packages() {
# Until Omarchy 4 is tagged and published for real, --dev installs the
# stop-gap package names from [omarchy-dev]. They provide/conflict the real
# names so testers can later move to omarchy/omarchy-settings cleanly.
local omarchy_package=omarchy
local settings_package=omarchy-settings
if (( use_dev_packages )); then
@@ -563,21 +505,18 @@ install_omarchy_4_packages() {
settings_package=omarchy-settings-dev
fi
# The bootloader stack (limine, snapper, etc.) is hard-depended by the
# Omarchy package, so it'll be pulled in automatically.
local core_packages=(
omarchy-keyring
"$settings_package"
omarchy-nvim
"$omarchy_package"
# checkupdates support for update tooling
fakeroot
pacman-contrib
)
local base_packages=()
log "Installing Omarchy 4 packages"
(( use_dev_packages )) && log "Using stop-gap packages from [omarchy-dev]"
log "Upgrading system packages and installing Omarchy 4 packages"
(( use_dev_packages )) && log "Using dev packages [omarchy-dev / omarchy-settings-dev]"
# --noconfirm answers "no" to conflict-removal prompts. --ask 4 preselects
# removing the conflicting package, which is required for legacy packages like
# ttf-jetbrains-mono-nerd -> ttf-jetbrains-mono-nerd-basic.
@@ -619,6 +558,7 @@ remove_retired_default_packages() {
chaotic-keyring
chaotic-mirrorlist
claude-code
dust
elephant
elephant-all
elephant-bluetooth
@@ -655,6 +595,7 @@ remove_retired_default_packages() {
playerctl
polkit-gnome
qt5-remoteobjects
satty
swaybg
swayosd
walker-bin
@@ -1100,6 +1041,99 @@ ensure_sleep_lock_service() {
fi
}
run_post_upgrade_migrations() {
PATH="$package_path" command -v omarchy-migrate >/dev/null 2>&1 || return 0
log "Running Omarchy migrations"
if ! run_as_user env \
HOME="$target_home" \
USER="$target_user" \
LOGNAME="$target_user" \
OMARCHY_PATH=/usr/share/omarchy \
PATH="$package_path" \
omarchy-migrate; then
warn "Could not run Omarchy migrations; the user may be prompted to run them after login."
fi
}
run_final_system_package_upgrade() {
log "Checking for remaining system package updates"
as_root env OMARCHY_UPDATE_PACMAN=1 pacman -Syu --noconfirm --ask 4 \
--overwrite '/etc/docker/daemon.json' \
--overwrite '/etc/gnupg/dirmngr.conf' \
--overwrite '/etc/modprobe.d/omarchy-usb-autosuspend.conf' \
--overwrite '/etc/sudoers.d/omarchy-asdcontrol' \
--overwrite '/etc/sudoers.d/omarchy-passwd-tries' \
--overwrite '/etc/sudoers.d/omarchy-tzupdate' \
--overwrite '/etc/sysctl.d/90-omarchy-file-watchers.conf' \
--overwrite '/etc/sysctl.d/99-omarchy-sysctl.conf' \
--overwrite '/etc/systemd/logind.conf.d/10-ignore-power-button.conf' \
--overwrite '/etc/systemd/resolved.conf.d/10-disable-multicast.conf' \
--overwrite '/etc/systemd/resolved.conf.d/20-docker-dns.conf' \
--overwrite '/etc/systemd/system.conf.d/10-faster-shutdown.conf' \
--overwrite '/etc/systemd/system/user@.service.d/10-faster-shutdown.conf' \
--overwrite '/etc/systemd/system/docker.service.d/no-block-boot.conf' \
--overwrite '/etc/systemd/system/plocate-updatedb.service.d/ac-only.conf' \
--overwrite '/usr/lib/systemd/system-sleep/unmount-fuse' \
--overwrite '/usr/share/plymouth/themes/omarchy/*'
}
run_post_upgrade_update_steps() {
local update_error_file update_output update_status
update_error_file="$target_home/.local/state/omarchy/updates/error"
if PATH="$package_path" command -v omarchy-update-aur-pkgs >/dev/null 2>&1; then
if ! run_as_user env \
HOME="$target_home" \
USER="$target_user" \
LOGNAME="$target_user" \
OMARCHY_PATH=/usr/share/omarchy \
PATH="$package_path" \
omarchy-update-aur-pkgs; then
warn "Could not update AUR packages; the update indicator may still show AUR updates after reboot."
fi
fi
if PATH="$package_path" command -v omarchy-update-mise >/dev/null 2>&1; then
if ! run_as_user env \
HOME="$target_home" \
USER="$target_user" \
LOGNAME="$target_user" \
OMARCHY_PATH=/usr/share/omarchy \
PATH="$package_path" \
omarchy-update-mise; then
warn "Could not update mise tools; running omarchy-update after reboot may still update mise-managed tools."
fi
fi
if PATH="$package_path" command -v omarchy-update-available >/dev/null 2>&1; then
log "Refreshing update indicator state"
update_status=0
update_output=$(run_as_user env \
HOME="$target_home" \
USER="$target_user" \
LOGNAME="$target_user" \
OMARCHY_PATH=/usr/share/omarchy \
PATH="$package_path" \
omarchy-update-available 2>&1) || update_status=$?
if (( update_status == 0 )); then
warn "Updates are still available after the upgrade; first-run will still offer to run omarchy-update:"
printf '%s\n' "$update_output" >&2
elif [[ -s $update_error_file ]]; then
warn "Could not confirm update state after upgrade; first-run will still offer to run omarchy-update:"
printf '%s\n' "$update_output" >&2
else
# The live upgrade has already completed the package update. Let first-run
# finish session-only setup, but skip its generic fresh-install update
# toast when the update checker confirms nothing remains.
run_as_user mkdir -p "$target_home/.local/state/omarchy"
run_as_user touch "$target_home/.local/state/omarchy/skip-first-run-update-notification"
fi
fi
}
enable_system_service() {
local unit="$1"
@@ -1579,6 +1613,17 @@ refresh_known_config_defaults() {
done < <(default_hash_paths refresh)
}
mark_removed_preinstalls_from_legacy_bindings() {
local bindings_file="$HOME/.config/hypr/bindings.lua"
local plain_bindings_sha="5d92d4008b04848256445da3cf5c10422a8d537baad499a4e63f60daecaefc6f"
[[ -f $bindings_file ]] || return 0
[[ $(file_sha256 "$bindings_file") == "$plain_bindings_sha" ]] || return 0
mkdir -p "$state_dir"
touch "$state_dir/preinstalls-removed"
}
copy_always_config_defaults() {
local rel
for rel in "${always_copy_config_files[@]}"; do
@@ -1720,6 +1765,7 @@ done
# and always write the v4-only entry points that older installs cannot have.
refresh_known_config_defaults
copy_missing_config_defaults "$root/config" "$HOME/.config"
mark_removed_preinstalls_from_legacy_bindings
copy_always_config_defaults
repair_chromium_copy_url_extension_flags
@@ -1787,7 +1833,7 @@ repair_sleep_lock_unit_override
install_bash_startup
unset rel file backup retired_config_files always_copy_config_files uwsm_env known_config_default_hashes_by_key
unset -f file_sha256 known_config_default_hashes default_hash_paths is_known_default_hash backup_config_file migrate_uwsm_env_customizations is_retired_config_file copy_config_default copy_missing_config_defaults refresh_known_config_defaults copy_always_config_defaults repair_chromium_copy_url_extension_flags repair_sleep_lock_unit_override is_known_bashrc_default install_bash_startup
unset -f file_sha256 known_config_default_hashes default_hash_paths is_known_default_hash backup_config_file migrate_uwsm_env_customizations is_retired_config_file copy_config_default copy_missing_config_defaults refresh_known_config_defaults mark_removed_preinstalls_from_legacy_bindings copy_always_config_defaults repair_chromium_copy_url_extension_flags repair_sleep_lock_unit_override is_known_bashrc_default install_bash_startup
mkdir -p "$HOME/.agents/skills" "$HOME/.claude/skills" "$HOME/.codex/skills" "$HOME/.pi/agent/skills"
if [[ -d $root/default/omarchy-skill ]]; then
@@ -1831,21 +1877,6 @@ for dir in Downloads Projects Pictures Videos; do
grep -qxF "$bookmark" "$HOME/.config/gtk-3.0/bookmarks" || echo "$bookmark" >>"$HOME/.config/gtk-3.0/bookmarks"
done
conf=/etc/vconsole.conf
hyprlua="$HOME/.config/hypr/input.lua"
if [[ -f $conf && -f $hyprlua ]]; then
sed -i '/^[[:space:]]*kb_layout[[:space:]]*=/d' "$hyprlua"
sed -i '/^[[:space:]]*kb_variant[[:space:]]*=/d' "$hyprlua"
if grep -q '^XKBLAYOUT=' "$conf"; then
layout=$(grep '^XKBLAYOUT=' "$conf" | cut -d= -f2 | tr -d '"')
sed -i "/^[[:space:]]*kb_options *=/i\ kb_layout = \"$layout\"," "$hyprlua"
fi
if grep -q '^XKBVARIANT=' "$conf"; then
variant=$(grep '^XKBVARIANT=' "$conf" | cut -d= -f2 | tr -d '"')
sed -i "/^[[:space:]]*kb_options *=/i\ kb_variant = \"$variant\"," "$hyprlua"
fi
fi
if [[ -n ${OMARCHY_USER_NAME//[[:space:]]/} ]]; then
git config --global user.name "$OMARCHY_USER_NAME" || true
fi
@@ -1866,10 +1897,53 @@ EOF
fi
mkdir -p "$HOME/.config/omarchy/themes" "$HOME/.config/btop/themes"
ln -snf "$HOME/.config/omarchy/current/theme/btop.theme" "$HOME/.config/btop/themes/current.theme"
if [[ ! -e $HOME/.config/omarchy/current/background && -d $HOME/.config/omarchy/current/theme/backgrounds ]]; then
background=$(find "$HOME/.config/omarchy/current/theme/backgrounds" -maxdepth 1 -type f \( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' -o -iname '*.webp' \) | sort | head -n1)
[[ -n ${background:-} ]] && ln -snf "$background" "$HOME/.config/omarchy/current/background"
legacy_current_dir="$HOME/.config/omarchy/current"
current_state_dir="$HOME/.local/state/omarchy/current"
if [[ -e $legacy_current_dir || -L $legacy_current_dir ]]; then
mkdir -p "$HOME/.local/state/omarchy"
if [[ ! -e $current_state_dir && ! -L $current_state_dir ]]; then
mv "$legacy_current_dir" "$current_state_dir"
else
if [[ -d $legacy_current_dir && -d $current_state_dir ]]; then
cp -an "$legacy_current_dir/." "$current_state_dir/" 2>/dev/null || true
fi
rm -rf "$legacy_current_dir"
fi
fi
replace_legacy_current_path() {
local file="$1"
[[ -f $file ]] || return 0
python3 - "$file" "$HOME" <<'PY'
from pathlib import Path
import sys
path = Path(sys.argv[1])
home = sys.argv[2]
text = path.read_text()
replacements = {
f"{home}/.config/omarchy/current": f"{home}/.local/state/omarchy/current",
"~/.config/omarchy/current": "~/.local/state/omarchy/current",
"../omarchy/current": "../../.local/state/omarchy/current",
}
for old, new in replacements.items():
text = text.replace(old, new)
path.write_text(text)
PY
}
for file in \
"$HOME/.config/alacritty/alacritty.toml" \
"$HOME/.config/foot/foot.ini" \
"$HOME/.config/ghostty/config" \
"$HOME/.config/hypr/hyprland.conf" \
"$HOME/.config/hyprland-preview-share-picker/config.yaml" \
"$HOME/.config/kitty/kitty.conf"; do
replace_legacy_current_path "$file"
done
ln -snf "$HOME/.local/state/omarchy/current/theme/btop.theme" "$HOME/.config/btop/themes/current.theme"
if [[ ! -e $HOME/.local/state/omarchy/current/background && -d $HOME/.local/state/omarchy/current/theme/backgrounds ]]; then
background=$(find "$HOME/.local/state/omarchy/current/theme/backgrounds" -maxdepth 1 -type f \( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' -o -iname '*.webp' \) | sort | head -n1)
[[ -n ${background:-} ]] && ln -snf "$background" "$HOME/.local/state/omarchy/current/background"
fi
mkdir -p "$HOME/.config/wireplumber/wireplumber.conf.d"
@@ -2030,9 +2104,20 @@ write_legacy_theme_hyprland_conf() {
set -euo pipefail
hyprland_conf="$HOME/.config/hypr/hyprland.conf"
[[ -f $hyprland_conf ]] || exit 0
python3 - "$hyprland_conf" "$HOME" <<'PY'
from pathlib import Path
import sys
path = Path(sys.argv[1])
home = sys.argv[2]
text = path.read_text()
text = text.replace(f"{home}/.config/omarchy/current", f"{home}/.local/state/omarchy/current")
text = text.replace("~/.config/omarchy/current", "~/.local/state/omarchy/current")
path.write_text(text)
PY
grep -q 'current/theme/hyprland.conf' "$hyprland_conf" || exit 0
theme_dir="$HOME/.config/omarchy/current/theme"
theme_dir="$HOME/.local/state/omarchy/current/theme"
colors="$theme_dir/colors.toml"
target="$theme_dir/hyprland.conf"
mkdir -p "$theme_dir"
@@ -2061,14 +2146,21 @@ refresh_current_theme_after_upgrade() {
theme_name=$(run_as_user env HOME="$target_home" bash -c '
set -euo pipefail
theme_name_path="$HOME/.config/omarchy/current/theme.name"
current_theme_path="$HOME/.config/omarchy/current/theme"
theme_name_path="$HOME/.local/state/omarchy/current/theme.name"
current_theme_path="$HOME/.local/state/omarchy/current/theme"
legacy_theme_name_path="$HOME/.config/omarchy/current/theme.name"
legacy_current_theme_path="$HOME/.config/omarchy/current/theme"
if [[ -f $theme_name_path ]]; then
read -r theme_name <"$theme_name_path" || true
printf "%s" "${theme_name:-}"
elif [[ -f $legacy_theme_name_path ]]; then
read -r theme_name <"$legacy_theme_name_path" || true
printf "%s" "${theme_name:-}"
elif [[ -L $current_theme_path ]]; then
basename -- "$(readlink "$current_theme_path")"
elif [[ -L $legacy_current_theme_path ]]; then
basename -- "$(readlink "$legacy_current_theme_path")"
else
printf ""
fi
@@ -2128,6 +2220,9 @@ apply_user_transition
cleanup_retired_services
ensure_sleep_lock_service
remove_retired_default_packages
run_post_upgrade_migrations
run_final_system_package_upgrade
run_post_upgrade_update_steps
refresh_current_theme_after_upgrade
# Do not force-reload Hyprland in the live upgraded session. The legacy
# default/hypr and theme hyprland.conf shims above exist specifically so the
+1 -1
View File
@@ -1,4 +1,4 @@
general.import = [ "~/.config/omarchy/current/theme/alacritty.toml" ]
general.import = [ "~/.local/state/omarchy/current/theme/alacritty.toml" ]
[env]
TERM = "xterm-256color"
+1 -1
View File
@@ -1,5 +1,5 @@
[main]
include=~/.config/omarchy/current/theme/foot.ini
include=~/.local/state/omarchy/current/theme/foot.ini
term=xterm-256color
font=JetBrainsMono Nerd Font:size=9
pad=14x14
+1 -1
View File
@@ -1,5 +1,5 @@
# Dynamic theme colors
config-file = ?"~/.config/omarchy/current/theme/ghostty.conf"
config-file = ?"~/.local/state/omarchy/current/theme/ghostty.conf"
# Font
font-family = "JetBrainsMono Nerd Font"
+19 -36
View File
@@ -1,44 +1,27 @@
-- Application bindings.
o.bind("SUPER + RETURN", "Terminal", { omarchy = "terminal" })
o.bind("SUPER + ALT + RETURN", "Tmux", { omarchy = "terminal-tmux" })
o.bind("SUPER + SHIFT + RETURN", "Browser", { omarchy = "browser" })
o.bind("SUPER + SHIFT + F", "File manager", { omarchy = "nautilus" })
o.bind("SUPER + ALT + SHIFT + F", "File manager (cwd)", { omarchy = "nautilus-cwd" })
o.bind("SUPER + SHIFT + B", "Browser", { omarchy = "browser" })
o.bind("SUPER + SHIFT + ALT + B", "Browser (private)", { omarchy = "browser --private" })
o.bind("SUPER + SHIFT + M", "Music", { omarchy = "spotify" })
o.bind("SUPER + SHIFT + ALT + M", "Music TUI", { tui = "cliamp", focus = true })
o.bind("SUPER + SHIFT + N", "Editor", { omarchy = "editor" })
o.bind("SUPER + SHIFT + D", "Docker", { tui = "lazydocker" })
o.bind("SUPER + SHIFT + G", "Signal", { omarchy = "signal" })
o.bind("SUPER + SHIFT + O", "Obsidian", { launch = "obsidian", focus = "^obsidian$" })
o.bind("SUPER + SHIFT + W", "Typora", { launch = "typora --enable-wayland-ime" })
o.bind("SUPER + SHIFT + SLASH", "Passwords", { launch = "1password" })
-- Keep only your personal keybinding overrides here. Add new bindings or
-- unbind defaults before replacing them.
-- Web app bindings.
o.bind("SUPER + SHIFT + A", "ChatGPT", { webapp = "https://chatgpt.com" })
o.bind("SUPER + SHIFT + ALT + A", "Grok", { webapp = "https://grok.com" })
o.bind("SUPER + SHIFT + C", "Calendar", { webapp = "https://app.hey.com/calendar/weeks/" })
o.bind("SUPER + SHIFT + E", "Email", { webapp = "https://app.hey.com" })
o.bind("SUPER + SHIFT + ALT + E", "New email", { webapp = "https://app.hey.com/messages/new?display=standalone&new_window=true" })
o.bind("SUPER + SHIFT + Y", "YouTube", { webapp = "https://youtube.com/" })
o.bind("SUPER + SHIFT + ALT + G", "WhatsApp", { webapp = "https://web.whatsapp.com/", focus = true })
o.bind(
"SUPER + SHIFT + CTRL + G",
"Google Messages",
{ webapp = "https://messages.google.com/web/conversations", focus = true }
)
o.bind("SUPER + SHIFT + P", "Google Photos", { webapp = "https://photos.google.com/", focus = true })
o.bind("SUPER + SHIFT + S", "Google Maps", { webapp = "https://maps.google.com/", focus = true })
o.bind("SUPER + SHIFT + X", "X", { webapp = "https://x.com/" })
o.bind("SUPER + SHIFT + ALT + X", "X Post", { webapp = "https://x.com/compose/post" })
-- See current bindings and descriptions:
-- omarchy menu keybindings --print
-- Add extra bindings below.
-- To disable every Omarchy default binding, set this in
-- ~/.config/hypr/hyprland.lua before require("default.hypr.omarchy"), then add
-- only the bindings you want below:
-- omarchy_default_bindings = false
-- To disable all preinstalled app/webapp bindings, set:
-- omarchy_preinstalled_bindings = false
-- Add a new binding.
-- o.bind("SUPER + SHIFT + R", "SSH", "alacritty -e ssh your-server")
-- Overwrite existing bindings with hl.unbind() first if needed.
-- Change an existing binding by unbinding it first, then binding the key again.
-- This example changes SUPER+SPACE from the launcher to the Omarchy root menu.
-- hl.unbind("SUPER + SPACE")
-- o.bind("SUPER + SPACE", "Omarchy menu", "omarchy-menu")
-- o.bind("SUPER + SPACE", "Omarchy menu", "omarchy-menu toggle root")
-- Disable a default binding without replacing it.
-- hl.unbind("SUPER + SHIFT + B")
-- Logitech MX Keys examples:
-- o.bind("SUPER + SHIFT + S", nil, "omarchy-capture-screenshot")
+12 -14
View File
@@ -1,23 +1,21 @@
-- Learn how to configure Hyprland: https://wiki.hypr.land/Configuring/Start/
-- Drop cached omarchy modules so hyprctl reload re-reads them from disk.
for k in pairs(package.loaded) do
if k:match("^default%.hypr") or k:match("^hypr%.") then
package.loaded[k] = nil
end
end
-- Omarchy's bootstrap keeps path setup out of this user config.
dofile((os.getenv("OMARCHY_PATH") or "/usr/share/omarchy") .. "/default/hypr/bootstrap.lua")
-- Load user modules from ~/.config and Omarchy defaults from $OMARCHY_PATH.
package.path = os.getenv("HOME")
.. "/.config/?.lua;"
.. (os.getenv("OMARCHY_PATH") or "/usr/share/omarchy")
.. "/?.lua;"
.. package.path
-- Disable all Omarchy default bindings. Add your own in hypr/bindings.lua.
-- omarchy_default_bindings = false
--
-- Or disable only bindings for Omarchy's preinstalled apps/web apps while
-- keeping core window-manager bindings:
-- omarchy_preinstalled_bindings = false
-- All Omarchy default setups
-- Load Omarchy defaults.
require("default.hypr.omarchy")
-- Change your own setup in these files and override defaults.
-- Put your personal overrides in these files. They're loaded after Omarchy's
-- defaults so package updates can improve the defaults without rewriting your
-- ~/.config/hypr files.
require("hypr.monitors")
require("hypr.input")
require("hypr.bindings")
+47 -45
View File
@@ -1,50 +1,52 @@
-- Control your input devices.
-- Keep only your personal input overrides here. Uncommented settings below
-- replace Omarchy's defaults.
-- Keyboard layout and options.
-- See https://wiki.hypr.land/Configuring/Basics/Variables/#input
hl.config({
input = {
-- Use multiple keyboard layouts and switch between them with Left Alt + Right Alt.
-- kb_layout = "us,dk,eu",
-- hl.config({
-- input = {
-- -- Use multiple keyboard layouts and switch between them with Left Alt + Right Alt.
-- kb_layout = "us,dk,eu",
-- kb_options = "compose:caps,grp:alts_toggle",
--
-- -- Use a specific keyboard variant if needed (e.g. intl for international keyboards).
-- kb_variant = "intl",
--
-- -- Change speed of keyboard repeat.
-- repeat_rate = 40,
-- repeat_delay = 250,
--
-- -- Start with numlock on by default.
-- numlock_by_default = true,
--
-- -- Increase sensitivity for mouse/trackpad (default: 0).
-- sensitivity = 0.35,
--
-- -- Turn off mouse acceleration (default: adaptive).
-- accel_profile = "flat",
--
-- touchpad = {
-- -- Use natural (inverse) scrolling.
-- natural_scroll = true,
--
-- -- Use two-finger clicks for right-click instead of lower-right corner.
-- clickfinger_behavior = true,
--
-- -- Control the speed of your scrolling.
-- scroll_factor = 0.4,
--
-- -- Enable the touchpad while typing.
-- disable_while_typing = false,
--
-- -- Left-click-and-drag with three fingers.
-- drag_3fg = 1,
-- },
-- },
-- })
-- Use a specific keyboard variant if needed (e.g. intl for international keyboards).
-- kb_variant = "intl",
kb_options = "compose:caps", -- ,grp:alts_toggle
-- Change speed of keyboard repeat.
repeat_rate = 40,
repeat_delay = 250,
-- Start with numlock on by default.
numlock_by_default = true,
-- Increase sensitivity for mouse/trackpad (default: 0).
-- sensitivity = 0.35,
-- Turn off mouse acceleration (default: adaptive).
-- accel_profile = "flat",
touchpad = {
-- Use natural (inverse) scrolling.
-- natural_scroll = true,
-- Use two-finger clicks for right-click instead of lower-right corner.
clickfinger_behavior = true,
-- Control the speed of your scrolling.
scroll_factor = 0.4,
-- Enable the touchpad while typing.
-- disable_while_typing = false,
-- Left-click-and-drag with three fingers.
-- drag_3fg = 1,
},
},
})
-- Scroll nicely in the terminal.
o.window("(Alacritty|kitty|foot)", { scroll_touchpad = 1.5 })
o.window("com.mitchellh.ghostty", { scroll_touchpad = 0.2 })
-- App-specific touchpad scroll speeds.
-- o.window("(Alacritty|kitty|foot)", { scroll_touchpad = 1.5 })
-- o.window("com.mitchellh.ghostty", { scroll_touchpad = 0.2 })
-- Enable touchpad gestures for changing workspaces.
-- See https://wiki.hypr.land/Configuring/Advanced-and-Cool/Gestures/
+5 -2
View File
@@ -1,5 +1,5 @@
-- See https://wiki.hypr.land/Configuring/Basics/Monitors/
-- List current monitors and resolutions possible: hyprctl monitors all
-- List current monitors and supported resolutions with: hyprctl monitors all
local omarchy_gdk_scale = 2
local omarchy_monitor_scale = "auto"
@@ -7,5 +7,8 @@ local omarchy_monitor_scale = "auto"
hl.env("GDK_SCALE", tostring(omarchy_gdk_scale))
hl.monitor({ output = "", mode = "preferred", position = "auto", scale = omarchy_monitor_scale })
-- Portrait/rotated secondary monitor (transform: 1 = 90°, 3 = 270°)
-- Configure a specific monitor.
-- hl.monitor({ output = "DP-2", mode = "2560x1440@144", position = "0x0", scale = 1 })
-- Portrait/rotated secondary monitor (transform: 1 = 90°, 3 = 270°).
-- hl.monitor({ output = "DP-2", mode = "preferred", position = "auto", scale = 1, transform = 1 })
@@ -1,7 +1,7 @@
# paths to stylesheets on the filesystem which should be applied to the application
#
# relative paths are resolved relative to the location of the config file
stylesheets: ["../omarchy/current/theme/hyprland-preview-share-picker.css"]
stylesheets: ["../../.local/state/omarchy/current/theme/hyprland-preview-share-picker.css"]
# default page selected when the picker is opened
default_page: outputs
+2 -2
View File
@@ -12,5 +12,5 @@
# Rotate the currently open image by 90 degrees
<Ctrl+r> = exec mogrify -rotate 90 "$imv_current_file"
# Edit the current image in Satty and quit the viewer
<Ctrl+e> = exec satty --filename "$imv_current_file" & ; quit
# Edit the current image in Tensaku and quit the viewer
<Ctrl+e> = exec tensaku-edit "$imv_current_file" & ; quit
+1 -1
View File
@@ -1,4 +1,4 @@
include ~/.config/omarchy/current/theme/kitty.conf
include ~/.local/state/omarchy/current/theme/kitty.conf
# Font
font_family JetBrainsMono Nerd Font
+19 -18
View File
@@ -15,12 +15,13 @@
# by default.
#
# AVAILABLE VARIABLES:
# {{ background }} - Main background color (e.g., "#1a1b26")
# {{ foreground }} - Main foreground/text color
# {{ cursor }} - Cursor color
# {{ bg }} - Main background color (e.g., "#1a1b26")
# {{ fg }} - Main foreground/text color
# {{ bright_fg }} - Bright foreground / cursor color
# {{ accent }} - Theme accent color
# {{ selection_background }} - Selection highlight background
# {{ selection_foreground }} - Selection highlight foreground
# {{ selection }} - Selection highlight background
# {{ selection_background }} - Selection highlight background alias
# {{ selection_foreground }} - Selection highlight foreground (derived from bright_fg)
#
# {{ color0 }} through {{ color15 }} - Standard 16-color terminal palette
# color0-7: Normal colors (black, red, green, yellow, blue, magenta, cyan, white)
@@ -35,35 +36,35 @@
# {{ variable_rgb }} - Decimal RGB values (e.g., "26,27,38")
#
# Example using modifiers:
# background = "{{ background }}" -> background = "#1a1b26"
# background = "{{ background_strip }}" -> background = "1a1b26"
# background = "rgb({{ background_rgb }})" -> background = "rgb(26,27,38)"
# background = "{{ bg }}" -> background = "#1a1b26"
# background = "{{ bg_strip }}" -> background = "1a1b26"
# background = "rgb({{ bg_rgb }})" -> background = "rgb(26,27,38)"
#
# ---------------------------------------------------------------------------
[colors.primary]
background = "{{ background }}"
foreground = "{{ foreground }}"
background = "{{ bg }}"
foreground = "{{ fg }}"
[colors.cursor]
text = "{{ background }}"
cursor = "{{ cursor }}"
text = "{{ bg }}"
cursor = "{{ bright_fg }}"
[colors.vi_mode_cursor]
text = "{{ background }}"
cursor = "{{ cursor }}"
text = "{{ bg }}"
cursor = "{{ bright_fg }}"
[colors.search.matches]
foreground = "{{ background }}"
foreground = "{{ bg }}"
background = "{{ yellow }}"
[colors.search.focused_match]
foreground = "{{ background }}"
foreground = "{{ bg }}"
background = "{{ red }}"
[colors.footer_bar]
foreground = "{{ background }}"
background = "{{ foreground }}"
foreground = "{{ bg }}"
background = "{{ fg }}"
[colors.selection]
text = "{{ selection_foreground }}"
+2 -3
View File
@@ -17,12 +17,11 @@ export OMARCHY_PATH
# Only prepend in dev-link mode. On a production install, the binaries are
# already on PATH as /usr/bin/omarchy-* via the omarchy package — prepending
# /usr/share/omarchy/bin would just be noise. omarchy-dev-unlink strips its
# checkout bin/ from the active PATH explicitly, so we don't dedupe here.
# /usr/share/omarchy/bin would just be noise.
if [ "$OMARCHY_PATH" != /usr/share/omarchy ]; then
case ":$PATH:" in
*":${OMARCHY_PATH%/}/bin:"*) ;;
*) PATH="${OMARCHY_PATH%/}/bin:$PATH" ;;
*) PATH="${OMARCHY_PATH%/}/bin${PATH:+:$PATH}" ;;
esac
export PATH
fi
+21 -13
View File
@@ -3,16 +3,18 @@ o.window({ tag = "floating-window" }, { float = true })
o.window({ tag = "floating-window" }, { center = true })
o.window({ tag = "floating-window" }, { size = { 875, 600 } })
o.window("(org.omarchy.btop|org.omarchy.terminal|org.omarchy.bash|org.codeberg.dnkl.foot|org.gnome.NautilusPreviewer|org.gnome.Evince|com.gabm.satty|Omarchy|About|TUI.float|imv|mpv)", {
tag = "+floating-window",
})
o.window(
"(org.omarchy.btop|org.omarchy.terminal|org.omarchy.bash|org.codeberg.dnkl.foot|org.gnome.NautilusPreviewer|org.gnome.Evince|Omarchy|About|TUI.float|imv|mpv)",
{
class = "(xdg-desktop-portal-gtk|sublime_text|DesktopEditors|org.gnome.Nautilus)",
title = "^(Open.*Files?|Open [F|f]older.*|Save.*Files?|Save.*As|Save|All Files|.*wants to [open|save].*|[C|c]hoose.*)",
},
{ tag = "+floating-window" }
tag = "+floating-window",
}
)
o.window({
class = "(xdg-desktop-portal-gtk|sublime_text|DesktopEditors|org.gnome.Nautilus)",
title = "^(Open.*Files?|Open [F|f]older.*|Save.*Files?|Save.*As|Save|All Files|.*wants to [open|save].*|[C|c]hoose.*)",
}, { tag = "+floating-window" })
o.window("dev.tensaku.Tensaku", { float = true })
o.window("dev.tensaku.Tensaku", { center = true })
o.window("org.gnome.Calculator", { float = true })
-- Fullscreen screensaver.
@@ -21,12 +23,18 @@ o.window("org.omarchy.screensaver", { float = true })
o.window("org.omarchy.screensaver", { animation = "slide" })
-- No transparency on media windows.
o.window("^(zoom|vlc|mpv|org.kde.kdenlive|com.obsproject.Studio|com.github.PintaProject.Pinta|imv|org.gnome.NautilusPreviewer)$", {
tag = "-default-opacity",
})
o.window("^(zoom|vlc|mpv|org.kde.kdenlive|com.obsproject.Studio|com.github.PintaProject.Pinta|imv|org.gnome.NautilusPreviewer)$", {
opacity = "1 1",
})
o.window(
"^(zoom|vlc|mpv|org.kde.kdenlive|com.obsproject.Studio|com.github.PintaProject.Pinta|imv|org.gnome.NautilusPreviewer)$",
{
tag = "-default-opacity",
}
)
o.window(
"^(zoom|vlc|mpv|org.kde.kdenlive|com.obsproject.Studio|com.github.PintaProject.Pinta|imv|org.gnome.NautilusPreviewer)$",
{
opacity = "1 1",
}
)
-- Popped window rounding.
o.window({ tag = "pop" }, { rounding = 8 })
+39
View File
@@ -0,0 +1,39 @@
-- Essential application bindings.
o.bind("SUPER + RETURN", "Terminal", { omarchy = "terminal" })
o.bind("SUPER + SHIFT + RETURN", "Browser", { omarchy = "browser" })
o.bind("SUPER + SHIFT + F", "File manager", { omarchy = "nautilus" })
o.bind("SUPER + ALT + SHIFT + F", "File manager (cwd)", { omarchy = "nautilus-cwd" })
o.bind("SUPER + SHIFT + B", "Browser", { omarchy = "browser" })
o.bind("SUPER + SHIFT + ALT + B", "Browser (private)", { omarchy = "browser --private" })
o.bind("SUPER + SHIFT + N", "Editor", { omarchy = "editor" })
if not o.preinstalled_bindings_enabled() then
return
end
-- Bindings for preinstalled Omarchy applications, TUIs, and web apps.
o.bind("SUPER + ALT + RETURN", "Tmux", { omarchy = "terminal-tmux" })
o.bind("SUPER + SHIFT + M", "Music", { omarchy = "spotify" })
o.bind("SUPER + SHIFT + ALT + M", "Music TUI", { tui = "cliamp", focus = true })
o.bind("SUPER + SHIFT + D", "Docker", { tui = "lazydocker" })
o.bind("SUPER + SHIFT + G", "Signal", { omarchy = "signal" })
o.bind("SUPER + SHIFT + O", "Obsidian", { launch = "obsidian", focus = "^obsidian$" })
o.bind("SUPER + SHIFT + W", "Typora", { launch = "typora --enable-wayland-ime" })
o.bind("SUPER + SHIFT + SLASH", "Passwords", { launch = "1password" })
o.bind("SUPER + SHIFT + A", "ChatGPT", { webapp = "https://chatgpt.com" })
o.bind("SUPER + SHIFT + ALT + A", "Grok", { webapp = "https://grok.com" })
o.bind("SUPER + SHIFT + C", "Calendar", { webapp = "https://app.hey.com/calendar/weeks/" })
o.bind("SUPER + SHIFT + E", "Email", { webapp = "https://app.hey.com" })
o.bind("SUPER + SHIFT + ALT + E", "New email", { webapp = "https://app.hey.com/messages/new?display=standalone&new_window=true" })
o.bind("SUPER + SHIFT + Y", "YouTube", { webapp = "https://youtube.com/" })
o.bind("SUPER + SHIFT + ALT + G", "WhatsApp", { webapp = "https://web.whatsapp.com/", focus = true })
o.bind(
"SUPER + SHIFT + CTRL + G",
"Google Messages",
{ webapp = "https://messages.google.com/web/conversations", focus = true }
)
o.bind("SUPER + SHIFT + P", "Google Photos", { webapp = "https://photos.google.com/", focus = true })
o.bind("SUPER + SHIFT + S", "Google Maps", { webapp = "https://maps.google.com/", focus = true })
o.bind("SUPER + SHIFT + X", "X", { webapp = "https://x.com/" })
o.bind("SUPER + SHIFT + ALT + X", "X Post", { webapp = "https://x.com/compose/post" })
+13
View File
@@ -0,0 +1,13 @@
-- Hyprland bootstrap for Omarchy's Lua module path.
local home = os.getenv("HOME")
-- Load generated state from ~/.local/state, user modules from ~/.config, and
-- Omarchy defaults from $OMARCHY_PATH.
package.path = home
.. "/.local/state/?.lua;"
.. home
.. "/.config/?.lua;"
.. (os.getenv("OMARCHY_PATH") or "/usr/share/omarchy")
.. "/?.lua;"
.. package.path
+18
View File
@@ -49,6 +49,24 @@ local function command_from(value, description)
return value
end
local function file_exists(path)
local file = io.open(path, "r")
if file then
file:close()
return true
end
return false
end
function o.preinstalled_bindings_enabled()
if _G.omarchy_preinstalled_bindings ~= nil then
return _G.omarchy_preinstalled_bindings == true
end
return not file_exists((os.getenv("HOME") or "") .. "/.local/state/omarchy/preinstalls-removed")
end
function o.bind(keys, description, dispatcher, options)
local opts = options or {}
+36 -2
View File
@@ -1,16 +1,46 @@
-- https://wiki.hypr.land/Configuring/Basics/Variables/#input
local function read_vconsole()
local values = {}
local file = io.open("/etc/vconsole.conf", "r")
if not file then
return values
end
for line in file:lines() do
local key, value = line:match("^%s*([%w_]+)%s*=%s*(.-)%s*$")
if key and value then
value = value:gsub("%s+#.*$", "")
value = value:gsub('^"(.*)"$', "%1")
value = value:gsub("^'(.*)'$", "%1")
values[key] = value
end
end
file:close()
return values
end
local vconsole = read_vconsole()
hl.config({
input = {
kb_layout = "us",
kb_variant = "",
kb_layout = vconsole.XKBLAYOUT or "us",
kb_variant = vconsole.XKBVARIANT or "",
kb_model = "",
kb_options = "compose:caps",
kb_rules = "",
follow_mouse = 1,
sensitivity = 0,
repeat_rate = 40,
repeat_delay = 250,
numlock_by_default = true,
touchpad = {
natural_scroll = false,
clickfinger_behavior = true,
scroll_factor = 0.4,
},
},
@@ -19,3 +49,7 @@ hl.config({
mouse_move_enables_dpms = true,
},
})
-- Scroll nicely in the terminal.
o.window("(Alacritty|kitty|foot)", { scroll_touchpad = 1.5 })
o.window("com.mitchellh.ghostty", { scroll_touchpad = 0.2 })
+9 -5
View File
@@ -1,17 +1,21 @@
-- Omarchy Hyprland setup: helpers, defaults, and current theme overrides.
require("default.hypr.helpers")
local require_optional = require("default.hypr.require_optional")
-- Use Omarchy defaults, but don't edit these directly.
require("default.hypr.autostart")
require("default.hypr.bindings.media")
require("default.hypr.bindings.clipboard")
require("default.hypr.bindings.tiling-v2")
require("default.hypr.bindings.utilities")
if _G.omarchy_default_bindings ~= false then
require("default.hypr.bindings.media")
require("default.hypr.bindings.clipboard")
require("default.hypr.bindings.tiling-v2")
require("default.hypr.bindings.utilities")
require_optional.module("default.hypr.bindings.applications")
end
require("default.hypr.envs")
require("default.hypr.looknfeel")
require("default.hypr.input")
require("default.hypr.windows")
-- Current theme overrides.
require("default.hypr.require_optional").module("omarchy.current.theme.hyprland")
require_optional.module("omarchy.current.theme.hyprland")
+1 -18
View File
@@ -4,26 +4,9 @@
local home = os.getenv("HOME")
-- /etc/omarchy.conf wins over process env so dev-link/unlink survives stale sessions.
local function read_dev_link_omarchy_path()
local f = io.open("/etc/omarchy.conf", "r")
if not f then return nil end
local value
for line in f:lines() do
local v = line:match('^%s*export%s+OMARCHY_PATH=%s*"?([^"\n]+)"?')
if v and #v > 0 then value = v end
end
f:close()
return value
end
local omarchy_path = read_dev_link_omarchy_path()
or os.getenv("OMARCHY_PATH")
or "/usr/share/omarchy"
return {
home = home,
config_home = os.getenv("XDG_CONFIG_HOME") or (home .. "/.config"),
state_home = os.getenv("XDG_STATE_HOME") or (home .. "/.local/state"),
omarchy_path = omarchy_path,
omarchy_path = os.getenv("OMARCHY_PATH") or "/usr/share/omarchy",
}
-13
View File
@@ -1,13 +0,0 @@
require("default.hypr.bindings.media")
require("default.hypr.bindings.clipboard")
require("default.hypr.bindings.tiling-v2")
require("default.hypr.bindings.utilities")
-- Application bindings without Omarchy's preinstalled web apps, TUIs, or desktop apps.
o.bind("SUPER + RETURN", "Terminal", { omarchy = "terminal" })
o.bind("SUPER + SHIFT + RETURN", "Browser", { omarchy = "browser" })
o.bind("SUPER + SHIFT + F", "File manager", { omarchy = "nautilus" })
o.bind("SUPER + ALT + SHIFT + F", "File manager (cwd)", { omarchy = "nautilus-cwd" })
o.bind("SUPER + SHIFT + B", "Browser", { omarchy = "browser" })
o.bind("SUPER + SHIFT + ALT + B", "Browser (private)", { omarchy = "browser --private" })
o.bind("SUPER + SHIFT + N", "Editor", { omarchy = "editor" })
@@ -0,0 +1,12 @@
[Trigger]
Operation = Install
Operation = Upgrade
Type = Package
Target = omarchy-settings
Target = omarchy-settings-dev
[Action]
Description = Pausing Hyprland config auto-reload for Omarchy settings update...
When = PreTransaction
Depends = omarchy
Exec = /usr/bin/omarchy-hyprland-reload-guard pause
@@ -0,0 +1,12 @@
[Trigger]
Operation = Install
Operation = Upgrade
Type = Package
Target = omarchy-settings
Target = omarchy-settings-dev
[Action]
Description = Reloading Hyprland after Omarchy settings update...
When = PostTransaction
Depends = omarchy
Exec = /usr/bin/omarchy-hyprland-reload-guard resume
+5 -5
View File
@@ -284,7 +284,7 @@
// Update
"update.omarchy": {"icon":"","label":"Omarchy","keywords":"system","action":"omarchy-launch-floating-terminal-with-presentation omarchy-update"},
"update.channel": {"icon":"󰔫","label":"Channel","keywords":"stable rc edge dev"},
"update.channel": {"icon":"󰔫","label":"Channel","keywords":"stable rc dev edge source"},
"update.config": {"icon":"","label":"Config","keywords":"refresh default"},
"update.themes": {"icon":"󰸌","label":"Extra Themes","action":"omarchy-launch-floating-terminal-with-presentation omarchy-theme-update"},
"update.process": {"icon":"","label":"Process","keywords":"restart services"},
@@ -293,10 +293,10 @@
"update.password": {"icon":"","label":"Password","keywords":"drive user"},
"update.timezone": {"icon":"","label":"Timezone","keywords":"time zone","action":"omarchy-menu-timezone"},
"update.time": {"icon":"","label":"Time","keywords":"clock ntp","action":"omarchy-launch-floating-terminal-with-presentation omarchy-update-time"},
"update.channel.stable": {"icon":"🟢","label":"Stable","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-channel-set stable'"},
"update.channel.rc": {"icon":"🟡","label":"RC","keywords":"release candidate","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-channel-set rc'"},
"update.channel.edge": {"icon":"🟠","label":"Edge","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-channel-set edge'"},
"update.channel.dev": {"icon":"🔴","label":"Dev","keywords":"development","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-channel-set dev'"},
"update.channel.stable": {"icon":"🟢","label":"Stable","checked":"[[ \"$(omarchy-channel-current)\" == \"stable\" ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-channel-set stable'"},
"update.channel.rc": {"icon":"🟡","label":"RC","keywords":"release candidate","checked":"[[ \"$(omarchy-channel-current)\" == \"rc\" ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-channel-set rc'"},
"update.channel.dev": {"icon":"🟠","label":"Dev","keywords":"development","checked":"[[ \"$(omarchy-channel-current)\" == \"dev\" ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-channel-set dev'"},
"update.channel.edge": {"icon":"🔴","label":"Edge","keywords":"source mode development quattro","checked":"[[ \"$(omarchy-channel-current)\" == \"edge\" ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-channel-set edge'"},
"update.process.hyprsunset": {"icon":"","label":"Hyprsunset","keywords":"restart","action":"omarchy-restart-hyprsunset"},
"update.process.osd": {"icon":"","label":"OSD","keywords":"restart","action":"omarchy-restart-shell"},
"update.process.shell": {"icon":"󰍜","label":"Shell","keywords":"restart bar quickshell omarchy-shell","action":"omarchy-restart-shell"},
@@ -1,9 +1,9 @@
[Unit]
Description=Watch for Omarchy user migrations
Description=Watch for Omarchy migrations
[Path]
PathExistsGlob=/usr/share/omarchy/migrations/user/*.sh
PathModified=/usr/share/omarchy/migrations/user
PathExistsGlob=/usr/share/omarchy/migrations/*.sh
PathModified=/usr/share/omarchy/migrations
Unit=omarchy-update-user-notify.service
[Install]
@@ -1,6 +1,6 @@
[Unit]
Description=Notify about pending Omarchy user migrations
ConditionPathExistsGlob=/usr/share/omarchy/migrations/user/*.sh
Description=Notify about pending Omarchy migrations
ConditionPathIsDirectory=/usr/share/omarchy/migrations
[Service]
Type=oneshot
+10 -10
View File
@@ -1,26 +1,26 @@
[colors.primary]
background = "{{ background }}"
foreground = "{{ foreground }}"
background = "{{ bg }}"
foreground = "{{ fg }}"
[colors.cursor]
text = "{{ background }}"
cursor = "{{ cursor }}"
text = "{{ bg }}"
cursor = "{{ bright_fg }}"
[colors.vi_mode_cursor]
text = "{{ background }}"
cursor = "{{ cursor }}"
text = "{{ bg }}"
cursor = "{{ bright_fg }}"
[colors.search.matches]
foreground = "{{ background }}"
foreground = "{{ bg }}"
background = "{{ yellow }}"
[colors.search.focused_match]
foreground = "{{ background }}"
foreground = "{{ bg }}"
background = "{{ red }}"
[colors.footer_bar]
foreground = "{{ background }}"
background = "{{ foreground }}"
foreground = "{{ bg }}"
background = "{{ fg }}"
[colors.selection]
text = "{{ selection_foreground }}"
+3 -3
View File
@@ -1,11 +1,11 @@
# Main background, empty for terminal default, need to be empty if you want transparent background
theme[main_bg]="{{ background }}"
theme[main_bg]="{{ bg }}"
# Main text color
theme[main_fg]="{{ foreground }}"
theme[main_fg]="{{ fg }}"
# Title color for boxes
theme[title]="{{ foreground }}"
theme[title]="{{ fg }}"
# Highlight color for keyboard shortcuts
theme[hi_fg]="{{ accent }}"
+1 -1
View File
@@ -1 +1 @@
{{ background_rgb }}
{{ bg_rgb }}
+3 -3
View File
@@ -1,10 +1,10 @@
[colors-dark]
foreground={{ foreground_strip }}
background={{ background_strip }}
foreground={{ fg_strip }}
background={{ bg_strip }}
selection-foreground={{ selection_foreground_strip }}
selection-background={{ selection_background_strip }}
cursor={{ background_strip }} {{ cursor_strip }}
cursor={{ bg_strip }} {{ bright_fg_strip }}
regular0={{ bg_strip }}
regular1={{ red_strip }}
+3 -3
View File
@@ -1,6 +1,6 @@
background = {{ background }}
foreground = {{ foreground }}
cursor-color = {{ cursor }}
background = {{ bg }}
foreground = {{ fg }}
cursor-color = {{ bright_fg }}
selection-background = {{ selection_background }}
selection-foreground = {{ selection_foreground }}
+78 -78
View File
@@ -1,137 +1,137 @@
-- Gum Style (generic) Variables
hl.env("FOREGROUND", "{{ foreground }}")
hl.env("BACKGROUND", "{{ background }}")
hl.env("FOREGROUND", "{{ fg }}")
hl.env("BACKGROUND", "{{ bg }}")
hl.env("BORDER_FOREGROUND", "{{ accent }}")
hl.env("BORDER_BACKGROUND", "{{ background }}")
hl.env("BORDER_BACKGROUND", "{{ bg }}")
-- Gum Confirm Style Variables
hl.env("GUM_CONFIRM_PROMPT_FOREGROUND", "{{ accent }}")
hl.env("GUM_CONFIRM_PROMPT_BACKGROUND", "{{ background }}")
hl.env("GUM_CONFIRM_PROMPT_BACKGROUND", "{{ bg }}")
hl.env("GUM_CONFIRM_SELECTED_FOREGROUND", "{{ selection_foreground }}")
hl.env("GUM_CONFIRM_SELECTED_BACKGROUND", "{{ selection_background }}")
hl.env("GUM_CONFIRM_UNSELECTED_FOREGROUND", "{{ foreground }}")
hl.env("GUM_CONFIRM_UNSELECTED_BACKGROUND", "{{ background }}")
hl.env("GUM_CONFIRM_UNSELECTED_FOREGROUND", "{{ fg }}")
hl.env("GUM_CONFIRM_UNSELECTED_BACKGROUND", "{{ bg }}")
-- Gum Input Style Variables
hl.env("GUM_INPUT_PROMPT_FOREGROUND", "{{ accent }}")
hl.env("GUM_INPUT_PROMPT_BACKGROUND", "{{ background }}")
hl.env("GUM_INPUT_PROMPT_BACKGROUND", "{{ bg }}")
hl.env("GUM_INPUT_PLACEHOLDER_FOREGROUND", "{{ muted }}")
hl.env("GUM_INPUT_PLACEHOLDER_BACKGROUND", "{{ background }}")
hl.env("GUM_INPUT_CURSOR_FOREGROUND", "{{ cursor }}")
hl.env("GUM_INPUT_CURSOR_BACKGROUND", "{{ background }}")
hl.env("GUM_INPUT_HEADER_FOREGROUND", "{{ foreground }}")
hl.env("GUM_INPUT_HEADER_BACKGROUND", "{{ background }}")
hl.env("GUM_INPUT_PLACEHOLDER_BACKGROUND", "{{ bg }}")
hl.env("GUM_INPUT_CURSOR_FOREGROUND", "{{ bright_fg }}")
hl.env("GUM_INPUT_CURSOR_BACKGROUND", "{{ bg }}")
hl.env("GUM_INPUT_HEADER_FOREGROUND", "{{ fg }}")
hl.env("GUM_INPUT_HEADER_BACKGROUND", "{{ bg }}")
-- Gum Choose Style Variables
hl.env("GUM_CHOOSE_CURSOR_FOREGROUND", "{{ accent }}")
hl.env("GUM_CHOOSE_CURSOR_BACKGROUND", "{{ background }}")
hl.env("GUM_CHOOSE_HEADER_FOREGROUND", "{{ foreground }}")
hl.env("GUM_CHOOSE_HEADER_BACKGROUND", "{{ background }}")
hl.env("GUM_CHOOSE_ITEM_FOREGROUND", "{{ foreground }}")
hl.env("GUM_CHOOSE_ITEM_BACKGROUND", "{{ background }}")
hl.env("GUM_CHOOSE_CURSOR_BACKGROUND", "{{ bg }}")
hl.env("GUM_CHOOSE_HEADER_FOREGROUND", "{{ fg }}")
hl.env("GUM_CHOOSE_HEADER_BACKGROUND", "{{ bg }}")
hl.env("GUM_CHOOSE_ITEM_FOREGROUND", "{{ fg }}")
hl.env("GUM_CHOOSE_ITEM_BACKGROUND", "{{ bg }}")
hl.env("GUM_CHOOSE_SELECTED_FOREGROUND", "{{ selection_foreground }}")
hl.env("GUM_CHOOSE_SELECTED_BACKGROUND", "{{ selection_background }}")
-- Gum Filter Style Variables
hl.env("GUM_FILTER_PROMPT_FOREGROUND", "{{ accent }}")
hl.env("GUM_FILTER_PROMPT_BACKGROUND", "{{ background }}")
hl.env("GUM_FILTER_TEXT_FOREGROUND", "{{ foreground }}")
hl.env("GUM_FILTER_TEXT_BACKGROUND", "{{ background }}")
hl.env("GUM_FILTER_PROMPT_BACKGROUND", "{{ bg }}")
hl.env("GUM_FILTER_TEXT_FOREGROUND", "{{ fg }}")
hl.env("GUM_FILTER_TEXT_BACKGROUND", "{{ bg }}")
hl.env("GUM_FILTER_MATCH_FOREGROUND", "{{ accent }}")
hl.env("GUM_FILTER_CURSOR_TEXT_FOREGROUND", "{{ cursor }}")
hl.env("GUM_FILTER_CURSOR_TEXT_BACKGROUND", "{{ background }}")
hl.env("GUM_FILTER_CURSOR_TEXT_FOREGROUND", "{{ bright_fg }}")
hl.env("GUM_FILTER_CURSOR_TEXT_BACKGROUND", "{{ bg }}")
hl.env("GUM_FILTER_SELECTED_FOREGROUND", "{{ selection_foreground }}")
hl.env("GUM_FILTER_SELECTED_BACKGROUND", "{{ selection_background }}")
hl.env("GUM_FILTER_INDICATOR_FOREGROUND", "{{ accent }}")
hl.env("GUM_FILTER_HEADER_FOREGROUND", "{{ foreground }}")
hl.env("GUM_FILTER_MATCH_BACKGROUND", "{{ background }}")
hl.env("GUM_FILTER_HEADER_BACKGROUND", "{{ background }}")
hl.env("GUM_FILTER_HEADER_FOREGROUND", "{{ fg }}")
hl.env("GUM_FILTER_MATCH_BACKGROUND", "{{ bg }}")
hl.env("GUM_FILTER_HEADER_BACKGROUND", "{{ bg }}")
hl.env("GUM_FILTER_PLACEHOLDER_FOREGROUND", "{{ muted }}")
hl.env("GUM_FILTER_PLACEHOLDER_BACKGROUND", "{{ background }}")
hl.env("GUM_FILTER_INDICATOR_BACKGROUND", "{{ background }}")
hl.env("GUM_FILTER_PLACEHOLDER_BACKGROUND", "{{ bg }}")
hl.env("GUM_FILTER_INDICATOR_BACKGROUND", "{{ bg }}")
hl.env("GUM_FILTER_SELECTED_PREFIX_FOREGROUND", "{{ selection_foreground }}")
hl.env("GUM_FILTER_SELECTED_PREFIX_BACKGROUND", "{{ selection_background }}")
hl.env("GUM_FILTER_UNSELECTED_PREFIX_FOREGROUND", "{{ muted }}")
hl.env("GUM_FILTER_UNSELECTED_PREFIX_BACKGROUND", "{{ background }}")
hl.env("GUM_FILTER_UNSELECTED_PREFIX_BACKGROUND", "{{ bg }}")
-- Gum Table Style Variables
hl.env("GUM_TABLE_HEADER_FOREGROUND", "{{ foreground }}")
hl.env("GUM_TABLE_HEADER_BACKGROUND", "{{ background }}")
hl.env("GUM_TABLE_CELL_FOREGROUND", "{{ foreground }}")
hl.env("GUM_TABLE_CELL_BACKGROUND", "{{ background }}")
hl.env("GUM_TABLE_HEADER_FOREGROUND", "{{ fg }}")
hl.env("GUM_TABLE_HEADER_BACKGROUND", "{{ bg }}")
hl.env("GUM_TABLE_CELL_FOREGROUND", "{{ fg }}")
hl.env("GUM_TABLE_CELL_BACKGROUND", "{{ bg }}")
hl.env("GUM_TABLE_BORDER_FOREGROUND", "{{ muted }}")
hl.env("GUM_TABLE_BORDER_BACKGROUND", "{{ background }}")
hl.env("GUM_TABLE_BORDER_BACKGROUND", "{{ bg }}")
hl.env("GUM_TABLE_SELECTED_FOREGROUND", "{{ selection_foreground }}")
hl.env("GUM_TABLE_SELECTED_BACKGROUND", "{{ selection_background }}")
-- Gum Spin Style Variables
hl.env("GUM_SPIN_SPINNER_FOREGROUND", "{{ accent }}")
hl.env("GUM_SPIN_SPINNER_BACKGROUND", "{{ background }}")
hl.env("GUM_SPIN_TITLE_FOREGROUND", "{{ foreground }}")
hl.env("GUM_SPIN_TITLE_BACKGROUND", "{{ background }}")
hl.env("GUM_SPIN_SPINNER_BACKGROUND", "{{ bg }}")
hl.env("GUM_SPIN_TITLE_FOREGROUND", "{{ fg }}")
hl.env("GUM_SPIN_TITLE_BACKGROUND", "{{ bg }}")
-- Gum File Style Variables
hl.env("GUM_FILE_CURSOR_FOREGROUND", "{{ cursor }}")
hl.env("GUM_FILE_CURSOR_BACKGROUND", "{{ background }}")
hl.env("GUM_FILE_SYMLINK_FOREGROUND", "{{ foreground }}")
hl.env("GUM_FILE_SYMLINK_BACKGROUND", "{{ background }}")
hl.env("GUM_FILE_DIRECTORY_FOREGROUND", "{{ foreground }}")
hl.env("GUM_FILE_DIRECTORY_BACKGROUND", "{{ background }}")
hl.env("GUM_FILE_FILE_FOREGROUND", "{{ foreground }}")
hl.env("GUM_FILE_FILE_BACKGROUND", "{{ background }}")
hl.env("GUM_FILE_CURSOR_FOREGROUND", "{{ bright_fg }}")
hl.env("GUM_FILE_CURSOR_BACKGROUND", "{{ bg }}")
hl.env("GUM_FILE_SYMLINK_FOREGROUND", "{{ fg }}")
hl.env("GUM_FILE_SYMLINK_BACKGROUND", "{{ bg }}")
hl.env("GUM_FILE_DIRECTORY_FOREGROUND", "{{ fg }}")
hl.env("GUM_FILE_DIRECTORY_BACKGROUND", "{{ bg }}")
hl.env("GUM_FILE_FILE_FOREGROUND", "{{ fg }}")
hl.env("GUM_FILE_FILE_BACKGROUND", "{{ bg }}")
hl.env("GUM_FILE_PERMISSIONS_FOREGROUND", "{{ muted }}")
hl.env("GUM_FILE_PERMISSIONS_BACKGROUND", "{{ background }}")
hl.env("GUM_FILE_PERMISSIONS_BACKGROUND", "{{ bg }}")
hl.env("GUM_FILE_SELECTED_FOREGROUND", "{{ selection_foreground }}")
hl.env("GUM_FILE_SELECTED_BACKGROUND", "{{ selection_background }}")
hl.env("GUM_FILE_FILE_SIZE_FOREGROUND", "{{ muted }}")
hl.env("GUM_FILE_FILE_SIZE_BACKGROUND", "{{ background }}")
hl.env("GUM_FILE_HEADER_FOREGROUND", "{{ foreground }}")
hl.env("GUM_FILE_HEADER_BACKGROUND", "{{ background }}")
hl.env("GUM_FILE_FILE_SIZE_BACKGROUND", "{{ bg }}")
hl.env("GUM_FILE_HEADER_FOREGROUND", "{{ fg }}")
hl.env("GUM_FILE_HEADER_BACKGROUND", "{{ bg }}")
-- Gum Pager Style Variables
hl.env("GUM_PAGER_FOREGROUND", "{{ foreground }}")
hl.env("GUM_PAGER_BACKGROUND", "{{ background }}")
hl.env("GUM_PAGER_FOREGROUND", "{{ fg }}")
hl.env("GUM_PAGER_BACKGROUND", "{{ bg }}")
hl.env("GUM_PAGER_LINE_NUMBER_FOREGROUND", "{{ muted }}")
hl.env("GUM_PAGER_LINE_NUMBER_BACKGROUND", "{{ background }}")
hl.env("GUM_PAGER_LINE_NUMBER_BACKGROUND", "{{ bg }}")
hl.env("GUM_PAGER_MATCH_FOREGROUND", "{{ accent }}")
hl.env("GUM_PAGER_MATCH_BACKGROUND", "{{ background }}")
hl.env("GUM_PAGER_MATCH_BACKGROUND", "{{ bg }}")
hl.env("GUM_PAGER_MATCH_HIGH_FOREGROUND", "{{ accent }}")
hl.env("GUM_PAGER_MATCH_HIGH_BACKGROUND", "{{ background }}")
hl.env("GUM_PAGER_MATCH_HIGH_BACKGROUND", "{{ bg }}")
hl.env("GUM_PAGER_HELP_FOREGROUND", "{{ muted }}")
hl.env("GUM_PAGER_HELP_BACKGROUND", "{{ background }}")
hl.env("GUM_PAGER_HELP_BACKGROUND", "{{ bg }}")
-- Gum Write Style Variables
hl.env("GUM_WRITE_BASE_FOREGROUND", "{{ foreground }}")
hl.env("GUM_WRITE_BASE_BACKGROUND", "{{ background }}")
hl.env("GUM_WRITE_BASE_FOREGROUND", "{{ fg }}")
hl.env("GUM_WRITE_BASE_BACKGROUND", "{{ bg }}")
hl.env("GUM_WRITE_CURSOR_LINE_NUMBER_FOREGROUND", "{{ muted }}")
hl.env("GUM_WRITE_CURSOR_LINE_NUMBER_BACKGROUND", "{{ background }}")
hl.env("GUM_WRITE_CURSOR_LINE_FOREGROUND", "{{ foreground }}")
hl.env("GUM_WRITE_CURSOR_LINE_NUMBER_BACKGROUND", "{{ bg }}")
hl.env("GUM_WRITE_CURSOR_LINE_FOREGROUND", "{{ fg }}")
hl.env("GUM_WRITE_CURSOR_LINE_BACKGROUND", "{{ selection_background }}")
hl.env("GUM_WRITE_CURSOR_FOREGROUND", "{{ cursor }}")
hl.env("GUM_WRITE_CURSOR_BACKGROUND", "{{ background }}")
hl.env("GUM_WRITE_CURSOR_FOREGROUND", "{{ bright_fg }}")
hl.env("GUM_WRITE_CURSOR_BACKGROUND", "{{ bg }}")
hl.env("GUM_WRITE_END_OF_BUFFER_FOREGROUND", "{{ muted }}")
hl.env("GUM_WRITE_END_OF_BUFFER_BACKGROUND", "{{ background }}")
hl.env("GUM_WRITE_END_OF_BUFFER_BACKGROUND", "{{ bg }}")
hl.env("GUM_WRITE_LINE_NUMBER_FOREGROUND", "{{ muted }}")
hl.env("GUM_WRITE_LINE_NUMBER_BACKGROUND", "{{ background }}")
hl.env("GUM_WRITE_HEADER_FOREGROUND", "{{ foreground }}")
hl.env("GUM_WRITE_HEADER_BACKGROUND", "{{ background }}")
hl.env("GUM_WRITE_LINE_NUMBER_BACKGROUND", "{{ bg }}")
hl.env("GUM_WRITE_HEADER_FOREGROUND", "{{ fg }}")
hl.env("GUM_WRITE_HEADER_BACKGROUND", "{{ bg }}")
hl.env("GUM_WRITE_PLACEHOLDER_FOREGROUND", "{{ muted }}")
hl.env("GUM_WRITE_PLACEHOLDER_BACKGROUND", "{{ background }}")
hl.env("GUM_WRITE_PROMPT_FOREGROUND", "{{ foreground }}")
hl.env("GUM_WRITE_PROMPT_BACKGROUND", "{{ background }}")
hl.env("GUM_WRITE_PLACEHOLDER_BACKGROUND", "{{ bg }}")
hl.env("GUM_WRITE_PROMPT_FOREGROUND", "{{ fg }}")
hl.env("GUM_WRITE_PROMPT_BACKGROUND", "{{ bg }}")
-- Gum Log Style Variables
hl.env("GUM_LOG_LEVEL_FOREGROUND", "{{ accent }}")
hl.env("GUM_LOG_LEVEL_BACKGROUND", "{{ background }}")
hl.env("GUM_LOG_LEVEL_BACKGROUND", "{{ bg }}")
hl.env("GUM_LOG_TIME_FOREGROUND", "{{ muted }}")
hl.env("GUM_LOG_TIME_BACKGROUND", "{{ background }}")
hl.env("GUM_LOG_PREFIX_FOREGROUND", "{{ foreground }}")
hl.env("GUM_LOG_PREFIX_BACKGROUND", "{{ background }}")
hl.env("GUM_LOG_MESSAGE_FOREGROUND", "{{ foreground }}")
hl.env("GUM_LOG_MESSAGE_BACKGROUND", "{{ background }}")
hl.env("GUM_LOG_KEY_FOREGROUND", "{{ foreground }}")
hl.env("GUM_LOG_KEY_BACKGROUND", "{{ background }}")
hl.env("GUM_LOG_VALUE_FOREGROUND", "{{ foreground }}")
hl.env("GUM_LOG_VALUE_BACKGROUND", "{{ background }}")
hl.env("GUM_LOG_TIME_BACKGROUND", "{{ bg }}")
hl.env("GUM_LOG_PREFIX_FOREGROUND", "{{ fg }}")
hl.env("GUM_LOG_PREFIX_BACKGROUND", "{{ bg }}")
hl.env("GUM_LOG_MESSAGE_FOREGROUND", "{{ fg }}")
hl.env("GUM_LOG_MESSAGE_BACKGROUND", "{{ bg }}")
hl.env("GUM_LOG_KEY_FOREGROUND", "{{ fg }}")
hl.env("GUM_LOG_KEY_BACKGROUND", "{{ bg }}")
hl.env("GUM_LOG_VALUE_FOREGROUND", "{{ fg }}")
hl.env("GUM_LOG_VALUE_BACKGROUND", "{{ bg }}")
hl.env("GUM_LOG_SEPARATOR_FOREGROUND", "{{ muted }}")
hl.env("GUM_LOG_SEPARATOR_BACKGROUND", "{{ background }}")
hl.env("GUM_LOG_SEPARATOR_BACKGROUND", "{{ bg }}")
+5 -5
View File
@@ -116,17 +116,17 @@ info = "color4"
hint = "color6"
[palette]
background = "{{ background }}"
foreground = "{{ foreground }}"
cursor = "{{ cursor }}"
background = "{{ bg }}"
foreground = "{{ fg }}"
cursor = "{{ bright_fg }}"
selection_background = "{{ selection_background }}"
selection_foreground = "{{ selection_foreground }}"
color0 = "{{ background }}"
color0 = "{{ bg }}"
color1 = "{{ red }}"
color2 = "{{ green }}"
color3 = "{{ yellow }}"
color4 = "{{ blue }}"
color5 = "{{ magenta }}"
color6 = "{{ cyan }}"
color7 = "{{ foreground }}"
color7 = "{{ fg }}"
color8 = "{{ muted }}"
@@ -1,12 +1,12 @@
@define-color foreground {{ foreground }};
@define-color background {{ background }};
@define-color foreground {{ fg }};
@define-color background {{ bg }};
@define-color accent {{ accent }};
@define-color muted {{ muted }};
@define-color card_bg {{ lighter_bg }};
@define-color text_dark {{ background }};
@define-color text_dark {{ bg }};
@define-color accent_hover {{ bright_blue }};
@define-color selected_tab {{ accent }};
@define-color text {{ foreground }};
@define-color text {{ fg }};
* {
all: unset;
+4 -4
View File
@@ -1,10 +1,10 @@
foreground {{ foreground }}
background {{ background }}
foreground {{ fg }}
background {{ bg }}
selection_foreground {{ selection_foreground }}
selection_background {{ selection_background }}
cursor {{ cursor }}
cursor_text_color {{ background }}
cursor {{ bright_fg }}
cursor_text_color {{ bg }}
active_border_color {{ accent }}
active_tab_background {{ accent }}
+3 -3
View File
@@ -34,9 +34,9 @@ return {
bright_magenta = "{{ bright_magenta }}",
accent = "{{ accent }}",
cursor = "{{ cursor }}",
foreground = "{{ foreground }}",
background = "{{ background }}",
cursor = "{{ bright_fg }}",
foreground = "{{ fg }}",
background = "{{ bg }}",
selection = "{{ selection }}",
selection_foreground = "{{ selection_foreground }}",
selection_background = "{{ selection_background }}",
+7 -7
View File
@@ -2,11 +2,11 @@
.theme-dark, .theme-light {
/* Core colors */
--background-primary: {{ background }};
--background-primary-alt: {{ background }};
--background-secondary: {{ background }};
--background-secondary-alt: {{ background }};
--text-normal: {{ foreground }};
--background-primary: {{ bg }};
--background-primary-alt: {{ bg }};
--background-secondary: {{ bg }};
--background-secondary-alt: {{ bg }};
--text-normal: {{ fg }};
/* Selection colors */
--text-selection: {{ selection_background }};
@@ -30,8 +30,8 @@
--interactive-accent-hover: {{ accent }};
/* Muted text */
--text-muted: color-mix(in srgb, {{ foreground }} 70%, transparent);
--text-faint: color-mix(in srgb, {{ foreground }} 55%, transparent);
--text-muted: color-mix(in srgb, {{ fg }} 70%, transparent);
--text-faint: color-mix(in srgb, {{ fg }} 55%, transparent);
/* Code */
--code-normal: {{ cyan }};
+17 -17
View File
@@ -2,20 +2,20 @@
"$schema": "https://raw.githubusercontent.com/earendil-works/pi/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
"name": "omarchy-system",
"vars": {
"background": "{{ background }}",
"foreground": "{{ foreground }}",
"background": "{{ bg }}",
"foreground": "{{ fg }}",
"accent": "{{ accent }}",
"selectionBackground": "{{ selection_background }}",
"selectionForeground": "{{ selection_foreground }}",
"selectedBackground": "{{ mix background accent 22% }}",
"color0": "{{ background }}",
"selectedBackground": "{{ mix bg accent 22% }}",
"color0": "{{ bg }}",
"color1": "{{ red }}",
"color2": "{{ green }}",
"color3": "{{ yellow }}",
"color4": "{{ blue }}",
"color5": "{{ magenta }}",
"color6": "{{ cyan }}",
"color7": "{{ foreground }}",
"color7": "{{ fg }}",
"color8": "{{ muted }}",
"color9": "{{ bright_red }}",
"color10": "{{ bright_green }}",
@@ -24,15 +24,15 @@
"color13": "{{ bright_magenta }}",
"color14": "{{ bright_cyan }}",
"color15": "{{ bright_fg }}",
"panel": "{{ mix background foreground 6% }}",
"panelAlt": "{{ mix background foreground 10% }}",
"panelPending": "{{ mix background accent 12% }}",
"panelSuccess": "{{ mix background green 12% }}",
"panelError": "{{ mix background red 12% }}",
"border": "{{ mix background foreground 30% }}",
"borderMuted": "{{ mix background foreground 20% }}",
"mutedText": "{{ mix foreground background 34% }}",
"dimText": "{{ mix foreground background 52% }}"
"panel": "{{ mix bg fg 6% }}",
"panelAlt": "{{ mix bg fg 10% }}",
"panelPending": "{{ mix bg accent 12% }}",
"panelSuccess": "{{ mix bg green 12% }}",
"panelError": "{{ mix bg red 12% }}",
"border": "{{ mix bg fg 30% }}",
"borderMuted": "{{ mix bg fg 20% }}",
"mutedText": "{{ mix fg bg 34% }}",
"dimText": "{{ mix fg bg 52% }}"
},
"colors": {
"accent": "accent",
@@ -88,8 +88,8 @@
"bashMode": "color3"
},
"export": {
"pageBg": "{{ background }}",
"cardBg": "{{ mix background foreground 6% }}",
"infoBg": "{{ mix background foreground 10% }}"
"pageBg": "{{ bg }}",
"cardBg": "{{ mix bg fg 6% }}",
"infoBg": "{{ mix bg fg 10% }}"
}
}
+34 -34
View File
@@ -4,9 +4,9 @@
[bar]
# Alpha companions (where present) range from 0 (invisible) to 1 (opaque).
background = "{{ background }}"
background = "{{ bg }}"
background-alpha = 1.0
text = "{{ foreground }}"
text = "{{ fg }}"
# Modules calling attention to themselves (recording, voxtype, alerts, updates)
active = "{{ red }}"
# Cross-axis size at font base-size 12. size-horizontal is the height of
@@ -21,7 +21,7 @@ size-vertical = 28
# lock, notifications, popups, and menu-style cards stay aligned with the
# current Hyprland active-border gradient.
active-border = "{{ shell_gradient hyprland_active_border accent }}"
active-border-foreground = "{{ shell_gradient hyprland_active_border foreground }}"
active-border-foreground = "{{ shell_gradient hyprland_active_border fg }}"
[controls]
# Shared state tokens for interactive control chrome (buttons, dropdowns,
@@ -31,32 +31,32 @@ active-border-foreground = "{{ shell_gradient hyprland_active_border foreground
# N, "Y X", "T X B", or "T R B L". Per-side keys like
# normal-border-width-left override the list. Each *-border accepts either a
# solid color or a Hyprland-style gradient, e.g. "rgba(...) rgba(...) 45deg".
normal-color = "{{ foreground }}"
normal-color = "{{ fg }}"
normal-fill-alpha = 0.04
normal-border = "{{ foreground }}"
normal-border = "{{ fg }}"
normal-border-width = 1
normal-border-alpha = 0.4
# Hover-cursor: mouse hover and the panel keyboard cursor.
hover-cursor-color = "{{ foreground }}"
hover-cursor-color = "{{ fg }}"
hover-cursor-fill-alpha = 0.08
hover-cursor-border = "{{ foreground }}"
hover-cursor-border = "{{ fg }}"
hover-cursor-border-width = 1
hover-cursor-border-alpha = 0.25
# Focus: Qt activeFocus. Mirror the hover-cursor values by default so
# mouse hover, keyboard cursor, and tab focus all read as the same state
# — themes that want focus to stand out override these four lines.
focus-color = "{{ foreground }}"
focus-color = "{{ fg }}"
focus-fill-alpha = 0.08
focus-border = "{{ foreground }}"
focus-border = "{{ fg }}"
focus-border-width = 1
focus-border-alpha = 0.25
# Selected: persistent chosen/current state.
selected-color = "{{ foreground }}"
selected-color = "{{ fg }}"
selected-fill-alpha = 0.18
selected-border = "{{ foreground }}"
selected-border = "{{ fg }}"
selected-border-width = 0
selected-border-alpha = 1.0
@@ -124,9 +124,9 @@ base-size = 12
# Border accepts either a solid color or a Hyprland-style gradient. Border
# widths accept one CSS-style scalar/list: N, "Y X", "T X B", or "T R B L";
# individual border-width-top/right/bottom/left keys override the list.
background = "{{ background }}"
background = "{{ bg }}"
background-alpha = 1.0
text = "{{ foreground }}"
text = "{{ fg }}"
border = "hyprland.active-border"
border-alpha = 1.0
# border-width = 2
@@ -134,16 +134,16 @@ border-alpha = 1.0
[tooltip]
# Hover tooltips across the bar, panels, and buttons. background-alpha of
# 0.97 mirrors the legacy hard-coded tooltip opacity.
background = "{{ background }}"
background = "{{ bg }}"
background-alpha = 0.97
text = "{{ foreground }}"
text = "{{ fg }}"
border = "hyprland.active-border-foreground"
border-alpha = 1.0
[notifications]
background = "{{ background }}"
background = "{{ bg }}"
background-alpha = 1.0
text = "{{ foreground }}"
text = "{{ fg }}"
# Conventionally matches the Hyprland active-window border. Border accepts
# either a solid color or the full active-border gradient.
border = "hyprland.active-border"
@@ -156,14 +156,14 @@ countdown = "{{ accent }}"
# companions go from 0 (invisible) to 1 (opaque). scrim is the full-screen
# dim layer behind the card; background is the card itself. Defaults
# mirror [menu] with the card at 0.95 to preserve the legacy translucency.
background = "{{ background }}"
background = "{{ bg }}"
background-alpha = 0.95
text = "{{ foreground }}"
text = "{{ fg }}"
border = "hyprland.active-border-foreground"
border-alpha = 1.0
scrim = "{{ background }}"
scrim = "{{ bg }}"
scrim-alpha = 0.5
selected-background = "{{ foreground }}"
selected-background = "{{ fg }}"
selected-background-alpha = 0.08
selected-text = "{{ accent }}"
selected-border = "hyprland.active-border-foreground"
@@ -173,14 +173,14 @@ selected-border-alpha = 0.25
# Cards, rows, and selected-row treatment. Alpha companions (where present)
# go from 0 (invisible) to 1 (opaque). scrim is the full-screen dim layer
# behind the card. Clipboard and emojis inherit these tokens.
background = "{{ background }}"
background = "{{ bg }}"
background-alpha = 1.0
text = "{{ foreground }}"
text = "{{ fg }}"
border = "hyprland.active-border-foreground"
border-alpha = 1.0
scrim = "{{ background }}"
scrim = "{{ bg }}"
scrim-alpha = 0.5
selected-background = "{{ foreground }}"
selected-background = "{{ fg }}"
selected-background-alpha = 0.08
selected-text = "{{ accent }}"
selected-border = "hyprland.active-border-foreground"
@@ -192,14 +192,14 @@ selected-border-alpha = 0.25
# text-error tints the lock icon, password text, and placeholder when
# authentication fails. border-alpha applies to both border and
# border-error (the two states are mutually exclusive in time).
background = "{{ background }}"
background = "{{ bg }}"
background-alpha = 1.0
text = "{{ foreground }}"
text = "{{ fg }}"
text-error = "{{ red }}"
border = "hyprland.active-border"
border-error = "{{ red }}"
border-alpha = 1.0
scrim = "{{ background }}"
scrim = "{{ bg }}"
scrim-alpha = 0.5
# accent is the lock-icon glyph color + text-selection tint.
accent = "{{ accent }}"
@@ -210,10 +210,10 @@ accent = "{{ accent }}"
# through idle, typing/authenticating, and wrong-password states.
# border-alpha applies to all three border states (they are mutually
# exclusive in time).
background = "{{ background }}"
background = "{{ bg }}"
background-alpha = 0.8
text = "{{ foreground }}"
placeholder = "{{ mix foreground background 34% }}"
text = "{{ fg }}"
placeholder = "{{ mix fg bg 34% }}"
text-error = "{{ red }}"
border = "hyprland.active-border"
border-active = "hyprland.active-border"
@@ -228,10 +228,10 @@ selection-alpha = 0.45
# the full-screen wash. Per-slice dim overlays and text outlines on top
# of the scrim track the foundational background color directly.
# unselected-border-alpha softens carousel slices that aren't selected.
scrim = "{{ background }}"
scrim = "{{ bg }}"
scrim-alpha = 0.5
text = "{{ foreground }}"
text = "{{ fg }}"
selected-border = "{{ accent }}"
selected-border-alpha = 1.0
unselected-border = "{{ foreground }}"
unselected-border = "{{ fg }}"
unselected-border-alpha = 0.28
+119 -119
View File
@@ -6,10 +6,10 @@
"semanticTokenColors": {
"parameter": "{{ cyan }}",
"parameter.declaration": "{{ cyan }}",
"variable": "{{ foreground }}",
"variable.declaration": "{{ foreground }}",
"variable": "{{ fg }}",
"variable.declaration": "{{ fg }}",
"variable.readonly": "{{ bright_yellow }}",
"variable.defaultLibrary": "{{ foreground }}",
"variable.defaultLibrary": "{{ fg }}",
"property": "{{ cyan }}",
"property.declaration": "{{ cyan }}",
"property.readonly": "{{ cyan }}",
@@ -27,7 +27,7 @@
"enumMember": "{{ orange }}",
"type": "{{ yellow }}",
"type.declaration": "{{ yellow }}",
"type.defaultLibrary": "{{ foreground }}",
"type.defaultLibrary": "{{ fg }}",
"typeParameter": "{{ yellow }}",
"namespace": "{{ blue }}",
"macro": "{{ cyan }}",
@@ -42,14 +42,14 @@
"comment.documentation": {"foreground": "{{ muted }}", "fontStyle": "italic"}
},
"colors": {
"foreground": "{{ foreground }}",
"foreground": "{{ fg }}",
"disabledForeground": "{{ dark_fg }}",
"focusBorder": "{{ accent }}80",
"widget.shadow": "{{ bg }}80",
"selection.background": "{{ selection_background }}80",
"descriptionForeground": "{{ muted }}",
"errorForeground": "{{ red }}",
"icon.foreground": "{{ foreground }}",
"icon.foreground": "{{ fg }}",
"sash.hoverBorder": "{{ accent }}",
"textBlockQuote.background": "{{ bg }}",
@@ -65,14 +65,14 @@
"toolbar.activeBackground": "{{ muted }}",
"button.background": "{{ accent }}",
"button.foreground": "{{ background }}",
"button.foreground": "{{ bg }}",
"button.hoverBackground": "{{ blue }}",
"button.secondaryForeground": "{{ foreground }}",
"button.secondaryForeground": "{{ fg }}",
"button.secondaryBackground": "{{ muted }}",
"button.secondaryHoverBackground": "{{ bg }}",
"button.border": "{{ accent }}20",
"checkbox.background": "{{ bg }}",
"checkbox.foreground": "{{ foreground }}",
"checkbox.foreground": "{{ fg }}",
"checkbox.border": "{{ muted }}",
"checkbox.selectBackground": "{{ accent }}",
"checkbox.selectBorder": "{{ accent }}",
@@ -80,15 +80,15 @@
"dropdown.background": "{{ bg }}",
"dropdown.listBackground": "{{ bg }}",
"dropdown.border": "{{ muted }}",
"dropdown.foreground": "{{ foreground }}",
"dropdown.foreground": "{{ fg }}",
"input.background": "{{ bg }}",
"input.border": "{{ muted }}",
"input.foreground": "{{ foreground }}",
"input.foreground": "{{ fg }}",
"input.placeholderForeground": "{{ muted }}",
"inputOption.activeBackground": "{{ accent }}40",
"inputOption.activeBorder": "{{ accent }}",
"inputOption.activeForeground": "{{ foreground }}",
"inputOption.activeForeground": "{{ fg }}",
"inputOption.hoverBackground": "{{ muted }}",
"inputValidation.errorBackground": "{{ red }}20",
"inputValidation.errorForeground": "{{ red }}",
@@ -106,22 +106,22 @@
"scrollbarSlider.hoverBackground": "{{ muted }}80",
"badge.background": "{{ accent }}",
"badge.foreground": "{{ background }}",
"badge.foreground": "{{ bg }}",
"progressBar.background": "{{ accent }}",
"list.activeSelectionBackground": "{{ accent }}30",
"list.activeSelectionForeground": "{{ foreground }}",
"list.activeSelectionIconForeground": "{{ foreground }}",
"list.activeSelectionForeground": "{{ fg }}",
"list.activeSelectionIconForeground": "{{ fg }}",
"list.dropBackground": "{{ accent }}20",
"list.focusBackground": "{{ accent }}20",
"list.focusForeground": "{{ foreground }}",
"list.focusForeground": "{{ fg }}",
"list.focusOutline": "{{ accent }}60",
"list.highlightForeground": "{{ accent }}",
"list.hoverBackground": "{{ bg }}",
"list.hoverForeground": "{{ foreground }}",
"list.hoverForeground": "{{ fg }}",
"list.inactiveSelectionBackground": "{{ muted }}40",
"list.inactiveSelectionForeground": "{{ foreground }}",
"list.inactiveSelectionForeground": "{{ fg }}",
"list.inactiveFocusBackground": "{{ muted }}40",
"list.inactiveFocusOutline": "{{ muted }}",
"list.invalidItemForeground": "{{ red }}",
@@ -137,32 +137,32 @@
"tree.tableColumnsBorder": "{{ muted }}",
"tree.tableOddRowsBackground": "{{ bg }}40",
"activityBar.background": "{{ background }}",
"activityBar.background": "{{ bg }}",
"activityBar.dropBorder": "{{ accent }}",
"activityBar.foreground": "{{ foreground }}",
"activityBar.foreground": "{{ fg }}",
"activityBar.inactiveForeground": "{{ muted }}",
"activityBar.border": "{{ bg }}",
"activityBarBadge.background": "{{ accent }}",
"activityBarBadge.foreground": "{{ background }}",
"activityBarBadge.foreground": "{{ bg }}",
"activityBar.activeBorder": "{{ accent }}",
"activityBar.activeBackground": "{{ bg }}40",
"sideBar.background": "{{ bg }}",
"sideBar.foreground": "{{ foreground }}",
"sideBar.foreground": "{{ fg }}",
"sideBar.border": "{{ bg }}",
"sideBar.dropBackground": "{{ accent }}20",
"sideBarTitle.foreground": "{{ foreground }}",
"sideBarTitle.foreground": "{{ fg }}",
"sideBarSectionHeader.background": "{{ bg }}",
"sideBarSectionHeader.foreground": "{{ foreground }}",
"sideBarSectionHeader.foreground": "{{ fg }}",
"sideBarSectionHeader.border": "{{ muted }}40",
"minimap.findMatchHighlight": "{{ accent }}80",
"minimap.selectionHighlight": "{{ accent }}60",
"minimap.errorHighlight": "{{ red }}",
"minimap.warningHighlight": "{{ yellow }}",
"minimap.background": "{{ background }}",
"minimap.background": "{{ bg }}",
"minimap.selectionOccurrenceHighlight": "{{ accent }}40",
"minimap.foregroundOpacity": "{{ background }}c0",
"minimap.foregroundOpacity": "{{ bg }}c0",
"minimapSlider.background": "{{ muted }}20",
"minimapSlider.hoverBackground": "{{ muted }}40",
"minimapSlider.activeBackground": "{{ muted }}60",
@@ -172,17 +172,17 @@
"editorGroup.border": "{{ muted }}40",
"editorGroup.dropBackground": "{{ accent }}20",
"editorGroup.dropIntoPromptForeground": "{{ foreground }}",
"editorGroup.dropIntoPromptForeground": "{{ fg }}",
"editorGroup.dropIntoPromptBackground": "{{ bg }}",
"editorGroup.dropIntoPromptBorder": "{{ accent }}",
"editorGroupHeader.noTabsBackground": "{{ bg }}",
"editorGroupHeader.tabsBackground": "{{ bg }}",
"editorGroupHeader.tabsBorder": "{{ bg }}",
"editorGroupHeader.border": "{{ bg }}",
"editorGroup.emptyBackground": "{{ background }}",
"tab.activeBackground": "{{ background }}",
"tab.unfocusedActiveBackground": "{{ background }}",
"tab.activeForeground": "{{ foreground }}",
"editorGroup.emptyBackground": "{{ bg }}",
"tab.activeBackground": "{{ bg }}",
"tab.unfocusedActiveBackground": "{{ bg }}",
"tab.activeForeground": "{{ fg }}",
"tab.activeBorder": "{{ accent }}",
"tab.activeBorderTop": "{{ accent }}",
"tab.unfocusedActiveBorder": "{{ muted }}",
@@ -194,22 +194,22 @@
"tab.unfocusedInactiveForeground": "{{ muted }}",
"tab.hoverBackground": "{{ muted }}40",
"tab.unfocusedHoverBackground": "{{ muted }}40",
"tab.hoverForeground": "{{ foreground }}",
"tab.hoverForeground": "{{ fg }}",
"tab.hoverBorder": "{{ accent }}40",
"tab.activeModifiedBorder": "{{ yellow }}",
"tab.inactiveModifiedBorder": "{{ yellow }}80",
"tab.unfocusedActiveModifiedBorder": "{{ yellow }}80",
"tab.unfocusedInactiveModifiedBorder": "{{ yellow }}60",
"tab.lastPinnedBorder": "{{ muted }}",
"editorPane.background": "{{ background }}",
"editorPane.background": "{{ bg }}",
"editor.background": "{{ background }}",
"editor.foreground": "{{ foreground }}",
"editor.background": "{{ bg }}",
"editor.foreground": "{{ fg }}",
"editorLineNumber.foreground": "{{ muted }}",
"editorLineNumber.activeForeground": "{{ foreground }}",
"editorLineNumber.activeForeground": "{{ fg }}",
"editorLineNumber.dimmedForeground": "{{ muted }}80",
"editorCursor.background": "{{ background }}",
"editorCursor.foreground": "{{ cursor }}",
"editorCursor.background": "{{ bg }}",
"editorCursor.foreground": "{{ bright_fg }}",
"editor.selectionBackground": "{{ selection_background }}60",
"editor.selectionForeground": "{{ selection_foreground }}",
"editor.inactiveSelectionBackground": "{{ selection_background }}30",
@@ -282,7 +282,7 @@
"editorBracketPairGuide.background4": "{{ cyan }}30",
"editorBracketPairGuide.background5": "{{ magenta }}30",
"editorBracketPairGuide.background6": "{{ orange }}30",
"editorOverviewRuler.background": "{{ background }}",
"editorOverviewRuler.background": "{{ bg }}",
"editorOverviewRuler.border": "{{ muted }}20",
"editorOverviewRuler.findMatchForeground": "{{ yellow }}80",
"editorOverviewRuler.rangeHighlightForeground": "{{ accent }}60",
@@ -311,9 +311,9 @@
"problemsErrorIcon.foreground": "{{ red }}",
"problemsWarningIcon.foreground": "{{ yellow }}",
"problemsInfoIcon.foreground": "{{ blue }}",
"editorUnnecessaryCode.opacity": "{{ background }}80",
"editorUnnecessaryCode.opacity": "{{ bg }}80",
"editorUnnecessaryCode.border": "{{ muted }}",
"editorGutter.background": "{{ background }}",
"editorGutter.background": "{{ bg }}",
"editorGutter.modifiedBackground": "{{ orange }}",
"editorGutter.addedBackground": "{{ green }}",
"editorGutter.deletedBackground": "{{ red }}",
@@ -343,20 +343,20 @@
"diffEditor.move.border": "{{ cyan }}80",
"diffEditor.moveActive.border": "{{ cyan }}",
"editorWidget.foreground": "{{ foreground }}",
"editorWidget.foreground": "{{ fg }}",
"editorWidget.background": "{{ bg }}",
"editorWidget.border": "{{ muted }}",
"editorWidget.resizeBorder": "{{ accent }}",
"editorSuggestWidget.background": "{{ bg }}",
"editorSuggestWidget.border": "{{ muted }}",
"editorSuggestWidget.foreground": "{{ foreground }}",
"editorSuggestWidget.foreground": "{{ fg }}",
"editorSuggestWidget.focusHighlightForeground": "{{ accent }}",
"editorSuggestWidget.highlightForeground": "{{ accent }}",
"editorSuggestWidget.selectedBackground": "{{ accent }}30",
"editorSuggestWidget.selectedForeground": "{{ foreground }}",
"editorSuggestWidget.selectedIconForeground": "{{ foreground }}",
"editorSuggestWidget.selectedForeground": "{{ fg }}",
"editorSuggestWidget.selectedIconForeground": "{{ fg }}",
"editorSuggestWidgetStatus.foreground": "{{ muted }}",
"editorHoverWidget.foreground": "{{ foreground }}",
"editorHoverWidget.foreground": "{{ fg }}",
"editorHoverWidget.background": "{{ bg }}",
"editorHoverWidget.border": "{{ muted }}",
"editorHoverWidget.highlightForeground": "{{ accent }}",
@@ -381,15 +381,15 @@
"peekViewEditorGutter.background": "{{ bg }}",
"peekViewEditor.matchHighlightBackground": "{{ yellow }}30",
"peekViewEditor.matchHighlightBorder": "{{ yellow }}",
"peekViewResult.background": "{{ background }}",
"peekViewResult.fileForeground": "{{ foreground }}",
"peekViewResult.background": "{{ bg }}",
"peekViewResult.fileForeground": "{{ fg }}",
"peekViewResult.lineForeground": "{{ muted }}",
"peekViewResult.matchHighlightBackground": "{{ yellow }}30",
"peekViewResult.selectionBackground": "{{ accent }}30",
"peekViewResult.selectionForeground": "{{ foreground }}",
"peekViewResult.selectionForeground": "{{ fg }}",
"peekViewTitle.background": "{{ bg }}",
"peekViewTitleDescription.foreground": "{{ muted }}",
"peekViewTitleLabel.foreground": "{{ foreground }}",
"peekViewTitleLabel.foreground": "{{ fg }}",
"merge.currentContentBackground": "{{ cyan }}20",
"merge.currentHeaderBackground": "{{ cyan }}40",
@@ -411,69 +411,69 @@
"mergeEditor.changeBase.background": "{{ muted }}20",
"mergeEditor.changeBase.word.background": "{{ muted }}40",
"panel.background": "{{ background }}",
"panel.background": "{{ bg }}",
"panel.border": "{{ muted }}40",
"panel.dropBorder": "{{ accent }}",
"panelTitle.activeBorder": "{{ accent }}",
"panelTitle.activeForeground": "{{ foreground }}",
"panelTitle.activeForeground": "{{ fg }}",
"panelTitle.inactiveForeground": "{{ muted }}",
"panelInput.border": "{{ muted }}",
"panelSection.border": "{{ muted }}40",
"panelSection.dropBackground": "{{ accent }}20",
"panelSectionHeader.background": "{{ bg }}",
"panelSectionHeader.foreground": "{{ foreground }}",
"panelSectionHeader.foreground": "{{ fg }}",
"panelSectionHeader.border": "{{ muted }}40",
"outputView.background": "{{ background }}",
"outputView.background": "{{ bg }}",
"outputViewStickyScroll.background": "{{ bg }}",
"statusBar.background": "{{ bg }}",
"statusBar.foreground": "{{ foreground }}",
"statusBar.foreground": "{{ fg }}",
"statusBar.border": "{{ bg }}",
"statusBar.debuggingBackground": "{{ yellow }}",
"statusBar.debuggingForeground": "{{ background }}",
"statusBar.debuggingForeground": "{{ bg }}",
"statusBar.debuggingBorder": "{{ yellow }}",
"statusBar.noFolderBackground": "{{ bg }}",
"statusBar.noFolderForeground": "{{ foreground }}",
"statusBar.noFolderForeground": "{{ fg }}",
"statusBar.noFolderBorder": "{{ bg }}",
"statusBar.focusBorder": "{{ accent }}",
"statusBarItem.activeBackground": "{{ muted }}",
"statusBarItem.hoverBackground": "{{ muted }}60",
"statusBarItem.hoverForeground": "{{ foreground }}",
"statusBarItem.prominentForeground": "{{ foreground }}",
"statusBarItem.hoverForeground": "{{ fg }}",
"statusBarItem.prominentForeground": "{{ fg }}",
"statusBarItem.prominentBackground": "{{ accent }}",
"statusBarItem.prominentHoverBackground": "{{ accent }}80",
"statusBarItem.remoteBackground": "{{ accent }}",
"statusBarItem.remoteForeground": "{{ background }}",
"statusBarItem.remoteForeground": "{{ bg }}",
"statusBarItem.remoteHoverBackground": "{{ accent }}80",
"statusBarItem.errorBackground": "{{ red }}",
"statusBarItem.errorForeground": "{{ background }}",
"statusBarItem.errorForeground": "{{ bg }}",
"statusBarItem.errorHoverBackground": "{{ red }}80",
"statusBarItem.warningBackground": "{{ yellow }}",
"statusBarItem.warningForeground": "{{ background }}",
"statusBarItem.warningForeground": "{{ bg }}",
"statusBarItem.warningHoverBackground": "{{ yellow }}80",
"statusBarItem.compactHoverBackground": "{{ muted }}",
"statusBarItem.focusBorder": "{{ accent }}",
"titleBar.activeBackground": "{{ bg }}",
"titleBar.activeForeground": "{{ foreground }}",
"titleBar.activeForeground": "{{ fg }}",
"titleBar.inactiveBackground": "{{ bg }}",
"titleBar.inactiveForeground": "{{ muted }}",
"titleBar.border": "{{ bg }}",
"menubar.selectionForeground": "{{ foreground }}",
"menubar.selectionForeground": "{{ fg }}",
"menubar.selectionBackground": "{{ accent }}30",
"menubar.selectionBorder": "{{ accent }}00",
"menu.foreground": "{{ foreground }}",
"menu.foreground": "{{ fg }}",
"menu.background": "{{ bg }}",
"menu.selectionForeground": "{{ foreground }}",
"menu.selectionForeground": "{{ fg }}",
"menu.selectionBackground": "{{ accent }}30",
"menu.selectionBorder": "{{ accent }}00",
"menu.separatorBackground": "{{ muted }}",
"menu.border": "{{ muted }}",
"commandCenter.foreground": "{{ foreground }}",
"commandCenter.activeForeground": "{{ foreground }}",
"commandCenter.foreground": "{{ fg }}",
"commandCenter.activeForeground": "{{ fg }}",
"commandCenter.background": "{{ bg }}",
"commandCenter.activeBackground": "{{ muted }}",
"commandCenter.border": "{{ muted }}",
@@ -483,10 +483,10 @@
"commandCenter.debuggingBackground": "{{ yellow }}20",
"notificationCenter.border": "{{ muted }}",
"notificationCenterHeader.foreground": "{{ foreground }}",
"notificationCenterHeader.foreground": "{{ fg }}",
"notificationCenterHeader.background": "{{ bg }}",
"notificationToast.border": "{{ muted }}",
"notifications.foreground": "{{ foreground }}",
"notifications.foreground": "{{ fg }}",
"notifications.background": "{{ bg }}",
"notifications.border": "{{ muted }}",
"notificationLink.foreground": "{{ accent }}",
@@ -495,18 +495,18 @@
"notificationsInfoIcon.foreground": "{{ blue }}",
"banner.background": "{{ accent }}20",
"banner.foreground": "{{ foreground }}",
"banner.foreground": "{{ fg }}",
"banner.iconForeground": "{{ accent }}",
"extensionButton.prominentBackground": "{{ accent }}",
"extensionButton.prominentForeground": "{{ background }}",
"extensionButton.prominentForeground": "{{ bg }}",
"extensionButton.prominentHoverBackground": "{{ accent }}80",
"extensionButton.background": "{{ muted }}",
"extensionButton.foreground": "{{ foreground }}",
"extensionButton.foreground": "{{ fg }}",
"extensionButton.hoverBackground": "{{ muted }}80",
"extensionButton.separator": "{{ background }}",
"extensionButton.separator": "{{ bg }}",
"extensionBadge.remoteBackground": "{{ accent }}",
"extensionBadge.remoteForeground": "{{ background }}",
"extensionBadge.remoteForeground": "{{ bg }}",
"extensionIcon.starForeground": "{{ yellow }}",
"extensionIcon.verifiedForeground": "{{ cyan }}",
"extensionIcon.preReleaseForeground": "{{ yellow }}",
@@ -515,21 +515,21 @@
"pickerGroup.border": "{{ muted }}",
"pickerGroup.foreground": "{{ accent }}",
"quickInput.background": "{{ bg }}",
"quickInput.foreground": "{{ foreground }}",
"quickInput.foreground": "{{ fg }}",
"quickInputList.focusBackground": "{{ accent }}30",
"quickInputList.focusForeground": "{{ foreground }}",
"quickInputList.focusIconForeground": "{{ foreground }}",
"quickInputList.focusForeground": "{{ fg }}",
"quickInputList.focusIconForeground": "{{ fg }}",
"quickInputTitle.background": "{{ bg }}",
"keybindingLabel.background": "{{ muted }}40",
"keybindingLabel.foreground": "{{ foreground }}",
"keybindingLabel.foreground": "{{ fg }}",
"keybindingLabel.border": "{{ muted }}",
"keybindingLabel.bottomBorder": "{{ muted }}",
"keybindingTable.headerBackground": "{{ bg }}",
"keybindingTable.rowsBackground": "{{ bg }}40",
"terminal.background": "{{ background }}",
"terminal.foreground": "{{ foreground }}",
"terminal.background": "{{ bg }}",
"terminal.foreground": "{{ fg }}",
"terminal.border": "{{ muted }}40",
"terminal.selectionBackground": "{{ selection_background }}60",
"terminal.selectionForeground": "{{ selection_foreground }}",
@@ -539,8 +539,8 @@
"terminal.findMatchHighlightBackground": "{{ yellow }}25",
"terminal.findMatchHighlightBorder": "{{ yellow }}60",
"terminal.hoverHighlightBackground": "{{ accent }}20",
"terminalCursor.background": "{{ background }}",
"terminalCursor.foreground": "{{ cursor }}",
"terminalCursor.background": "{{ bg }}",
"terminalCursor.foreground": "{{ bright_fg }}",
"terminal.ansiBlack": "{{ bg }}",
"terminal.ansiRed": "{{ red }}",
"terminal.ansiGreen": "{{ green }}",
@@ -561,20 +561,20 @@
"terminalCommandDecoration.defaultBackground": "{{ muted }}",
"terminalCommandDecoration.successBackground": "{{ green }}",
"terminalCommandDecoration.errorBackground": "{{ red }}",
"terminalOverviewRuler.cursorForeground": "{{ cursor }}",
"terminalOverviewRuler.cursorForeground": "{{ bright_fg }}",
"terminalOverviewRuler.findMatchForeground": "{{ yellow }}",
"terminalStickyScroll.background": "{{ bg }}",
"terminalStickyScrollHover.background": "{{ muted }}40",
"debugToolBar.background": "{{ bg }}",
"debugToolBar.border": "{{ muted }}",
"debugView.stateLabelForeground": "{{ foreground }}",
"debugView.stateLabelForeground": "{{ fg }}",
"debugView.stateLabelBackground": "{{ accent }}30",
"debugView.valueChangedHighlight": "{{ cyan }}40",
"debugView.exceptionLabelForeground": "{{ background }}",
"debugView.exceptionLabelForeground": "{{ bg }}",
"debugView.exceptionLabelBackground": "{{ red }}",
"debugTokenExpression.name": "{{ magenta }}",
"debugTokenExpression.value": "{{ foreground }}",
"debugTokenExpression.value": "{{ fg }}",
"debugTokenExpression.string": "{{ green }}",
"debugTokenExpression.boolean": "{{ orange }}",
"debugTokenExpression.number": "{{ orange }}",
@@ -594,14 +594,14 @@
"testing.message.info.decorationForeground": "{{ blue }}",
"testing.message.info.lineBackground": "{{ blue }}15",
"welcomePage.background": "{{ background }}",
"welcomePage.background": "{{ bg }}",
"welcomePage.tileBackground": "{{ bg }}",
"welcomePage.tileHoverBackground": "{{ muted }}40",
"welcomePage.tileBorder": "{{ muted }}",
"welcomePage.progress.background": "{{ muted }}",
"welcomePage.progress.foreground": "{{ accent }}",
"walkThrough.embeddedEditorBackground": "{{ bg }}",
"walkthrough.stepTitle.foreground": "{{ foreground }}",
"walkthrough.stepTitle.foreground": "{{ fg }}",
"gitDecoration.addedResourceForeground": "{{ green }}",
"gitDecoration.modifiedResourceForeground": "{{ orange }}",
@@ -614,21 +614,21 @@
"gitDecoration.conflictingResourceForeground": "{{ yellow }}",
"gitDecoration.submoduleResourceForeground": "{{ magenta }}",
"settings.headerForeground": "{{ foreground }}",
"settings.headerForeground": "{{ fg }}",
"settings.modifiedItemIndicator": "{{ accent }}",
"settings.dropdownBackground": "{{ bg }}",
"settings.dropdownForeground": "{{ foreground }}",
"settings.dropdownForeground": "{{ fg }}",
"settings.dropdownBorder": "{{ muted }}",
"settings.dropdownListBorder": "{{ muted }}",
"settings.checkboxBackground": "{{ bg }}",
"settings.checkboxForeground": "{{ foreground }}",
"settings.checkboxForeground": "{{ fg }}",
"settings.checkboxBorder": "{{ muted }}",
"settings.rowHoverBackground": "{{ bg }}",
"settings.textInputBackground": "{{ bg }}",
"settings.textInputForeground": "{{ foreground }}",
"settings.textInputForeground": "{{ fg }}",
"settings.textInputBorder": "{{ muted }}",
"settings.numberInputBackground": "{{ bg }}",
"settings.numberInputForeground": "{{ foreground }}",
"settings.numberInputForeground": "{{ fg }}",
"settings.numberInputBorder": "{{ muted }}",
"settings.focusedRowBackground": "{{ accent }}10",
"settings.focusedRowBorder": "{{ accent }}40",
@@ -637,9 +637,9 @@
"settings.settingsHeaderHoverForeground": "{{ accent }}",
"breadcrumb.foreground": "{{ muted }}",
"breadcrumb.background": "{{ background }}",
"breadcrumb.focusForeground": "{{ foreground }}",
"breadcrumb.activeSelectionForeground": "{{ foreground }}",
"breadcrumb.background": "{{ bg }}",
"breadcrumb.focusForeground": "{{ fg }}",
"breadcrumb.activeSelectionForeground": "{{ fg }}",
"breadcrumbPicker.background": "{{ bg }}",
"editor.snippetTabstopHighlightBackground": "{{ accent }}20",
@@ -656,9 +656,9 @@
"symbolIcon.enumeratorForeground": "{{ yellow }}",
"symbolIcon.enumeratorMemberForeground": "{{ orange }}",
"symbolIcon.eventForeground": "{{ yellow }}",
"symbolIcon.fieldForeground": "{{ foreground }}",
"symbolIcon.fileForeground": "{{ foreground }}",
"symbolIcon.folderForeground": "{{ foreground }}",
"symbolIcon.fieldForeground": "{{ fg }}",
"symbolIcon.fileForeground": "{{ fg }}",
"symbolIcon.folderForeground": "{{ fg }}",
"symbolIcon.functionForeground": "{{ blue }}",
"symbolIcon.interfaceForeground": "{{ yellow }}",
"symbolIcon.keyForeground": "{{ bright_magenta }}",
@@ -671,12 +671,12 @@
"symbolIcon.objectForeground": "{{ yellow }}",
"symbolIcon.operatorForeground": "{{ bright_blue }}",
"symbolIcon.packageForeground": "{{ yellow }}",
"symbolIcon.propertyForeground": "{{ foreground }}",
"symbolIcon.propertyForeground": "{{ fg }}",
"symbolIcon.referenceForeground": "{{ bright_magenta }}",
"symbolIcon.snippetForeground": "{{ green }}",
"symbolIcon.stringForeground": "{{ green }}",
"symbolIcon.structForeground": "{{ yellow }}",
"symbolIcon.textForeground": "{{ foreground }}",
"symbolIcon.textForeground": "{{ fg }}",
"symbolIcon.typeParameterForeground": "{{ yellow }}",
"symbolIcon.unitForeground": "{{ orange }}",
"symbolIcon.variableForeground": "{{ bright_magenta }}",
@@ -699,10 +699,10 @@
"debugConsole.infoForeground": "{{ blue }}",
"debugConsole.warningForeground": "{{ yellow }}",
"debugConsole.errorForeground": "{{ red }}",
"debugConsole.sourceForeground": "{{ foreground }}",
"debugConsole.sourceForeground": "{{ fg }}",
"debugConsoleInputIcon.foreground": "{{ accent }}",
"notebook.editorBackground": "{{ background }}",
"notebook.editorBackground": "{{ bg }}",
"notebook.cellBorderColor": "{{ muted }}40",
"notebook.cellHoverBackground": "{{ bg }}40",
"notebook.cellInsertionIndicator": "{{ accent }}",
@@ -724,7 +724,7 @@
"notebookStatusSuccessIcon.foreground": "{{ green }}",
"notebookEditorOverviewRuler.runningCellForeground": "{{ accent }}",
"charts.foreground": "{{ foreground }}",
"charts.foreground": "{{ fg }}",
"charts.lines": "{{ muted }}",
"charts.red": "{{ red }}",
"charts.blue": "{{ blue }}",
@@ -746,7 +746,7 @@
"inlineChatInput.border": "{{ muted }}",
"inlineChatInput.focusBorder": "{{ accent }}",
"inlineChatInput.placeholderForeground": "{{ muted }}",
"inlineChatInput.background": "{{ background }}",
"inlineChatInput.background": "{{ bg }}",
"inlineChatDiff.inserted": "{{ green }}20",
"inlineChatDiff.removed": "{{ red }}20",
@@ -766,7 +766,7 @@
"name": "Variable",
"scope": ["variable", "string constant.other.placeholder"],
"settings": {
"foreground": "{{ foreground }}"
"foreground": "{{ fg }}"
}
},
{
@@ -867,7 +867,7 @@
"name": "Type Builtin",
"scope": ["storage.type.primitive", "support.type"],
"settings": {
"foreground": "{{ foreground }}"
"foreground": "{{ fg }}"
}
},
{
@@ -1016,7 +1016,7 @@
"name": "Tag Attribute",
"scope": ["entity.other.attribute-name"],
"settings": {
"foreground": "{{ foreground }}"
"foreground": "{{ fg }}"
}
},
{
@@ -1030,7 +1030,7 @@
"name": "CSS Value",
"scope": ["support.constant.property-value.css", "meta.property-value.css"],
"settings": {
"foreground": "{{ foreground }}"
"foreground": "{{ fg }}"
}
},
{
@@ -1109,7 +1109,7 @@
"name": "Markdown Bold",
"scope": ["markup.bold", "punctuation.definition.bold.markdown"],
"settings": {
"foreground": "{{ foreground }}",
"foreground": "{{ fg }}",
"fontStyle": "bold"
}
},
@@ -1117,7 +1117,7 @@
"name": "Markdown Italic",
"scope": ["markup.italic", "punctuation.definition.italic.markdown"],
"settings": {
"foreground": "{{ foreground }}",
"foreground": "{{ fg }}",
"fontStyle": "italic"
}
},
@@ -1175,7 +1175,7 @@
"name": "This/Self",
"scope": ["variable.language.this", "variable.language.self", "variable.language.special.self"],
"settings": {
"foreground": "{{ foreground }}",
"foreground": "{{ fg }}",
"fontStyle": "italic"
}
},
@@ -1183,7 +1183,7 @@
"name": "Object Keys",
"scope": ["meta.object-literal.key", "string.unquoted.label.js"],
"settings": {
"foreground": "{{ foreground }}"
"foreground": "{{ fg }}"
}
},
{
@@ -1205,7 +1205,7 @@
"name": "Shell Variable",
"scope": ["variable.other.normal.shell", "variable.other.positional.shell", "variable.other.bracket.shell"],
"settings": {
"foreground": "{{ foreground }}"
"foreground": "{{ fg }}"
}
},
{
@@ -1268,7 +1268,7 @@
"name": "Make Variable",
"scope": ["variable.other.makefile"],
"settings": {
"foreground": "{{ foreground }}"
"foreground": "{{ fg }}"
}
},
{
@@ -1282,7 +1282,7 @@
"name": "Python Self",
"scope": ["variable.parameter.function.language.special.self.python"],
"settings": {
"foreground": "{{ foreground }}",
"foreground": "{{ fg }}",
"fontStyle": "italic"
}
},
@@ -1298,7 +1298,7 @@
"name": "PHP Variable",
"scope": ["variable.other.php", "punctuation.definition.variable.php"],
"settings": {
"foreground": "{{ foreground }}"
"foreground": "{{ fg }}"
}
},
{
@@ -1333,7 +1333,7 @@
"name": "GraphQL Field",
"scope": ["variable.graphql", "variable.other.graphql"],
"settings": {
"foreground": "{{ foreground }}"
"foreground": "{{ fg }}"
}
}
]
+2 -2
View File
@@ -1,2 +1,2 @@
@define-color foreground {{ foreground }};
@define-color background {{ background }};
@define-color foreground {{ fg }};
@define-color background {{ bg }};
+30 -36
View File
@@ -42,6 +42,11 @@ Three layers populate `$HOME`:
`/etc/skel` only fires at user creation. Existing users picking up new
defaults must use the resync command.
Current generated theme state lives under
`~/.local/state/omarchy/current/`. Keep `~/.config/omarchy/` for files a user
may intentionally version in a dotfile manager, such as user themes, hooks,
shell layout, plugin sources, and themed template overrides.
## Build-time map (repo → installed paths)
```
@@ -54,16 +59,15 @@ bin/omarchy-debug,
bin/omarchy-debug-idle,
bin/omarchy-upload-log ──► omarchy-settings /usr/bin/ (needed before omarchy is installed)
default/libalpm/hooks/00-omarchy-update-guard.hook
──► omarchy /usr/share/libalpm/hooks/00-omarchy-update-guard.hook
default/libalpm/hooks/*.hook
──► omarchy /usr/share/libalpm/hooks/*.hook
install/** ──► omarchy /usr/share/omarchy/install/
migrations/system/** ──► omarchy /usr/share/omarchy/migrations/system/
migrations/user/** ──► omarchy /usr/share/omarchy/migrations/user/
migrations/** ──► omarchy /usr/share/omarchy/migrations/
themes/** ──► omarchy /usr/share/omarchy/themes/
shell/** ──► omarchy /usr/share/omarchy/shell/
version ──► omarchy /usr/share/omarchy/version
+ /etc/skel/.local/state/omarchy/migrations/user/*
+ /etc/skel/.local/state/omarchy/migrations/*
config/** ──► omarchy-settings /etc/skel/.config/** (seeds new users)
/usr/share/omarchy/config/** (resync source)
@@ -159,8 +163,8 @@ It only does the things `/etc/skel` can't:
`omarchy dev link` against a dev checkout repoints them correctly.
- `xdg-user-dirs-update` (Templates/Public/Desktop folded back into `$HOME`)
and `~/.config/gtk-3.0/bookmarks` (needs `$HOME` expansion).
- Sync `XKBLAYOUT` / `XKBVARIANT` from `/etc/vconsole.conf` into
`~/.config/hypr/input.lua`.
- Hyprland's package-owned default input reads `XKBLAYOUT` / `XKBVARIANT`
from `/etc/vconsole.conf`; no per-user Hyprland config rewrite is needed.
- `xdg-settings set default-web-browser chromium.desktop` and
`xdg-mime default HEY.desktop x-scheme-handler/mailto` (XDG-aware paths).
- `omarchy-refresh-applications` (composes generated `.desktop` launchers).
@@ -180,37 +184,26 @@ the root-side work.
See [`migrations.md`](migrations.md) for the full migration model, authoring
guidelines, and troubleshooting notes.
Omarchy migrations are split by scope:
- `migrations/system/*.sh` — root, noninteractive, safe to run from pacman.
The `omarchy` package `post_upgrade()` runs `omarchy-migrate-system` after an
`omarchy` package upgrade, so even explicit direct-pacman bypasses still get
system migrations applied. Completion state lives in
`/var/lib/omarchy/migrations/system/`.
- `migrations/user/*.sh` — current user/session, may be interactive, and may
touch `~/.config`, `~/.local`, user systemd, DBus, browser prefs, etc.
Completion state lives in `~/.local/state/omarchy/migrations/user/`.
Package upgrades happen as root, but user migrations must run as each user and
may be interactive. There is no root-owned "user migration required" marker. A
user migration is pending only when a script exists in `migrations/user/` and
that user's matching state file is missing.
Omarchy migrations live in `migrations/*.sh` and run per-user through
`omarchy-migrate`. Completion state lives in
`~/.local/state/omarchy/migrations/`, so every user gets a chance to run every
migration. Migrations run as the user; privileged work should invoke the
appropriate helper or privilege prompt. Migrations must be idempotent;
machine-wide repairs should no-op when another user already applied them.
Each graphical user has `omarchy-update-user-notify.path` watching the packaged
user migration directory. When that directory changes, or when the path unit is
migration directory. When that directory changes, or when the path unit is
started on login, `omarchy-update-user-notify.service` runs
`omarchy-migrate-notify` as that user. The notifier checks
`omarchy-migrate --pending user`. If this user has missing migration state, it
shows a notification that opens a terminal for `omarchy-migrate`. The notifier
never runs user migrations in the background.
`omarchy-migrate --pending`. If this user has missing migration state, it shows a
notification that opens a terminal for `omarchy-migrate`. The notifier never runs
migrations in the background.
`omarchy-migrate` waits for any active pacman transaction to finish, runs
pending system migrations, then runs pending user migrations. It does not need
`--force`; migrations happen when state files are missing. For watchers and
diagnostics, `omarchy-migrate --pending [all|system|user]` prints
scope-prefixed pending migration filenames and exits `0` when any are pending.
`omarchy update` runs `omarchy-migrate` after the package transaction in the
already-visible update terminal, then runs `omarchy-hook post-update`.
`omarchy-migrate` waits for any active pacman transaction to finish, then runs
pending migrations. It does not need `--force`; migrations happen when state
files are missing. `omarchy update` runs `omarchy-migrate` after the package
transaction in the already-visible update terminal, then runs
`omarchy-hook post-update`.
## First-run (`omarchy-first-run`)
@@ -281,7 +274,8 @@ return to the packaged default.
| Per-user file that's static but lives outside `~/.config` | `default/`, then add `install -Dm644 ... $pkgdir/etc/skel/...` in `omarchy-settings` PKGBUILD |
| Runtime tweak that needs `$HOME` or live system state | extend `omarchy-finalize-user`, or add a per-user leaf under `install/user/` and wire into `install/user/all.sh` |
| One-time root-side setup step | `install/config/*.sh` or `install/hardware/*.sh`, wire into `omarchy-setup-system` or `install/hardware/all.sh` |
| Noninteractive root fix for existing installs | `migrations/system/<unix-timestamp>.sh` |
| User/session fix for existing installs | `migrations/user/<unix-timestamp>.sh` |
| One-time fix for existing installs | `migrations/<unix-timestamp>.sh` |
| User-facing `omarchy-*` command | `bin/omarchy-<group>-<verb>` — see `GROUP_DESCRIPTIONS` in `bin/omarchy` |
| New theme | `themes/<name>/` (+ matching templates under `default/themed/` if they need theme colors) |
| New stock theme | `themes/<name>/` (+ matching templates under `default/themed/` if they need theme colors) |
| User-installed theme | `~/.config/omarchy/themes/<name>/` |
| Generated current theme/background state | `~/.local/state/omarchy/current/` |
+58 -208
View File
@@ -4,59 +4,30 @@ Omarchy migrations are one-time repair scripts for existing installs. They are
used when a package update needs to change state that pacman cannot safely own by
itself.
## The two migration scopes
## Migration model
Omarchy migrations are split by execution context:
Migrations live in:
```text
migrations/system/*.sh
migrations/user/*.sh
migrations/*.sh
```
### System migrations
They run as the current Omarchy user through `omarchy-migrate`, normally during
`omarchy update`. A migration may touch user/session state (`~/.config`,
`~/.local`, user systemd, browser/editor prefs, DBus/session state), and may also
perform machine-wide repairs when needed.
System migrations run as root and must be noninteractive.
Use system migrations for machine-wide state, for example:
- `/etc` drop-ins or legacy config cleanup
- `/boot` / bootloader cleanup
- systemd system units or service state
- hardware quirks
- package-owned layout transitions
Note that it's not necessary to write a migration for any file that will be package-owned.
State lives in:
Completion state is per-user:
```text
/var/lib/omarchy/migrations/system/<migration filename>
~/.local/state/omarchy/migrations/<migration filename>
```
### User migrations
User migrations run as the current graphical/login user and may be interactive.
Use user migrations for per-user or session-aware state, for example:
- `~/.config` changes
- `~/.local` state
- user systemd units
- browser/editor preferences
- DBus/session-dependent updates
- prompts that need to happen in a visible terminal
State lives in:
```text
~/.local/state/omarchy/migrations/user/<migration filename>
```
A user migration is pending for a given user only when the script exists under
`/usr/share/omarchy/migrations/user/` and that user's matching state file is
missing.
There is no global root-owned “user migrations required” queue.
That means every user gets a chance to run every migration. Migrations run as the
user; privileged operations should invoke the appropriate helper or privilege
prompt themselves. Migrations must be idempotent: if one user already applied a
machine-wide repair, the same migration running for another user should detect
that and no-op.
## When migrations run
@@ -69,15 +40,8 @@ omarchy-migrate
omarchy-hook post-update
```
`omarchy-migrate`:
1. waits for any active pacman transaction to finish
2. runs pending system migrations
3. runs pending user migrations for the current user
System migrations usually already ran during the pacman transaction via the
`omarchy` package `post_upgrade()`, but the second check is intentional and
idempotent.
`omarchy-migrate` waits for any active pacman transaction to finish, then runs
all pending migrations for the current user in the visible update terminal.
### During direct pacman updates
@@ -87,28 +51,21 @@ Raw `sudo pacman -Syu` is guarded. Users should normally run:
omarchy update
```
If a user explicitly bypasses the guard, the `omarchy` package still runs system
migrations from `post_upgrade()`:
If a user explicitly bypasses the guard, user sessions watch the packaged
migration directory and run a notifier. The notifier checks:
```bash
omarchy-migrate-system
omarchy-migrate --pending
```
User migrations are never run by pacman. Instead, the user session watches the
packaged user migration directory and runs a notifier. The notifier checks:
```bash
omarchy-migrate --pending user
```
If that user has pending user migrations, it shows a notification that opens a
If that user has pending migrations, it shows a notification that opens a
terminal for:
```bash
omarchy-migrate
```
The notifier never runs user migrations silently in the background.
The notifier never runs migrations silently in the background.
### Manually
@@ -126,179 +83,72 @@ Use:
```bash
omarchy-migrate --pending
omarchy-migrate --pending system
omarchy-migrate --pending user
```
Exit behavior:
- `0` — one or more matching migrations are pending
- non-zero — no matching migrations are pending
- `0` — one or more migrations are pending
- non-zero — no migrations are pending
Output is scope-prefixed:
Output is one pending migration per line:
```text
system/100-system.sh
user/200-user.sh
1781158082.sh
```
The lower-level runners also support `--pending` and print filenames without the
scope prefix:
## Creating a migration
Use the helper:
```bash
omarchy-migrate-system --pending
omarchy-migrate-user --pending
omarchy-dev-add-migration --no-edit
```
Prefer `omarchy-migrate --pending ...` in user-facing tools and watchers.
This creates:
## Writing migrations
Create a migration with:
```bash
omarchy-dev-add-migration system --no-edit
omarchy-dev-add-migration user --no-edit
```text
migrations/<unix timestamp>.sh
```
Choose the scope based on the state being changed, not on convenience.
New migration format:
### File format
- File permissions must be `0644` (`-rw-r--r--`). Migration runners execute them
with `bash -euo pipefail`, not through executable bits.
- No shebang line.
- Start with an `echo` describing what the migration does.
- Use `$OMARCHY_PATH` to reference the Omarchy directory.
- Be idempotent. Check existing state before changing it.
- Use helper commands such as `omarchy-cmd-present`, `omarchy-cmd-missing`,
`omarchy-pkg-add`, `omarchy-pkg-drop`, `omarchy-pkg-present`, and
`omarchy-pkg-missing` when appropriate.
Migrations are plain shell files:
- filename: unix timestamp, generated by `omarchy-dev-add-migration`
- mode: `0644`
- no shebang
- start with an `echo` describing the migration
- use `$OMARCHY_PATH` for Omarchy-owned files
- should be idempotent
- should be as simple as possible to accomplish the task
Example system migration:
Example:
```bash
echo "Remove legacy Limine config"
echo "Relink Neovim theme to Omarchy current state"
rm -f /boot/EFI/limine/limine.conf
theme_link="$HOME/.config/nvim/lua/plugins/theme.lua"
current_relative_target="../../../../.local/state/omarchy/current/theme/neovim.lua"
[[ -L $theme_link ]] || exit 0
ln -sfn "$current_relative_target" "$theme_link"
```
Example user migration:
## Testing migrations
Run a migration against a temporary home when possible:
```bash
echo "Refresh user app launchers"
omarchy-refresh-applications
HOME=$(mktemp -d) bash -euo pipefail migrations/<timestamp>.sh
```
### Execution model
Migration runners execute scripts with strict shell settings:
```bash
bash -euo pipefail <migration>
```
`$OMARCHY_PATH` is exported into the migration process.
A migration is marked complete only after the script exits successfully. If it
fails, the marker is not written and the migration will be retried later.
Because failed migrations can be retried after doing partial work, migrations
must be idempotent. Prefer operations that are safe to run more than once:
```bash
mkdir -p ~/.config/example
rm -f ~/.config/example/legacy.conf
install -Dm644 "$OMARCHY_PATH/default/example.conf" ~/.config/example/example.conf
systemctl --user enable --now some-unit.service || true
```
Use `|| true` only when a failure is genuinely acceptable.
## What belongs in a migration?
Good migration uses:
- deleting or moving legacy files that block the packaged layout
- marking or enabling new service state
- migrating old config paths to new config paths
- repairing known bad state from an earlier Omarchy release
- one-time compatibility for existing installs
Bad migration uses:
- fresh-install setup that belongs in `install/` or `/etc/skel`
- package installation that belongs in package dependencies or package lists
- recurring maintenance
- arbitrary cleanup that should be a user command
- pre-4 upgrade work that belongs in `omarchy-upgrade-to-4`
- hidden user/session work from pacman
## Fresh installs and new users
Fresh users created from the packaged layout should not have to run historical
user migrations. The package seeds user migration markers into `/etc/skel` so
new users start with shipped user migrations marked complete.
The ISO/finalization path also marks shipped user migrations complete for the
freshly-created install user when running:
```bash
omarchy-finalize-user --first-install
```
Existing users keep their own migration state and run only migrations whose
state files are missing.
## Troubleshooting
### See what is pending
```bash
omarchy-migrate --pending
```
### Retry failed migrations
Fix the underlying problem, then run:
To rerun a migration locally, remove its marker and run the migrator:
```bash
rm ~/.local/state/omarchy/migrations/<migration>.sh
omarchy-migrate
```
A failed migration is not marked complete, so it will retry.
### Re-run a completed migration manually
Remove its marker, then run the migration command again:
```bash
rm ~/.local/state/omarchy/migrations/user/<migration>.sh
omarchy-migrate
```
For system migrations:
```bash
sudo rm /var/lib/omarchy/migrations/system/<migration>.sh
omarchy-migrate
```
Be careful: migrations should be idempotent, but manually removing markers is an
advanced troubleshooting step.
## Agent checklist
Before adding a migration:
1. Is this a one-time repair for existing installs?
2. Is it system state or user/session state?
3. Can it run safely more than once?
4. Will it fail loudly if the important work fails?
5. Does it avoid hidden interactive work from pacman?
6. Does it belong in `omarchy-upgrade-to-4` instead?
7. Did you add or update tests if behavior changed?
If the answer to any of these is unclear, stop and ask before adding the
migration.
Omarchy 4.0 is upgraded through `bin/omarchy-upgrade-to-4`, not through the
normal migration runner. Do not add compatibility migrations for old installer
layouts; put pre-4 package-layout transition work in the upgrade command instead.
+4
View File
@@ -143,6 +143,10 @@ sizing in `themes/<name>/shell.toml`. Defaults are generated from
`default/themed/shell.toml.tpl`; a theme may also drop a hand-written
`shell.toml` next to its `colors.toml` to replace the generated file.
`colors.toml` uses `fg` and `bg` for the foundational text/background
palette. The shell exposes those to QML as `Color.foreground` and
`Color.background`, so shell roles still use the readable role names.
The shell exposes these tokens to QML via two singletons in
`qs.Commons`:
+31 -18
View File
@@ -1,22 +1,23 @@
# Omarchy theming
Omarchy themes live under `themes/<name>/` in the source tree, with optional
user themes under `~/.config/omarchy/themes/<name>/`. A theme normally starts
with a `colors.toml`; Omarchy generates the rest of the theme files from
Omarchy themes live under `themes/<name>/` in the source tree (installed at
`/usr/share/omarchy/themes/<name>/`), with optional user themes under
`~/.config/omarchy/themes/<name>/`. A theme normally starts with a
`colors.toml`; Omarchy generates the active theme files from
`default/themed/*.tpl` when `omarchy-theme-set <name>` runs.
## Theme activation flow
`omarchy-theme-set <name>` builds a clean staging directory at
`~/.config/omarchy/current/next-theme`:
`~/.local/state/omarchy/current/next-theme`:
1. Copy the first-party theme from `themes/<name>/`.
2. Overlay any user theme files from `~/.config/omarchy/themes/<name>/`.
3. If needed, generate `colors.toml` from `alacritty.toml`.
4. Run `omarchy-theme-set-templates` to render templates into the staging
theme.
5. Move the staging theme into `~/.config/omarchy/current/theme` and notify the
running shell.
5. Move the staging theme into `~/.local/state/omarchy/current/theme`, write
`~/.local/state/omarchy/current/theme.name`, and notify the running shell.
Template rendering only happens when the staged theme has `colors.toml`.
Existing files are never overwritten by a template, so a hand-written
@@ -32,21 +33,33 @@ built-in template, the built-in output is skipped.
`colors.toml` provides the palette keys used by templates. Common keys are:
```toml
foreground = "#a9b1d6"
background = "#1a1b26"
accent = "#7aa2f7"
color1 = "#f7768e"
color4 = "#7aa2f7"
bg = "#1a1b26"
fg = "#a9b1d6"
accent = "#7aa2f7"
selection = "#292e42"
red = "#f7768e"
blue = "#7aa2f7"
```
Any key can be referenced from a template with `{{ key }}`. The shell also
uses a few semantic palette keys directly:
Any key can be referenced from a template with `{{ key }}`. The foundational
shell palette is loaded from:
- `foreground`
- `background`
- `fg` — primary readable text color
- `bg` — primary background color
- `accent` — preferred when present; otherwise some places fall back to
`color4`
- `urgent` / `color1`
- `urgent` / `red` / `color1`
For older user themes and templates, `foreground` aliases to `fg` and
`background` aliases to `bg`.
The neutral ramp is centered on `bg -> bright_fg`. Dark themes should read from
darkest to lightest; light themes should read from lightest to darkest. Terminal
and editor cursors use `bright_fg`; there is no separate cursor palette key.
`selection` is the text-selection background stop in that ramp; Omarchy derives
`selection_background = selection` and `selection_foreground = bright_fg`. Use
`omarchy dev theme-preview [theme]` to inspect that ramp, including `dark_bg`,
`darker_bg`, and a selected-text sample.
## Template placeholders
@@ -69,8 +82,8 @@ For a color key such as `accent = "#7aa2f7"`:
percentage:
```text
{{ mix background foreground 15% }}
{{ mix_strip background accent 0.35 }}
{{ mix bg fg 15% }}
{{ mix_strip bg accent 0.35 }}
{{ mix_rgb color0 color7 50 }}
```
+49 -104
View File
@@ -10,13 +10,12 @@ bypass it:
The design goal is:
- System/root migrations should run automatically from package transactions when
safe.
- User/session migrations should never run invisibly from pacman because they may
need `$HOME`, DBus/session state, a graphical session, or user interaction.
- Users who bypass `omarchy update` should still get system migrations from
pacman and should be notified only when their own user migration state is
missing a shipped user migration.
- `omarchy update` owns the visible update pipeline: package transaction,
migrations, post-update hooks, update-state refresh, and restart checks.
- Migrations run per-user after pacman finishes, because they may need `$HOME`,
DBus/session state, a graphical session, sudo, or user interaction.
- Users who bypass `omarchy update` are nudged back by the pacman guard; if they
explicitly bypass it, their session is notified when migrations are pending.
## State and coordination files
@@ -25,8 +24,8 @@ The design goal is:
| `${XDG_RUNTIME_DIR:-/tmp}/omarchy-update.lock` | user | Prevent overlapping update runs. Owned by `omarchy-update`; compatibility wrappers inherit/respect it. |
| `/tmp/omarchy-update.log` | user | Transcript of `omarchy update`, used by `omarchy-update-analyze-logs`. |
| `~/.local/state/omarchy/updates/` | user | Update-check state for the shell widget (`packages`, `aur`, `available`, `checked-at`, `error`). |
| `/var/lib/omarchy/migrations/system/` | root | System migration markers. |
| `~/.local/state/omarchy/migrations/user/` | user | User migration markers. |
| `~/.local/state/omarchy/current/` | user | Generated active theme, selected theme name, and current background symlink. |
| `~/.local/state/omarchy/migrations/` | user | Per-user migration markers. |
| `~/.local/state/omarchy/reboot-required` | user | Optional reboot marker checked by `omarchy-update-restart`. |
| `~/.local/state/omarchy/restart-*-required` | user | Optional service/app restart markers checked by `omarchy-update-restart`. |
@@ -35,83 +34,32 @@ The design goal is:
See [`migrations.md`](migrations.md) for the full migration model, authoring
guidelines, and troubleshooting notes.
Migrations are scoped by directory:
Migrations live in:
```text
migrations/system/*.sh
migrations/user/*.sh
migrations/*.sh
```
### System migrations
System migrations are root-owned, noninteractive fixes for existing installs.
They may touch `/etc`, `/usr`, `/boot`, system services, hardware configuration,
and other machine-wide state.
Runner:
```bash
omarchy-migrate-system
```
Completion state:
```text
/var/lib/omarchy/migrations/system/<migration filename>
```
Pacman integration:
```text
pkgbuilds/omarchy/omarchy.install post_upgrade()
```
The `omarchy` package calls `omarchy-migrate-system` from `post_upgrade()`.
The runner is idempotent, so repeated calls only check the state files.
### User migrations
User migrations are current-user/session fixes. They may touch `~/.config`,
`~/.local`, user systemd units, browser/editor preferences, DBus/session state,
or ask questions.
Runner:
```bash
omarchy-migrate-user
```
Public command:
They run as the current user through:
```bash
omarchy-migrate
```
Completion state:
Completion state is per-user:
```text
~/.local/state/omarchy/migrations/user/<migration filename>
~/.local/state/omarchy/migrations/<migration filename>
```
A user migration is pending only when a script exists in `migrations/user/` and
that user's matching state file is missing. There is no global root-owned queue
for user migrations.
Every user gets a chance to run every migration. Migrations run as the user;
privileged work should invoke the appropriate helper or privilege prompt.
Migrations must be idempotent; if one user already applied a machine-wide repair,
the migration should no-op for other users.
`omarchy-migrate` is the public command. It waits for any active pacman
transaction to finish, runs pending system migrations, then runs pending user
migrations. It does not need `--force`; migrations should happen when they are
pending.
For watchers and diagnostics, `omarchy-migrate --pending [all|system|user]`
prints pending migration names and exits `0` when any are pending. Output is
scope-prefixed, for example:
```text
system/100-system.sh
user/200-user.sh
```
When no matching migrations are pending, it prints nothing and exits non-zero.
For watchers and diagnostics, `omarchy-migrate --pending` prints pending
migration names and exits `0` when any are pending. When no migrations are
pending, it prints nothing and exits non-zero.
## Raw pacman guard
@@ -151,6 +99,14 @@ sudo env OMARCHY_ALLOW_DIRECT_PACMAN=1 pacman -Syu
The guard does not start `omarchy update` itself because pacman is already in a
transaction setup path; it only aborts with instructions.
The `omarchy` package also installs ALPM hooks for `omarchy-settings` /
`omarchy-settings-dev` installs and upgrades. The pre-transaction hook runs
`omarchy-hyprland-reload-guard pause` to disable live Hyprland config reloads
while `/usr/share/omarchy/default/hypr/**` is replaced. The post-transaction
hook runs `omarchy-hyprland-reload-guard resume`, forces one `hyprctl reload`,
and restores the session's previous `misc.disable_autoreload` and
`debug.suppress_errors` values.
## Path 1: `omarchy update`
High-level flow:
@@ -178,10 +134,8 @@ omarchy-update
Important behavior:
- `omarchy update` checks/runs system and user migrations in the same visible
terminal via `omarchy-migrate`.
- `omarchy update` still benefits from pacman-triggered system migrations
because the system migration hook runs as part of the pacman transaction.
- `omarchy update` checks/runs migrations in the same visible terminal via
`omarchy-migrate` after pacman finishes.
- A failure should leave enough output in `/tmp/omarchy-update.log` and the
terminal transcript to debug.
@@ -193,10 +147,9 @@ High-level flow:
sudo pacman -Syu
├─ pre-transaction guard aborts and tells the user to run omarchy update
└─ if explicitly bypassed, upgrades omarchy and related packages
├─ omarchy post_upgrade runs omarchy-migrate-system as root
└─ user session notices migration directory changes
├─ omarchy-update-user-notify.path triggers, if enabled
├─ omarchy-migrate-notify checks omarchy-migrate --pending user
├─ omarchy-migrate-notify checks omarchy-migrate --pending
├─ if this user has missing migration state, show notification
└─ click opens terminal: omarchy-migrate
```
@@ -206,12 +159,11 @@ Fallbacks:
- `omarchy-first-run` enables the user notification path unit.
- `omarchy-first-run` also invokes `omarchy-migrate-notify` on graphical
startup, so users who updated before the path unit existed still get prompted
if they have missing user migration state.
- The notifier is only a prompt. It does not run user migrations in the
background.
if they have missing migration state.
- The notifier is only a prompt. It does not run migrations in the background.
- Direct pacman updates do not run `omarchy-hook post-update` unless the user
explicitly runs that hook; without a package-update marker, the only user-side
pending state we can derive is missing user migration markers.
explicitly runs that hook; without a package-update marker, the only pending
state we can derive is missing per-user migration markers.
## Shell update indicator
@@ -256,11 +208,9 @@ scripts.
| `omarchy-update-confirm` | Gum confirmation copy for `omarchy update`. | **Question.** Could be inlined into `omarchy-update`; separate file only helps keep copy isolated. |
| `omarchy-update-keyring` | Ensures Omarchy keyring and Arch keyring are current before the main transaction. | **Keep, but review.** It uses targeted `pacman -Sy` for keyring bootstrapping; acceptable for this special case but should remain tightly scoped. |
| `omarchy-update-system-pkgs` | Runs `sudo env OMARCHY_UPDATE_PACMAN=1 pacman -Syu --noconfirm` with targeted transition `--overwrite` entries so the ALPM guard allows the transaction and early package-layout conflicts are handled. | **Keep for now.** Small leaf command, clear/testable. |
| `omarchy-migrate-system` | Runs root/system migrations from `migrations/system`. Called by `omarchy` package `post_upgrade()` and by `omarchy-migrate` when system migration state is missing. | **Keep.** This is the important direct-`pacman -Syu` integration. |
| `omarchy-migrate-user` | Checks `migrations/user` against this user's state and runs only missing user migrations. Supports `--pending` and prints pending filenames. | **Keep internal.** Public users should generally run `omarchy-migrate`. |
| `omarchy-migrate` | Public migration command. Waits for pacman, then runs pending system and user migrations. Supports `--pending [all|system|user]` and prints scope-prefixed pending filenames. | **Keep.** This replaces the discarded `omarchy-update-user-finalize` name and no longer needs `--force`. |
| `omarchy-migrate` | Public migration command. Waits for pacman, then runs all pending migrations for the current user. Supports `--pending`. | **Keep.** This replaces the discarded `omarchy-update-user-finalize` name and no longer needs `--force`. |
| `omarchy-update-pacman-guard` | ALPM pre-transaction guard that aborts direct `pacman -Syu` style upgrades unless Omarchy set `OMARCHY_UPDATE_PACMAN=1` or the user explicitly set `OMARCHY_ALLOW_DIRECT_PACMAN=1`. | **Keep internal/hidden.** This is what nudges users back to `omarchy update`. |
| `omarchy-migrate-notify` | Internal notification helper for direct pacman updates. Uses `omarchy-migrate --pending user` and shows notification only when this user has pending migrations. | **Keep internal/hidden.** Clear name now that the public command is `omarchy-migrate`. |
| `omarchy-migrate-notify` | Internal notification helper for direct pacman updates. Uses `omarchy-migrate --pending` and shows notification only when this user has pending migrations. | **Keep internal/hidden.** Clear name now that the public command is `omarchy-migrate`. |
| `omarchy-update-user-notify` | Hidden compatibility wrapper for `omarchy-migrate-notify`. | **Temporary.** Keep only for old callers. |
| `omarchy-update-available` | Update checker for shell widget and post-update refresh. Writes update state. | **Keep.** Could eventually be renamed `omarchy-update-check`, but current name matches widget semantics. |
| `omarchy-update-aur-pkgs` | Updates AUR packages with `yay -Sua` if foreign packages exist and AUR is reachable. | **Question.** Omarchy is package-backed now, but users may still install AUR packages. Keep for now. |
@@ -273,36 +223,31 @@ scripts.
## Closed decisions
1. **System migrations run from the `omarchy` package**
- `omarchy.install post_upgrade()` calls `omarchy-migrate-system`.
- We do not need a separate system-migration ALPM hook from
`omarchy-settings`.
1. **Migrations run per-user from the update pipeline**
- `omarchy update` runs `omarchy-migrate` after pacman finishes.
- Package-time migration runners do not apply migrations inside pacman.
- Every user has per-user migration markers, and migrations must be
idempotent when they repair machine-wide state.
2. **Root vs user migrations stay separate**
- Do not use `su {user}` from pacman to run user migrations.
- User migrations need the user's real session and should be visible.
- Pending user work is determined only by comparing `migrations/user/*.sh`
against `~/.local/state/omarchy/migrations/user/`.
3. **Migration notification naming**
2. **Migration notification naming**
- The real helper is `omarchy-migrate-notify`.
- `omarchy-update-user-notify` remains only as a hidden compatibility wrapper.
4. **Update pipeline ownership**
3. **Update pipeline ownership**
- `omarchy-update` owns the full update pipeline now.
- `omarchy-update-perform` is only a hidden compatibility wrapper for
`omarchy-update -y`.
5. **Mise remains in the blessed update path**
4. **Mise remains in the blessed update path**
- `omarchy-update-mise` intentionally runs as part of `omarchy update`.
6. **Orphan cleanup stays in the update path for now**
5. **Orphan cleanup stays in the update path for now**
- It is prompt-only and never removes packages noninteractively.
7. **Direct pacman user follow-up is based on actual migration state**
6. **Direct pacman user follow-up is based on actual migration state**
- Direct `sudo pacman -Syu` no longer uses a fake user-update marker.
- User notifications are shown only when `omarchy-migrate --pending user`
finds missing per-user migration state.
- User notifications are shown only when `omarchy-migrate --pending` finds
missing per-user migration state.
## Remaining concerns

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