diff --git a/dot_config/aerospace/aerospace.toml b/dot_config/aerospace/aerospace.toml
new file mode 100644
index 0000000..de7ef24
--- /dev/null
+++ b/dot_config/aerospace/aerospace.toml
@@ -0,0 +1,215 @@
+# You can use it to add commands that run after login to macOS user session.
+# 'start-at-login' needs to be 'true' for 'after-login-command' to work
+# Available commands: https://nikitabobko.github.io/AeroSpace/commands
+after-login-command = []
+
+# You can use it to add commands that run after AeroSpace startup.
+# 'after-startup-command' is run after 'after-login-command'
+# Available commands : https://nikitabobko.github.io/AeroSpace/commands
+after-startup-command = []
+
+# Start AeroSpace at login
+start-at-login = true
+
+# Normalizations. See: https://nikitabobko.github.io/AeroSpace/guide#normalization
+enable-normalization-flatten-containers = true
+enable-normalization-opposite-orientation-for-nested-containers = true
+
+# See: https://nikitabobko.github.io/AeroSpace/guide#layouts
+# The 'accordion-padding' specifies the size of accordion padding
+# You can set 0 to disable the padding feature
+accordion-padding = 30
+
+# Possible values: tiles|accordion
+default-root-container-layout = 'tiles'
+
+# Possible values: horizontal|vertical|auto
+# 'auto' means: wide monitor (anything wider than high) gets horizontal orientation,
+# tall monitor (anything higher than wide) gets vertical orientation
+default-root-container-orientation = 'auto'
+
+# Mouse follows focus when focused monitor changes
+# Drop it from your config, if you don't like this behavior
+# See https://nikitabobko.github.io/AeroSpace/guide#on-focus-changed-callbacks
+# See https://nikitabobko.github.io/AeroSpace/commands#move-mouse
+# Fallback value (if you omit the key): on-focused-monitor-changed = []
+on-focused-monitor-changed = ['move-mouse monitor-lazy-center']
+
+# You can effectively turn off macOS "Hide application" (cmd-h) feature by toggling this flag
+# Useful if you don't use this macOS feature, but accidentally hit cmd-h or cmd-alt-h key
+# Also see: https://nikitabobko.github.io/AeroSpace/goodies#disable-hide-app
+automatically-unhide-macos-hidden-apps = false
+
+# Possible values: (qwerty|dvorak)
+# See https://nikitabobko.github.io/AeroSpace/guide#key-mapping
+[key-mapping]
+preset = 'qwerty'
+
+# Gaps between windows (inner-*) and between monitor edges (outer-*).
+# Possible values:
+# - Constant: gaps.outer.top = 8
+# - Per monitor: gaps.outer.top = [{ monitor.main = 16 }, { monitor."some-pattern" = 32 }, 24]
+# In this example, 24 is a default value when there is no match.
+# Monitor pattern is the same as for 'workspace-to-monitor-force-assignment'.
+# See: https://nikitabobko.github.io/AeroSpace/guide#assign-workspaces-to-monitors
+[gaps]
+inner.horizontal = 4
+inner.vertical = 4
+outer.left = 0
+outer.bottom = 0
+outer.top = 30
+outer.right = 0
+
+# 'main' binding mode declaration
+# See: https://nikitabobko.github.io/AeroSpace/guide#binding-modes
+# 'main' binding mode must be always presented
+# Fallback value (if you omit the key): mode.main.binding = {}
+[mode.main.binding]
+
+# All possible keys:
+# - Letters. a, b, c, ..., z
+# - Numbers. 0, 1, 2, ..., 9
+# - Keypad numbers. keypad0, keypad1, keypad2, ..., keypad9
+# - F-keys. f1, f2, ..., f20
+# - Special keys. minus, equal, period, comma, slash, backslash, quote, semicolon, backtick,
+# leftSquareBracket, rightSquareBracket, space, enter, esc, backspace, tab
+# - Keypad special. keypadClear, keypadDecimalMark, keypadDivide, keypadEnter, keypadEqual,
+# keypadMinus, keypadMultiply, keypadPlus
+# - Arrows. left, down, up, right
+
+# All possible modifiers: cmd, alt, ctrl, shift
+
+# All possible commands: https://nikitabobko.github.io/AeroSpace/commands
+
+# See: https://nikitabobko.github.io/AeroSpace/commands#exec-and-forget
+# You can uncomment the following lines to open up terminal with alt + enter shortcut (like in i3)
+# alt-enter = '''exec-and-forget osascript -e '
+# tell application "Terminal"
+# do script
+# activate
+# end tell'
+# '''
+
+# See: https://nikitabobko.github.io/AeroSpace/commands#layout
+alt-slash = 'layout tiles horizontal vertical'
+alt-comma = 'layout accordion horizontal vertical'
+
+# See: https://nikitabobko.github.io/AeroSpace/commands#focus
+alt-shift-left = 'focus left'
+alt-shift-down = 'focus down'
+alt-shift-up = 'focus up'
+alt-shift-right = 'focus right'
+
+ctrl-alt-shift-left = 'focus-monitor left --wrap-around'
+ctrl-alt-shift-right = 'focus-monitor right --wrap-around'
+ctrl-alt-shift-up = 'focus-monitor up --wrap-around'
+ctrl-alt-shift-down = 'focus-monitor down --wrap-around'
+
+# See: https://nikitabobko.github.io/AeroSpace/commands#move
+alt-shift-h = 'move left'
+alt-shift-j = 'move down'
+alt-shift-k = 'move up'
+alt-shift-l = 'move right'
+
+# See: https://nikitabobko.github.io/AeroSpace/commands#resize
+alt-shift-minus = 'resize smart -50'
+alt-shift-equal = 'resize smart +50'
+
+# See: https://nikitabobko.github.io/AeroSpace/commands#workspace
+alt-1 = 'workspace 1'
+alt-2 = 'workspace 2'
+alt-3 = 'workspace 3'
+alt-4 = 'workspace 4'
+alt-5 = 'workspace 5'
+alt-6 = 'workspace 6'
+alt-7 = 'workspace 7'
+alt-8 = 'workspace 8'
+alt-9 = 'workspace 9'
+# alt-a = 'workspace A' # In your config, you can drop workspace bindings that you don't need
+# alt-b = 'workspace B'
+# alt-c = 'workspace C'
+# alt-d = 'workspace D'
+# alt-e = 'workspace E'
+# alt-f = 'workspace F'
+# alt-g = 'workspace G'
+# alt-i = 'workspace I'
+# alt-m = 'workspace M'
+# alt-n = 'workspace N'
+# alt-o = 'workspace O'
+# alt-p = 'workspace P'
+# alt-q = 'workspace Q'
+# alt-r = 'workspace R'
+# alt-s = 'workspace S'
+# alt-t = 'workspace T'
+# alt-u = 'workspace U'
+# alt-v = 'workspace V'
+# alt-w = 'workspace W'
+# alt-x = 'workspace X'
+# alt-y = 'workspace Y'
+# alt-z = 'workspace Z'
+
+# See: https://nikitabobko.github.io/AeroSpace/commands#move-node-to-workspace
+alt-shift-1 = 'move-node-to-workspace 1'
+alt-shift-2 = 'move-node-to-workspace 2'
+alt-shift-3 = 'move-node-to-workspace 3'
+alt-shift-4 = 'move-node-to-workspace 4'
+alt-shift-5 = 'move-node-to-workspace 5'
+alt-shift-6 = 'move-node-to-workspace 6'
+alt-shift-7 = 'move-node-to-workspace 7'
+alt-shift-8 = 'move-node-to-workspace 8'
+alt-shift-9 = 'move-node-to-workspace 9'
+# alt-shift-a = 'move-node-to-workspace A'
+# alt-shift-b = 'move-node-to-workspace B'
+# alt-shift-c = 'move-node-to-workspace C'
+# alt-shift-d = 'move-node-to-workspace D'
+# alt-shift-e = 'move-node-to-workspace E'
+# alt-shift-f = 'move-node-to-workspace F'
+# alt-shift-g = 'move-node-to-workspace G'
+# alt-shift-i = 'move-node-to-workspace I'
+# alt-shift-m = 'move-node-to-workspace M'
+# alt-shift-n = 'move-node-to-workspace N'
+# alt-shift-o = 'move-node-to-workspace O'
+# alt-shift-p = 'move-node-to-workspace P'
+# alt-shift-q = 'move-node-to-workspace Q'
+# alt-shift-r = 'move-node-to-workspace R'
+# alt-shift-s = 'move-node-to-workspace S'
+# alt-shift-t = 'move-node-to-workspace T'
+# alt-shift-u = 'move-node-to-workspace U'
+# alt-shift-v = 'move-node-to-workspace V'
+# alt-shift-w = 'move-node-to-workspace W'
+# alt-shift-x = 'move-node-to-workspace X'
+# alt-shift-y = 'move-node-to-workspace Y'
+# alt-shift-z = 'move-node-to-workspace Z'
+
+# See: https://nikitabobko.github.io/AeroSpace/commands#workspace-back-and-forth
+alt-tab = 'workspace-back-and-forth'
+# See: https://nikitabobko.github.io/AeroSpace/commands#move-workspace-to-monitor
+alt-shift-tab = 'move-workspace-to-monitor --wrap-around next'
+
+# See: https://nikitabobko.github.io/AeroSpace/commands#mode
+alt-shift-semicolon = 'mode service'
+
+# 'service' binding mode declaration.
+# See: https://nikitabobko.github.io/AeroSpace/guide#binding-modes
+[mode.service.binding]
+esc = ['reload-config', 'mode main']
+r = ['flatten-workspace-tree', 'mode main'] # reset layout
+f = ['layout floating tiling', 'mode main'] # Toggle between floating and tiling layout
+backspace = ['close-all-windows-but-current', 'mode main']
+
+# sticky is not yet supported https://github.com/nikitabobko/AeroSpace/issues/2
+#s = ['layout sticky tiling', 'mode main']
+
+alt-shift-h = ['join-with left', 'mode main']
+alt-shift-j = ['join-with down', 'mode main']
+alt-shift-k = ['join-with up', 'mode main']
+alt-shift-l = ['join-with right', 'mode main']
+
+down = 'volume down'
+up = 'volume up'
+shift-down = ['volume set 0', 'mode main']
+
+[workspace-to-monitor-force-assignment]
+1 = 'built-in'
+2 = ['^DELL U2723QE \(1\)$', 'BenQ EX2710 \(2\)$']
+3 = ['^DELL U2723QE \(2\)$', 'BenQ EX2710 \(1\)$']
diff --git a/dot_config/flake/flake.lock b/dot_config/flake/flake.lock
index 9616981..8468f33 100644
--- a/dot_config/flake/flake.lock
+++ b/dot_config/flake/flake.lock
@@ -83,18 +83,21 @@
},
"darwin": {
"inputs": {
- "nixpkgs": "nixpkgs"
+ "nixpkgs": [
+ "nixpkgs"
+ ]
},
"locked": {
- "lastModified": 1737162735,
- "narHash": "sha256-5T+HkouTMGaRm0rh3kgD4Z1O7ONKfgjyoPQH5rSyreU=",
+ "lastModified": 1737421067,
+ "narHash": "sha256-/hgw8fDKDpko0XqOw1e9tX8lS2Hqecg7W/JsONun6Qc=",
"owner": "lnl7",
"repo": "nix-darwin",
- "rev": "87131f51f8256952d1a306b5521cedc2dc61aa08",
+ "rev": "cae8d1c4a3bd37be5887203fe3b0c3a860c53a07",
"type": "github"
},
"original": {
"owner": "lnl7",
+ "ref": "nix-darwin-24.11",
"repo": "nix-darwin",
"type": "github"
}
@@ -118,6 +121,24 @@
}
},
"flake-utils_2": {
+ "inputs": {
+ "systems": "systems_2"
+ },
+ "locked": {
+ "lastModified": 1731533236,
+ "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "flake-utils_3": {
"locked": {
"lastModified": 1659877975,
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
@@ -132,6 +153,21 @@
"type": "github"
}
},
+ "flakey-profile": {
+ "locked": {
+ "lastModified": 1712898590,
+ "narHash": "sha256-FhGIEU93VHAChKEXx905TSiPZKga69bWl1VB37FK//I=",
+ "owner": "lf-",
+ "repo": "flakey-profile",
+ "rev": "243c903fd8eadc0f63d205665a92d4df91d42d9d",
+ "type": "github"
+ },
+ "original": {
+ "owner": "lf-",
+ "repo": "flakey-profile",
+ "type": "github"
+ }
+ },
"flake-utils_3": {
"inputs": {
"systems": [
@@ -243,20 +279,20 @@
"inputs": {
"crane": "crane",
"flake-utils": "flake-utils",
- "nixpkgs": "nixpkgs_2",
+ "nixpkgs": "nixpkgs",
"rust-overlay": "rust-overlay"
},
"locked": {
- "lastModified": 1735933851,
- "narHash": "sha256-xN5pImisRyD4cnkUkc9uJeyeeex2dyZWeJugjoLjqyI=",
+ "lastModified": 1737319839,
+ "narHash": "sha256-wGfX2YcD9Hyqi7sQ8FSqUbN8/Rhftp01YyHoTWYPL8U=",
"owner": "helix-editor",
"repo": "helix",
- "rev": "dabfb6ceeae1da57fb93efcd254e917db49655e6",
+ "rev": "e7ac2fcdecfdbf43a4f772e7f7c163b43b3d0b9b",
"type": "github"
},
"original": {
"owner": "helix-editor",
- "ref": "25.01",
+ "ref": "25.01.1",
"repo": "helix",
"type": "github"
}
@@ -268,11 +304,11 @@
]
},
"locked": {
- "lastModified": 1737299337,
- "narHash": "sha256-0NBrY2A7buujKmeCbieopOMSbLxTu8TFcTLqAbTnQDw=",
+ "lastModified": 1739051380,
+ "narHash": "sha256-p1QSLO8DJnANY+ppK7fjD8GqfCrEIDjso1CSRHsXL7Y=",
"owner": "nix-community",
"repo": "home-manager",
- "rev": "f8ef4541bb8a54a8b52f19b52912119e689529b3",
+ "rev": "5af1b9a0f193ab6138b89a8e0af8763c21bbf491",
"type": "github"
},
"original": {
@@ -303,10 +339,45 @@
"type": "github"
}
},
- "nixgl": {
+ "lix": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1737234286,
+ "narHash": "sha256-CCKIAE84dzkrnlxJCKFyffAxP3yfsOAbdvydUGqq24g=",
+ "rev": "2837da71ec1588c1187d2e554719b15904a46c8b",
+ "type": "tarball",
+ "url": "https://git.lix.systems/api/v1/repos/lix-project/lix/archive/2837da71ec1588c1187d2e554719b15904a46c8b.tar.gz?rev=2837da71ec1588c1187d2e554719b15904a46c8b"
+ },
+ "original": {
+ "type": "tarball",
+ "url": "https://git.lix.systems/lix-project/lix/archive/2.92.0.tar.gz"
+ }
+ },
+ "lix-module": {
"inputs": {
"flake-utils": "flake-utils_2",
- "nixpkgs": "nixpkgs_3"
+ "flakey-profile": "flakey-profile",
+ "lix": "lix",
+ "nixpkgs": [
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1737237494,
+ "narHash": "sha256-YMLrcBpf0TR5r/eaqm8lxzFPap2TxCor0ZGcK3a7+b8=",
+ "rev": "b90bf629bbd835e61f1317b99e12f8c831017006",
+ "type": "tarball",
+ "url": "https://git.lix.systems/api/v1/repos/lix-project/nixos-module/archive/b90bf629bbd835e61f1317b99e12f8c831017006.tar.gz?rev=b90bf629bbd835e61f1317b99e12f8c831017006"
+ },
+ "original": {
+ "type": "tarball",
+ "url": "https://git.lix.systems/lix-project/nixos-module/archive/2.92.0.tar.gz"
+ }
+ },
+ "nixgl": {
+ "inputs": {
+ "flake-utils": "flake-utils_3",
+ "nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1713543440,
@@ -323,38 +394,6 @@
}
},
"nixpkgs": {
- "locked": {
- "lastModified": 1736241350,
- "narHash": "sha256-CHd7yhaDigUuJyDeX0SADbTM9FXfiWaeNyY34FL1wQU=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "8c9fd3e564728e90829ee7dbac6edc972971cd0f",
- "type": "github"
- },
- "original": {
- "owner": "NixOS",
- "ref": "nixpkgs-unstable",
- "repo": "nixpkgs",
- "type": "github"
- }
- },
- "nixpkgs-unstable": {
- "locked": {
- "lastModified": 1737062831,
- "narHash": "sha256-Tbk1MZbtV2s5aG+iM99U8FqwxU/YNArMcWAv6clcsBc=",
- "owner": "nixos",
- "repo": "nixpkgs",
- "rev": "5df43628fdf08d642be8ba5b3625a6c70731c19c",
- "type": "github"
- },
- "original": {
- "owner": "nixos",
- "ref": "nixos-unstable",
- "repo": "nixpkgs",
- "type": "github"
- }
- },
- "nixpkgs_2": {
"locked": {
"lastModified": 1728018373,
"narHash": "sha256-NOiTvBbRLIOe5F6RbHaAh6++BNjsb149fGZd1T4+KBg=",
@@ -370,7 +409,23 @@
"type": "github"
}
},
- "nixpkgs_3": {
+ "nixpkgs-unstable": {
+ "locked": {
+ "lastModified": 1739020877,
+ "narHash": "sha256-mIvECo/NNdJJ/bXjNqIh8yeoSjVLAuDuTUzAo7dzs8Y=",
+ "owner": "nixos",
+ "repo": "nixpkgs",
+ "rev": "a79cfe0ebd24952b580b1cf08cd906354996d547",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nixos",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs_2": {
"locked": {
"lastModified": 1660551188,
"narHash": "sha256-a1LARMMYQ8DPx1BgoI/UN4bXe12hhZkCNqdxNi6uS0g=",
@@ -385,13 +440,13 @@
"type": "github"
}
},
- "nixpkgs_4": {
+ "nixpkgs_3": {
"locked": {
- "lastModified": 1737299813,
- "narHash": "sha256-Qw2PwmkXDK8sPQ5YQ/y/icbQ+TYgbxfjhgnkNJyT1X8=",
+ "lastModified": 1738843498,
+ "narHash": "sha256-7x+Q4xgFj9UxZZO9aUDCR8h4vyYut4zPUvfj3i+jBHE=",
"owner": "nixos",
"repo": "nixpkgs",
- "rev": "107d5ef05c0b1119749e381451389eded30fb0d5",
+ "rev": "f5a32fa27df91dfc4b762671a0e0a859a8a0058f",
"type": "github"
},
"original": {
@@ -422,8 +477,9 @@
"darwin": "darwin",
"helix": "helix",
"home-manager": "home-manager",
+ "lix-module": "lix-module",
"nixgl": "nixgl",
- "nixpkgs": "nixpkgs_4",
+ "nixpkgs": "nixpkgs_3",
"nixpkgs-unstable": "nixpkgs-unstable"
}
},
@@ -510,56 +566,6 @@
"repo": "default",
"type": "github"
}
- },
- "tinted-foot": {
- "flake": false,
- "locked": {
- "lastModified": 1726913040,
- "narHash": "sha256-+eDZPkw7efMNUf3/Pv0EmsidqdwNJ1TaOum6k7lngDQ=",
- "owner": "tinted-theming",
- "repo": "tinted-foot",
- "rev": "fd1b924b6c45c3e4465e8a849e67ea82933fcbe4",
- "type": "github"
- },
- "original": {
- "owner": "tinted-theming",
- "repo": "tinted-foot",
- "rev": "fd1b924b6c45c3e4465e8a849e67ea82933fcbe4",
- "type": "github"
- }
- },
- "tinted-kitty": {
- "flake": false,
- "locked": {
- "lastModified": 1716423189,
- "narHash": "sha256-2xF3sH7UIwegn+2gKzMpFi3pk5DlIlM18+vj17Uf82U=",
- "owner": "tinted-theming",
- "repo": "tinted-kitty",
- "rev": "eb39e141db14baef052893285df9f266df041ff8",
- "type": "github"
- },
- "original": {
- "owner": "tinted-theming",
- "repo": "tinted-kitty",
- "rev": "eb39e141db14baef052893285df9f266df041ff8",
- "type": "github"
- }
- },
- "tinted-tmux": {
- "flake": false,
- "locked": {
- "lastModified": 1729501581,
- "narHash": "sha256-1ohEFMC23elnl39kxWnjzH1l2DFWWx4DhFNNYDTYt54=",
- "owner": "tinted-theming",
- "repo": "tinted-tmux",
- "rev": "f0e7f7974a6441033eb0a172a0342e96722b4f14",
- "type": "github"
- },
- "original": {
- "owner": "tinted-theming",
- "repo": "tinted-tmux",
- "type": "github"
- }
}
},
"root": "root",
diff --git a/dot_config/flake/flake.nix b/dot_config/flake/flake.nix
index 2a674fd..c523251 100644
--- a/dot_config/flake/flake.nix
+++ b/dot_config/flake/flake.nix
@@ -4,20 +4,28 @@
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11";
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable";
+ lix-module = {
+ url = "https://git.lix.systems/lix-project/nixos-module/archive/2.92.0.tar.gz";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
home-manager = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs";
};
nixgl.url = "github:nix-community/nixGL";
- helix.url = "github:helix-editor/helix/25.01";
+ helix.url = "github:helix-editor/helix/25.01.1";
stylix.url = "github:danth/stylix/release-24.11";
- darwin.url = "github:lnl7/nix-darwin";
+ darwin = {
+ url = "github:lnl7/nix-darwin/nix-darwin-24.11";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
};
outputs = {
self,
nixpkgs,
nixpkgs-unstable,
+ lix-module,
home-manager,
darwin,
helix,
@@ -44,11 +52,44 @@
specialArgs = {inherit inputs outputs;};
modules = [./nixos/mal/configuration.nix];
};
+
+ wash = nixpkgs.lib.nixosSystem {
+ specialArgs = {inherit inputs outputs;};
+ modules = [
+ lix-module.nixosModules.default
+ ./nixos/wash/configuration.nix
+
+ home-manager.nixosModules.home-manager
+ {
+ home-manager.useGlobalPkgs = true;
+ home-manager.useUserPackages = true;
+
+ home-manager.extraSpecialArgs = {inherit inputs outputs;};
+ home-manager.users.tyler = import ./home/wash/wash.nix;
+ }
+ ];
+ };
};
darwinConfigurations."MAC-C57KK2TC69" = darwin.lib.darwinSystem {
- specialArgs = {inherit inputs outputs;};
- modules = [./home/hinge/darwin.nix];
+ pkgs = allPkgs."aarch64-darwin";
+ specialArgs = {inherit inputs;};
+
+ modules = [
+ lix-module.nixosModules.default
+
+ ./home/hinge/darwin.nix
+
+ home-manager.darwinModules.home-manager
+ {
+ home-manager.useGlobalPkgs = true;
+ home-manager.useUserPackages = true;
+
+ home-manager.extraSpecialArgs = {inherit inputs outputs;};
+ home-manager.users."tyler.mayoff" = import ./home/hinge/hinge.nix;
+ users.users."tyler.mayoff".home = "/Users/tyler.mayoff";
+ }
+ ];
};
homeConfigurations = {
@@ -64,17 +105,17 @@
modules = [stylix.homeManagerModules.stylix ./home/wash/wash.nix];
};
- "tyler@mal" = home-manager.lib.homeManagerConfiguration {
- pkgs = allPkgs;
- extraSpecialArgs = {inherit inputs outputs;};
- modules = [./home/mal/mal.nix];
- };
+ # "tyler@mal" = home-manager.lib.homeManagerConfiguration {
+ # pkgs = allPkgs;
+ # extraSpecialArgs = {inherit inputs outputs;};
+ # modules = [./home/mal/mal.nix];
+ # };
- "tyler.mayoff@MAC-C57KK2TC69" = home-manager.lib.homeManagerConfiguration {
- pkgs = allPkgs."aarch64-darwin";
- extraSpecialArgs = {inherit inputs outputs;};
- modules = [stylix.homeManagerModules.stylix ./home/hinge/hinge.nix];
- };
+ # "tyler.mayoff@MAC-C57KK2TC69" = home-manager.lib.homeManagerConfiguration {
+ # pkgs = allPkgs."aarch64-darwin";
+ # extraSpecialArgs = {inherit inputs outputs;};
+ # modules = [./home/hinge/hinge.nix];
+ # };
};
};
}
diff --git a/dot_config/flake/home/common.nix b/dot_config/flake/home/common.nix
index e06989d..4392098 100644
--- a/dot_config/flake/home/common.nix
+++ b/dot_config/flake/home/common.nix
@@ -1,25 +1,19 @@
{
inputs,
outputs,
- # lib,
- # config,
pkgs,
...
}: {
- nixpkgs.config.allowUnfree = true;
-
- home.username = "tyler";
- home.homeDirectory = "/home/tyler";
+ #nixpkgs.config.allowUnfree = true;
home.enableNixpkgsReleaseCheck = false;
xdg.enable = true;
imports = [
+ ./shell.nix
./fish.nix
./nushell.nix
- # ./nom.nix
- # ./neovim.nix
];
nixpkgs = {
@@ -32,10 +26,7 @@
};
home.packages = with pkgs; [
- # Fonts
- #(nerdfonts.override {fonts = ["JetBrainsMono"];})
-
- unstable.nix-output-monitor
+ # unstable.nix-output-monitor
# dotfiles
age
@@ -57,7 +48,7 @@
git
fzf
- zoxide
+ just
# Software Dev
tig
@@ -128,6 +119,8 @@
programs.zellij = {
enable = true;
package = pkgs.unstable.zellij;
+ enableFishIntegration = false;
+ enableZshIntegration = false;
};
programs.starship = {
@@ -156,6 +149,10 @@
shellWrapperName = "y";
};
- home.stateVersion = "23.11";
+ programs.zoxide = {
+ enable = true;
+ };
+
+ # home.stateVersion = "23.11";
programs.home-manager.enable = true;
}
diff --git a/dot_config/flake/home/empty_shell.nix b/dot_config/flake/home/empty_shell.nix
new file mode 100644
index 0000000..cb69f38
--- /dev/null
+++ b/dot_config/flake/home/empty_shell.nix
@@ -0,0 +1,21 @@
+{...}: {
+ home.shellAliases = {
+ # Git
+ gc = "git commit";
+ gcm = "git commit -m";
+ gac = "git add . and git commit";
+ gacp = "gac and git push";
+ gs = "git status";
+
+ # nix
+ flake = "nix flake";
+
+ # home-manager
+ hm-upgrade = "nix flake update --flake ~/.local/share/chezmoi/dot_config/flake#";
+ hm-update = "home-manager switch --flake ~/.config/flake";
+
+ # chezmoi
+ dot_apply = "chezmoi apply";
+ dot_pull = "chezmoi update";
+ };
+}
diff --git a/dot_config/flake/home/fish.nix b/dot_config/flake/home/fish.nix
index 591945e..d8d837a 100644
--- a/dot_config/flake/home/fish.nix
+++ b/dot_config/flake/home/fish.nix
@@ -7,8 +7,8 @@
set -gx DEBEMAIL "tyler@tylermayoff.com"
fish_add_path $HOME/.local/bin
- fish_add_path /opt/homebrew/bin
- fish_add_path /opt/homebrew/opt/llvm@18/bin
+ # fish_add_path /opt/homebrew/bin
+ # fish_add_path /opt/homebrew/opt/llvm@18/bin
if test -e $HOME/.config/fish/variables-$(hostname)fish
source $HOME/.config/fish/variables-$(hostname).fish
@@ -39,36 +39,5 @@
src = pkgs.fishPlugins.forgit.src;
}
];
-
- shellAliases = {
- # ls
- ls = "eza $eza_params";
- l = "eza --git-ignore $eza_params";
- ll = "eza --all --header --long $eza_params";
- llm = "eza --all --header --long --sort=modified $eza_params";
- la = "eza -lbhHigUmuSa";
- lx = "eza -lbhHigUmuSa@";
- lt = "eza --tree $eza_params";
- tree = "eza --tree $eza_params";
-
- # Git
- gc = "git commit";
- gcm = "git commit -m";
- gac = "git add . && git commit";
- gacp = "gac && git push";
- gs = "git status";
-
- # yac = "yadm add . && yadm commit";
- # yacp = "yac && yadm push";
- # yc = "pushd $HOME/.local/share/yadm/repo.git && git-forgit add && yadm commit && popd";
- # yd = "pushd $HOME/.local/share/yadm/repo.git && git-forgit diff && popd";
-
- # nix
- flake = "nix flake";
-
- # home-manager
- hm-upgrade = "nix flake update --flake ~/.local/share/chezmoi/dot_config/flake#";
- hm-update = "home-manager switch --flake ~/.config/flake";
- };
};
}
diff --git a/dot_config/flake/home/gui.nix b/dot_config/flake/home/gui.nix
index 38172ae..59a7430 100644
--- a/dot_config/flake/home/gui.nix
+++ b/dot_config/flake/home/gui.nix
@@ -21,6 +21,8 @@
# Office
libreoffice
obsidian
+
+ (config.lib.nixGL.wrap unstable.onagre)
];
# programs.vscode.enable = true;
diff --git a/dot_config/flake/home/guidebolt/guidebolt.nix b/dot_config/flake/home/guidebolt/guidebolt.nix
index d68916d..fe600f7 100644
--- a/dot_config/flake/home/guidebolt/guidebolt.nix
+++ b/dot_config/flake/home/guidebolt/guidebolt.nix
@@ -8,9 +8,14 @@
}: {
imports = [../common.nix];
- home.packages = with pkgs; [
- # clang_17
- # clang-tools
- just
- ];
+ home = {
+ username = "tyler";
+ homeDirectory = "/home/tyler";
+
+ packages = with pkgs; [
+ # clang_17
+ # clang-tools
+ just
+ ];
+ };
}
diff --git a/dot_config/flake/home/hinge/darwin.nix b/dot_config/flake/home/hinge/darwin.nix
index 7057040..a44ab98 100644
--- a/dot_config/flake/home/hinge/darwin.nix
+++ b/dot_config/flake/home/hinge/darwin.nix
@@ -1,8 +1,62 @@
{
- inputs,
outputs,
+ pkgs,
lib,
...
}: {
# services.aerospace.enable = true;
+
+ imports = [
+ # ../fish.nix
+ ./sketchybar.nix
+ ];
+
+ nixpkgs = {
+ overlays = [
+ outputs.overlays.additions
+ outputs.overlays.modifications
+ outputs.overlays.unstable-packages
+ ];
+
+ config = {
+ allowUnfree = true;
+ };
+ };
+
+ nix.extraOptions =
+ ''
+ auto-optimise-store = true
+ experimental-features = nix-command flakes
+ ''
+ + lib.optionalString (pkgs.system == "aarch64-darwin") ''
+ extra-platforms = x86_64-darwin aarch64-darwin
+ '';
+
+ users.knownUsers = ["tyler.mayoff"];
+ users.users."tyler.mayoff" = {
+ uid = 502;
+ shell = pkgs.fish;
+ };
+
+ system.defaults.NSGlobalDomain._HIHideMenuBar = true;
+
+ security.pam.enableSudoTouchIdAuth = true;
+
+ environment.systemPackages = with pkgs; [
+ pinentry_mac
+ llvmPackages_19.clang-tools
+
+ sketchybar
+ sbarlua
+
+ lua
+
+ # android-tools
+ jdk17
+ ];
+
+ programs.fish.enable = true;
+ programs.zsh.enable = true;
+
+ system.stateVersion = 5;
}
diff --git a/dot_config/flake/home/hinge/hinge.nix b/dot_config/flake/home/hinge/hinge.nix
index 0a66d2d..68b9a90 100644
--- a/dot_config/flake/home/hinge/hinge.nix
+++ b/dot_config/flake/home/hinge/hinge.nix
@@ -1,24 +1,15 @@
-{
- lib,
- pkgs,
- ...
-}: let
- # mac-app-util-src = builtins.fetchTarball {
- # url = "https://github.com/hraban/mac-app-util/archive/master.tar.gz";
- # sha256 = "1w80vjcnaysjlzxsp3v4pxq4yswbjvxs8ann2bk0m7rkjljnzz6m";
- # };
- # mac-app-util = import mac-app-util-src {};
-in rec {
+{pkgs, ...}: {
imports = [
../stylix.nix
../common.nix
../kitty.nix
- # mac-app-util.homeManagerModules.default
];
+ # xdg.enable = lib.mkForce false;
+
home = {
- username = lib.mkForce "tyler.mayoff";
- homeDirectory = lib.mkForce "/Users/tyler.mayoff";
+ username = "tyler.mayoff";
+ # homeDirectory = /Users/tyler.mayoff;
packages = with pkgs; [
bazel_7
@@ -26,10 +17,7 @@ in rec {
conan
black
-
- # clang
- # biome
- deno
+
swiftlint
unstable.helix-gpt
unstable.lsp-ai
@@ -42,13 +30,17 @@ in rec {
just
yarn
cocoapods
- # android-tools
- jdk17
];
sessionVariables = {
ANDROID_HOME = "/Users/tyler.mayoff/Library/Android/sdk";
PATH = "$PATH:/Users/tyler.mayoff/Library/Android/sdk/platform-tools";
};
+
+ file.".gnupg/gpg-agent.conf".text = ''
+ pinentry-program ${pkgs.pinentry_mac}/Applications/pinentry-mac.app/Contents/MacOS/pinentry-mac
+ '';
};
+
+ home.stateVersion = "24.11";
}
diff --git a/dot_config/flake/home/hinge/sketchybar.nix b/dot_config/flake/home/hinge/sketchybar.nix
new file mode 100644
index 0000000..7d864af
--- /dev/null
+++ b/dot_config/flake/home/hinge/sketchybar.nix
@@ -0,0 +1,6 @@
+{...}: {
+ # services.sketchybar = {
+ # enable = true;
+ # extraPackages = [];
+ # };
+}
diff --git a/dot_config/flake/home/mal/mal.nix b/dot_config/flake/home/mal/mal.nix
index efc4eac..f64fd05 100644
--- a/dot_config/flake/home/mal/mal.nix
+++ b/dot_config/flake/home/mal/mal.nix
@@ -1,3 +1,8 @@
{pkgs, ...}: {
imports = [../common.nix];
+
+ home = {
+ username = "tyler";
+ homeDirectory = "/home/tyler";
+ };
}
diff --git a/dot_config/flake/home/nushell.nix b/dot_config/flake/home/nushell.nix
index 23af502..98a6704 100644
--- a/dot_config/flake/home/nushell.nix
+++ b/dot_config/flake/home/nushell.nix
@@ -1,44 +1,48 @@
-{pkgs, ...}: {
+{
+ config,
+ pkgs,
+ lib,
+ ...
+}: {
programs.nushell = {
enable = true;
- envFile = {
- text = ''
- $env.EDITOR = hx
- $env.GIT_EDITOR = $env.EDITOR
- $env.DEBMAIL = "tyler@tylermayoff.com"
- $env.XDG_CONFIG_HOME = "$HOME/.config"
- $env.XDG_CACHE_HOME = "$HOME/.cache"
- $env.XDG_DATA_HOME = "$HOME/.local/share"
- $env.XDG_STATE_HOME = "$HOME/.local/state"
-
- zoxide init nushell | save -f ~/.config/nushell/zoxide.nu
- '';
- };
-
shellAliases = {
# Git
gc = "git commit";
- gcm = "git commit -m";
gac = "git add . and git commit";
gacp = "gac and git push";
gs = "git status";
- yac = "yadm add --interactive and yadm commit";
- yacp = "yac and yadm push";
-
# nix
flake = "nix flake";
# home-manager
- hm-upgrade = "nix flake update --flake ~/.config/home-manager/";
- hm-update = "home-manager switch --impure";
+ hm-upgrade = "nix flake update --flake ~/.local/share/chezmoi/dot_config/flake#";
+ hm-update = "home-manager switch --flake ~/.config/flake";
+
+ # chezmoi
+ dot_apply = "chezmoi apply";
+ dot_pull = "chezmoi update";
};
- configFile = {
- text = ''
- source ~/.config/nushell/zoxide.nu
- '';
- };
+ extraConfig = ''
+ $env.PATH = ($env.PATH | split row (char esep) | append "~/.nix-profile/bin")
+ $env.PATH = ($env.PATH | split row (char esep) | append "/nix/var/nix/profiles/default/bin")
+
+ $env.config.show_banner = false
+
+ def gcm [message: string] {
+ gc -m $"($message)"
+ }
+
+ use ${pkgs.nu_scripts}/share/nu_scripts/nu-hooks/nu-hooks/direnv/direnv.nu *
+
+ use ${pkgs.nu_scripts}/share/nu_scripts/aliases/git/git-aliases.nu *
+ use ${pkgs.nu_scripts}/share/nu_scripts/custom-completions/git/git-completions.nu *
+ use ${pkgs.nu_scripts}/share/nu_scripts/custom-completions/just/just-completions.nu *
+ use ${pkgs.nu_scripts}/share/nu_scripts/custom-completions/rg/rg-completions.nu *
+ use ${pkgs.nu_scripts}/share/nu_scripts/custom-completions/zellij/zellij-completions.nu *
+ '';
};
}
diff --git a/dot_config/flake/home/wash/wash.nix b/dot_config/flake/home/wash/wash.nix
index 3367f07..44925b6 100644
--- a/dot_config/flake/home/wash/wash.nix
+++ b/dot_config/flake/home/wash/wash.nix
@@ -1,7 +1,348 @@
-{pkgs, ...}: {
- imports = [../common.nix ../gnome.nix ../home-backup.nix ../gui.nix ../stylix.nix];
+{
+ config,
+ pkgs,
+ ...
+}: let
+ mod = "Mod4";
+ term = "kitty";
+ menu = "wmenu-run";
+in {
+ imports = [../common.nix ../gnome.nix ../home-backup.nix ../gui.nix];
- home.packages = with pkgs; [
- ventoy
- ];
+ programs.feh.enable = true;
+ programs.waybar = {
+ enable = true;
+ style = ''
+ * {
+ font-size: 15px;
+ font-family: "CodeNewRoman Nerd Font Propo";
+ }
+
+ window#waybar {
+ all:unset;
+ }
+
+ .modules-left {
+ padding: 7px;
+ margin: 10 0 5 10;
+ border-radius: 10px;
+ background: alpha(@background, .6);
+ box-shadow: 0px 0px 2px rgba(0, 0, 0, .6);
+ }
+
+ .modules-center {
+ padding: 7px;
+ margin: 10 0 5 0;
+ border-radius: 10px;
+ background: alpha(@background, .6);
+ box-shadow: 0px 0px 2px rgab(0, 0, 0, .6);
+ }
+
+ .modules-right {
+ padding: 7px;
+ margin: 10 0 5 0;
+ border-radius: 10px;
+ background: alpha(@background, .6);
+ box-shadow: 0px 0px 2px rgab(0, 0, 0, .6);
+ }
+
+ tooltip {
+ background: @background
+ }
+ '';
+
+ settings = {
+ mainBar = {
+ layer = "top";
+ position = "top";
+ reload_style_on_change = true;
+
+ modules-left = ["clock" "tray"];
+ modules-center = ["sway/workspaces"];
+ modules-right = ["battery"];
+
+ "sway/workspaces" = {
+ format = "{icon}";
+ format-icons = {
+ active = "";
+ default = "";
+ empty = "";
+ };
+ };
+
+ "clock" = {
+ format = "{:%I:%M:%S %p} ";
+ interval = 1;
+ tooltip-format = "{calendar}";
+ calendar = {
+ format = {
+ today = "{}";
+ };
+ };
+ actions = {
+ on-click-right = "shift_down";
+ on-clock = "shift_up";
+ };
+ };
+
+ battery = {
+ interval = 30;
+ states = {
+ good = 95;
+ warning = 30;
+ critical = 20;
+ };
+ format = "{capacity}% {icon}";
+ format-charging = "{capacicty}% ";
+ format-plugged = "{capacity}% ";
+ format-alt = "{time} {icon}";
+ format-icons = [
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ];
+ };
+
+ tray = {
+ icon-size = 14;
+ spacing = 10;
+ };
+ };
+ };
+ };
+
+ wayland.windowManager.sway = {
+ enable = true;
+ checkConfig = true;
+ config = {
+ output."*".scale = "1";
+
+ startup = [
+ {command = "feh .config/flake/wallpaper.jpp";}
+ ];
+
+
+ # Home row direction keys, like vim
+ up = "k";
+ left = "h";
+ down = "j";
+ right = "l";
+
+ ### Idle configuration
+ #
+ # Example configuration:
+ #
+ # exec swayidle -w \
+ # timeout 300 'swaylock -f -c 000000' \
+ # timeout 600 'swaymsg "output * power off"' resume 'swaymsg "output * power on"' \
+ # before-sleep 'swaylock -f -c 000000'
+ #
+ # This will lock your screen after 300 seconds of inactivity, then turn off
+ # your displays after another 300 seconds, and turn your screens back on when
+ # resumed. It will also lock your screen before your computer goes to sleep.
+
+ ### Input configuration
+ #
+ # Example configuration:
+ #
+ # input "2:14:SynPS/2_Synaptics_TouchPad" {
+ # dwt enabled
+ # tap enabled
+ # natural_scroll enabled
+ # middle_emulation enabled
+ # }
+ #
+ # You can get the names of your inputs by running: swaymsg -t get_inputs
+ # Read `man 5 sway-input` for more information about this section.
+
+ input = {
+ "*" = {
+ tap = "enabled";
+ natural_scroll = "enabled";
+ };
+ };
+
+ ### Key bindings
+ #
+ # Basics:
+
+ keybindings = {
+ # Start a terminal
+ "${mod}+Return" = "exec ${term}";
+
+ # Kill focused window
+ "${mod}+Shift+q" = "kill";
+
+ # Start launcher
+ "${mod}+d" = "exec ${menu}";
+
+ # Reload the configuration file
+ "${mod}+Shift+c" = "reload";
+
+ "${mod}+r" = "mode resize";
+
+ # Moving around:
+
+ # Move your focus around
+ # "${mod}+$left" = "focus left";
+ # "${mod}+$down" = "focus down";
+ # "${mod}+$up" = "focus up";
+ # "${mod}+$right" = "focus right";
+ # Or use $mod+[up|down|left|right]
+ "${mod}+Left" = "focus left";
+ "${mod}+Down" = "focus down";
+ "${mod}+Up" = "focus up";
+ "${mod}+Right" = "focus right";
+ };
+
+ # Drag floating windows by holding down $mod and left mouse button.
+ # Resize them with right mouse button + $mod.
+ # Despite the name, also works for non-floating windows.
+ # Change normal to inverse to use left mouse button for resizing and right
+ # mouse button for dragging.
+ # floating_modifier $mod normal
+
+ # Exit sway (logs you out of your Wayland session)
+ # bindsym $mod+Shift+e exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -B 'Yes, exit sway' 'swaymsg exit'
+
+ # # Move the focused window with the same, but add Shift
+ # bindsym $mod+Shift+$left move left
+ # bindsym $mod+Shift+$down move down
+ # bindsym $mod+Shift+$up move up
+ # bindsym $mod+Shift+$right move right
+ # # Ditto, with arrow keys
+ # bindsym $mod+Shift+Left move left
+ # bindsym $mod+Shift+Down move down
+ # bindsym $mod+Shift+Up move up
+ # bindsym $mod+Shift+Right move right
+ # #
+ # # Workspaces:
+ # #
+ # # Switch to workspace
+ # bindsym $mod+1 workspace number 1
+ # bindsym $mod+2 workspace number 2
+ # bindsym $mod+3 workspace number 3
+ # bindsym $mod+4 workspace number 4
+ # bindsym $mod+5 workspace number 5
+ # bindsym $mod+6 workspace number 6
+ # bindsym $mod+7 workspace number 7
+ # bindsym $mod+8 workspace number 8
+ # bindsym $mod+9 workspace number 9
+ # bindsym $mod+0 workspace number 10
+ # # Move focused container to workspace
+ # bindsym $mod+Shift+1 move container to workspace number 1
+ # bindsym $mod+Shift+2 move container to workspace number 2
+ # bindsym $mod+Shift+3 move container to workspace number 3
+ # bindsym $mod+Shift+4 move container to workspace number 4
+ # bindsym $mod+Shift+5 move container to workspace number 5
+ # bindsym $mod+Shift+6 move container to workspace number 6
+ # bindsym $mod+Shift+7 move container to workspace number 7
+ # bindsym $mod+Shift+8 move container to workspace number 8
+ # bindsym $mod+Shift+9 move container to workspace number 9
+ # bindsym $mod+Shift+0 move container to workspace number 10
+ # # Note: workspaces can have any name you want, not just numbers.
+ # # We just use 1-10 as the default.
+ # #
+ # # Layout stuff:
+ # #
+ # # You can "split" the current object of your focus with
+ # # $mod+b or $mod+v, for horizontal and vertical splits
+ # # respectively.
+ # bindsym $mod+b splith
+ # bindsym $mod+v splitv
+
+ # # Switch the current container between different layout styles
+ # bindsym $mod+s layout stacking
+ # bindsym $mod+w layout tabbed
+ # bindsym $mod+e layout toggle split
+
+ # # Make the current focus fullscreen
+ # bindsym $mod+f fullscreen
+
+ # # Toggle the current focus between tiling and floating mode
+ # bindsym $mod+Shift+space floating toggle
+
+ # # Swap focus between the tiling area and the floating area
+ # bindsym $mod+space focus mode_toggle
+
+ # # Move focus to the parent container
+ # bindsym $mod+a focus parent
+ # #
+ # # Scratchpad:
+ # #
+ # # Sway has a "scratchpad", which is a bag of holding for windows.
+ # # You can send windows there and get them back later.
+
+ # # Move the currently focused window to the scratchpad
+ # bindsym $mod+Shift+minus move scratchpad
+
+ # # Show the next scratchpad window or hide the focused scratchpad window.
+ # # If there are multiple scratchpad windows, this command cycles through them.
+ # bindsym $mod+minus scratchpad show
+ # #
+ # # Resizing containers:
+ # #
+ # mode "resize" {
+ # # left will shrink the containers width
+ # # right will grow the containers width
+ # # up will shrink the containers height
+ # # down will grow the containers height
+ # bindsym $left resize shrink width 10px
+ # bindsym $down resize grow height 10px
+ # bindsym $up resize shrink height 10px
+ # bindsym $right resize grow width 10px
+
+ # # Ditto, with arrow keys
+ # bindsym Left resize shrink width 10px
+ # bindsym Down resize grow height 10px
+ # bindsym Up resize shrink height 10px
+ # bindsym Right resize grow width 10px
+
+ # # Return to default mode
+ # bindsym Return mode "default"
+ # bindsym Escape mode "default"
+ # }
+
+ # #
+ # # Utilities:
+ # #
+ # # Special keys to adjust volume via PulseAudio
+ # bindsym --locked XF86AudioMute exec pactl set-sink-mute \@DEFAULT_SINK@ toggle
+ # bindsym --locked XF86AudioLowerVolume exec pactl set-sink-volume \@DEFAULT_SINK@ -5%
+ # bindsym --locked XF86AudioRaiseVolume exec pactl set-sink-volume \@DEFAULT_SINK@ +5%
+ # bindsym --locked XF86AudioMicMute exec pactl set-source-mute \@DEFAULT_SOURCE@ toggle
+ # # Special keys to adjust brightness via brightnessctl
+ # bindsym --locked XF86MonBrightnessDown exec brightnessctl set 5%-
+ # bindsym --locked XF86MonBrightnessUp exec brightnessctl set 5%+
+ # # Special key to take a screenshot with grim
+ # bindsym Print exec grim
+
+ #
+ # Status Bar:
+ #
+ # Read `man 5 sway-bar` for more information about this section.
+
+ bars = [
+ {
+ command = "waybar";
+ position = "top";
+ }
+ ];
+ };
+ };
+
+ home = {
+ username = "tyler";
+ homeDirectory = "/home/tyler";
+
+ packages = with pkgs; [
+ ventoy
+ (config.lib.nixGL.wrap renderdoc)
+ ];
+
+ stateVersion = "23.11";
+ };
}
diff --git a/dot_config/flake/nixos/wash/configuration.nix b/dot_config/flake/nixos/wash/configuration.nix
new file mode 100644
index 0000000..f5fe33d
--- /dev/null
+++ b/dot_config/flake/nixos/wash/configuration.nix
@@ -0,0 +1,151 @@
+# Edit this configuration file to define what should be installed on
+# your system. Help is available in the configuration.nix(5) man page
+# and in the NixOS manual (accessible by running ‘nixos-help’).
+{
+ outputs,
+ pkgs,
+ ...
+}: {
+ imports = [
+ # Include the results of the hardware scan.
+ ./hardware-configuration.nix
+ ];
+
+ nixpkgs = {
+ overlays = [
+ outputs.overlays.additions
+ outputs.overlays.modifications
+ outputs.overlays.unstable-packages
+ ];
+
+ config = {
+ allowUnfree = true;
+ };
+ };
+
+ # Bootloader.
+ boot.loader.systemd-boot.enable = true;
+ boot.loader.efi.canTouchEfiVariables = true;
+
+ nix.settings.experimental-features = ["nix-command" "flakes"];
+
+ networking.hostName = "wash"; # Define your hostname.
+ # networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
+
+ # Configure network proxy if necessary
+ # networking.proxy.default = "http://user:password@proxy:port/";
+ # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";
+
+ # Enable networking
+ networking.networkmanager.enable = true;
+
+ # Set your time zone.
+ time.timeZone = "America/New_York";
+
+ # Select internationalisation properties.
+ i18n.defaultLocale = "en_US.UTF-8";
+
+ i18n.extraLocaleSettings = {
+ LC_ADDRESS = "en_US.UTF-8";
+ LC_IDENTIFICATION = "en_US.UTF-8";
+ LC_MEASUREMENT = "en_US.UTF-8";
+ LC_MONETARY = "en_US.UTF-8";
+ LC_NAME = "en_US.UTF-8";
+ LC_NUMERIC = "en_US.UTF-8";
+ LC_PAPER = "en_US.UTF-8";
+ LC_TELEPHONE = "en_US.UTF-8";
+ LC_TIME = "en_US.UTF-8";
+ };
+
+ # Enable the X11 windowing system.
+ services.xserver.enable = true;
+
+ # Enable the GNOME Desktop Environment.
+ services.xserver.displayManager.gdm.enable = true;
+ services.xserver.desktopManager.gnome.enable = true;
+
+ # Configure keymap in X11
+ services.xserver.xkb = {
+ layout = "us";
+ variant = "";
+ };
+
+ # Enable CUPS to print documents.
+ services.printing.enable = true;
+
+ services.fprintd.enable = true;
+
+ # Enable sound with pipewire.
+ hardware.pulseaudio.enable = false;
+ security.rtkit.enable = true;
+ services.pipewire = {
+ enable = true;
+ alsa.enable = true;
+ alsa.support32Bit = true;
+ pulse.enable = true;
+ # If you want to use JACK applications, uncomment this
+ #jack.enable = true;
+
+ # use the example session manager (no others are packaged yet so this is enabled by default,
+ # no need to redefine it in your config for now)
+ #media-session.enable = true;
+ };
+
+ services.gnome.gnome-keyring.enable = true;
+
+ # Enable touchpad support (enabled default in most desktopManager).
+ # services.xserver.libinput.enable = true;
+
+ # Define a user account. Don't forget to set a password with ‘passwd’.
+ users.users.tyler = {
+ isNormalUser = true;
+ description = "tyler";
+ extraGroups = ["networkmanager" "wheel"];
+ shell = pkgs.fish;
+ };
+
+ environment.systemPackages = with pkgs; [
+ sqlite
+ vscode
+ ];
+
+ fonts.packages = with pkgs; [
+ nerdfonts
+ ];
+
+ # Install firefox.
+ programs.firefox.enable = true;
+ programs.fish.enable = true;
+ programs.sway = {
+ enable = true;
+ # package = null;
+ wrapperFeatures.gtk = true;
+ };
+
+ # Some programs need SUID wrappers, can be configured further or are
+ # started in user sessions.
+ # programs.mtr.enable = true;
+ # programs.gnupg.agent = {
+ # enable = true;
+ # enableSSHSupport = true;
+ # };
+
+ # List services that you want to enable:
+
+ # Enable the OpenSSH daemon.
+ # services.openssh.enable = true;
+
+ # Open ports in the firewall.
+ # networking.firewall.allowedTCPPorts = [ ... ];
+ # networking.firewall.allowedUDPPorts = [ ... ];
+ # Or disable the firewall altogether.
+ # networking.firewall.enable = false;
+
+ # This value determines the NixOS release from which the default
+ # settings for stateful data, like file locations and database versions
+ # on your system were taken. It‘s perfectly fine and recommended to leave
+ # this value at the release version of the first install of this system.
+ # Before changing this value read the documentation for this option
+ # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
+ system.stateVersion = "24.11"; # Did you read the comment?
+}
diff --git a/dot_config/flake/nixos/wash/hardware-configuration.nix b/dot_config/flake/nixos/wash/hardware-configuration.nix
new file mode 100644
index 0000000..6ae3ebf
--- /dev/null
+++ b/dot_config/flake/nixos/wash/hardware-configuration.nix
@@ -0,0 +1,40 @@
+# Do not modify this file! It was generated by ‘nixos-generate-config’
+# and may be overwritten by future invocations. Please make changes
+# to /etc/nixos/configuration.nix instead.
+{ config, lib, pkgs, modulesPath, ... }:
+
+{
+ imports =
+ [ (modulesPath + "/installer/scan/not-detected.nix")
+ ];
+
+ boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "thunderbolt" "usb_storage" "sd_mod" ];
+ boot.initrd.kernelModules = [ ];
+ boot.kernelModules = [ "kvm-amd" ];
+ boot.extraModulePackages = [ ];
+
+ fileSystems."/" =
+ { device = "/dev/disk/by-uuid/16fd6400-4e28-4d88-8719-a76aa590f59c";
+ fsType = "ext4";
+ };
+
+ fileSystems."/boot" =
+ { device = "/dev/disk/by-uuid/6BB1-3DA5";
+ fsType = "vfat";
+ options = [ "fmask=0077" "dmask=0077" ];
+ };
+
+ swapDevices =
+ [ { device = "/dev/disk/by-uuid/eac18653-6290-46d3-b925-c1974f2c8f48"; }
+ ];
+
+ # Enables DHCP on each ethernet and wireless interface. In case of scripted networking
+ # (the default) this is the recommended approach. When using systemd-networkd it's
+ # still possible to use this option, but it's recommended to use it in conjunction
+ # with explicit per-interface declarations with `networking.interfaces..useDHCP`.
+ networking.useDHCP = lib.mkDefault true;
+ # networking.interfaces.wlp1s0.useDHCP = lib.mkDefault true;
+
+ nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
+ hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
+}
diff --git a/dot_config/flake/nushell.nix b/dot_config/flake/nushell.nix
deleted file mode 100644
index 6cfa022..0000000
--- a/dot_config/flake/nushell.nix
+++ /dev/null
@@ -1,15 +0,0 @@
-{pkgs, ...}: {
- programs.nushell = {
- enable = true;
-
- envFile = ''
- $env.EDITOR = hx
- $env.GIT_EDITOR = $env.EDITOR
- $env.DEBMAIL = "tyler@tylermayoff.com"
- $env.XDG_CONFIG_HOME = "$HOME/.config"
- $env.XDG_CACHE_HOME = "$HOME/.cache"
- $env.XDG_DATA_HOME = "$HOME/.local/share"
- $env.XDG_STATE_HOME = "$HOME/.local/state"
- '';
- };
-}
diff --git a/dot_config/flake/pkgs/default.nix b/dot_config/flake/pkgs/default.nix
index 5d56bdc..952d3a4 100644
--- a/dot_config/flake/pkgs/default.nix
+++ b/dot_config/flake/pkgs/default.nix
@@ -1,2 +1,9 @@
pkgs: {
+ sbarlua = {
+ src = pkgs.fetchFromGitHub {
+ repo = "SbarLua";
+ owner = "FelixKratz";
+ rev = "437bd2031da38ccda75827cb7548e7baa4aa9978";
+ };
+ };
}
diff --git a/dot_config/helix/languages.toml b/dot_config/helix/languages.toml
index d1af0c5..1d3f5f8 100644
--- a/dot_config/helix/languages.toml
+++ b/dot_config/helix/languages.toml
@@ -2,6 +2,7 @@
clangd = { command = "clangd", args = ["--header-insertion=never"]}
biome = { command = "biome", args = ["lsp-proxy"] }
fish_lsp = {command = "fish-lsp", args = ["start"]}
+slangd = {command = "slangd"}
[[language]]
name = "fish"
@@ -26,6 +27,33 @@ scope = "source.nix"
auto-format = true
formatter = { command = "alejandra", args = ["-q"] }
+[[language]]
+name = "objc"
+scope = "source.objc"
+file-types = ["m", "mm", "M"]
+injection-regex = "objc"
+roots = ["xcodeproj"]
+comment-token = "//"
+indent = { tab-width = 2, unit = " " }
+language-servers = [ {name = "clangd"} ]
+
+[[grammar]]
+name = "objc"
+source = { git = "https://github.com/tree-sitter-grammars/tree-sitter-objc", rev = "18802acf31d0b5c1c1d50bdbc9eb0e1636cab9ed" }
+
+
+[[language]]
+name = "slang"
+scope = "source.slang"
+file-types = ["slang"]
+auto-format = true
+language-servers = [{name = "slangd"}]
+comment-token = "//"
+
+[[grammar]]
+name = "slang"
+source = { git = "https://github.com/tree-sitter-grammars/tree-sitter-slang", rev = "3ed23c04a412a0559162d9cadf96dfff7cb36079" }
+
##################
### BiomeJS Setup
##################
diff --git a/dot_config/sketchybar/bar.lua b/dot_config/sketchybar/bar.lua
new file mode 100644
index 0000000..b364094
--- /dev/null
+++ b/dot_config/sketchybar/bar.lua
@@ -0,0 +1,9 @@
+local colors = require("colors")
+
+-- Equivalent to the --bar domain
+sbar.bar({
+ height = 40,
+ color = colors.bar.bg,
+ padding_right = 2,
+ padding_left = 2,
+})
diff --git a/dot_config/sketchybar/colors.lua b/dot_config/sketchybar/colors.lua
new file mode 100644
index 0000000..fb95015
--- /dev/null
+++ b/dot_config/sketchybar/colors.lua
@@ -0,0 +1,28 @@
+return {
+ black = 0xff181819,
+ white = 0xffe2e2e3,
+ red = 0xfffc5d7c,
+ green = 0xff9ed072,
+ blue = 0xff76cce0,
+ yellow = 0xffe7c664,
+ orange = 0xfff39660,
+ magenta = 0xffb39df3,
+ grey = 0xff7f8490,
+ transparent = 0x00000000,
+
+ bar = {
+ bg = 0xf02c2e34,
+ border = 0xff2c2e34,
+ },
+ popup = {
+ bg = 0xc02c2e34,
+ border = 0xff7f8490
+ },
+ bg1 = 0xff363944,
+ bg2 = 0xff414550,
+
+ with_alpha = function(color, alpha)
+ if alpha > 1.0 or alpha < 0.0 then return color end
+ return (color & 0x00ffffff) | (math.floor(alpha * 255.0) << 24)
+ end,
+}
diff --git a/dot_config/sketchybar/colors.sh b/dot_config/sketchybar/colors.sh
new file mode 100644
index 0000000..f7929b7
--- /dev/null
+++ b/dot_config/sketchybar/colors.sh
@@ -0,0 +1,57 @@
+#!/usr/bin/env sh
+
+# Color Palette -- Catppuccin Macchiato
+export BLACK=0xff181926
+#export WHITE=0xffcad3f5
+#export RED=0xffed8796
+#export GREEN=0xffa6da95
+#export BLUE=0xff8aadf4
+#export YELLOW=0xffeed49f
+export ORANGE=0xfff5a97f
+export MAGENTA=0xffc6a0f6
+export GREY=0xff939ab7
+#export SKY=0xff91d7e3
+#export PINK=0xfff5bde6
+export TRANSPARENT=0x00000000
+
+export ROSEWATER=0xFFf5e0dc #f5e0dc
+export FLAMINGO=0xFFf2cdcd #f2cdcd
+export PINK=0xFFf5c2e7 #f5c2e7
+export MAUVE=0xFFcba6f7 #cba6f7
+export RED=0xFFf38ba8 #f38ba8
+export MAROON=0xFFeba0ac #eba0ac
+export PEACH=0xFFfab387 #fab387
+export YELLOW=0xFFf9e2af #f9e2af
+export GREEN=0xFFa6e3a1 #a6e3a1
+export TEAL=0xFF94e2d5 #94e2d5
+export SKY=0xFF89dceb #89dceb
+export SAPPHIRE=0xFF74c7ec #74c7ec
+export BLUE=0xFF89b4fa #89b4fa
+export LAVENDER=0xFFb4befe #b4befe
+
+export WHITE=0xFFcdd6f4 #cdd6f4
+export DARK_WHITE=0xFF9399b2 #9399b2
+
+export ITEM_COLOR=0xff1e1e2e
+#export ITEM_COLOR=$BLACK
+
+# General bar colors
+export BAR_COLOR=$DARK_WHITE
+export ICON_COLOR=$WHITE # Color of all icons
+export LABEL_COLOR=$WHITE # Color of all labels
+export ALT_LABEL_COLOR=$WHITE
+
+export SPACE_BACKGROUND=$ITEM_COLOR
+#export SPACE_BACKGROUND2=0xffa6adc8
+export SPACE_SELECTED=$PEACH
+#export SPACE_DESELECTED=$LAVENDER
+export SPACE_BACKGROUND2=0xffa6adc8
+#export SPACE_SELECTED=0xffcdd6f4
+export SPACE_DESELECTED=0xff313244
+export OPEN_APPS_BACKGROUND=$ITEM_COLOR
+export CALENDAR_BACKGROUND=0xffb8c0e0
+
+export POPUP_BACKGROUND_COLOR=$BLACK
+export POPUP_BORDER_COLOR=$WHITE
+
+export SHADOW_COLOR=$BLACK
diff --git a/dot_config/sketchybar/default.lua b/dot_config/sketchybar/default.lua
new file mode 100644
index 0000000..f9d463b
--- /dev/null
+++ b/dot_config/sketchybar/default.lua
@@ -0,0 +1,52 @@
+local settings = require("settings")
+local colors = require("colors")
+
+-- Equivalent to the --default domain
+sbar.default({
+ updates = "when_shown",
+ icon = {
+ font = {
+ family = settings.font.text,
+ style = settings.font.style_map["Bold"],
+ size = 14.0
+ },
+ color = colors.white,
+ padding_left = settings.paddings,
+ padding_right = settings.paddings,
+ background = { image = { corner_radius = 9 } },
+ },
+ label = {
+ font = {
+ family = settings.font.text,
+ style = settings.font.style_map["Semibold"],
+ size = 13.0
+ },
+ color = colors.white,
+ padding_left = settings.paddings,
+ padding_right = settings.paddings,
+ },
+ background = {
+ height = 28,
+ corner_radius = 9,
+ border_width = 2,
+ border_color = colors.bg2,
+ image = {
+ corner_radius = 9,
+ border_color = colors.grey,
+ border_width = 1
+ }
+ },
+ popup = {
+ background = {
+ border_width = 2,
+ corner_radius = 9,
+ border_color = colors.popup.border,
+ color = colors.popup.bg,
+ shadow = { drawing = true },
+ },
+ blur_radius = 50,
+ },
+ padding_left = 5,
+ padding_right = 5,
+ scroll_texts = true,
+})
diff --git a/dot_config/sketchybar/executable_sketchybarrc b/dot_config/sketchybar/executable_sketchybarrc
new file mode 100755
index 0000000..95ece11
--- /dev/null
+++ b/dot_config/sketchybar/executable_sketchybarrc
@@ -0,0 +1,5 @@
+#!/usr/bin/env lua
+
+-- Load the sketchybar-package and prepare the helper binaries
+require("helpers")
+require("init")
diff --git a/dot_config/sketchybar/helpers/app_icons.lua b/dot_config/sketchybar/helpers/app_icons.lua
new file mode 100644
index 0000000..f87d1bd
--- /dev/null
+++ b/dot_config/sketchybar/helpers/app_icons.lua
@@ -0,0 +1,313 @@
+return {
+ ["Live"] = ":ableton:",
+ ["Adobe Bridge"] = ":adobe_bridge:",
+ ["Affinity Designer"] = ":affinity_designer:",
+ ["Affinity Designer 2"] = ":affinity_designer_2:",
+ ["Affinity Photo"] = ":affinity_photo:",
+ ["Affinity Photo 2"] = ":affinity_photo_2:",
+ ["Affinity Publisher"] = ":affinity_publisher:",
+ ["Affinity Publisher 2"] = ":affinity_publisher_2:",
+ ["Airmail"] = ":airmail:",
+ ["Alacritty"] = ":alacritty:",
+ ["Alfred"] = ":alfred:",
+ ["Android Messages"] = ":android_messages:",
+ ["Android Studio"] = ":android_studio:",
+ ["Anki"] = ":anki:",
+ ["Anytype"] = ":anytype:",
+ ["App Eraser"] = ":app_eraser:",
+ ["App Store"] = ":app_store:",
+ ["Arc"] = ":arc:",
+ ["Arduino"] = ":arduino:",
+ ["Arduino IDE"] = ":arduino:",
+ ["Atom"] = ":atom:",
+ ["Audacity"] = ":audacity:",
+ ["Bambu Studio"] = ":bambu_studio:",
+ ["MoneyMoney"] = ":bank:",
+ ["Battle.net"] = ":battle_net:",
+ ["Bear"] = ":bear:",
+ ["BetterTouchTool"] = ":bettertouchtool:",
+ ["Bilibili"] = ":bilibili:",
+ ["哔哩哔哩"] = ":bilibili:",
+ ["Bitwarden"] = ":bit_warden:",
+ ["Blender"] = ":blender:",
+ ["BluOS Controller"] = ":bluos_controller:",
+ ["Calibre"] = ":book:",
+ ["Brave Browser"] = ":brave_browser:",
+ ["BusyCal"] = ":busycal:",
+ ["Calculator"] = ":calculator:",
+ ["Calculette"] = ":calculator:",
+ ["Calendar"] = ":calendar:",
+ ["日历"] = ":calendar:",
+ ["Fantastical"] = ":calendar:",
+ ["Cron"] = ":calendar:",
+ ["Amie"] = ":calendar:",
+ ["Calendrier"] = ":calendar:",
+ ["Notion Calendar"] = ":calendar:",
+ ["Caprine"] = ":caprine:",
+ ["Amazon Chime"] = ":chime:",
+ ["Citrix Workspace"] = ":citrix:",
+ ["Citrix Viewer"] = ":citrix:",
+ ["Claude"] = ":claude:",
+ ["ClickUp"] = ":click_up:",
+ ["Code"] = ":code:",
+ ["Code - Insiders"] = ":code:",
+ ["Cold Turkey Blocker"] = ":cold_turkey_blocker:",
+ ["Color Picker"] = ":color_picker:",
+ ["数码测色计"] = ":color_picker:",
+ ["Copilot"] = ":copilot:",
+ ["CotEditor"] = ":coteditor:",
+ ["Creative Cloud"] = ":creative_cloud:",
+ ["Cursor"] = ":cursor:",
+ ["Cypress"] = ":cypress:",
+ ["DataGrip"] = ":datagrip:",
+ ["DataSpell"] = ":dataspell:",
+ ["DaVinci Resolve"] = ":davinciresolve:",
+ ["Deezer"] = ":deezer:",
+ ["Default"] = ":default:",
+ ["CleanMyMac X"] = ":desktop:",
+ ["DEVONthink 3"] = ":devonthink3:",
+ ["DingTalk"] = ":dingtalk:",
+ ["钉钉"] = ":dingtalk:",
+ ["阿里钉"] = ":dingtalk:",
+ ["Discord"] = ":discord:",
+ ["Discord Canary"] = ":discord:",
+ ["Discord PTB"] = ":discord:",
+ ["Docker"] = ":docker:",
+ ["Docker Desktop"] = ":docker:",
+ ["GrandTotal"] = ":dollar:",
+ ["Receipts"] = ":dollar:",
+ ["Double Commander"] = ":doublecmd:",
+ ["Drafts"] = ":drafts:",
+ ["draw.io"] = ":draw_io:",
+ ["Dropbox"] = ":dropbox:",
+ ["Element"] = ":element:",
+ ["Emacs"] = ":emacs:",
+ ["Evernote Legacy"] = ":evernote_legacy:",
+ ["FaceTime"] = ":face_time:",
+ ["FaceTime 通话"] = ":face_time:",
+ ["Figma"] = ":figma:",
+ ["Final Cut Pro"] = ":final_cut_pro:",
+ ["Finder"] = ":finder:",
+ ["访达"] = ":finder:",
+ ["Firefox"] = ":firefox:",
+ ["Firefox Developer Edition"] = ":firefox_developer_edition:",
+ ["Firefox Nightly"] = ":firefox_developer_edition:",
+ ["Folx"] = ":folx:",
+ ["Fork"] = ":fork:",
+ ["FreeTube"] = ":freetube:",
+ ["Fusion"] = ":fusion:",
+ ["System Preferences"] = ":gear:",
+ ["System Settings"] = ":gear:",
+ ["系统设置"] = ":gear:",
+ ["Réglages Système"] = ":gear:",
+ ["GitHub Desktop"] = ":git_hub:",
+ ["Godot"] = ":godot:",
+ ["GoLand"] = ":goland:",
+ ["Chromium"] = ":google_chrome:",
+ ["Google Chrome"] = ":google_chrome:",
+ ["Google Chrome Canary"] = ":google_chrome:",
+ ["Grammarly Editor"] = ":grammarly:",
+ ["Home Assistant"] = ":home_assistant:",
+ ["Hyper"] = ":hyper:",
+ ["IntelliJ IDEA"] = ":idea:",
+ ["IINA"] = ":iina:",
+ ["Adobe Illustrator"] = ":illustrator:",
+ ["Illustrator"] = ":illustrator:",
+ ["Adobe InDesign"] = ":indesign:",
+ ["InDesign"] = ":indesign:",
+ ["Inkdrop"] = ":inkdrop:",
+ ["Inkscape"] = ":inkscape:",
+ ["Insomnia"] = ":insomnia:",
+ ["Iris"] = ":iris:",
+ ["iTerm"] = ":iterm:",
+ ["iTerm2"] = ":iterm:",
+ ["Jellyfin Media Player"] = ":jellyfin:",
+ ["Joplin"] = ":joplin:",
+ ["카카오톡"] = ":kakaotalk:",
+ ["KakaoTalk"] = ":kakaotalk:",
+ ["Kakoune"] = ":kakoune:",
+ ["KeePassXC"] = ":kee_pass_x_c:",
+ ["Keyboard Maestro"] = ":keyboard_maestro:",
+ ["Keynote"] = ":keynote:",
+ ["Keynote 讲演"] = ":keynote:",
+ ["kitty"] = ":kitty:",
+ ["League of Legends"] = ":league_of_legends:",
+ ["LibreWolf"] = ":libre_wolf:",
+ ["Adobe Lightroom"] = ":lightroom:",
+ ["Lightroom Classic"] = ":lightroomclassic:",
+ ["LINE"] = ":line:",
+ ["Linear"] = ":linear:",
+ ["LM Studio"] = ":lm_studio:",
+ ["LocalSend"] = ":localsend:",
+ ["Logic Pro"] = ":logicpro:",
+ ["Logseq"] = ":logseq:",
+ ["Canary Mail"] = ":mail:",
+ ["HEY"] = ":mail:",
+ ["Mail"] = ":mail:",
+ ["Mailspring"] = ":mail:",
+ ["MailMate"] = ":mail:",
+ ["Superhuman"] = ":mail:",
+ ["Spark"] = ":mail:",
+ ["邮件"] = ":mail:",
+ ["MAMP"] = ":mamp:",
+ ["MAMP PRO"] = ":mamp:",
+ ["Maps"] = ":maps:",
+ ["Google Maps"] = ":maps:",
+ ["Marta"] = ":marta:",
+ ["Matlab"] = ":matlab:",
+ ["Mattermost"] = ":mattermost:",
+ ["Messages"] = ":messages:",
+ ["信息"] = ":messages:",
+ ["Nachrichten"] = ":messages:",
+ ["Messenger"] = ":messenger:",
+ ["Microsoft Edge"] = ":microsoft_edge:",
+ ["Microsoft Excel"] = ":microsoft_excel:",
+ ["Microsoft Outlook"] = ":microsoft_outlook:",
+ ["Microsoft PowerPoint"] = ":microsoft_power_point:",
+ ["Microsoft Remote Desktop"] = ":microsoft_remote_desktop:",
+ ["Microsoft Teams"] = ":microsoft_teams:",
+ ["Microsoft Teams (work or school)"] = ":microsoft_teams:",
+ ["Microsoft Word"] = ":microsoft_word:",
+ ["Min"] = ":min_browser:",
+ ["Miro"] = ":miro:",
+ ["MongoDB Compass"] = ":mongodb:",
+ ["mpv"] = ":mpv:",
+ ["Mullvad Browser"] = ":mullvad_browser:",
+ ["Music"] = ":music:",
+ ["音乐"] = ":music:",
+ ["Musique"] = ":music:",
+ ["Neovide"] = ":neovide:",
+ ["neovide"] = ":neovide:",
+ ["Neovim"] = ":neovim:",
+ ["neovim"] = ":neovim:",
+ ["nvim"] = ":neovim:",
+ ["网易云音乐"] = ":netease_music:",
+ ["Noodl"] = ":noodl:",
+ ["Noodl Editor"] = ":noodl:",
+ ["NordVPN"] = ":nord_vpn:",
+ ["Notability"] = ":notability:",
+ ["Notes"] = ":notes:",
+ ["备忘录"] = ":notes:",
+ ["Notion"] = ":notion:",
+ ["Nova"] = ":nova:",
+ ["Numbers"] = ":numbers:",
+ ["Numbers 表格"] = ":numbers:",
+ ["Obsidian"] = ":obsidian:",
+ ["OBS"] = ":obsstudio:",
+ ["OmniFocus"] = ":omni_focus:",
+ ["1Password"] = ":one_password:",
+ ["Open Video Downloader"] = ":open_video_downloader:",
+ ["ChatGPT"] = ":openai:",
+ ["OpenVPN Connect"] = ":openvpn_connect:",
+ ["Opera"] = ":opera:",
+ ["OrbStack"] = ":orbstack:",
+ ["OrcaSlicer"] = ":orcaslicer:",
+ ["Orion"] = ":orion:",
+ ["Orion RC"] = ":orion:",
+ ["Pages"] = ":pages:",
+ ["Pages 文稿"] = ":pages:",
+ ["Parallels Desktop"] = ":parallels:",
+ ["Parsec"] = ":parsec:",
+ ["Preview"] = ":pdf:",
+ ["预览"] = ":pdf:",
+ ["Skim"] = ":pdf:",
+ ["zathura"] = ":pdf:",
+ ["Aperçu"] = ":pdf:",
+ ["PDF Expert"] = ":pdf_expert:",
+ ["Pearcleaner"] = ":pearcleaner:",
+ ["Phoenix Slides"] = ":phoenix_slides:",
+ ["Adobe Photoshop"] = ":photoshop:",
+ ["PhpStorm"] = ":php_storm:",
+ ["Pi-hole Remote"] = ":pihole:",
+ ["Pine"] = ":pine:",
+ ["Plex"] = ":plex:",
+ ["Plexamp"] = ":plexamp:",
+ ["Podcasts"] = ":podcasts:",
+ ["播客"] = ":podcasts:",
+ ["PomoDone App"] = ":pomodone:",
+ ["Postman"] = ":postman:",
+ ["Proton Mail"] = ":proton_mail:",
+ ["Proton Mail Bridge"] = ":proton_mail:",
+ ["PrusaSlicer"] = ":prusaslicer:",
+ ["SuperSlicer"] = ":prusaslicer:",
+ ["PyCharm"] = ":pycharm:",
+ ["QQ"] = ":qq:",
+ ["QQ音乐"] = ":qqmusic:",
+ ["QQMusic"] = ":qqmusic:",
+ ["Quantumult X"] = ":quantumult_x:",
+ ["qutebrowser"] = ":qute_browser:",
+ ["Raindrop.io"] = ":raindrop_io:",
+ ["Reeder"] = ":reeder5:",
+ ["Reminders"] = ":reminders:",
+ ["提醒事项"] = ":reminders:",
+ ["Rappels"] = ":reminders:",
+ ["Replit"] = ":replit:",
+ ["Rider"] = ":rider:",
+ ["JetBrains Rider"] = ":rider:",
+ ["Rio"] = ":rio:",
+ ["Royal TSX"] = ":royaltsx:",
+ ["Safari"] = ":safari:",
+ ["Safari浏览器"] = ":safari:",
+ ["Safari Technology Preview"] = ":safari:",
+ ["Sequel Ace"] = ":sequel_ace:",
+ ["Sequel Pro"] = ":sequel_pro:",
+ ["Setapp"] = ":setapp:",
+ ["SF Symbols"] = ":sf_symbols:",
+ ["Signal"] = ":signal:",
+ ["sioyek"] = ":sioyek:",
+ ["Sketch"] = ":sketch:",
+ ["Skype"] = ":skype:",
+ ["Slack"] = ":slack:",
+ ["Spark Desktop"] = ":spark:",
+ ["Spotify"] = ":spotify:",
+ ["Spotlight"] = ":spotlight:",
+ ["Sublime Text"] = ":sublime_text:",
+ ["superProductivity"] = ":superproductivity:",
+ ["Tana"] = ":tana:",
+ ["TeamSpeak 3"] = ":team_speak:",
+ ["Telegram"] = ":telegram:",
+ ["Terminal"] = ":terminal:",
+ ["终端"] = ":terminal:",
+ ["Typora"] = ":text:",
+ ["Microsoft To Do"] = ":things:",
+ ["Things"] = ":things:",
+ ["Thunderbird"] = ":thunderbird:",
+ ["TickTick"] = ":tick_tick:",
+ ["TIDAL"] = ":tidal:",
+ ["Tiny RDM"] = ":tinyrdm:",
+ ["Todoist"] = ":todoist:",
+ ["Toggl Track"] = ":toggl_track:",
+ ["Tor Browser"] = ":tor_browser:",
+ ["Tower"] = ":tower:",
+ ["Transmit"] = ":transmit:",
+ ["Trello"] = ":trello:",
+ ["Tweetbot"] = ":twitter:",
+ ["Twitter"] = ":twitter:",
+ ["UTM"] = ":utm:",
+ ["MacVim"] = ":vim:",
+ ["Vim"] = ":vim:",
+ ["VimR"] = ":vim:",
+ ["Vivaldi"] = ":vivaldi:",
+ ["VLC"] = ":vlc:",
+ ["VMware Fusion"] = ":vmware_fusion:",
+ ["VSCodium"] = ":vscodium:",
+ ["Warp"] = ":warp:",
+ ["WebStorm"] = ":web_storm:",
+ ["微信"] = ":wechat:",
+ ["WeChat"] = ":wechat:",
+ ["企业微信"] = ":wecom:",
+ ["WeCom"] = ":wecom:",
+ ["WezTerm"] = ":wezterm:",
+ ["WhatsApp"] = ":whats_app:",
+ ["WhatsApp"] = ":whats_app:",
+ ["Xcode"] = ":xcode:",
+ ["Yandex Music"] = ":yandex_music:",
+ ["Yuque"] = ":yuque:",
+ ["语雀"] = ":yuque:",
+ ["Zed"] = ":zed:",
+ ["Zen Browser"] = ":zen_browser:",
+ ["Zeplin"] = ":zeplin:",
+ ["zoom.us"] = ":zoom:",
+ ["Zotero"] = ":zotero:",
+ ["Zulip"] = ":zulip:",
+}
diff --git a/dot_config/sketchybar/helpers/default_font.lua b/dot_config/sketchybar/helpers/default_font.lua
new file mode 100644
index 0000000..fb1f16e
--- /dev/null
+++ b/dot_config/sketchybar/helpers/default_font.lua
@@ -0,0 +1,13 @@
+return {
+ text = "SF Pro", -- Used for text
+ numbers = "SF Mono", -- Used for numbers
+
+ -- Unified font style map
+ style_map = {
+ ["Regular"] = "Regular",
+ ["Semibold"] = "Semibold",
+ ["Bold"] = "Bold",
+ ["Heavy"] = "Heavy",
+ ["Black"] = "Black",
+ }
+}
diff --git a/dot_config/sketchybar/helpers/dot_gitignore b/dot_config/sketchybar/helpers/dot_gitignore
new file mode 100644
index 0000000..ba077a4
--- /dev/null
+++ b/dot_config/sketchybar/helpers/dot_gitignore
@@ -0,0 +1 @@
+bin
diff --git a/dot_config/sketchybar/helpers/event_providers/cpu_load/cpu.h b/dot_config/sketchybar/helpers/event_providers/cpu_load/cpu.h
new file mode 100644
index 0000000..413f70f
--- /dev/null
+++ b/dot_config/sketchybar/helpers/event_providers/cpu_load/cpu.h
@@ -0,0 +1,58 @@
+#include
+#include
+#include
+#include
+
+struct cpu {
+ host_t host;
+ mach_msg_type_number_t count;
+ host_cpu_load_info_data_t load;
+ host_cpu_load_info_data_t prev_load;
+ bool has_prev_load;
+
+ int user_load;
+ int sys_load;
+ int total_load;
+};
+
+static inline void cpu_init(struct cpu* cpu) {
+ cpu->host = mach_host_self();
+ cpu->count = HOST_CPU_LOAD_INFO_COUNT;
+ cpu->has_prev_load = false;
+}
+
+static inline void cpu_update(struct cpu* cpu) {
+ kern_return_t error = host_statistics(cpu->host,
+ HOST_CPU_LOAD_INFO,
+ (host_info_t)&cpu->load,
+ &cpu->count );
+
+ if (error != KERN_SUCCESS) {
+ printf("Error: Could not read cpu host statistics.\n");
+ return;
+ }
+
+ if (cpu->has_prev_load) {
+ uint32_t delta_user = cpu->load.cpu_ticks[CPU_STATE_USER]
+ - cpu->prev_load.cpu_ticks[CPU_STATE_USER];
+
+ uint32_t delta_system = cpu->load.cpu_ticks[CPU_STATE_SYSTEM]
+ - cpu->prev_load.cpu_ticks[CPU_STATE_SYSTEM];
+
+ uint32_t delta_idle = cpu->load.cpu_ticks[CPU_STATE_IDLE]
+ - cpu->prev_load.cpu_ticks[CPU_STATE_IDLE];
+
+ cpu->user_load = (double)delta_user / (double)(delta_system
+ + delta_user
+ + delta_idle) * 100.0;
+
+ cpu->sys_load = (double)delta_system / (double)(delta_system
+ + delta_user
+ + delta_idle) * 100.0;
+
+ cpu->total_load = cpu->user_load + cpu->sys_load;
+ }
+
+ cpu->prev_load = cpu->load;
+ cpu->has_prev_load = true;
+}
diff --git a/dot_config/sketchybar/helpers/event_providers/cpu_load/cpu_load.c b/dot_config/sketchybar/helpers/event_providers/cpu_load/cpu_load.c
new file mode 100644
index 0000000..ee97613
--- /dev/null
+++ b/dot_config/sketchybar/helpers/event_providers/cpu_load/cpu_load.c
@@ -0,0 +1,41 @@
+#include "cpu.h"
+#include "../sketchybar.h"
+
+int main (int argc, char** argv) {
+ float update_freq;
+ if (argc < 3 || (sscanf(argv[2], "%f", &update_freq) != 1)) {
+ printf("Usage: %s \"\" \"\"\n", argv[0]);
+ exit(1);
+ }
+
+ alarm(0);
+ struct cpu cpu;
+ cpu_init(&cpu);
+
+ // Setup the event in sketchybar
+ char event_message[512];
+ snprintf(event_message, 512, "--add event '%s'", argv[1]);
+ sketchybar(event_message);
+
+ char trigger_message[512];
+ for (;;) {
+ // Acquire new info
+ cpu_update(&cpu);
+
+ // Prepare the event message
+ snprintf(trigger_message,
+ 512,
+ "--trigger '%s' user_load='%d' sys_load='%02d' total_load='%02d'",
+ argv[1],
+ cpu.user_load,
+ cpu.sys_load,
+ cpu.total_load );
+
+ // Trigger the event
+ sketchybar(trigger_message);
+
+ // Wait
+ usleep(update_freq * 1000000);
+ }
+ return 0;
+}
diff --git a/dot_config/sketchybar/helpers/event_providers/cpu_load/makefile b/dot_config/sketchybar/helpers/event_providers/cpu_load/makefile
new file mode 100644
index 0000000..6366a0f
--- /dev/null
+++ b/dot_config/sketchybar/helpers/event_providers/cpu_load/makefile
@@ -0,0 +1,5 @@
+bin/cpu_load: cpu_load.c cpu.h ../sketchybar.h | bin
+ clang -std=c99 -O3 $< -o $@
+
+bin:
+ mkdir bin
diff --git a/dot_config/sketchybar/helpers/event_providers/makefile b/dot_config/sketchybar/helpers/event_providers/makefile
new file mode 100644
index 0000000..8c1ca39
--- /dev/null
+++ b/dot_config/sketchybar/helpers/event_providers/makefile
@@ -0,0 +1,3 @@
+all:
+ (cd cpu_load && $(MAKE))
+ (cd network_load && $(MAKE))
diff --git a/dot_config/sketchybar/helpers/event_providers/network_load/makefile b/dot_config/sketchybar/helpers/event_providers/network_load/makefile
new file mode 100644
index 0000000..e464482
--- /dev/null
+++ b/dot_config/sketchybar/helpers/event_providers/network_load/makefile
@@ -0,0 +1,5 @@
+bin/network_load: network_load.c network.h ../sketchybar.h | bin
+ clang -std=c99 -O3 $< -o $@
+
+bin:
+ mkdir bin
diff --git a/dot_config/sketchybar/helpers/event_providers/network_load/network.h b/dot_config/sketchybar/helpers/event_providers/network_load/network.h
new file mode 100644
index 0000000..25175e5
--- /dev/null
+++ b/dot_config/sketchybar/helpers/event_providers/network_load/network.h
@@ -0,0 +1,90 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+static char unit_str[3][6] = { { " Bps" }, { "KBps" }, { "MBps" }, };
+
+enum unit {
+ UNIT_BPS,
+ UNIT_KBPS,
+ UNIT_MBPS
+};
+struct network {
+ uint32_t row;
+ struct ifmibdata data;
+ struct timeval tv_nm1, tv_n, tv_delta;
+
+ int up;
+ int down;
+ enum unit up_unit, down_unit;
+};
+
+static inline void ifdata(uint32_t net_row, struct ifmibdata* data) {
+ static size_t size = sizeof(struct ifmibdata);
+ static int32_t data_option[] = { CTL_NET, PF_LINK, NETLINK_GENERIC, IFMIB_IFDATA, 0, IFDATA_GENERAL };
+ data_option[4] = net_row;
+ sysctl(data_option, 6, data, &size, NULL, 0);
+}
+
+static inline void network_init(struct network* net, char* ifname) {
+ memset(net, 0, sizeof(struct network));
+
+ static int count_option[] = { CTL_NET, PF_LINK, NETLINK_GENERIC, IFMIB_SYSTEM, IFMIB_IFCOUNT };
+ uint32_t interface_count = 0;
+ size_t size = sizeof(uint32_t);
+ sysctl(count_option, 5, &interface_count, &size, NULL, 0);
+
+ for (int i = 0; i < interface_count; i++) {
+ ifdata(i, &net->data);
+ if (strcmp(net->data.ifmd_name, ifname) == 0) {
+ net->row = i;
+ break;
+ }
+ }
+}
+
+static inline void network_update(struct network* net) {
+ gettimeofday(&net->tv_n, NULL);
+ timersub(&net->tv_n, &net->tv_nm1, &net->tv_delta);
+ net->tv_nm1 = net->tv_n;
+
+ uint64_t ibytes_nm1 = net->data.ifmd_data.ifi_ibytes;
+ uint64_t obytes_nm1 = net->data.ifmd_data.ifi_obytes;
+ ifdata(net->row, &net->data);
+
+ double time_scale = (net->tv_delta.tv_sec + 1e-6*net->tv_delta.tv_usec);
+ if (time_scale < 1e-6 || time_scale > 1e2) return;
+ double delta_ibytes = (double)(net->data.ifmd_data.ifi_ibytes - ibytes_nm1)
+ / time_scale;
+ double delta_obytes = (double)(net->data.ifmd_data.ifi_obytes - obytes_nm1)
+ / time_scale;
+
+ double exponent_ibytes = log10(delta_ibytes);
+ double exponent_obytes = log10(delta_obytes);
+
+ if (exponent_ibytes < 3) {
+ net->down_unit = UNIT_BPS;
+ net->down = delta_ibytes;
+ } else if (exponent_ibytes < 6) {
+ net->down_unit = UNIT_KBPS;
+ net->down = delta_ibytes / 1000.0;
+ } else if (exponent_ibytes < 9) {
+ net->down_unit = UNIT_MBPS;
+ net->down = delta_ibytes / 1000000.0;
+ }
+
+ if (exponent_obytes < 3) {
+ net->up_unit = UNIT_BPS;
+ net->up = delta_obytes;
+ } else if (exponent_obytes < 6) {
+ net->up_unit = UNIT_KBPS;
+ net->up = delta_obytes / 1000.0;
+ } else if (exponent_obytes < 9) {
+ net->up_unit = UNIT_MBPS;
+ net->up = delta_obytes / 1000000.0;
+ }
+}
diff --git a/dot_config/sketchybar/helpers/event_providers/network_load/network_load.c b/dot_config/sketchybar/helpers/event_providers/network_load/network_load.c
new file mode 100644
index 0000000..06afe95
--- /dev/null
+++ b/dot_config/sketchybar/helpers/event_providers/network_load/network_load.c
@@ -0,0 +1,42 @@
+#include
+#include "network.h"
+#include "../sketchybar.h"
+
+int main (int argc, char** argv) {
+ float update_freq;
+ if (argc < 4 || (sscanf(argv[3], "%f", &update_freq) != 1)) {
+ printf("Usage: %s \"\" \"\" \"\"\n", argv[0]);
+ exit(1);
+ }
+
+ alarm(0);
+ // Setup the event in sketchybar
+ char event_message[512];
+ snprintf(event_message, 512, "--add event '%s'", argv[2]);
+ sketchybar(event_message);
+
+ struct network network;
+ network_init(&network, argv[1]);
+ char trigger_message[512];
+ for (;;) {
+ // Acquire new info
+ network_update(&network);
+
+ // Prepare the event message
+ snprintf(trigger_message,
+ 512,
+ "--trigger '%s' upload='%03d%s' download='%03d%s'",
+ argv[2],
+ network.up,
+ unit_str[network.up_unit],
+ network.down,
+ unit_str[network.down_unit]);
+
+ // Trigger the event
+ sketchybar(trigger_message);
+
+ // Wait
+ usleep(update_freq * 1000000);
+ }
+ return 0;
+}
diff --git a/dot_config/sketchybar/helpers/event_providers/sketchybar.h b/dot_config/sketchybar/helpers/event_providers/sketchybar.h
new file mode 100644
index 0000000..72bf06a
--- /dev/null
+++ b/dot_config/sketchybar/helpers/event_providers/sketchybar.h
@@ -0,0 +1,122 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+typedef char* env;
+
+#define MACH_HANDLER(name) void name(env env)
+typedef MACH_HANDLER(mach_handler);
+
+struct mach_message {
+ mach_msg_header_t header;
+ mach_msg_size_t msgh_descriptor_count;
+ mach_msg_ool_descriptor_t descriptor;
+};
+
+struct mach_buffer {
+ struct mach_message message;
+ mach_msg_trailer_t trailer;
+};
+
+static mach_port_t g_mach_port = 0;
+
+static inline mach_port_t mach_get_bs_port() {
+ mach_port_name_t task = mach_task_self();
+
+ mach_port_t bs_port;
+ if (task_get_special_port(task,
+ TASK_BOOTSTRAP_PORT,
+ &bs_port ) != KERN_SUCCESS) {
+ return 0;
+ }
+
+ char* name = getenv("BAR_NAME");
+ if (!name) name = "sketchybar";
+ uint32_t lookup_len = 16 + strlen(name);
+
+ char buffer[lookup_len];
+ snprintf(buffer, lookup_len, "git.felix.%s", name);
+
+ mach_port_t port;
+ if (bootstrap_look_up(bs_port, buffer, &port) != KERN_SUCCESS) return 0;
+ return port;
+}
+
+static inline bool mach_send_message(mach_port_t port, char* message, uint32_t len) {
+ if (!message || !port) {
+ return false;
+ }
+
+ struct mach_message msg = { 0 };
+ msg.header.msgh_remote_port = port;
+ msg.header.msgh_local_port = 0;
+ msg.header.msgh_id = 0;
+ msg.header.msgh_bits = MACH_MSGH_BITS_SET(MACH_MSG_TYPE_COPY_SEND,
+ MACH_MSG_TYPE_MAKE_SEND,
+ 0,
+ MACH_MSGH_BITS_COMPLEX );
+
+ msg.header.msgh_size = sizeof(struct mach_message);
+ msg.msgh_descriptor_count = 1;
+ msg.descriptor.address = message;
+ msg.descriptor.size = len * sizeof(char);
+ msg.descriptor.copy = MACH_MSG_VIRTUAL_COPY;
+ msg.descriptor.deallocate = false;
+ msg.descriptor.type = MACH_MSG_OOL_DESCRIPTOR;
+
+ kern_return_t err = mach_msg(&msg.header,
+ MACH_SEND_MSG,
+ sizeof(struct mach_message),
+ 0,
+ MACH_PORT_NULL,
+ MACH_MSG_TIMEOUT_NONE,
+ MACH_PORT_NULL );
+
+ return err == KERN_SUCCESS;
+}
+
+static inline uint32_t format_message(char* message, char* formatted_message) {
+ // This is not actually robust, switch to stack based messaging.
+ char outer_quote = 0;
+ uint32_t caret = 0;
+ uint32_t message_length = strlen(message) + 1;
+ for (int i = 0; i < message_length; ++i) {
+ if (message[i] == '"' || message[i] == '\'') {
+ if (outer_quote && outer_quote == message[i]) outer_quote = 0;
+ else if (!outer_quote) outer_quote = message[i];
+ continue;
+ }
+ formatted_message[caret] = message[i];
+ if (message[i] == ' ' && !outer_quote) formatted_message[caret] = '\0';
+ caret++;
+ }
+
+ if (caret > 0 && formatted_message[caret] == '\0'
+ && formatted_message[caret - 1] == '\0') {
+ caret--;
+ }
+ formatted_message[caret] = '\0';
+ return caret + 1;
+}
+
+static inline void sketchybar(char* message) {
+ char formatted_message[strlen(message) + 2];
+ uint32_t length = format_message(message, formatted_message);
+ if (!length) return;
+
+ if (!g_mach_port) g_mach_port = mach_get_bs_port();
+ if (!mach_send_message(g_mach_port, formatted_message, length)) {
+ g_mach_port = mach_get_bs_port();
+ if (!mach_send_message(g_mach_port, formatted_message, length)) {
+ // No sketchybar instance running, exit.
+ exit(0);
+ }
+ }
+}
diff --git a/dot_config/sketchybar/helpers/init.lua b/dot_config/sketchybar/helpers/init.lua
new file mode 100644
index 0000000..351531a
--- /dev/null
+++ b/dot_config/sketchybar/helpers/init.lua
@@ -0,0 +1,4 @@
+-- Add the sketchybar module to the package cpath
+package.cpath = package.cpath .. ";/Users/" .. os.getenv("USER") .. "/.local/share/sketchybar_lua/?.so"
+
+os.execute("(cd helpers && make)")
diff --git a/dot_config/sketchybar/helpers/makefile b/dot_config/sketchybar/helpers/makefile
new file mode 100644
index 0000000..3246108
--- /dev/null
+++ b/dot_config/sketchybar/helpers/makefile
@@ -0,0 +1,3 @@
+all:
+ (cd event_providers && $(MAKE)) >/dev/null
+ (cd menus && $(MAKE)) >/dev/null
diff --git a/dot_config/sketchybar/helpers/menus/makefile b/dot_config/sketchybar/helpers/menus/makefile
new file mode 100644
index 0000000..0cb454e
--- /dev/null
+++ b/dot_config/sketchybar/helpers/menus/makefile
@@ -0,0 +1,5 @@
+bin/menus: menus.c | bin
+ clang -std=c99 -O3 -F/System/Library/PrivateFrameworks/ -framework Carbon -framework SkyLight $< -o $@
+
+bin:
+ mkdir bin
diff --git a/dot_config/sketchybar/helpers/menus/menus.c b/dot_config/sketchybar/helpers/menus/menus.c
new file mode 100644
index 0000000..2e77822
--- /dev/null
+++ b/dot_config/sketchybar/helpers/menus/menus.c
@@ -0,0 +1,248 @@
+#include
+
+void ax_init() {
+ const void *keys[] = { kAXTrustedCheckOptionPrompt };
+ const void *values[] = { kCFBooleanTrue };
+
+ CFDictionaryRef options;
+ options = CFDictionaryCreate(kCFAllocatorDefault,
+ keys,
+ values,
+ sizeof(keys) / sizeof(*keys),
+ &kCFCopyStringDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks );
+
+ bool trusted = AXIsProcessTrustedWithOptions(options);
+ CFRelease(options);
+ if (!trusted) exit(1);
+}
+
+void ax_perform_click(AXUIElementRef element) {
+ if (!element) return;
+ AXUIElementPerformAction(element, kAXCancelAction);
+ usleep(150000);
+ AXUIElementPerformAction(element, kAXPressAction);
+}
+
+CFStringRef ax_get_title(AXUIElementRef element) {
+ CFTypeRef title = NULL;
+ AXError error = AXUIElementCopyAttributeValue(element,
+ kAXTitleAttribute,
+ &title );
+
+ if (error != kAXErrorSuccess) return NULL;
+ return title;
+}
+
+void ax_select_menu_option(AXUIElementRef app, int id) {
+ AXUIElementRef menubars_ref = NULL;
+ CFArrayRef children_ref = NULL;
+
+ AXError error = AXUIElementCopyAttributeValue(app,
+ kAXMenuBarAttribute,
+ (CFTypeRef*)&menubars_ref);
+ if (error == kAXErrorSuccess) {
+ error = AXUIElementCopyAttributeValue(menubars_ref,
+ kAXVisibleChildrenAttribute,
+ (CFTypeRef*)&children_ref );
+
+ if (error == kAXErrorSuccess) {
+ uint32_t count = CFArrayGetCount(children_ref);
+ if (id < count) {
+ AXUIElementRef item = CFArrayGetValueAtIndex(children_ref, id);
+ ax_perform_click(item);
+ }
+ if (children_ref) CFRelease(children_ref);
+ }
+ if (menubars_ref) CFRelease(menubars_ref);
+ }
+}
+
+void ax_print_menu_options(AXUIElementRef app) {
+ AXUIElementRef menubars_ref = NULL;
+ CFTypeRef menubar = NULL;
+ CFArrayRef children_ref = NULL;
+
+ AXError error = AXUIElementCopyAttributeValue(app,
+ kAXMenuBarAttribute,
+ (CFTypeRef*)&menubars_ref);
+ if (error == kAXErrorSuccess) {
+ error = AXUIElementCopyAttributeValue(menubars_ref,
+ kAXVisibleChildrenAttribute,
+ (CFTypeRef*)&children_ref );
+
+ if (error == kAXErrorSuccess) {
+ uint32_t count = CFArrayGetCount(children_ref);
+
+ for (int i = 1; i < count; i++) {
+ AXUIElementRef item = CFArrayGetValueAtIndex(children_ref, i);
+ CFTypeRef title = ax_get_title(item);
+
+ if (title) {
+ uint32_t buffer_len = 2*CFStringGetLength(title);
+ char buffer[2*CFStringGetLength(title)];
+ CFStringGetCString(title, buffer, buffer_len, kCFStringEncodingUTF8);
+ printf("%s\n", buffer);
+ CFRelease(title);
+ }
+ }
+ }
+ if (menubars_ref) CFRelease(menubars_ref);
+ if (children_ref) CFRelease(children_ref);
+ }
+}
+
+AXUIElementRef ax_get_extra_menu_item(char* alias) {
+ pid_t pid = 0;
+ CGRect bounds = CGRectNull;
+ CFArrayRef window_list = CGWindowListCopyWindowInfo(kCGWindowListOptionAll,
+ kCGNullWindowID );
+ char owner_buffer[256];
+ char name_buffer[256];
+ char buffer[512];
+ int window_count = CFArrayGetCount(window_list);
+ for (int i = 0; i < window_count; ++i) {
+ CFDictionaryRef dictionary = CFArrayGetValueAtIndex(window_list, i);
+ if (!dictionary) continue;
+
+ CFStringRef owner_ref = CFDictionaryGetValue(dictionary,
+ kCGWindowOwnerName);
+
+ CFNumberRef owner_pid_ref = CFDictionaryGetValue(dictionary,
+ kCGWindowOwnerPID);
+
+ CFStringRef name_ref = CFDictionaryGetValue(dictionary, kCGWindowName);
+ CFNumberRef layer_ref = CFDictionaryGetValue(dictionary, kCGWindowLayer);
+ CFDictionaryRef bounds_ref = CFDictionaryGetValue(dictionary,
+ kCGWindowBounds);
+
+ if (!name_ref || !owner_ref || !owner_pid_ref || !layer_ref || !bounds_ref)
+ continue;
+
+ long long int layer = 0;
+ CFNumberGetValue(layer_ref, CFNumberGetType(layer_ref), &layer);
+ uint64_t owner_pid = 0;
+ CFNumberGetValue(owner_pid_ref,
+ CFNumberGetType(owner_pid_ref),
+ &owner_pid );
+
+ if (layer != 0x19) continue;
+ bounds = CGRectNull;
+ if (!CGRectMakeWithDictionaryRepresentation(bounds_ref, &bounds)) continue;
+ CFStringGetCString(owner_ref,
+ owner_buffer,
+ sizeof(owner_buffer),
+ kCFStringEncodingUTF8);
+
+ CFStringGetCString(name_ref,
+ name_buffer,
+ sizeof(name_buffer),
+ kCFStringEncodingUTF8);
+ snprintf(buffer, sizeof(buffer), "%s,%s", owner_buffer, name_buffer);
+
+ if (strcmp(buffer, alias) == 0) {
+ pid = owner_pid;
+ break;
+ }
+ }
+ CFRelease(window_list);
+ if (!pid) return NULL;
+
+ AXUIElementRef app = AXUIElementCreateApplication(pid);
+ if (!app) return NULL;
+ AXUIElementRef result = NULL;
+ CFTypeRef extras = NULL;
+ CFArrayRef children_ref = NULL;
+ AXError error = AXUIElementCopyAttributeValue(app,
+ kAXExtrasMenuBarAttribute,
+ &extras );
+ if (error == kAXErrorSuccess) {
+ error = AXUIElementCopyAttributeValue(extras,
+ kAXVisibleChildrenAttribute,
+ (CFTypeRef*)&children_ref );
+
+ if (error == kAXErrorSuccess) {
+ uint32_t count = CFArrayGetCount(children_ref);
+ for (uint32_t i = 0; i < count; i++) {
+ AXUIElementRef item = CFArrayGetValueAtIndex(children_ref, i);
+ CFTypeRef position_ref = NULL;
+ CFTypeRef size_ref = NULL;
+ AXUIElementCopyAttributeValue(item, kAXPositionAttribute,
+ &position_ref );
+ AXUIElementCopyAttributeValue(item, kAXSizeAttribute,
+ &size_ref );
+ if (!position_ref || !size_ref) continue;
+
+ CGPoint position = CGPointZero;
+ AXValueGetValue(position_ref, kAXValueCGPointType, &position);
+ CGSize size = CGSizeZero;
+ AXValueGetValue(size_ref, kAXValueCGSizeType, &size);
+ CFRelease(position_ref);
+ CFRelease(size_ref);
+ // The offset is exactly 8 on macOS Sonoma...
+ // printf("%f %f\n", position.x, bounds.origin.x);
+ if (error == kAXErrorSuccess
+ && fabs(position.x - bounds.origin.x) <= 10) {
+ result = item;
+ break;
+ }
+ }
+ }
+ }
+
+ CFRelease(app);
+ return result;
+}
+
+extern int SLSMainConnectionID();
+extern void SLSSetMenuBarVisibilityOverrideOnDisplay(int cid, int did, bool enabled);
+extern void SLSSetMenuBarVisibilityOverrideOnDisplay(int cid, int did, bool enabled);
+extern void SLSSetMenuBarInsetAndAlpha(int cid, double u1, double u2, float alpha);
+void ax_select_menu_extra(char* alias) {
+ AXUIElementRef item = ax_get_extra_menu_item(alias);
+ if (!item) return;
+ SLSSetMenuBarInsetAndAlpha(SLSMainConnectionID(), 0, 1, 0.0);
+ SLSSetMenuBarVisibilityOverrideOnDisplay(SLSMainConnectionID(), 0, true);
+ SLSSetMenuBarInsetAndAlpha(SLSMainConnectionID(), 0, 1, 0.0);
+ ax_perform_click(item);
+ SLSSetMenuBarVisibilityOverrideOnDisplay(SLSMainConnectionID(), 0, false);
+ SLSSetMenuBarInsetAndAlpha(SLSMainConnectionID(), 0, 1, 1.0);
+ CFRelease(item);
+}
+
+extern void _SLPSGetFrontProcess(ProcessSerialNumber* psn);
+extern void SLSGetConnectionIDForPSN(int cid, ProcessSerialNumber* psn, int* cid_out);
+extern void SLSConnectionGetPID(int cid, pid_t* pid_out);
+AXUIElementRef ax_get_front_app() {
+ ProcessSerialNumber psn;
+ _SLPSGetFrontProcess(&psn);
+ int target_cid;
+ SLSGetConnectionIDForPSN(SLSMainConnectionID(), &psn, &target_cid);
+
+ pid_t pid;
+ SLSConnectionGetPID(target_cid, &pid);
+ return AXUIElementCreateApplication(pid);
+}
+
+int main (int argc, char **argv) {
+ if (argc == 1) {
+ printf("Usage: %s [-l | -s id/alias ]\n", argv[0]);
+ exit(0);
+ }
+ ax_init();
+ if (strcmp(argv[1], "-l") == 0) {
+ AXUIElementRef app = ax_get_front_app();
+ if (!app) return 1;
+ ax_print_menu_options(app);
+ CFRelease(app);
+ } else if (argc == 3 && strcmp(argv[1], "-s") == 0) {
+ int id = 0;
+ if (sscanf(argv[2], "%d", &id) == 1) {
+ AXUIElementRef app = ax_get_front_app();
+ if (!app) return 1;
+ ax_select_menu_option(app, id);
+ CFRelease(app);
+ } else ax_select_menu_extra(argv[2]);
+ }
+ return 0;
+}
diff --git a/dot_config/sketchybar/icons.lua b/dot_config/sketchybar/icons.lua
new file mode 100644
index 0000000..2e52a91
--- /dev/null
+++ b/dot_config/sketchybar/icons.lua
@@ -0,0 +1,92 @@
+local settings = require("settings")
+
+local icons = {
+ sf_symbols = {
+ plus = "",
+ loading = "",
+ apple = "",
+ gear = "",
+ cpu = "",
+ clipboard = "",
+
+ switch = {
+ on = "",
+ off = "",
+ },
+ volume = {
+ _100="",
+ _66="",
+ _33="",
+ _10="",
+ _0="",
+ },
+ battery = {
+ _100 = "",
+ _75 = "",
+ _50 = "",
+ _25 = "",
+ _0 = "",
+ charging = ""
+ },
+ wifi = {
+ upload = "",
+ download = "",
+ connected = "",
+ disconnected = "",
+ router = "",
+ },
+ media = {
+ back = "",
+ forward = "",
+ play_pause = "",
+ },
+ },
+
+ -- Alternative NerdFont icons
+ nerdfont = {
+ plus = "",
+ loading = "",
+ apple = "",
+ gear = "",
+ cpu = "",
+ clipboard = "Missing Icon",
+
+ switch = {
+ on = "",
+ off = "",
+ },
+ volume = {
+ _100="",
+ _66="",
+ _33="",
+ _10="",
+ _0="",
+ },
+ battery = {
+ _100 = "",
+ _75 = "",
+ _50 = "",
+ _25 = "",
+ _0 = "",
+ charging = ""
+ },
+ wifi = {
+ upload = "",
+ download = "",
+ connected = "",
+ disconnected = "",
+ router = "Missing Icon"
+ },
+ media = {
+ back = "",
+ forward = "",
+ play_pause = "",
+ },
+ },
+}
+
+if not (settings.icons == "NerdFont") then
+ return icons.sf_symbols
+else
+ return icons.nerdfont
+end
diff --git a/dot_config/sketchybar/icons.sh b/dot_config/sketchybar/icons.sh
new file mode 100644
index 0000000..147c4f5
--- /dev/null
+++ b/dot_config/sketchybar/icons.sh
@@ -0,0 +1,42 @@
+#!/usr/bin/env sh
+
+# General Icons
+LOADING=
+APPLE=
+PREFERENCES=
+ACTIVITY=
+LOCK=
+MAIL=
+MAIL_OPEN=
+BELL=
+BELL_DOT=
+CALENDAR=
+
+# Git Icons
+GIT_ISSUE=
+GIT_DISCUSSION=
+GIT_PULL_REQUEST=
+GIT_COMMIT=
+GIT_INDICATOR=
+
+# Spotify Icons
+SPOTIFY_BACK=
+SPOTIFY_PLAY_PAUSE=
+SPOTIFY_NEXT=
+SPOTIFY_SHUFFLE=
+SPOTIFY_REPEAT=
+
+# Yabai Icons
+YABAI_STACK=
+YABAI_FULLSCREEN_ZOOM=
+YABAI_PARENT_ZOOM=
+YABAI_FLOAT=
+YABAI_GRID=
+
+# Battery Icons
+BATTERY_FULL=
+BATTERY_75=
+BATTERY_50=
+BATTERY_25=
+BATTERY_0=
+BATTERY_CHARGING=
diff --git a/dot_config/sketchybar/init.lua b/dot_config/sketchybar/init.lua
new file mode 100644
index 0000000..e1bf892
--- /dev/null
+++ b/dot_config/sketchybar/init.lua
@@ -0,0 +1,16 @@
+-- Require the sketchybar module
+sbar = require("sketchybar")
+
+-- Set the bar name, if you are using another bar instance than sketchybar
+-- sbar.set_bar_name("bottom_bar")
+
+-- Bundle the entire initial configuration into a single message to sketchybar
+sbar.begin_config()
+require("bar")
+require("default")
+require("items")
+sbar.end_config()
+
+-- Run the event loop of the sketchybar module (without this there will be no
+-- callback functions executed in the lua module)
+sbar.event_loop()
diff --git a/dot_config/sketchybar/items/apple.lua b/dot_config/sketchybar/items/apple.lua
new file mode 100644
index 0000000..8b11ef1
--- /dev/null
+++ b/dot_config/sketchybar/items/apple.lua
@@ -0,0 +1,36 @@
+local colors = require("colors")
+local icons = require("icons")
+local settings = require("settings")
+
+-- Padding item required because of bracket
+sbar.add("item", { width = 5 })
+
+local apple = sbar.add("item", {
+ icon = {
+ font = { size = 16.0 },
+ string = icons.apple,
+ padding_right = 8,
+ padding_left = 8,
+ },
+ label = { drawing = false },
+ background = {
+ color = colors.bg2,
+ border_color = colors.black,
+ border_width = 1
+ },
+ padding_left = 1,
+ padding_right = 1,
+ click_script = "$CONFIG_DIR/helpers/menus/bin/menus -s 0"
+})
+
+-- Double border for apple using a single item bracket
+sbar.add("bracket", { apple.name }, {
+ background = {
+ color = colors.transparent,
+ height = 30,
+ border_color = colors.grey,
+ }
+})
+
+-- Padding item required because of bracket
+sbar.add("item", { width = 7 })
diff --git a/dot_config/sketchybar/items/calendar.lua b/dot_config/sketchybar/items/calendar.lua
new file mode 100644
index 0000000..4a42249
--- /dev/null
+++ b/dot_config/sketchybar/items/calendar.lua
@@ -0,0 +1,49 @@
+local settings = require("settings")
+local colors = require("colors")
+
+-- Padding item required because of bracket
+sbar.add("item", { position = "right", width = settings.group_paddings })
+
+local cal = sbar.add("item", {
+ icon = {
+ color = colors.white,
+ padding_left = 8,
+ font = {
+ style = settings.font.style_map["Black"],
+ size = 12.0,
+ },
+ },
+ label = {
+ color = colors.white,
+ padding_right = 8,
+ width = 49,
+ align = "right",
+ font = { family = settings.font.numbers },
+ },
+ position = "right",
+ update_freq = 30,
+ padding_left = 1,
+ padding_right = 1,
+ background = {
+ color = colors.bg2,
+ border_color = colors.black,
+ border_width = 1
+ },
+ click_script = "open -a 'Calendar'"
+})
+
+-- Double border for calendar using a single item bracket
+sbar.add("bracket", { cal.name }, {
+ background = {
+ color = colors.transparent,
+ height = 30,
+ border_color = colors.grey,
+ }
+})
+
+-- Padding item required because of bracket
+sbar.add("item", { position = "right", width = settings.group_paddings })
+
+cal:subscribe({ "forced", "routine", "system_woke" }, function(env)
+ cal:set({ icon = os.date("%a. %d %b."), label = os.date("%H:%M") })
+end)
diff --git a/dot_config/sketchybar/items/front_app.lua b/dot_config/sketchybar/items/front_app.lua
new file mode 100644
index 0000000..a5be8ad
--- /dev/null
+++ b/dot_config/sketchybar/items/front_app.lua
@@ -0,0 +1,22 @@
+local colors = require("colors")
+local settings = require("settings")
+
+local front_app = sbar.add("item", "front_app", {
+ display = "active",
+ icon = { drawing = false },
+ label = {
+ font = {
+ style = settings.font.style_map["Black"],
+ size = 12.0,
+ },
+ },
+ updates = true,
+})
+
+front_app:subscribe("front_app_switched", function(env)
+ front_app:set({ label = { string = env.INFO } })
+end)
+
+front_app:subscribe("mouse.clicked", function(env)
+ sbar.trigger("swap_menus_and_spaces")
+end)
diff --git a/dot_config/sketchybar/items/init.lua b/dot_config/sketchybar/items/init.lua
new file mode 100644
index 0000000..dad59fa
--- /dev/null
+++ b/dot_config/sketchybar/items/init.lua
@@ -0,0 +1,7 @@
+require("items.apple")
+require("items.menus")
+require("items.spaces")
+require("items.front_app")
+require("items.calendar")
+require("items.widgets")
+require("items.media")
diff --git a/dot_config/sketchybar/items/media.lua b/dot_config/sketchybar/items/media.lua
new file mode 100644
index 0000000..adcaea2
--- /dev/null
+++ b/dot_config/sketchybar/items/media.lua
@@ -0,0 +1,118 @@
+local icons = require("icons")
+local colors = require("colors")
+
+local whitelist = { ["Spotify"] = true,
+ ["Music"] = true };
+
+local media_cover = sbar.add("item", {
+ position = "right",
+ background = {
+ image = {
+ string = "media.artwork",
+ scale = 0.85,
+ },
+ color = colors.transparent,
+ },
+ label = { drawing = false },
+ icon = { drawing = false },
+ drawing = false,
+ updates = true,
+ popup = {
+ align = "center",
+ horizontal = true,
+ }
+})
+
+local media_artist = sbar.add("item", {
+ position = "right",
+ drawing = false,
+ padding_left = 3,
+ padding_right = 0,
+ width = 0,
+ icon = { drawing = false },
+ label = {
+ width = 0,
+ font = { size = 9 },
+ color = colors.with_alpha(colors.white, 0.6),
+ max_chars = 18,
+ y_offset = 6,
+ },
+})
+
+local media_title = sbar.add("item", {
+ position = "right",
+ drawing = false,
+ padding_left = 3,
+ padding_right = 0,
+ icon = { drawing = false },
+ label = {
+ font = { size = 11 },
+ width = 0,
+ max_chars = 16,
+ y_offset = -5,
+ },
+})
+
+sbar.add("item", {
+ position = "popup." .. media_cover.name,
+ icon = { string = icons.media.back },
+ label = { drawing = false },
+ click_script = "nowplaying-cli previous",
+})
+sbar.add("item", {
+ position = "popup." .. media_cover.name,
+ icon = { string = icons.media.play_pause },
+ label = { drawing = false },
+ click_script = "nowplaying-cli togglePlayPause",
+})
+sbar.add("item", {
+ position = "popup." .. media_cover.name,
+ icon = { string = icons.media.forward },
+ label = { drawing = false },
+ click_script = "nowplaying-cli next",
+})
+
+local interrupt = 0
+local function animate_detail(detail)
+ if (not detail) then interrupt = interrupt - 1 end
+ if interrupt > 0 and (not detail) then return end
+
+ sbar.animate("tanh", 30, function()
+ media_artist:set({ label = { width = detail and "dynamic" or 0 } })
+ media_title:set({ label = { width = detail and "dynamic" or 0 } })
+ end)
+end
+
+media_cover:subscribe("media_change", function(env)
+ if whitelist[env.INFO.app] then
+ local drawing = (env.INFO.state == "playing")
+ media_artist:set({ drawing = drawing, label = env.INFO.artist, })
+ media_title:set({ drawing = drawing, label = env.INFO.title, })
+ media_cover:set({ drawing = drawing })
+
+ if drawing then
+ animate_detail(true)
+ interrupt = interrupt + 1
+ sbar.delay(5, animate_detail)
+ else
+ media_cover:set({ popup = { drawing = false } })
+ end
+ end
+end)
+
+media_cover:subscribe("mouse.entered", function(env)
+ interrupt = interrupt + 1
+ animate_detail(true)
+end)
+
+media_cover:subscribe("mouse.exited", function(env)
+ animate_detail(false)
+end)
+
+media_cover:subscribe("mouse.clicked", function(env)
+ media_cover:set({ popup = { drawing = "toggle" }})
+end)
+
+media_title:subscribe("mouse.exited.global", function(env)
+ media_cover:set({ popup = { drawing = false }})
+end)
diff --git a/dot_config/sketchybar/items/menus.lua b/dot_config/sketchybar/items/menus.lua
new file mode 100644
index 0000000..6a5e344
--- /dev/null
+++ b/dot_config/sketchybar/items/menus.lua
@@ -0,0 +1,76 @@
+local colors = require("colors")
+local icons = require("icons")
+local settings = require("settings")
+
+local menu_watcher = sbar.add("item", {
+ drawing = false,
+ updates = false,
+})
+local space_menu_swap = sbar.add("item", {
+ drawing = false,
+ updates = true,
+})
+sbar.add("event", "swap_menus_and_spaces")
+
+local max_items = 15
+local menu_items = {}
+for i = 1, max_items, 1 do
+ local menu = sbar.add("item", "menu." .. i, {
+ padding_left = settings.paddings,
+ padding_right = settings.paddings,
+ drawing = false,
+ icon = { drawing = false },
+ label = {
+ font = {
+ style = settings.font.style_map[i == 1 and "Heavy" or "Semibold"]
+ },
+ padding_left = 6,
+ padding_right = 6,
+ },
+ click_script = "$CONFIG_DIR/helpers/menus/bin/menus -s " .. i,
+ })
+
+ menu_items[i] = menu
+end
+
+sbar.add("bracket", { '/menu\\..*/' }, {
+ background = { color = colors.bg1 }
+})
+
+local menu_padding = sbar.add("item", "menu.padding", {
+ drawing = false,
+ width = 5
+})
+
+local function update_menus(env)
+ sbar.exec("$CONFIG_DIR/helpers/menus/bin/menus -l", function(menus)
+ sbar.set('/menu\\..*/', { drawing = false })
+ menu_padding:set({ drawing = true })
+ id = 1
+ for menu in string.gmatch(menus, '[^\r\n]+') do
+ if id < max_items then
+ menu_items[id]:set( { label = menu, drawing = true } )
+ else break end
+ id = id + 1
+ end
+ end)
+end
+
+menu_watcher:subscribe("front_app_switched", update_menus)
+
+space_menu_swap:subscribe("swap_menus_and_spaces", function(env)
+ local drawing = menu_items[1]:query().geometry.drawing == "on"
+ if drawing then
+ menu_watcher:set( { updates = false })
+ sbar.set("/menu\\..*/", { drawing = false })
+ sbar.set("/space\\..*/", { drawing = true })
+ sbar.set("front_app", { drawing = true })
+ else
+ menu_watcher:set( { updates = true })
+ sbar.set("/space\\..*/", { drawing = false })
+ sbar.set("front_app", { drawing = false })
+ update_menus()
+ end
+end)
+
+return menu_watcher
diff --git a/dot_config/sketchybar/items/spaces.lua b/dot_config/sketchybar/items/spaces.lua
new file mode 100644
index 0000000..9d0dcf5
--- /dev/null
+++ b/dot_config/sketchybar/items/spaces.lua
@@ -0,0 +1,177 @@
+local colors = require("colors")
+local icons = require("icons")
+local settings = require("settings")
+local app_icons = require("helpers.app_icons")
+
+local spaces = {}
+
+for i = 1, 10, 1 do
+ local space = sbar.add("space", "space." .. i, {
+ space = i,
+ icon = {
+ font = { family = settings.font.numbers },
+ string = i,
+ padding_left = 15,
+ padding_right = 8,
+ color = colors.white,
+ highlight_color = colors.red,
+ },
+ label = {
+ padding_right = 20,
+ color = colors.grey,
+ highlight_color = colors.white,
+ font = "sketchybar-app-font:Regular:16.0",
+ y_offset = -1,
+ },
+ padding_right = 1,
+ padding_left = 1,
+ background = {
+ color = colors.bg1,
+ border_width = 1,
+ height = 26,
+ border_color = colors.black,
+ },
+ popup = { background = { border_width = 5, border_color = colors.black } }
+ })
+
+ spaces[i] = space
+
+ -- Single item bracket for space items to achieve double border on highlight
+ local space_bracket = sbar.add("bracket", { space.name }, {
+ background = {
+ color = colors.transparent,
+ border_color = colors.bg2,
+ height = 28,
+ border_width = 2
+ }
+ })
+
+ -- Padding space
+ sbar.add("space", "space.padding." .. i, {
+ space = i,
+ script = "",
+ width = settings.group_paddings,
+ })
+
+ local space_popup = sbar.add("item", {
+ position = "popup." .. space.name,
+ padding_left= 5,
+ padding_right= 0,
+ background = {
+ drawing = true,
+ image = {
+ corner_radius = 9,
+ scale = 0.2
+ }
+ }
+ })
+
+ space:subscribe("space_change", function(env)
+ local selected = env.SELECTED == "true"
+ local color = selected and colors.grey or colors.bg2
+ space:set({
+ icon = { highlight = selected, },
+ label = { highlight = selected },
+ background = { border_color = selected and colors.black or colors.bg2 }
+ })
+ space_bracket:set({
+ background = { border_color = selected and colors.grey or colors.bg2 }
+ })
+ end)
+
+ space:subscribe("mouse.clicked", function(env)
+ if env.BUTTON == "other" then
+ space_popup:set({ background = { image = "space." .. env.SID } })
+ space:set({ popup = { drawing = "toggle" } })
+ else
+ local op = (env.BUTTON == "right") and "--destroy" or "--focus"
+ sbar.exec("yabai -m space " .. op .. " " .. env.SID)
+ end
+ end)
+
+ space:subscribe("mouse.exited", function(_)
+ space:set({ popup = { drawing = false } })
+ end)
+end
+
+local space_window_observer = sbar.add("item", {
+ drawing = false,
+ updates = true,
+})
+
+local spaces_indicator = sbar.add("item", {
+ padding_left = -3,
+ padding_right = 0,
+ icon = {
+ padding_left = 8,
+ padding_right = 9,
+ color = colors.grey,
+ string = icons.switch.on,
+ },
+ label = {
+ width = 0,
+ padding_left = 0,
+ padding_right = 8,
+ string = "Spaces",
+ color = colors.bg1,
+ },
+ background = {
+ color = colors.with_alpha(colors.grey, 0.0),
+ border_color = colors.with_alpha(colors.bg1, 0.0),
+ }
+})
+
+space_window_observer:subscribe("space_windows_change", function(env)
+ local icon_line = ""
+ local no_app = true
+ for app, count in pairs(env.INFO.apps) do
+ no_app = false
+ local lookup = app_icons[app]
+ local icon = ((lookup == nil) and app_icons["Default"] or lookup)
+ icon_line = icon_line .. icon
+ end
+
+ if (no_app) then
+ icon_line = " —"
+ end
+ sbar.animate("tanh", 10, function()
+ spaces[env.INFO.space]:set({ label = icon_line })
+ end)
+end)
+
+spaces_indicator:subscribe("swap_menus_and_spaces", function(env)
+ local currently_on = spaces_indicator:query().icon.value == icons.switch.on
+ spaces_indicator:set({
+ icon = currently_on and icons.switch.off or icons.switch.on
+ })
+end)
+
+spaces_indicator:subscribe("mouse.entered", function(env)
+ sbar.animate("tanh", 30, function()
+ spaces_indicator:set({
+ background = {
+ color = { alpha = 1.0 },
+ border_color = { alpha = 1.0 },
+ },
+ icon = { color = colors.bg1 },
+ label = { width = "dynamic" }
+ })
+ end)
+end)
+
+spaces_indicator:subscribe("mouse.exited", function(env)
+ sbar.animate("tanh", 30, function()
+ spaces_indicator:set({
+ background = {
+ color = { alpha = 0.0 },
+ border_color = { alpha = 0.0 },
+ },
+ icon = { color = colors.grey },
+ label = { width = 0, }
+ })
+ end)
+end)
+
+spaces_indicator:subscribe("mouse.clicked", function(env)
+ sbar.trigger("swap_menus_and_spaces")
+end)
diff --git a/dot_config/sketchybar/items/widgets/battery.lua b/dot_config/sketchybar/items/widgets/battery.lua
new file mode 100644
index 0000000..88e74df
--- /dev/null
+++ b/dot_config/sketchybar/items/widgets/battery.lua
@@ -0,0 +1,100 @@
+local icons = require("icons")
+local colors = require("colors")
+local settings = require("settings")
+
+local battery = sbar.add("item", "widgets.battery", {
+ position = "right",
+ icon = {
+ font = {
+ style = settings.font.style_map["Regular"],
+ size = 19.0,
+ }
+ },
+ label = { font = { family = settings.font.numbers } },
+ update_freq = 180,
+ popup = { align = "center" }
+})
+
+local remaining_time = sbar.add("item", {
+ position = "popup." .. battery.name,
+ icon = {
+ string = "Time remaining:",
+ width = 100,
+ align = "left"
+ },
+ label = {
+ string = "??:??h",
+ width = 100,
+ align = "right"
+ },
+})
+
+
+battery:subscribe({"routine", "power_source_change", "system_woke"}, function()
+ sbar.exec("pmset -g batt", function(batt_info)
+ local icon = "!"
+ local label = "?"
+
+ local found, _, charge = batt_info:find("(%d+)%%")
+ if found then
+ charge = tonumber(charge)
+ label = charge .. "%"
+ end
+
+ local color = colors.green
+ local charging, _, _ = batt_info:find("AC Power")
+
+ if charging then
+ icon = icons.battery.charging
+ else
+ if found and charge > 80 then
+ icon = icons.battery._100
+ elseif found and charge > 60 then
+ icon = icons.battery._75
+ elseif found and charge > 40 then
+ icon = icons.battery._50
+ elseif found and charge > 20 then
+ icon = icons.battery._25
+ color = colors.orange
+ else
+ icon = icons.battery._0
+ color = colors.red
+ end
+ end
+
+ local lead = ""
+ if found and charge < 10 then
+ lead = "0"
+ end
+
+ battery:set({
+ icon = {
+ string = icon,
+ color = color
+ },
+ label = { string = lead .. label },
+ })
+ end)
+end)
+
+battery:subscribe("mouse.clicked", function(env)
+ local drawing = battery:query().popup.drawing
+ battery:set( { popup = { drawing = "toggle" } })
+
+ if drawing == "off" then
+ sbar.exec("pmset -g batt", function(batt_info)
+ local found, _, remaining = batt_info:find(" (%d+:%d+) remaining")
+ local label = found and remaining .. "h" or "No estimate"
+ remaining_time:set( { label = label })
+ end)
+ end
+end)
+
+sbar.add("bracket", "widgets.battery.bracket", { battery.name }, {
+ background = { color = colors.bg1 }
+})
+
+sbar.add("item", "widgets.battery.padding", {
+ position = "right",
+ width = settings.group_paddings
+})
diff --git a/dot_config/sketchybar/items/widgets/cpu.lua b/dot_config/sketchybar/items/widgets/cpu.lua
new file mode 100644
index 0000000..970da0e
--- /dev/null
+++ b/dot_config/sketchybar/items/widgets/cpu.lua
@@ -0,0 +1,69 @@
+local icons = require("icons")
+local colors = require("colors")
+local settings = require("settings")
+
+-- Execute the event provider binary which provides the event "cpu_update" for
+-- the cpu load data, which is fired every 2.0 seconds.
+sbar.exec("killall cpu_load >/dev/null; $CONFIG_DIR/helpers/event_providers/cpu_load/bin/cpu_load cpu_update 2.0")
+
+local cpu = sbar.add("graph", "widgets.cpu" , 42, {
+ position = "right",
+ graph = { color = colors.blue },
+ background = {
+ height = 22,
+ color = { alpha = 0 },
+ border_color = { alpha = 0 },
+ drawing = true,
+ },
+ icon = { string = icons.cpu },
+ label = {
+ string = "cpu ??%",
+ font = {
+ family = settings.font.numbers,
+ style = settings.font.style_map["Bold"],
+ size = 9.0,
+ },
+ align = "right",
+ padding_right = 0,
+ width = 0,
+ y_offset = 4
+ },
+ padding_right = settings.paddings + 6
+})
+
+cpu:subscribe("cpu_update", function(env)
+ -- Also available: env.user_load, env.sys_load
+ local load = tonumber(env.total_load)
+ cpu:push({ load / 100. })
+
+ local color = colors.blue
+ if load > 30 then
+ if load < 60 then
+ color = colors.yellow
+ elseif load < 80 then
+ color = colors.orange
+ else
+ color = colors.red
+ end
+ end
+
+ cpu:set({
+ graph = { color = color },
+ label = "cpu " .. env.total_load .. "%",
+ })
+end)
+
+cpu:subscribe("mouse.clicked", function(env)
+ sbar.exec("open -a 'Activity Monitor'")
+end)
+
+-- Background around the cpu item
+sbar.add("bracket", "widgets.cpu.bracket", { cpu.name }, {
+ background = { color = colors.bg1 }
+})
+
+-- Background around the cpu item
+sbar.add("item", "widgets.cpu.padding", {
+ position = "right",
+ width = settings.group_paddings
+})
diff --git a/dot_config/sketchybar/items/widgets/init.lua b/dot_config/sketchybar/items/widgets/init.lua
new file mode 100644
index 0000000..c919c76
--- /dev/null
+++ b/dot_config/sketchybar/items/widgets/init.lua
@@ -0,0 +1,4 @@
+require("items.widgets.battery")
+require("items.widgets.volume")
+require("items.widgets.wifi")
+require("items.widgets.cpu")
diff --git a/dot_config/sketchybar/items/widgets/volume.lua b/dot_config/sketchybar/items/widgets/volume.lua
new file mode 100644
index 0000000..14d1bb6
--- /dev/null
+++ b/dot_config/sketchybar/items/widgets/volume.lua
@@ -0,0 +1,152 @@
+local colors = require("colors")
+local icons = require("icons")
+local settings = require("settings")
+
+local popup_width = 250
+
+local volume_percent = sbar.add("item", "widgets.volume1", {
+ position = "right",
+ icon = { drawing = false },
+ label = {
+ string = "??%",
+ padding_left = -1,
+ font = { family = settings.font.numbers }
+ },
+})
+
+local volume_icon = sbar.add("item", "widgets.volume2", {
+ position = "right",
+ padding_right = -1,
+ icon = {
+ string = icons.volume._100,
+ width = 0,
+ align = "left",
+ color = colors.grey,
+ font = {
+ style = settings.font.style_map["Regular"],
+ size = 14.0,
+ },
+ },
+ label = {
+ width = 25,
+ align = "left",
+ font = {
+ style = settings.font.style_map["Regular"],
+ size = 14.0,
+ },
+ },
+})
+
+local volume_bracket = sbar.add("bracket", "widgets.volume.bracket", {
+ volume_icon.name,
+ volume_percent.name
+}, {
+ background = { color = colors.bg1 },
+ popup = { align = "center" }
+})
+
+sbar.add("item", "widgets.volume.padding", {
+ position = "right",
+ width = settings.group_paddings
+})
+
+local volume_slider = sbar.add("slider", popup_width, {
+ position = "popup." .. volume_bracket.name,
+ slider = {
+ highlight_color = colors.blue,
+ background = {
+ height = 6,
+ corner_radius = 3,
+ color = colors.bg2,
+ },
+ knob= {
+ string = "",
+ drawing = true,
+ },
+ },
+ background = { color = colors.bg1, height = 2, y_offset = -20 },
+ click_script = 'osascript -e "set volume output volume $PERCENTAGE"'
+})
+
+volume_percent:subscribe("volume_change", function(env)
+ local volume = tonumber(env.INFO)
+ local icon = icons.volume._0
+ if volume > 60 then
+ icon = icons.volume._100
+ elseif volume > 30 then
+ icon = icons.volume._66
+ elseif volume > 10 then
+ icon = icons.volume._33
+ elseif volume > 0 then
+ icon = icons.volume._10
+ end
+
+ local lead = ""
+ if volume < 10 then
+ lead = "0"
+ end
+
+ volume_icon:set({ label = icon })
+ volume_percent:set({ label = lead .. volume .. "%" })
+ volume_slider:set({ slider = { percentage = volume } })
+end)
+
+local function volume_collapse_details()
+ local drawing = volume_bracket:query().popup.drawing == "on"
+ if not drawing then return end
+ volume_bracket:set({ popup = { drawing = false } })
+ sbar.remove('/volume.device\\.*/')
+end
+
+local current_audio_device = "None"
+local function volume_toggle_details(env)
+ if env.BUTTON == "right" then
+ sbar.exec("open /System/Library/PreferencePanes/Sound.prefpane")
+ return
+ end
+
+ local should_draw = volume_bracket:query().popup.drawing == "off"
+ if should_draw then
+ volume_bracket:set({ popup = { drawing = true } })
+ sbar.exec("SwitchAudioSource -t output -c", function(result)
+ current_audio_device = result:sub(1, -2)
+ sbar.exec("SwitchAudioSource -a -t output", function(available)
+ current = current_audio_device
+ local color = colors.grey
+ local counter = 0
+
+ for device in string.gmatch(available, '[^\r\n]+') do
+ local color = colors.grey
+ if current == device then
+ color = colors.white
+ end
+ sbar.add("item", "volume.device." .. counter, {
+ position = "popup." .. volume_bracket.name,
+ width = popup_width,
+ align = "center",
+ label = { string = device, color = color },
+ click_script = 'SwitchAudioSource -s "' .. device .. '" && sketchybar --set /volume.device\\.*/ label.color=' .. colors.grey .. ' --set $NAME label.color=' .. colors.white
+
+ })
+ counter = counter + 1
+ end
+ end)
+ end)
+ else
+ volume_collapse_details()
+ end
+end
+
+local function volume_scroll(env)
+ local delta = env.INFO.delta
+ if not (env.INFO.modifier == "ctrl") then delta = delta * 10.0 end
+
+ sbar.exec('osascript -e "set volume output volume (output volume of (get volume settings) + ' .. delta .. ')"')
+end
+
+volume_icon:subscribe("mouse.clicked", volume_toggle_details)
+volume_icon:subscribe("mouse.scrolled", volume_scroll)
+volume_percent:subscribe("mouse.clicked", volume_toggle_details)
+volume_percent:subscribe("mouse.exited.global", volume_collapse_details)
+volume_percent:subscribe("mouse.scrolled", volume_scroll)
+
diff --git a/dot_config/sketchybar/items/widgets/wifi.lua b/dot_config/sketchybar/items/widgets/wifi.lua
new file mode 100644
index 0000000..6153360
--- /dev/null
+++ b/dot_config/sketchybar/items/widgets/wifi.lua
@@ -0,0 +1,234 @@
+local icons = require("icons")
+local colors = require("colors")
+local settings = require("settings")
+
+-- Execute the event provider binary which provides the event "network_update"
+-- for the network interface "en0", which is fired every 2.0 seconds.
+sbar.exec("killall network_load >/dev/null; $CONFIG_DIR/helpers/event_providers/network_load/bin/network_load en0 network_update 2.0")
+
+local popup_width = 250
+
+local wifi_up = sbar.add("item", "widgets.wifi1", {
+ position = "right",
+ padding_left = -5,
+ width = 0,
+ icon = {
+ padding_right = 0,
+ font = {
+ style = settings.font.style_map["Bold"],
+ size = 9.0,
+ },
+ string = icons.wifi.upload,
+ },
+ label = {
+ font = {
+ family = settings.font.numbers,
+ style = settings.font.style_map["Bold"],
+ size = 9.0,
+ },
+ color = colors.red,
+ string = "??? Bps",
+ },
+ y_offset = 4,
+})
+
+local wifi_down = sbar.add("item", "widgets.wifi2", {
+ position = "right",
+ padding_left = -5,
+ icon = {
+ padding_right = 0,
+ font = {
+ style = settings.font.style_map["Bold"],
+ size = 9.0,
+ },
+ string = icons.wifi.download,
+ },
+ label = {
+ font = {
+ family = settings.font.numbers,
+ style = settings.font.style_map["Bold"],
+ size = 9.0,
+ },
+ color = colors.blue,
+ string = "??? Bps",
+ },
+ y_offset = -4,
+})
+
+local wifi = sbar.add("item", "widgets.wifi.padding", {
+ position = "right",
+ label = { drawing = false },
+})
+
+-- Background around the item
+local wifi_bracket = sbar.add("bracket", "widgets.wifi.bracket", {
+ wifi.name,
+ wifi_up.name,
+ wifi_down.name
+}, {
+ background = { color = colors.bg1 },
+ popup = { align = "center", height = 30 }
+})
+
+local ssid = sbar.add("item", {
+ position = "popup." .. wifi_bracket.name,
+ icon = {
+ font = {
+ style = settings.font.style_map["Bold"]
+ },
+ string = icons.wifi.router,
+ },
+ width = popup_width,
+ align = "center",
+ label = {
+ font = {
+ size = 15,
+ style = settings.font.style_map["Bold"]
+ },
+ max_chars = 18,
+ string = "????????????",
+ },
+ background = {
+ height = 2,
+ color = colors.grey,
+ y_offset = -15
+ }
+})
+
+local hostname = sbar.add("item", {
+ position = "popup." .. wifi_bracket.name,
+ icon = {
+ align = "left",
+ string = "Hostname:",
+ width = popup_width / 2,
+ },
+ label = {
+ max_chars = 20,
+ string = "????????????",
+ width = popup_width / 2,
+ align = "right",
+ }
+})
+
+local ip = sbar.add("item", {
+ position = "popup." .. wifi_bracket.name,
+ icon = {
+ align = "left",
+ string = "IP:",
+ width = popup_width / 2,
+ },
+ label = {
+ string = "???.???.???.???",
+ width = popup_width / 2,
+ align = "right",
+ }
+})
+
+local mask = sbar.add("item", {
+ position = "popup." .. wifi_bracket.name,
+ icon = {
+ align = "left",
+ string = "Subnet mask:",
+ width = popup_width / 2,
+ },
+ label = {
+ string = "???.???.???.???",
+ width = popup_width / 2,
+ align = "right",
+ }
+})
+
+local router = sbar.add("item", {
+ position = "popup." .. wifi_bracket.name,
+ icon = {
+ align = "left",
+ string = "Router:",
+ width = popup_width / 2,
+ },
+ label = {
+ string = "???.???.???.???",
+ width = popup_width / 2,
+ align = "right",
+ },
+})
+
+sbar.add("item", { position = "right", width = settings.group_paddings })
+
+wifi_up:subscribe("network_update", function(env)
+ local up_color = (env.upload == "000 Bps") and colors.grey or colors.red
+ local down_color = (env.download == "000 Bps") and colors.grey or colors.blue
+ wifi_up:set({
+ icon = { color = up_color },
+ label = {
+ string = env.upload,
+ color = up_color
+ }
+ })
+ wifi_down:set({
+ icon = { color = down_color },
+ label = {
+ string = env.download,
+ color = down_color
+ }
+ })
+end)
+
+wifi:subscribe({"wifi_change", "system_woke"}, function(env)
+ sbar.exec("ipconfig getifaddr en0", function(ip)
+ local connected = not (ip == "")
+ wifi:set({
+ icon = {
+ string = connected and icons.wifi.connected or icons.wifi.disconnected,
+ color = connected and colors.white or colors.red,
+ },
+ })
+ end)
+end)
+
+local function hide_details()
+ wifi_bracket:set({ popup = { drawing = false } })
+end
+
+local function toggle_details()
+ local should_draw = wifi_bracket:query().popup.drawing == "off"
+ if should_draw then
+ wifi_bracket:set({ popup = { drawing = true }})
+ sbar.exec("networksetup -getcomputername", function(result)
+ hostname:set({ label = result })
+ end)
+ sbar.exec("ipconfig getifaddr en0", function(result)
+ ip:set({ label = result })
+ end)
+ sbar.exec("ipconfig getsummary en0 | awk -F ' SSID : ' '/ SSID : / {print $2}'", function(result)
+ ssid:set({ label = result })
+ end)
+ sbar.exec("networksetup -getinfo Wi-Fi | awk -F 'Subnet mask: ' '/^Subnet mask: / {print $2}'", function(result)
+ mask:set({ label = result })
+ end)
+ sbar.exec("networksetup -getinfo Wi-Fi | awk -F 'Router: ' '/^Router: / {print $2}'", function(result)
+ router:set({ label = result })
+ end)
+ else
+ hide_details()
+ end
+end
+
+wifi_up:subscribe("mouse.clicked", toggle_details)
+wifi_down:subscribe("mouse.clicked", toggle_details)
+wifi:subscribe("mouse.clicked", toggle_details)
+wifi:subscribe("mouse.exited.global", hide_details)
+
+local function copy_label_to_clipboard(env)
+ local label = sbar.query(env.NAME).label.value
+ sbar.exec("echo \"" .. label .. "\" | pbcopy")
+ sbar.set(env.NAME, { label = { string = icons.clipboard, align="center" } })
+ sbar.delay(1, function()
+ sbar.set(env.NAME, { label = { string = label, align = "right" } })
+ end)
+end
+
+ssid:subscribe("mouse.clicked", copy_label_to_clipboard)
+hostname:subscribe("mouse.clicked", copy_label_to_clipboard)
+ip:subscribe("mouse.clicked", copy_label_to_clipboard)
+mask:subscribe("mouse.clicked", copy_label_to_clipboard)
+router:subscribe("mouse.clicked", copy_label_to_clipboard)
diff --git a/dot_config/sketchybar/settings.lua b/dot_config/sketchybar/settings.lua
new file mode 100644
index 0000000..7713dc4
--- /dev/null
+++ b/dot_config/sketchybar/settings.lua
@@ -0,0 +1,22 @@
+return {
+ paddings = 3,
+ group_paddings = 5,
+
+ icons = "sf-symbols", -- alternatively available: NerdFont
+
+ -- This is a font configuration for SF Pro and SF Mono (installed manually)
+ font = require("helpers.default_font"),
+
+ -- Alternatively, this is a font config for JetBrainsMono Nerd Font
+ -- font = {
+ -- text = "JetBrainsMono Nerd Font", -- Used for text
+ -- numbers = "JetBrainsMono Nerd Font", -- Used for numbers
+ -- style_map = {
+ -- ["Regular"] = "Regular",
+ -- ["Semibold"] = "Medium",
+ -- ["Bold"] = "SemiBold",
+ -- ["Heavy"] = "Bold",
+ -- ["Black"] = "ExtraBold",
+ -- },
+ -- },
+}
diff --git a/dot_config/yazi/empty_yazi.toml b/dot_config/yazi/empty_yazi.toml
index 6b9e794..01e4961 100644
--- a/dot_config/yazi/empty_yazi.toml
+++ b/dot_config/yazi/empty_yazi.toml
@@ -1,2 +1,2 @@
[manager]
-ratio = [1, 1, 0]
+ratio = [0, 4, 0]
diff --git a/dot_config/zellij/config.kdl b/dot_config/zellij/config.kdl
new file mode 100644
index 0000000..24bbc66
--- /dev/null
+++ b/dot_config/zellij/config.kdl
@@ -0,0 +1,414 @@
+//
+// THIS FILE WAS AUTOGENERATED BY ZELLIJ, THE PREVIOUS FILE AT THIS LOCATION WAS COPIED TO: /home/tyler/.config/zellij/config.kdl.bak
+//
+
+keybinds clear-defaults=true {
+ locked {
+ bind "Ctrl g" { SwitchToMode "normal"; }
+ }
+ pane {
+ bind "left" { MoveFocus "left"; }
+ bind "down" { MoveFocus "down"; }
+ bind "up" { MoveFocus "up"; }
+ bind "right" { MoveFocus "right"; }
+ bind "c" { SwitchToMode "renamepane"; PaneNameInput 0; }
+ bind "d" { NewPane "down"; SwitchToMode "locked"; }
+ bind "e" { TogglePaneEmbedOrFloating; SwitchToMode "locked"; }
+ bind "f" { ToggleFocusFullscreen; SwitchToMode "locked"; }
+ bind "h" { MoveFocus "left"; }
+ bind "j" { MoveFocus "down"; }
+ bind "k" { MoveFocus "up"; }
+ bind "l" { MoveFocus "right"; }
+ bind "n" { NewPane; SwitchToMode "locked"; }
+ bind "p" { SwitchToMode "normal"; }
+ bind "r" { NewPane "right"; SwitchToMode "locked"; }
+ bind "w" { ToggleFloatingPanes; SwitchToMode "locked"; }
+ bind "x" { CloseFocus; SwitchToMode "locked"; }
+ bind "z" { TogglePaneFrames; SwitchToMode "locked"; }
+ bind "tab" { SwitchFocus; }
+ }
+ tab {
+ bind "left" { GoToPreviousTab; }
+ bind "down" { GoToNextTab; }
+ bind "up" { GoToPreviousTab; }
+ bind "right" { GoToNextTab; }
+ bind "1" { GoToTab 1; SwitchToMode "locked"; }
+ bind "2" { GoToTab 2; SwitchToMode "locked"; }
+ bind "3" { GoToTab 3; SwitchToMode "locked"; }
+ bind "4" { GoToTab 4; SwitchToMode "locked"; }
+ bind "5" { GoToTab 5; SwitchToMode "locked"; }
+ bind "6" { GoToTab 6; SwitchToMode "locked"; }
+ bind "7" { GoToTab 7; SwitchToMode "locked"; }
+ bind "8" { GoToTab 8; SwitchToMode "locked"; }
+ bind "9" { GoToTab 9; SwitchToMode "locked"; }
+ bind "[" { BreakPaneLeft; SwitchToMode "locked"; }
+ bind "]" { BreakPaneRight; SwitchToMode "locked"; }
+ bind "b" { BreakPane; SwitchToMode "locked"; }
+ bind "h" { GoToPreviousTab; }
+ bind "j" { GoToNextTab; }
+ bind "k" { GoToPreviousTab; }
+ bind "l" { GoToNextTab; }
+ bind "n" { NewTab; SwitchToMode "locked"; }
+ bind "r" { SwitchToMode "renametab"; TabNameInput 0; }
+ bind "s" { ToggleActiveSyncTab; SwitchToMode "locked"; }
+ bind "t" { SwitchToMode "normal"; }
+ bind "x" { CloseTab; SwitchToMode "locked"; }
+ bind "tab" { ToggleTab; }
+ }
+ resize {
+ bind "left" { Resize "Increase left"; }
+ bind "down" { Resize "Increase down"; }
+ bind "up" { Resize "Increase up"; }
+ bind "right" { Resize "Increase right"; }
+ bind "+" { Resize "Increase"; }
+ bind "-" { Resize "Decrease"; }
+ bind "=" { Resize "Increase"; }
+ bind "H" { Resize "Decrease left"; }
+ bind "J" { Resize "Decrease down"; }
+ bind "K" { Resize "Decrease up"; }
+ bind "L" { Resize "Decrease right"; }
+ bind "h" { Resize "Increase left"; }
+ bind "j" { Resize "Increase down"; }
+ bind "k" { Resize "Increase up"; }
+ bind "l" { Resize "Increase right"; }
+ bind "r" { SwitchToMode "normal"; }
+ }
+ move {
+ bind "left" { MovePane "left"; }
+ bind "down" { MovePane "down"; }
+ bind "up" { MovePane "up"; }
+ bind "right" { MovePane "right"; }
+ bind "h" { MovePane "left"; }
+ bind "j" { MovePane "down"; }
+ bind "k" { MovePane "up"; }
+ bind "l" { MovePane "right"; }
+ bind "m" { SwitchToMode "normal"; }
+ bind "n" { MovePane; }
+ bind "p" { MovePaneBackwards; }
+ bind "tab" { MovePane; }
+ }
+ scroll {
+ bind "Alt left" { MoveFocusOrTab "left"; SwitchToMode "locked"; }
+ bind "Alt down" { MoveFocus "down"; SwitchToMode "locked"; }
+ bind "Alt up" { MoveFocus "up"; SwitchToMode "locked"; }
+ bind "Alt right" { MoveFocusOrTab "right"; SwitchToMode "locked"; }
+ bind "e" { EditScrollback; SwitchToMode "locked"; }
+ bind "f" { SwitchToMode "entersearch"; SearchInput 0; }
+ bind "Alt h" { MoveFocusOrTab "left"; SwitchToMode "locked"; }
+ bind "Alt j" { MoveFocus "down"; SwitchToMode "locked"; }
+ bind "Alt k" { MoveFocus "up"; SwitchToMode "locked"; }
+ bind "Alt l" { MoveFocusOrTab "right"; SwitchToMode "locked"; }
+ bind "s" { SwitchToMode "normal"; }
+ }
+ search {
+ bind "c" { SearchToggleOption "CaseSensitivity"; }
+ bind "n" { Search "down"; }
+ bind "o" { SearchToggleOption "WholeWord"; }
+ bind "p" { Search "up"; }
+ bind "w" { SearchToggleOption "Wrap"; }
+ }
+ session {
+ bind "c" {
+ LaunchOrFocusPlugin "configuration" {
+ floating true
+ move_to_focused_tab true
+ }
+ SwitchToMode "locked"
+ }
+ bind "d" { Detach; }
+ bind "o" { SwitchToMode "normal"; }
+ bind "p" {
+ LaunchOrFocusPlugin "plugin-manager" {
+ floating true
+ move_to_focused_tab true
+ }
+ SwitchToMode "locked"
+ }
+ bind "w" {
+ LaunchOrFocusPlugin "session-manager" {
+ floating true
+ move_to_focused_tab true
+ }
+ SwitchToMode "locked"
+ }
+ }
+ shared_among "normal" "locked" {
+ bind "Alt left" { MoveFocusOrTab "left"; }
+ bind "Alt down" { MoveFocus "down"; }
+ bind "Alt up" { MoveFocus "up"; }
+ bind "Alt right" { MoveFocusOrTab "right"; }
+ bind "Alt +" { Resize "Increase"; }
+ bind "Alt -" { Resize "Decrease"; }
+ bind "Alt =" { Resize "Increase"; }
+ bind "Alt [" { PreviousSwapLayout; }
+ bind "Alt ]" { NextSwapLayout; }
+ bind "Alt f" { ToggleFloatingPanes; }
+ bind "Alt h" { MoveFocusOrTab "left"; }
+ bind "Alt i" { MoveTab "left"; }
+ bind "Alt j" { MoveFocus "down"; }
+ bind "Alt k" { MoveFocus "up"; }
+ bind "Alt l" { MoveFocusOrTab "right"; }
+ bind "Alt n" { NewPane; }
+ bind "Alt o" { MoveTab "right"; }
+ }
+ shared_except "locked" "renametab" "renamepane" {
+ bind "Ctrl g" { SwitchToMode "locked"; }
+ bind "Ctrl q" { Quit; }
+ }
+ shared_except "locked" "entersearch" {
+ bind "enter" { SwitchToMode "locked"; }
+ }
+ shared_except "locked" "entersearch" "renametab" "renamepane" {
+ bind "esc" { SwitchToMode "locked"; }
+ }
+ shared_except "locked" "entersearch" "renametab" "renamepane" "move" {
+ bind "m" { SwitchToMode "move"; }
+ }
+ shared_except "locked" "entersearch" "search" "renametab" "renamepane" "session" {
+ bind "o" { SwitchToMode "session"; }
+ }
+ shared_except "locked" "tab" "entersearch" "renametab" "renamepane" {
+ bind "t" { SwitchToMode "tab"; }
+ }
+ shared_except "locked" "tab" "scroll" "entersearch" "renametab" "renamepane" {
+ bind "s" { SwitchToMode "scroll"; }
+ }
+ shared_among "normal" "resize" "tab" "scroll" "prompt" "tmux" {
+ bind "p" { SwitchToMode "pane"; }
+ }
+ shared_except "locked" "resize" "pane" "tab" "entersearch" "renametab" "renamepane" {
+ bind "r" { SwitchToMode "resize"; }
+ }
+ shared_among "scroll" "search" {
+ bind "PageDown" { PageScrollDown; }
+ bind "PageUp" { PageScrollUp; }
+ bind "left" { PageScrollUp; }
+ bind "down" { ScrollDown; }
+ bind "up" { ScrollUp; }
+ bind "right" { PageScrollDown; }
+ bind "Ctrl b" { PageScrollUp; }
+ bind "Ctrl c" { ScrollToBottom; SwitchToMode "locked"; }
+ bind "d" { HalfPageScrollDown; }
+ bind "Ctrl f" { PageScrollDown; }
+ bind "h" { PageScrollUp; }
+ bind "j" { ScrollDown; }
+ bind "k" { ScrollUp; }
+ bind "l" { PageScrollDown; }
+ bind "u" { HalfPageScrollUp; }
+ }
+ entersearch {
+ bind "Ctrl c" { SwitchToMode "scroll"; }
+ bind "esc" { SwitchToMode "scroll"; }
+ bind "enter" { SwitchToMode "search"; }
+ }
+ renametab {
+ bind "esc" { UndoRenameTab; SwitchToMode "tab"; }
+ }
+ shared_among "renametab" "renamepane" {
+ bind "Ctrl c" { SwitchToMode "locked"; }
+ }
+ renamepane {
+ bind "esc" { UndoRenamePane; SwitchToMode "pane"; }
+ }
+}
+
+// Plugin aliases - can be used to change the implementation of Zellij
+// changing these requires a restart to take effect
+plugins {
+ compact-bar location="zellij:compact-bar"
+ configuration location="zellij:configuration"
+ filepicker location="zellij:strider" {
+ cwd "/"
+ }
+ plugin-manager location="zellij:plugin-manager"
+ session-manager location="zellij:session-manager"
+ status-bar location="zellij:status-bar"
+ strider location="zellij:strider"
+ tab-bar location="zellij:tab-bar"
+ welcome-screen location="zellij:session-manager" {
+ welcome_screen true
+ }
+}
+
+// Plugins to load in the background when a new session starts
+// eg. "file:/path/to/my-plugin.wasm"
+// eg. "https://example.com/my-plugin.wasm"
+load_plugins {
+}
+
+// Use a simplified UI without special fonts (arrow glyphs)
+// Options:
+// - true
+// - false (Default)
+//
+// simplified_ui true
+
+// Choose the theme that is specified in the themes section.
+// Default: default
+//
+// theme "dracula"
+
+// Choose the base input mode of zellij.
+// Default: normal
+//
+default_mode "locked"
+
+// Choose the path to the default shell that zellij will use for opening new panes
+// Default: $SHELL
+//
+// default_shell "fish"
+
+// Choose the path to override cwd that zellij will use for opening new panes
+//
+// default_cwd "/tmp"
+
+// The name of the default layout to load on startup
+// Default: "default"
+//
+// default_layout "compact"
+
+// The folder in which Zellij will look for layouts
+// (Requires restart)
+//
+// layout_dir "/tmp"
+
+// The folder in which Zellij will look for themes
+// (Requires restart)
+//
+// theme_dir "/tmp"
+
+// Toggle enabling the mouse mode.
+// On certain configurations, or terminals this could
+// potentially interfere with copying text.
+// Options:
+// - true (default)
+// - false
+//
+// mouse_mode false
+
+// Toggle having pane frames around the panes
+// Options:
+// - true (default, enabled)
+// - false
+//
+// pane_frames false
+
+// When attaching to an existing session with other users,
+// should the session be mirrored (true)
+// or should each user have their own cursor (false)
+// (Requires restart)
+// Default: false
+//
+// mirror_session true
+
+// Choose what to do when zellij receives SIGTERM, SIGINT, SIGQUIT or SIGHUP
+// eg. when terminal window with an active zellij session is closed
+// (Requires restart)
+// Options:
+// - detach (Default)
+// - quit
+//
+// on_force_close "quit"
+
+// Configure the scroll back buffer size
+// This is the number of lines zellij stores for each pane in the scroll back
+// buffer. Excess number of lines are discarded in a FIFO fashion.
+// (Requires restart)
+// Valid values: positive integers
+// Default value: 10000
+//
+// scroll_buffer_size 10000
+
+// Provide a command to execute when copying text. The text will be piped to
+// the stdin of the program to perform the copy. This can be used with
+// terminal emulators which do not support the OSC 52 ANSI control sequence
+// that will be used by default if this option is not set.
+// Examples:
+//
+// copy_command "xclip -selection clipboard" // x11
+// copy_command "wl-copy" // wayland
+// copy_command "pbcopy" // osx
+//
+// copy_command "pbcopy"
+
+// Choose the destination for copied text
+// Allows using the primary selection buffer (on x11/wayland) instead of the system clipboard.
+// Does not apply when using copy_command.
+// Options:
+// - system (default)
+// - primary
+//
+// copy_clipboard "primary"
+
+// Enable automatic copying (and clearing) of selection when releasing mouse
+// Default: true
+//
+// copy_on_select true
+
+// Path to the default editor to use to edit pane scrollbuffer
+// Default: $EDITOR or $VISUAL
+// scrollback_editor "/usr/bin/vim"
+
+// A fixed name to always give the Zellij session.
+// Consider also setting `attach_to_session true,`
+// otherwise this will error if such a session exists.
+// Default:
+//
+// session_name "My singleton session"
+
+// When `session_name` is provided, attaches to that session
+// if it is already running or creates it otherwise.
+// Default: false
+//
+// attach_to_session true
+
+// Toggle between having Zellij lay out panes according to a predefined set of layouts whenever possible
+// Options:
+// - true (default)
+// - false
+//
+// auto_layout false
+
+// Whether sessions should be serialized to the cache folder (including their tabs/panes, cwds and running commands) so that they can later be resurrected
+// Options:
+// - true (default)
+// - false
+//
+// session_serialization false
+
+// Whether pane viewports are serialized along with the session, default is false
+// Options:
+// - true
+// - false (default)
+//
+// serialize_pane_viewport false
+
+// Scrollback lines to serialize along with the pane viewport when serializing sessions, 0
+// defaults to the scrollback size. If this number is higher than the scrollback size, it will
+// also default to the scrollback size. This does nothing if `serialize_pane_viewport` is not true.
+//
+// scrollback_lines_to_serialize 10000
+
+// Enable or disable the rendering of styled and colored underlines (undercurl).
+// May need to be disabled for certain unsupported terminals
+// (Requires restart)
+// Default: true
+//
+// styled_underlines false
+
+// How often in seconds sessions are serialized
+//
+// serialization_interval 10000
+
+// Enable or disable writing of session metadata to disk (if disabled, other sessions might not know
+// metadata info on this session)
+// (Requires restart)
+// Default: false
+//
+// disable_session_metadata false
+
+// Enable or disable support for the enhanced Kitty Keyboard Protocol (the host terminal must also support it)
+// (Requires restart)
+// Default: true (if the host terminal supports it)
+//
+// support_kitty_keyboard_protocol false
diff --git a/dot_config/zellij/layouts/default.kdl b/dot_config/zellij/layouts/default.kdl
new file mode 100644
index 0000000..048d126
--- /dev/null
+++ b/dot_config/zellij/layouts/default.kdl
@@ -0,0 +1,20 @@
+layout {
+ default_tab_template {
+ pane size=1 borderless=true {
+ plugin location="zellij:tab-bar"
+ }
+ children
+ pane size=2 borderless=true {
+ plugin location="zellij:status-bar"
+ }
+ }
+
+ tab name="IDE" {
+ pane split_direction="vertical" {
+ pane command="yazi" size="20%"
+ pane command="hx"
+ }
+ }
+
+ tab name="shell"
+}
diff --git a/dot_config/zellij/layouts/empty_default.kdl b/dot_config/zellij/layouts/empty_default.kdl
deleted file mode 100644
index 0bc2c6a..0000000
--- a/dot_config/zellij/layouts/empty_default.kdl
+++ /dev/null
@@ -1,12 +0,0 @@
-layout {
- pane size=1 borderless=true {
- plugin location="tab-bar"
- }
- pane split_direction="vertical" {
- pane size="33%" command="yazi"
- pane
- }
- pane size=2 borderless=true {
- plugin location="zellij:status-bar"
- }
-}
diff --git a/run_home-manager.sh.tmpl b/run_home-manager.sh.tmpl
new file mode 100644
index 0000000..1157cab
--- /dev/null
+++ b/run_home-manager.sh.tmpl
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+home-manager switch --flake ~/.config/flake/
+darwin-rebuild switch --flake ~/.config/flake/