From 26de676486a3169ea921941970aca16696a9ff45 Mon Sep 17 00:00:00 2001 From: blahai Date: Wed, 23 Oct 2024 17:45:29 +0300 Subject: [PATCH] add wezterm config (borrowed from isabel) --- flake.lock | 283 ++++++++++---- flake.nix | 3 +- modules/home-manager/cli/default.nix | 1 + modules/home-manager/cli/wezterm/bar.lua | 360 ++++++++++++++++++ .../home-manager/cli/wezterm/catppuccin.lua | 351 +++++++++++++++++ modules/home-manager/cli/wezterm/default.nix | 11 + modules/home-manager/cli/wezterm/keybinds.lua | 77 ++++ modules/home-manager/cli/wezterm/utils.lua | 18 + modules/home-manager/cli/wezterm/wezterm.lua | 88 +++++ 9 files changed, 1112 insertions(+), 80 deletions(-) create mode 100644 modules/home-manager/cli/wezterm/bar.lua create mode 100644 modules/home-manager/cli/wezterm/catppuccin.lua create mode 100644 modules/home-manager/cli/wezterm/default.nix create mode 100644 modules/home-manager/cli/wezterm/keybinds.lua create mode 100644 modules/home-manager/cli/wezterm/utils.lua create mode 100644 modules/home-manager/cli/wezterm/wezterm.lua diff --git a/flake.lock b/flake.lock index f807138..6827d7e 100644 --- a/flake.lock +++ b/flake.lock @@ -41,11 +41,11 @@ ] }, "locked": { - "lastModified": 1728326504, - "narHash": "sha256-dQXAj+4d6neY7ldCiH6gNym3upP49PVxRzEPxXlD9Aw=", + "lastModified": 1729527199, + "narHash": "sha256-D5/YksfRga8Akd04ZtIkuYSIOjXVrAzQIQBSeplokzU=", "owner": "hyprwm", "repo": "aquamarine", - "rev": "65dd97b5d21e917295159bbef1d52e06963f4eb0", + "rev": "8d732fa8aff8b12ef2b1e2f00fc8153e41312b72", "type": "github" }, "original": { @@ -71,18 +71,17 @@ }, "chaotic": { "inputs": { - "fenix": "fenix", "flake-schemas": "flake-schemas", "home-manager": "home-manager", "jovian": "jovian", "nixpkgs": "nixpkgs" }, "locked": { - "lastModified": 1728835058, - "narHash": "sha256-GbcJ90E8+wBkBh9C1HxBTwKsOkGU41CRaPrd1ksFPtA=", + "lastModified": 1729599319, + "narHash": "sha256-e/4JPcIRte5zkwqmGFrFo3763e0iHURX6N0apz4jbI0=", "owner": "chaotic-cx", "repo": "nyx", - "rev": "ec6b449d3d096a0e79db5f8c4a321ea9ec836e40", + "rev": "1b86b304c8eb1437d9337a760e7f930826fc4d6d", "type": "github" }, "original": { @@ -92,28 +91,6 @@ "type": "github" } }, - "fenix": { - "inputs": { - "nixpkgs": [ - "chaotic", - "nixpkgs" - ], - "rust-analyzer-src": "rust-analyzer-src" - }, - "locked": { - "lastModified": 1728455642, - "narHash": "sha256-abYGwrL6ak5sBRqwPh+V3CPJ6Pa89p378t51b7BO1lE=", - "owner": "nix-community", - "repo": "fenix", - "rev": "3b47535a5c782e4f4ad59cd4bdb23636b6926e03", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "fenix", - "type": "github" - } - }, "flake-compat": { "flake": false, "locked": { @@ -160,6 +137,41 @@ "url": "https://flakehub.com/f/DeterminateSystems/flake-schemas/%3D0.1.5.tar.gz" } }, + "flake-utils": { + "inputs": { + "systems": "systems_3" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "freetype2": { + "flake": false, + "locked": { + "lastModified": 1687587065, + "narHash": "sha256-+Fh+/k+NWL5Ow9sDLtp8Cv/8rLNA1oByQQCIQS/bysY=", + "owner": "wez", + "repo": "freetype2", + "rev": "e4586d960f339cf75e2e0b34aee30a0ed8353c0d", + "type": "github" + }, + "original": { + "owner": "wez", + "repo": "freetype2", + "rev": "e4586d960f339cf75e2e0b34aee30a0ed8353c0d", + "type": "github" + } + }, "gitignore": { "inputs": { "nixpkgs": [ @@ -182,6 +194,23 @@ "type": "github" } }, + "harfbuzz": { + "flake": false, + "locked": { + "lastModified": 1711722720, + "narHash": "sha256-GdxcAPx5QyniSHPAN1ih28AD9JLUPR0ItqW9JEsl3pU=", + "owner": "harfbuzz", + "repo": "harfbuzz", + "rev": "63973005bc07aba599b47fdd4cf788647b601ccd", + "type": "github" + }, + "original": { + "owner": "harfbuzz", + "ref": "8.4.0", + "repo": "harfbuzz", + "type": "github" + } + }, "home-manager": { "inputs": { "nixpkgs": [ @@ -190,11 +219,11 @@ ] }, "locked": { - "lastModified": 1728337164, - "narHash": "sha256-VdRTjJFyq4Q9U7Z/UoC2Q5jK8vSo6E86lHc2OanXtvc=", + "lastModified": 1729414726, + "narHash": "sha256-Dtmm1OU8Ymiy9hVWn/a2B8DhRYo9Eoyx9veERdOBR4o=", "owner": "nix-community", "repo": "home-manager", - "rev": "038630363e7de57c36c417fd2f5d7c14773403e4", + "rev": "fe56302339bb28e3471632379d733547caec8103", "type": "github" }, "original": { @@ -210,11 +239,11 @@ ] }, "locked": { - "lastModified": 1728791962, - "narHash": "sha256-nr5QiXwQcZmf6/auC1UpX8iAtINMtdi2mH+OkqJQVmU=", + "lastModified": 1729551526, + "narHash": "sha256-7LAGY32Xl14OVQp3y6M43/0AtHYYvV6pdyBcp3eoz0s=", "owner": "nix-community", "repo": "home-manager", - "rev": "64c6325b28ebd708653dd41d88f306023f296184", + "rev": "5ec753a1fc4454df9285d8b3ec0809234defb975", "type": "github" }, "original": { @@ -239,11 +268,11 @@ ] }, "locked": { - "lastModified": 1727821604, - "narHash": "sha256-hNw5J6xatedqytYowx0mJKgctjA4lQARZFdgnzM2RpM=", + "lastModified": 1728669738, + "narHash": "sha256-EDNAU9AYcx8OupUzbTbWE1d3HYdeG0wO6Msg3iL1muk=", "owner": "hyprwm", "repo": "hyprcursor", - "rev": "d60e1e01e6e6633ef1c87148b9137cc1dd39263d", + "rev": "0264e698149fcb857a66a53018157b41f8d97bb0", "type": "github" }, "original": { @@ -266,11 +295,11 @@ "xdph": "xdph" }, "locked": { - "lastModified": 1728836804, - "narHash": "sha256-h0osFav6gem66yIZYpGruvN7fYAfLIklcK29BuBPLbg=", + "lastModified": 1729657195, + "narHash": "sha256-YGk7oeyyfvZs4d8qAyMBPg2J/euYK48hPiI6PLKEa30=", "owner": "hyprwm", "repo": "Hyprland", - "rev": "5c3bd8e93d9f25be3e16a0445ba6fce8d30b6d73", + "rev": "6e0aadc585c6d9fdaaebfa5853adbf9610897c82", "type": "github" }, "original": { @@ -345,11 +374,11 @@ ] }, "locked": { - "lastModified": 1727300645, - "narHash": "sha256-OvAtVLaSRPnbXzOwlR1fVqCXR7i+ICRX3aPMCdIiv+c=", + "lastModified": 1728941256, + "narHash": "sha256-WRypmcZ2Bw94lLmcmxYokVOHPJSZ7T06V49QZ4tkZeQ=", "owner": "hyprwm", "repo": "hyprutils", - "rev": "3f5293432b6dc6a99f26aca2eba3876d2660665c", + "rev": "fd4be8b9ca932f7384e454bcd923c5451ef2aa85", "type": "github" }, "original": { @@ -392,11 +421,11 @@ ] }, "locked": { - "lastModified": 1728410210, - "narHash": "sha256-vn6qupt1U0M6Hf3eXhK3/K4Du0Z7A60qYS1G14QsRY8=", + "lastModified": 1729177642, + "narHash": "sha256-DdKal+ZhB9QD/tnEwFg4cZ4j4YnrkvSljBxnyG+3eE0=", "owner": "Jovian-Experiments", "repo": "Jovian-NixOS", - "rev": "a25f915ec05196d15e3f7f8555ffb612d4f1045d", + "rev": "bb69165ff372ddbd3228a03513922acd783040e8", "type": "github" }, "original": { @@ -405,6 +434,23 @@ "type": "github" } }, + "libpng": { + "flake": false, + "locked": { + "lastModified": 1549245649, + "narHash": "sha256-1+cRp0Ungme/OGfc9kGJbklYIWAFxk8Il1M+NV4KSgw=", + "owner": "glennrp", + "repo": "libpng", + "rev": "8439534daa1d3a5705ba92e653eda9251246dd61", + "type": "github" + }, + "original": { + "owner": "glennrp", + "repo": "libpng", + "rev": "8439534daa1d3a5705ba92e653eda9251246dd61", + "type": "github" + } + }, "matugen": { "inputs": { "nixpkgs": "nixpkgs_3" @@ -449,11 +495,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1728492678, - "narHash": "sha256-9UTxR8eukdg+XZeHgxW5hQA9fIKHsKCdOIUycTryeVw=", + "lastModified": 1729413321, + "narHash": "sha256-I4tuhRpZFa6Fu6dcH9Dlo5LlH17peT79vx1y1SpeKt0=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "5633bcff0c6162b9e4b5f1264264611e950c8ec7", + "rev": "1997e4aa514312c1af7e2bda7fad1644e778ff26", "type": "github" }, "original": { @@ -481,11 +527,11 @@ }, "nixpkgs-stable_2": { "locked": { - "lastModified": 1728156290, - "narHash": "sha256-uogSvuAp+1BYtdu6UWuObjHqSbBohpyARXDWqgI12Ss=", + "lastModified": 1729357638, + "narHash": "sha256-66RHecx+zohbZwJVEPF7uuwHeqf8rykZTMCTqIrOew4=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "17ae88b569bb15590549ff478bab6494dde4a907", + "rev": "bb8c2cf7ea0dd2e18a52746b2c3a5b0c73b93c22", "type": "github" }, "original": { @@ -497,11 +543,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1728018373, - "narHash": "sha256-NOiTvBbRLIOe5F6RbHaAh6++BNjsb149fGZd1T4+KBg=", + "lastModified": 1729413321, + "narHash": "sha256-I4tuhRpZFa6Fu6dcH9Dlo5LlH17peT79vx1y1SpeKt0=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "bc947f541ae55e999ffdb4013441347d83b00feb", + "rev": "1997e4aa514312c1af7e2bda7fad1644e778ff26", "type": "github" }, "original": { @@ -529,11 +575,11 @@ }, "nixpkgs_4": { "locked": { - "lastModified": 1728492678, - "narHash": "sha256-9UTxR8eukdg+XZeHgxW5hQA9fIKHsKCdOIUycTryeVw=", + "lastModified": 1729413321, + "narHash": "sha256-I4tuhRpZFa6Fu6dcH9Dlo5LlH17peT79vx1y1SpeKt0=", "owner": "nixos", "repo": "nixpkgs", - "rev": "5633bcff0c6162b9e4b5f1264264611e950c8ec7", + "rev": "1997e4aa514312c1af7e2bda7fad1644e778ff26", "type": "github" }, "original": { @@ -543,6 +589,22 @@ "type": "github" } }, + "nixpkgs_5": { + "locked": { + "lastModified": 1726238386, + "narHash": "sha256-3//V84fYaGVncFImitM6lSAliRdrGayZLdxWlpcuGk0=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "01f064c99c792715054dc7a70e4c1626dbbec0c3", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, "pre-commit-hooks": { "inputs": { "flake-compat": "flake-compat", @@ -554,11 +616,11 @@ "nixpkgs-stable": "nixpkgs-stable" }, "locked": { - "lastModified": 1728092656, - "narHash": "sha256-eMeCTJZ5xBeQ0f9Os7K8DThNVSo9gy4umZLDfF5q6OM=", + "lastModified": 1729104314, + "narHash": "sha256-pZRZsq5oCdJt3upZIU4aslS9XwFJ+/nVtALHIciX/BI=", "owner": "cachix", "repo": "git-hooks.nix", - "rev": "1211305a5b237771e13fcca0c51e60ad47326a9a", + "rev": "3c3e88f0f544d6bb54329832616af7eb971b6be6", "type": "github" }, "original": { @@ -577,23 +639,28 @@ "matugen": "matugen", "nixpkgs": "nixpkgs_4", "sops-nix": "sops-nix", - "spicetify-nix": "spicetify-nix" + "spicetify-nix": "spicetify-nix", + "wezterm": "wezterm" } }, - "rust-analyzer-src": { - "flake": false, + "rust-overlay": { + "inputs": { + "nixpkgs": [ + "wezterm", + "nixpkgs" + ] + }, "locked": { - "lastModified": 1728386838, - "narHash": "sha256-Lk64EoJkvp3WMGVJK3CR1TYcNghX0/BqHPLW5zdvmLE=", - "owner": "rust-lang", - "repo": "rust-analyzer", - "rev": "efaf8bd5de34e2f47bd57425b83e0c7974902176", + "lastModified": 1726280639, + "narHash": "sha256-YfLRPlFZWrT2oRLNAoqf7G3+NnUTDdlIJk6tmBU7kXM=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "e9f8641c92f26fd1e076e705edb12147c384171d", "type": "github" }, "original": { - "owner": "rust-lang", - "ref": "nightly", - "repo": "rust-analyzer", + "owner": "oxalica", + "repo": "rust-overlay", "type": "github" } }, @@ -605,11 +672,11 @@ "nixpkgs-stable": "nixpkgs-stable_2" }, "locked": { - "lastModified": 1728345710, - "narHash": "sha256-lpunY1+bf90ts+sA2/FgxVNIegPDKCpEoWwOPu4ITTQ=", + "lastModified": 1729669122, + "narHash": "sha256-SpS3rSwYcskdOpx+jeCv1lcZDdkT/K5qT8dlenCBQ8c=", "owner": "Mic92", "repo": "sops-nix", - "rev": "06535d0e3d0201e6a8080dd32dbfde339b94f01b", + "rev": "a4c33bfecb93458d90f9eb26f1cf695b47285243", "type": "github" }, "original": { @@ -626,11 +693,11 @@ ] }, "locked": { - "lastModified": 1728792969, - "narHash": "sha256-TwQNBUFNmvr7rSOH5onI2Rj6FoJ6wWzdnMH6P4mwyps=", + "lastModified": 1729657027, + "narHash": "sha256-olxRDZg+/cQZQPW9pEcKfyubHEzqvQsGRrQBw9kTBGg=", "owner": "Gerg-L", "repo": "spicetify-nix", - "rev": "1f3c6931100c64f6747d47f8a7b8d7a75fc5844e", + "rev": "b9d886969141231ca687a915a2c33b3e85c3085c", "type": "github" }, "original": { @@ -669,6 +736,47 @@ "type": "github" } }, + "systems_3": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "wezterm": { + "inputs": { + "flake-utils": "flake-utils", + "freetype2": "freetype2", + "harfbuzz": "harfbuzz", + "libpng": "libpng", + "nixpkgs": "nixpkgs_5", + "rust-overlay": "rust-overlay", + "zlib": "zlib" + }, + "locked": { + "dir": "nix", + "lastModified": 1729006311, + "narHash": "sha256-1xtKJHu6CFnOhp4snof+WSTwcdPgwIaD6mBODP/cv3w=", + "owner": "wez", + "repo": "wezterm", + "rev": "9ddca7bde92090792dbcdc65c1e9897c362196d7", + "type": "github" + }, + "original": { + "dir": "nix", + "owner": "wez", + "repo": "wezterm", + "type": "github" + } + }, "xdph": { "inputs": { "hyprland-protocols": [ @@ -709,6 +817,23 @@ "repo": "xdg-desktop-portal-hyprland", "type": "github" } + }, + "zlib": { + "flake": false, + "locked": { + "lastModified": 1484501380, + "narHash": "sha256-j5b6aki1ztrzfCqu8y729sPar8GpyQWIrajdzpJC+ww=", + "owner": "madler", + "repo": "zlib", + "rev": "cacf7f1d4e3d44d871b605da3b647f07d718623f", + "type": "github" + }, + "original": { + "owner": "madler", + "ref": "v1.2.11", + "repo": "zlib", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index d68d770..fa0da28 100644 --- a/flake.nix +++ b/flake.nix @@ -47,9 +47,10 @@ inputs.nixpkgs.follows = "nixpkgs"; }; + wezterm.url = "github:wez/wezterm?dir=nix"; + catppuccin = { url = "github:catppuccin/nix"; - inputs.nixpkgs.follows = "nixpkgs"; }; hyprland.url = "github:hyprwm/Hyprland"; diff --git a/modules/home-manager/cli/default.nix b/modules/home-manager/cli/default.nix index d97cf32..d10b1a6 100644 --- a/modules/home-manager/cli/default.nix +++ b/modules/home-manager/cli/default.nix @@ -5,5 +5,6 @@ ./fish/default.nix ./alacritty/default.nix ./foot/default.nix + ./wezterm/default.nix ]; } diff --git a/modules/home-manager/cli/wezterm/bar.lua b/modules/home-manager/cli/wezterm/bar.lua new file mode 100644 index 0000000..bec46ea --- /dev/null +++ b/modules/home-manager/cli/wezterm/bar.lua @@ -0,0 +1,360 @@ +-- https://github.com/nekowinston/wezterm-bar +local wezterm = require("wezterm") + +local M = {} + +-- default configuration +local config = { + position = "top", -- or "bottom" + max_width = 32, + dividers = "slant_right", -- "slant_right" or "slant_left", "arrows", "rounded", false + indicator = { + leader = { + enabled = true, + off = " ", + on = " ", + }, + mode = { + enabled = true, + names = { + resize_mode = "RESIZE", + copy_mode = "VISUAL", + search_mode = "SEARCH", + }, + }, + }, + tabs = { + numerals = "arabic", -- or "roman" + pane_count = "superscript", -- or "subscript", false + brackets = { + active = { "", ":" }, + inactive = { "", ":" }, + }, + }, + clock = { + enabled = false, + format = "%I:%M %P", -- https://docs.rs/chrono/latest/chrono/format/strftime/index.html + }, +} + +-- parsed config +local C = {} + +local function tableMerge(t1, t2) + for k, v in pairs(t2) do + if type(v) == "table" then + if type(t1[k] or false) == "table" then + tableMerge(t1[k] or {}, t2[k] or {}) + else + t1[k] = v + end + else + t1[k] = v + end + end + return t1 +end + +local dividers = { + slant_right = { + left = utf8.char(0xe0be), + right = utf8.char(0xe0bc), + }, + slant_left = { + left = utf8.char(0xe0bb), + right = utf8.char(0xe0b8), + }, + arrows = { + left = utf8.char(0xe0b2), + right = utf8.char(0xe0b0), + }, + rounded = { + left = utf8.char(0xe0b6), + right = utf8.char(0xe0b4), + }, +} + +-- conforming to https://github.com/wez/wezterm/commit/e4ae8a844d8feaa43e1de34c5cc8b4f07ce525dd +-- exporting an apply_to_config function, even though we don't change the users config +M.apply_to_config = function(c, opts) + -- make the opts arg optional + if not opts then + opts = {} + end + + -- combine user config with defaults + config = tableMerge(config, opts) + C.div = { + l = "", + r = "", + } + + if config.dividers then + C.div.l = dividers[config.dividers].left + C.div.r = dividers[config.dividers].right + end + + C.leader = { + enabled = config.indicator.leader.enabled and true, + off = config.indicator.leader.off, + on = config.indicator.leader.on, + } + + C.mode = { + enabled = config.indicator.mode.enabled, + names = config.indicator.mode.names, + } + + C.tabs = { + numerals = config.tabs.numerals, + pane_count_style = config.tabs.pane_count, + brackets = { + active = config.tabs.brackets.active, + inactive = config.tabs.brackets.inactive, + }, + } + + C.clock = { + enabled = config.clock.enabled, + format = config.clock.format, + } + + -- set the right-hand padding to 0 spaces, if the rounded style is active + C.p = (config.dividers == "rounded") and "" or " " + + -- set wezterm config options according to the parsed config + c.use_fancy_tab_bar = false + c.tab_bar_at_bottom = config.position == "bottom" + c.tab_max_width = config.max_width +end + +-- superscript/subscript +local function numberStyle(number, script) + local scripts = { + superscript = { + "⁰", + "¹", + "²", + "³", + "⁴", + "⁵", + "⁶", + "⁷", + "⁸", + "⁹", + }, + subscript = { + "₀", + "₁", + "₂", + "₃", + "₄", + "₅", + "₆", + "₇", + "₈", + "₉", + }, + } + local numbers = scripts[script] + local number_string = tostring(number) + local result = "" + for i = 1, #number_string do + local char = number_string:sub(i, i) + local num = tonumber(char) + if num then + result = result .. numbers[num + 1] + else + result = result .. char + end + end + return result +end + +local roman_numerals = { + "Ⅰ", + "Ⅱ", + "Ⅲ", + "Ⅳ", + "Ⅴ", + "Ⅵ", + "Ⅶ", + "Ⅷ", + "Ⅸ", + "Ⅹ", + "Ⅺ", + "Ⅻ", +} + +-- custom tab bar +wezterm.on("format-tab-title", function(tab, tabs, _panes, conf, _hover, _max_width) + local colours = conf.resolved_palette.tab_bar + + local active_tab_index = 0 + for _, t in ipairs(tabs) do + if t.is_active == true then + active_tab_index = t.tab_index + end + end + + local rainbow = { + conf.resolved_palette.ansi[2], + conf.resolved_palette.indexed[16], + conf.resolved_palette.ansi[4], + conf.resolved_palette.ansi[3], + conf.resolved_palette.ansi[5], + conf.resolved_palette.ansi[6], + } + + local i = tab.tab_index % 6 + local active_bg = rainbow[i + 1] + local active_fg = colours.background + local inactive_bg = colours.inactive_tab.bg_color + local inactive_fg = colours.inactive_tab.fg_color + local new_tab_bg = colours.new_tab.bg_color + + local s_bg, s_fg, e_bg, e_fg + + -- the last tab + if tab.tab_index == #tabs - 1 then + if tab.is_active then + s_bg = active_bg + s_fg = active_fg + e_bg = new_tab_bg + e_fg = active_bg + else + s_bg = inactive_bg + s_fg = inactive_fg + e_bg = new_tab_bg + e_fg = inactive_bg + end + elseif tab.tab_index == active_tab_index - 1 then + s_bg = inactive_bg + s_fg = inactive_fg + e_bg = rainbow[(i + 1) % 6 + 1] + e_fg = inactive_bg + elseif tab.is_active then + s_bg = active_bg + s_fg = active_fg + e_bg = inactive_bg + e_fg = active_bg + else + s_bg = inactive_bg + s_fg = inactive_fg + e_bg = inactive_bg + e_fg = inactive_bg + end + + local pane_count = "" + if C.tabs.pane_count_style then + local tabi = wezterm.mux.get_tab(tab.tab_id) + local muxpanes = tabi:panes() + local count = #muxpanes == 1 and "" or tostring(#muxpanes) + pane_count = numberStyle(count, C.tabs.pane_count_style) + end + + local index_i + if C.tabs.numerals == "roman" then + index_i = roman_numerals[tab.tab_index + 1] + else + index_i = tab.tab_index + 1 + end + + local index + if tab.is_active then + index = string.format("%s%s%s ", C.tabs.brackets.active[1], index_i, C.tabs.brackets.active[2]) + else + index = string.format("%s%s%s ", C.tabs.brackets.inactive[1], index_i, C.tabs.brackets.inactive[2]) + end + + -- start and end hardcoded numbers are the Powerline + " " padding + local fillerwidth = 2 + string.len(index) + string.len(pane_count) + 2 + + -- prefer renamed table titles to the default title + local tabtitle = tab.tab_title + if #tabtitle <= 0 then + tabtitle = tab.active_pane.title + end + + local width = conf.tab_max_width - fillerwidth - 1 + if (#tabtitle + fillerwidth) > conf.tab_max_width then + tabtitle = wezterm.truncate_right(tabtitle, width) .. "…" + end + + local title = string.format(" %s%s%s%s", index, tabtitle, pane_count, C.p) + + return { + { Background = { Color = s_bg } }, + { Foreground = { Color = s_fg } }, + { Text = title }, + { Background = { Color = e_bg } }, + { Foreground = { Color = e_fg } }, + { Text = C.div.r }, + } +end) + +wezterm.on("update-status", function(window, _pane) + local active_kt = window:active_key_table() ~= nil + local show = C.leader.enabled or (active_kt and C.mode.enabled) + if not show then + window:set_left_status("") + return + end + + local present, conf = pcall(window.effective_config, window) + if not present then + return + end + local palette = conf.resolved_palette + + local leader = "" + if C.leader.enabled then + local leader_text = C.leader.off + if window:leader_is_active() then + leader_text = C.leader.on + end + leader = wezterm.format({ + { Foreground = { Color = palette.background } }, + { Background = { Color = palette.ansi[5] } }, + { Text = " " .. leader_text .. C.p }, + }) + end + + local mode = "" + if C.mode.enabled then + local mode_text = "" + local active = window:active_key_table() + if C.mode.names[active] ~= nil then + mode_text = C.mode.names[active] .. "" + end + mode = wezterm.format({ + { Foreground = { Color = palette.background } }, + { Background = { Color = palette.ansi[5] } }, + { Attribute = { Intensity = "Bold" } }, + { Text = mode_text }, + "ResetAttributes", + }) + end + + local first_tab_active = window:mux_window():tabs_with_info()[1].is_active + local divider_bg = first_tab_active and palette.ansi[2] or palette.tab_bar.inactive_tab.bg_color + + local divider = wezterm.format({ + { Background = { Color = divider_bg } }, + { Foreground = { Color = palette.ansi[5] } }, + { Text = C.div.r }, + }) + + window:set_left_status(leader .. mode .. divider) + + if C.clock.enabled then + local time = wezterm.time.now():format(C.clock.format) + window:set_right_status(wezterm.format({ + { Background = { Color = palette.tab_bar.background } }, + { Foreground = { Color = palette.ansi[6] } }, + { Text = time }, + })) + end +end) + +return M diff --git a/modules/home-manager/cli/wezterm/catppuccin.lua b/modules/home-manager/cli/wezterm/catppuccin.lua new file mode 100644 index 0000000..c83e434 --- /dev/null +++ b/modules/home-manager/cli/wezterm/catppuccin.lua @@ -0,0 +1,351 @@ +local wezterm = require("wezterm") + +local M = {} + +local colors = { + latte = { + rosewater = "#dc8a78", + flamingo = "#dd7878", + pink = "#ea76cb", + mauve = "#8839ef", + red = "#d20f39", + maroon = "#e64553", + peach = "#fe640b", + yellow = "#df8e1d", + green = "#40a02b", + teal = "#179299", + sky = "#04a5e5", + sapphire = "#209fb5", + blue = "#1e66f5", + lavender = "#7287fd", + text = "#4c4f69", + subtext1 = "#5c5f77", + subtext0 = "#6c6f85", + overlay2 = "#7c7f93", + overlay1 = "#8c8fa1", + overlay0 = "#9ca0b0", + surface2 = "#acb0be", + surface1 = "#bcc0cc", + surface0 = "#ccd0da", + crust = "#dce0e8", + mantle = "#e6e9ef", + base = "#eff1f5", + }, + frappe = { + rosewater = "#f2d5cf", + flamingo = "#eebebe", + pink = "#f4b8e4", + mauve = "#ca9ee6", + red = "#e78284", + maroon = "#ea999c", + peach = "#ef9f76", + yellow = "#e5c890", + green = "#a6d189", + teal = "#81c8be", + sky = "#99d1db", + sapphire = "#85c1dc", + blue = "#8caaee", + lavender = "#babbf1", + text = "#c6d0f5", + subtext1 = "#b5bfe2", + subtext0 = "#a5adce", + overlay2 = "#949cbb", + overlay1 = "#838ba7", + overlay0 = "#737994", + surface2 = "#626880", + surface1 = "#51576d", + surface0 = "#414559", + base = "#303446", + mantle = "#292c3c", + crust = "#232634", + }, + macchiato = { + rosewater = "#f4dbd6", + flamingo = "#f0c6c6", + pink = "#f5bde6", + mauve = "#c6a0f6", + red = "#ed8796", + maroon = "#ee99a0", + peach = "#f5a97f", + yellow = "#eed49f", + green = "#a6da95", + teal = "#8bd5ca", + sky = "#91d7e3", + sapphire = "#7dc4e4", + blue = "#8aadf4", + lavender = "#b7bdf8", + text = "#cad3f5", + subtext1 = "#b8c0e0", + subtext0 = "#a5adcb", + overlay2 = "#939ab7", + overlay1 = "#8087a2", + overlay0 = "#6e738d", + surface2 = "#5b6078", + surface1 = "#494d64", + surface0 = "#363a4f", + base = "#24273a", + mantle = "#1e2030", + crust = "#181926", + }, + mocha = { + rosewater = "#f5e0dc", + flamingo = "#f2cdcd", + pink = "#f5c2e7", + mauve = "#cba6f7", + red = "#f38ba8", + maroon = "#eba0ac", + peach = "#fab387", + yellow = "#f9e2af", + green = "#a6e3a1", + teal = "#94e2d5", + sky = "#89dceb", + sapphire = "#74c7ec", + blue = "#89b4fa", + lavender = "#b4befe", + text = "#cdd6f4", + subtext1 = "#bac2de", + subtext0 = "#a6adc8", + overlay2 = "#9399b2", + overlay1 = "#7f849c", + overlay0 = "#6c7086", + surface2 = "#585b70", + surface1 = "#45475a", + surface0 = "#313244", + base = "#1e1e2e", + mantle = "#181825", + crust = "#11111b", + }, + espresso = { + rosewater = "#ece3e1", + flamingo = "#e1d2d2", + pink = "#ddccd8", + mauve = "#bbb2c9", + red = "#c4a2aa", + maroon = "#cbadb1", + peach = "#d5beb4", + yellow = "#ece3d3", + green = "#b9ddb6", + teal = "#badad4", + sky = "#b8d4db", + sapphire = "#a9c0ce", + blue = "#aab3c7", + lavender = "#bfc1d2", + text = "#d3d6e1", + subtext1 = "#bec2d2", + subtext0 = "#a8adc3", + overlay2 = "#9299b4", + overlay1 = "#7c84a5", + overlay0 = "#686f94", + surface2 = "#555a7b", + surface1 = "#434664", + surface0 = "#30314b", + base = "#101010", + mantle = "#090909", + crust = "#080808", + }, + evergarden = { + rosewater = "#E3A8D1", + flamingo = "#E3A8D1", + pink = "#E3A8D1", + mauve = "#D6A0D1", + red = "#E67E80", + maroon = "#E67E80", + peach = "#E69875", + yellow = "#DBBC7F", + green = "#B2C98F", + teal = "#93C9A1", + sky = "#97C9C3", + sapphire = "#9BB5CF", + blue = "#9BB5CF", + lavender = "#D6A0D1", + text = "#D9E4DC", + subtext1 = "#C9D6D0", + subtext0 = "#AEC2BE", + overlay2 = "#99ADAD", + overlay1 = "#6E8585", + overlay0 = "#5E6C70", + surface2 = "#46545B", + surface1 = "#3D494F", + surface0 = "#343E44", + base = "#252B2E", + mantle = "#1C2225", + crust = "#171C1F", + }, +} + +local mappings = { + -- custom flavor + evergarden = "Evergarden", + espresso = "Catppuccin Espresso", + -- default flavors + mocha = "Catppuccin Mocha", + macchiato = "Catppuccin Macchiato", + frappe = "Catppuccin Frappe", + latte = "Catppuccin Latte", +} + +function M.select(palette, flavor, accent) + local c = palette[flavor] + -- shorthand to check for the Latte flavor + local isLatte = palette == "latte" + + return { + foreground = c.text, + background = c.base, + + cursor_fg = isLatte and c.base or c.crust, + cursor_bg = c.rosewater, + cursor_border = c.rosewater, + + selection_fg = c.text, + selection_bg = c.surface2, + + scrollbar_thumb = c.surface2, + + split = c.overlay0, + + ansi = { + isLatte and c.subtext1 or c.surface1, + c.red, + c.green, + c.yellow, + c.blue, + c.pink, + c.teal, + isLatte and c.surface2 or c.subtext1, + }, + + brights = { + isLatte and c.subtext0 or c.surface2, + c.red, + c.green, + c.yellow, + c.blue, + c.pink, + c.teal, + isLatte and c.surface1 or c.subtext0, + }, + + indexed = { [16] = c.peach, [17] = c.rosewater }, + + -- nightbuild only + compose_cursor = c.flamingo, + + tab_bar = { + background = c.crust, + active_tab = { + bg_color = c[accent], + fg_color = c.crust, + }, + inactive_tab = { + bg_color = c.mantle, + fg_color = c.text, + }, + inactive_tab_hover = { + bg_color = c.base, + fg_color = c.text, + }, + new_tab = { + bg_color = c.surface0, + fg_color = c.text, + }, + new_tab_hover = { + bg_color = c.surface1, + fg_color = c.text, + }, + -- fancy tab bar + inactive_tab_edge = c.surface0, + }, + + visual_bell = c.surface0, + } +end + +local function select_for_appearance(appearance, options) + if appearance:find("Dark") then + return options.dark + else + return options.light + end +end + +local function tableMerge(t1, t2) + for k, v in pairs(t2) do + if type(v) == "table" then + if type(t1[k] or false) == "table" then + tableMerge(t1[k] or {}, t2[k] or {}) + else + t1[k] = v + end + else + t1[k] = v + end + end + return t1 +end + +function M.apply_to_config(c, opts) + if not opts then + opts = {} + end + + -- default options + local defaults = { + flavor = "mocha", + accent = "pink", + sync = false, + sync_flavors = { light = "latte", dark = "mocha" }, + color_overrides = { evergarden = {}, espresso = {}, mocha = {}, macchiato = {}, frappe = {}, latte = {} }, + token_overrides = { evergarden = {}, espresso = {}, mocha = {}, macchiato = {}, frappe = {}, latte = {} }, + } + + local o = tableMerge(defaults, opts) + + -- insert all flavors + local color_schemes = {} + local palette = tableMerge(colors, o.color_overrides) + for flavor, name in pairs(mappings) do + local spec = M.select(palette, flavor, o.accent) + local overrides = o.token_overrides[flavor] + color_schemes[name] = tableMerge(spec, overrides) + end + if c.color_schemes == nil then + c.color_schemes = {} + end + c.color_schemes = tableMerge(c.color_schemes, color_schemes) + + if opts.sync then + c.color_scheme = select_for_appearance(wezterm.gui.get_appearance(), { + dark = mappings[o.sync_flavors.dark], + light = mappings[o.sync_flavors.light], + }) + c.command_palette_bg_color = select_for_appearance(wezterm.gui.get_appearance(), { + dark = colors[o.sync_flavors.dark].crust, + light = colors[o.sync_flavors.light].crust, + }) + c.command_palette_fg_color = select_for_appearance(wezterm.gui.get_appearance(), { + dark = colors[o.sync_flavors.dark].text, + light = colors[o.sync_flavors.light].text, + }) + else + c.color_scheme = mappings[o.flavor] + c.command_palette_bg_color = colors[o.flavor].crust + c.command_palette_fg_color = colors[o.flavor].text + end + + local window_frame = { + active_titlebar_bg = colors[o.flavor].crust, + active_titlebar_fg = colors[o.flavor].text, + inactive_titlebar_bg = colors[o.flavor].crust, + inactive_titlebar_fg = colors[o.flavor].text, + button_fg = colors[o.flavor].text, + button_bg = colors[o.flavor].base, + } + + if c.window_frame == nil then + c.window_frame = {} + end + c.window_frame = tableMerge(c.window_frame, window_frame) +end + +return M diff --git a/modules/home-manager/cli/wezterm/default.nix b/modules/home-manager/cli/wezterm/default.nix new file mode 100644 index 0000000..02a8c41 --- /dev/null +++ b/modules/home-manager/cli/wezterm/default.nix @@ -0,0 +1,11 @@ +{ inputs, pkgs, lib, config, ... }: +{ + home.packages = with pkgs; [ + inputs.wezterm.packages.${pkgs.system}.default + ]; + + xdg.configFile."wezterm" = { + source = config.lib.file.mkOutOfStoreSymlink "/home/pingu/.config/nixos/modules/home-manager/cli/wezterm"; + recursive = true; + }; +} diff --git a/modules/home-manager/cli/wezterm/keybinds.lua b/modules/home-manager/cli/wezterm/keybinds.lua new file mode 100644 index 0000000..48a5af4 --- /dev/null +++ b/modules/home-manager/cli/wezterm/keybinds.lua @@ -0,0 +1,77 @@ +local wezterm = require("wezterm") +local act = wezterm.action + +local utils = require("utils") + +local M = {} + +local openUrl = act.QuickSelectArgs({ + label = "open url", + patterns = { "https?://\\S+" }, + action = wezterm.action_callback(function(window, pane) + local url = window:get_selection_text_for_pane(pane) + wezterm.open_with(url) + end), +}) + +local changeCtpFlavor = act.InputSelector({ + title = "Change Catppuccin flavor", + choices = { + { label = "Evergarden" }, + { label = "Espresso" }, + { label = "Mocha" }, + { label = "Macchiato" }, + { label = "Frappe" }, + { label = "Latte" }, + }, + action = wezterm.action_callback(function(window, _, _, label) + if label then + window:set_config_overrides({ color_scheme = "Catppuccin " .. label }) + end + end), +}) + +local getNewName = act.PromptInputLine({ + description = "Enter new name for tab", + action = wezterm.action_callback(function(window, pane, line) + if line then + window:active_tab():set_title(line) + end + end), +}) + +local keys = {} +local map = function(key, mods, action) + if type(mods) == "string" then + table.insert(keys, { key = key, mods = mods, action = action }) + elseif type(mods) == "table" then + for _, mod in pairs(mods) do + table.insert(keys, { key = key, mods = mod, action = action }) + end + end +end + +map("Enter", "ALT", act.ToggleFullScreen) + +map("e", "CTRL|SHIFT", getNewName) +map("o", { "LEADER", "SUPER" }, openUrl) +map("t", "ALT", changeCtpFlavor) + +local mods +if utils.is_windows() then + mods = "ALT" +else + mods = "SUPER" +end + +M.apply = function(c) + c.leader = { + key = " ", + mods = mods, + timeout_milliseconds = math.maxinteger, + } + c.keys = keys + -- c.disable_default_key_bindings = true +end + +return M diff --git a/modules/home-manager/cli/wezterm/utils.lua b/modules/home-manager/cli/wezterm/utils.lua new file mode 100644 index 0000000..d52e175 --- /dev/null +++ b/modules/home-manager/cli/wezterm/utils.lua @@ -0,0 +1,18 @@ +local wezterm = require("wezterm") +local M = {} + +M.is_windows = function() + return wezterm.target_triple:find("windows") ~= nil +end + +---@return boolean +M.is_linux = function() + return wezterm.target_triple:find("linux") ~= nil +end + +---@return boolean +M.is_darwin = function() + return wezterm.target_triple:find("darwin") ~= nil +end + +return M diff --git a/modules/home-manager/cli/wezterm/wezterm.lua b/modules/home-manager/cli/wezterm/wezterm.lua new file mode 100644 index 0000000..8324bb0 --- /dev/null +++ b/modules/home-manager/cli/wezterm/wezterm.lua @@ -0,0 +1,88 @@ +local utils = require("utils") +local wezterm = require("wezterm") + +local c = {} +if wezterm.c_builder then + c = wezterm.config_builder() +end + +c.enable_wayland = true + +-- theme +require("catppuccin").apply_to_config(c) +require("bar").apply_to_config(c) + +if utils.is_linux() then + c.window_background_opacity = 0.90 +elseif utils.is_darwin() then + c.window_background_opacity = 0.95 + c.macos_window_background_blur = 15 +elseif utils.is_windows() then + -- c.window_background_image = "C:\\Users\\Isabel\\Pictures\\wallpapers\\catgirl.jpg" + -- c.window_background_image_hsb = { + -- brightness = 0.03, -- make the bg darker so we can see what we are doing + -- } + -- c.win32_system_backdrop = "Tabbed" + -- c.window_background_opacity = 0.95 +end + +-- load my keybinds +require("keybinds").apply(c) + +-- default shell +if utils.is_linux() or utils.is_darwin() then + c.default_prog = { "/etc/profiles/per-user/pingu/bin/fish", "--login" } +elseif utils.is_windows() then + c.default_prog = { "wsl.exe" } + c.default_domain = "WSL:NixOS" + c.launch_menu = { + { + label = "PowerShell", + args = { "pwsh.exe", "-NoLogo" }, + domain = { DomainName = "local" }, + }, + } +end + +-- window stuff +if utils.is_linux() then + c.window_decorations = "TITLE | RESIZE" +else + c.window_decorations = "RESIZE" +end +c.window_padding = { left = 10, right = 0, top = 0, bottom = 0 } +c.adjust_window_size_when_changing_font_size = false + +-- fonts +c.font = wezterm.font_with_fallback({ + "Maple Mono", + "Symbols Nerd Font", +}) +c.font_size = 13 +c.adjust_window_size_when_changing_font_size = false +c.window_frame = { + font = wezterm.font("Maple Mono"), + font_size = c.font_size, +} + +-- QOL +c.audible_bell = "Disabled" +c.default_cursor_style = "BlinkingBar" +c.window_close_confirmation = "NeverPrompt" +-- c.prefer_to_spawn_tabs = true + +if utils.is_windows() then + c.front_end = "OpenGL" +else + c.front_end = "WebGpu" +end + +-- this is nix so lets not do it +-- enable this if i ever setup nix to statically link +-- c.automatically_reload_config = false +c.check_for_updates = false + +-- TODO: +-- https://wezfurlong.org/wezterm/config/lua/config/tiling_desktop_environments.html + +return c