From b3b4b78660557a2ac3c3623d87549e14136a45b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jalil=20David=20Salam=C3=A9=20Messina?= Date: Sun, 21 Jan 2024 20:56:00 +0100 Subject: [PATCH] feat: Move home.nix into this repo This makes it much easier to test and apply changes. --- docs/default.nix | 15 ++- flake.lock | 234 ++++++----------------------------- flake.nix | 51 ++++---- home/default.nix | 109 ++++++++++++++++ home/gui/default.nix | 88 +++++++++++++ home/gui/keybindings.nix | 120 ++++++++++++++++++ home/gui/sway-config.nix | 76 ++++++++++++ home/gui/waybar-settings.nix | 68 ++++++++++ home/options.nix | 136 ++++++++++++++++++++ home/users.nix | 30 +++++ 10 files changed, 703 insertions(+), 224 deletions(-) create mode 100644 home/default.nix create mode 100644 home/gui/default.nix create mode 100644 home/gui/keybindings.nix create mode 100644 home/gui/sway-config.nix create mode 100644 home/gui/waybar-settings.nix create mode 100644 home/options.nix create mode 100644 home/users.nix diff --git a/docs/default.nix b/docs/default.nix index a37f36e..e0d791a 100644 --- a/docs/default.nix +++ b/docs/default.nix @@ -1,20 +1,25 @@ -{ pkgs, lib, markdown }: +{ pkgs, lib }: let - eval = lib.evalModules { modules = [ ../nixos/options.nix ]; }; + nixos-eval = lib.evalModules { modules = [ ../nixos/options.nix ]; }; + home-eval = lib.evalModules { modules = [ ../home/options.nix ]; }; nixos-markdown = (pkgs.nixosOptionsDoc { - inherit (eval) options; + inherit (nixos-eval) options; + transformOptions = option: option // { visible = option.visible && builtins.elemAt option.loc 0 == "jconfig"; }; + }).optionsCommonMark; + home-markdown = (pkgs.nixosOptionsDoc { + inherit (home-eval) options; transformOptions = option: option // { visible = option.visible && builtins.elemAt option.loc 0 == "jconfig"; }; }).optionsCommonMark; in { - markdown = nixos-markdown; + inherit nixos-markdown home-markdown; docs = pkgs.stdenvNoCC.mkDerivation { name = "nixos-configuration-book"; src = ./.; patchPhase = '' # copy generated options removing the declared by statement - sed '/^\*Declared by:\*$/,/^$/d' <${markdown} >> src/home-options.md + sed '/^\*Declared by:\*$/,/^$/d' <${home-markdown} >> src/home-options.md sed '/^\*Declared by:\*$/,/^$/d' <${nixos-markdown} >> src/nixos-options.md ''; diff --git a/flake.lock b/flake.lock index 84521a9..fd07ca3 100644 --- a/flake.lock +++ b/flake.lock @@ -3,11 +3,9 @@ "audiomenu": { "inputs": { "flake-schemas": [ - "home-config", "flake-schemas" ], "nixpkgs": [ - "home-config", "nixpkgs" ] }, @@ -205,22 +203,6 @@ } }, "flake-compat_3": { - "flake": false, - "locked": { - "lastModified": 1696426674, - "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", - "type": "github" - }, - "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, - "flake-compat_4": { "flake": false, "locked": { "lastModified": 1673956053, @@ -239,7 +221,6 @@ "flake-parts": { "inputs": { "nixpkgs-lib": [ - "home-config", "nvim-config", "neovim-nightly", "nixpkgs" @@ -262,7 +243,6 @@ "flake-parts_2": { "inputs": { "nixpkgs-lib": [ - "home-config", "nvim-config", "neovim-nightly", "hercules-ci-effects", @@ -350,24 +330,6 @@ "type": "github" } }, - "flake-utils_4": { - "inputs": { - "systems": "systems_4" - }, - "locked": { - "lastModified": 1701680307, - "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, "fromYaml": { "flake": false, "locked": { @@ -385,28 +347,6 @@ } }, "gitignore": { - "inputs": { - "nixpkgs": [ - "home-config", - "pre-commit-hooks", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1703887061, - "narHash": "sha256-gGPa9qWNc6eCXT/+Z5/zMkyYOuRZqeFZBDbopNZQkuY=", - "owner": "hercules-ci", - "repo": "gitignore.nix", - "rev": "43e1aa1308018f37118e34d3a9cb4f5e75dc11d5", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "gitignore.nix", - "type": "github" - } - }, - "gitignore_2": { "inputs": { "nixpkgs": [ "pre-commit-hooks", @@ -429,7 +369,7 @@ }, "haumea": { "inputs": { - "nixpkgs": "nixpkgs" + "nixpkgs": "nixpkgs_2" }, "locked": { "lastModified": 1685133229, @@ -450,7 +390,6 @@ "inputs": { "flake-parts": "flake-parts_2", "nixpkgs": [ - "home-config", "nvim-config", "neovim-nightly", "nixpkgs" @@ -470,39 +409,6 @@ "type": "github" } }, - "home-config": { - "inputs": { - "audiomenu": "audiomenu", - "flake-schemas": [ - "flake-schemas" - ], - "home-manager": [ - "home-manager" - ], - "jpassmenu": "jpassmenu", - "nixpkgs": [ - "nixpkgs" - ], - "nvim-config": "nvim-config", - "pre-commit-hooks": "pre-commit-hooks", - "stylix": [ - "stylix" - ] - }, - "locked": { - "lastModified": 1705689735, - "narHash": "sha256-VlVZjrNWYFu4AxTwVTkFeh5Fa3EX/BciJFX+A/VSzhU=", - "owner": "jalil-salame", - "repo": "home.nix", - "rev": "ac659d85eac97c3f189a0674c090148e782edc41", - "type": "github" - }, - "original": { - "owner": "jalil-salame", - "repo": "home.nix", - "type": "github" - } - }, "home-manager": { "inputs": { "nixpkgs": [ @@ -525,11 +431,9 @@ "jpassmenu": { "inputs": { "flake-schemas": [ - "home-config", "flake-schemas" ], "nixpkgs": [ - "home-config", "nixpkgs" ] }, @@ -551,7 +455,6 @@ "inputs": { "flake-utils": "flake-utils", "nixpkgs": [ - "home-config", "nvim-config", "neovim-nightly", "nixpkgs" @@ -559,11 +462,11 @@ }, "locked": { "dir": "contrib", - "lastModified": 1705595580, - "narHash": "sha256-nk57t1MPmwhQbPh1HPDv5P9+hmg/phVdNIFlR+yt5IE=", + "lastModified": 1705697470, + "narHash": "sha256-Htn7xl9hjkDB+A8x0Y6/okwEUgCwKaKJFk4QNcXHN5k=", "owner": "neovim", "repo": "neovim", - "rev": "78b000c74d631fb097bc2ada0c929153f96d9769", + "rev": "d3a8e9217f39c59dd7762bd22a76b8bd03ca85ff", "type": "github" }, "original": { @@ -580,17 +483,16 @@ "hercules-ci-effects": "hercules-ci-effects", "neovim-flake": "neovim-flake", "nixpkgs": [ - "home-config", "nvim-config", "nixpkgs" ] }, "locked": { - "lastModified": 1705622661, - "narHash": "sha256-x1ojDA4uEVUXhWcDgWdz9gG4CTX9+VNMW0c3mHUdpPM=", + "lastModified": 1705709061, + "narHash": "sha256-Ai6ZAztEf310lxq93JWDzBKQfBlBZnGoHqAJYMV8W+M=", "owner": "nix-community", "repo": "neovim-nightly-overlay", - "rev": "e53738305c3ee233abd025cc4947a282eeb2e8c0", + "rev": "664ff2a12e3f733dc1db467bd8b905438440f924", "type": "github" }, "original": { @@ -617,7 +519,6 @@ "nix-github-actions": { "inputs": { "nixpkgs": [ - "home-config", "nvim-config", "nixneovim", "nixneovimplugins", @@ -644,14 +545,12 @@ "flake-utils": "flake-utils_2", "haumea": "haumea", "home-manager": [ - "home-config", "nvim-config", "home-manager" ], "nix-flake-tests": "nix-flake-tests", "nixneovimplugins": "nixneovimplugins", "nixpkgs": [ - "home-config", "nvim-config", "nixpkgs" ], @@ -659,11 +558,11 @@ "nmt": "nmt" }, "locked": { - "lastModified": 1705506712, - "narHash": "sha256-LdRzA4JHWwp3QbFpekW5HjygniDGaE2JrrShJkXH3kk=", + "lastModified": 1705702328, + "narHash": "sha256-yDPcAUzGlQ4e7JKHVligTUpXcB2X18QNOrA5pzmeus0=", "owner": "NixNeovim", "repo": "NixNeovim", - "rev": "90334259a6b1d63c3571aaf9a356af40412f5885", + "rev": "30e3b1854039a16d8fd08a1ed3f5aaf6c114060e", "type": "github" }, "original": { @@ -675,13 +574,11 @@ "nixneovimplugins": { "inputs": { "flake-utils": [ - "home-config", "nvim-config", "nixneovim", "flake-utils" ], "nixpkgs": [ - "home-config", "nvim-config", "nixneovim", "nixpkgs" @@ -718,17 +615,16 @@ }, "nixpkgs": { "locked": { - "lastModified": 1681001314, - "narHash": "sha256-5sDnCLdrKZqxLPK4KA8+f4A3YKO/u6ElpMILvX0g72c=", - "owner": "nix-community", - "repo": "nixpkgs.lib", - "rev": "367c0e1086a4eb4502b24d872cea2c7acdd557f4", - "type": "github" + "lastModified": 1705496572, + "narHash": "sha256-rPIe9G5EBLXdBdn9ilGc0nq082lzQd0xGGe092R/5QE=", + "rev": "842d9d80cfd4560648c785f8a4e6f3b096790e19", + "revCount": 572380, + "type": "tarball", + "url": "https://api.flakehub.com/f/pinned/NixOS/nixpkgs/0.1.572380%2Brev-842d9d80cfd4560648c785f8a4e6f3b096790e19/018d1ccc-5ecb-7493-8d22-0252128f007d/source.tar.gz" }, "original": { - "owner": "nix-community", - "repo": "nixpkgs.lib", - "type": "github" + "type": "tarball", + "url": "https://flakehub.com/f/NixOS/nixpkgs/0.1.%2A.tar.gz" } }, "nixpkgs-stable": { @@ -747,34 +643,19 @@ "type": "github" } }, - "nixpkgs-stable_2": { - "locked": { - "lastModified": 1704874635, - "narHash": "sha256-YWuCrtsty5vVZvu+7BchAxmcYzTMfolSPP5io8+WYCg=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "3dc440faeee9e889fe2d1b4d25ad0f430d449356", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-23.11", - "repo": "nixpkgs", - "type": "github" - } - }, "nixpkgs_2": { "locked": { - "lastModified": 1705496572, - "narHash": "sha256-rPIe9G5EBLXdBdn9ilGc0nq082lzQd0xGGe092R/5QE=", - "rev": "842d9d80cfd4560648c785f8a4e6f3b096790e19", - "revCount": 572380, - "type": "tarball", - "url": "https://api.flakehub.com/f/pinned/NixOS/nixpkgs/0.1.572380%2Brev-842d9d80cfd4560648c785f8a4e6f3b096790e19/018d1ccc-5ecb-7493-8d22-0252128f007d/source.tar.gz" + "lastModified": 1681001314, + "narHash": "sha256-5sDnCLdrKZqxLPK4KA8+f4A3YKO/u6ElpMILvX0g72c=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "367c0e1086a4eb4502b24d872cea2c7acdd557f4", + "type": "github" }, "original": { - "type": "tarball", - "url": "https://flakehub.com/f/NixOS/nixpkgs/0.1.%2A.tar.gz" + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" } }, "nmd": { @@ -813,26 +694,23 @@ "nvim-config": { "inputs": { "flake-schemas": [ - "home-config", "flake-schemas" ], "home-manager": [ - "home-config", "home-manager" ], "neovim-nightly": "neovim-nightly", "nixneovim": "nixneovim", "nixpkgs": [ - "home-config", "nixpkgs" ] }, "locked": { - "lastModified": 1705639513, - "narHash": "sha256-DaTlPN6NPwlSd/akaTgYglaZ6WiThog0F8dcOGiz4lc=", + "lastModified": 1705812323, + "narHash": "sha256-WKya3PLecFkoyzdcwSqAWcgfscZK/cPLPvLDgwg0z5U=", "owner": "jalil-salame", "repo": "nvim-config", - "rev": "dfb3aa49bbdc634bf5ba981747492a547ad4bcf7", + "rev": "4adc6eaee9db8d0153765580fd04efb3e2fe1b3c", "type": "github" }, "original": { @@ -844,7 +722,6 @@ "poetry2nix": { "inputs": { "flake-utils": [ - "home-config", "nvim-config", "nixneovim", "nixneovimplugins", @@ -852,7 +729,6 @@ ], "nix-github-actions": "nix-github-actions", "nixpkgs": [ - "home-config", "nvim-config", "nixneovim", "nixneovimplugins", @@ -879,7 +755,6 @@ "flake-utils": "flake-utils_3", "gitignore": "gitignore", "nixpkgs": [ - "home-config", "nixpkgs" ], "nixpkgs-stable": "nixpkgs-stable" @@ -898,38 +773,16 @@ "type": "github" } }, - "pre-commit-hooks_2": { - "inputs": { - "flake-compat": "flake-compat_3", - "flake-utils": "flake-utils_4", - "gitignore": "gitignore_2", - "nixpkgs": [ - "nixpkgs" - ], - "nixpkgs-stable": "nixpkgs-stable_2" - }, - "locked": { - "lastModified": 1705229514, - "narHash": "sha256-itILy0zimR/iyUGq5Dgg0fiW8plRDyxF153LWGsg3Cw=", - "owner": "cachix", - "repo": "pre-commit-hooks.nix", - "rev": "ffa9a5b90b0acfaa03b1533b83eaf5dead819a05", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "pre-commit-hooks.nix", - "type": "github" - } - }, "root": { "inputs": { + "audiomenu": "audiomenu", "flake-schemas": "flake-schemas", - "home-config": "home-config", "home-manager": "home-manager", + "jpassmenu": "jpassmenu", "nixos-hardware": "nixos-hardware", - "nixpkgs": "nixpkgs_2", - "pre-commit-hooks": "pre-commit-hooks_2", + "nixpkgs": "nixpkgs", + "nvim-config": "nvim-config", + "pre-commit-hooks": "pre-commit-hooks", "stylix": "stylix" } }, @@ -944,7 +797,7 @@ "base16-kitty": "base16-kitty", "base16-tmux": "base16-tmux", "base16-vim": "base16-vim", - "flake-compat": "flake-compat_4", + "flake-compat": "flake-compat_3", "home-manager": [ "home-manager" ], @@ -1011,21 +864,6 @@ "repo": "default", "type": "github" } - }, - "systems_4": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } } }, "root": "root", diff --git a/flake.nix b/flake.nix index a756369..e303beb 100644 --- a/flake.nix +++ b/flake.nix @@ -10,11 +10,18 @@ inputs.nixpkgs.url = "https://flakehub.com/f/NixOS/nixpkgs/0.1.*.tar.gz"; - inputs.home-config.url = "github:jalil-salame/home.nix"; - inputs.home-config.inputs.stylix.follows = "stylix"; - inputs.home-config.inputs.nixpkgs.follows = "nixpkgs"; - inputs.home-config.inputs.home-manager.follows = "home-manager"; - inputs.home-config.inputs.flake-schemas.follows = "flake-schemas"; + inputs.jpassmenu.url = "github:jalil-salame/jpassmenu"; + inputs.jpassmenu.inputs.nixpkgs.follows = "nixpkgs"; + inputs.jpassmenu.inputs.flake-schemas.follows = "flake-schemas"; + + inputs.audiomenu.url = "github:jalil-salame/audiomenu"; + inputs.audiomenu.inputs.nixpkgs.follows = "nixpkgs"; + inputs.audiomenu.inputs.flake-schemas.follows = "flake-schemas"; + + inputs.nvim-config.url = "github:jalil-salame/nvim-config"; + inputs.nvim-config.inputs.nixpkgs.follows = "nixpkgs"; + inputs.nvim-config.inputs.home-manager.follows = "home-manager"; + inputs.nvim-config.inputs.flake-schemas.follows = "flake-schemas"; inputs.home-manager.url = "https://flakehub.com/f/nix-community/home-manager/0.1.*.tar.gz"; inputs.home-manager.inputs.nixpkgs.follows = "nixpkgs"; @@ -33,10 +40,11 @@ , nixpkgs , stylix , home-manager - , home-config , nixos-hardware , pre-commit-hooks - , ... + , jpassmenu + , audiomenu + , nvim-config }: let inherit (nixpkgs) lib; @@ -47,10 +55,7 @@ pkgs = import nixpkgs { inherit system; }; }); # Module documentation - doc = forEachSupportedSystem ({ pkgs, system }: import ./docs { - inherit (home-config.packages.${system}) markdown; - inherit pkgs lib; - }); + doc = forEachSupportedSystem ({ pkgs, system }: import ./docs { inherit pkgs lib; }); in { # Schemas tell Nix about the structure of your flake's outputs @@ -65,21 +70,22 @@ packages = doc; + # Provide necessary overlays + overlays = { + nixneovim = nvim-config.overlays.nixneovim; + neovim-nightly = nvim-config.overlays.neovim-nightly; + jpassmenu = jpassmenu.overlays.default; + audiomenu = audiomenu.overlays.default; + }; + # Nix files formatter (run `nix fmt`) formatter = forEachSupportedSystem ({ pkgs, ... }: pkgs.nixpkgs-fmt); - inherit (home-config) overlays; - # Example vm configuration nixosConfigurations.vm = let system = "x86_64-linux"; - overlays = [ - home-config.overlays.jpassmenu - home-config.overlays.audiomenu - home-config.overlays.nixneovim - home-config.overlays.neovim-nightly - ]; + overlays = builtins.attrValues self.overlays; config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [ "steam-original" ]; @@ -119,6 +125,9 @@ nixosModules = let + overlays = builtins.attrValues self.overlays; + homeManagerModuleSandalone = import ./home { inherit overlays nvim-config stylix; }; + homeManagerModuleNixOS = import ./home { inherit overlays nvim-config; }; nixosModule = { imports = [ (import ./nixos { inherit stylix; }) @@ -127,7 +136,7 @@ home-manager.useGlobalPkgs = true; home-manager.useUserPackages = true; - home-manager.sharedModules = [ home-config.nixosModules.nixosModule ]; + home-manager.sharedModules = [ homeManagerModuleNixOS ]; # Pin nixpkgs nix.registry.nixpkgs.flake = nixpkgs; @@ -145,7 +154,7 @@ in { default = nixosModule; - inherit nixosModule; + inherit nixosModule homeManagerModuleNixOS homeManagerModuleSandalone; } // machineModules; devShells = forEachSupportedSystem ({ pkgs, system }: { default = pkgs.mkShell { inherit (self.checks.${system}.pre-commit-check) shellHook; }; }); diff --git a/home/default.nix b/home/default.nix new file mode 100644 index 0000000..ddeabbc --- /dev/null +++ b/home/default.nix @@ -0,0 +1,109 @@ +{ overlays, nvim-config, stylix ? null }: { config, pkgs, lib, ... }: +let + cfg = config.jhome; + devcfg = cfg.dev; +in +{ + imports = [ + # Apply overlays + { nixpkgs = { inherit overlays; }; } + nvim-config.nixosModules.default + ./options.nix + ./gui + ./users.nix + ] ++ lib.optionals (stylix != null) [ + stylix.homeManagerModules.stylix + { + stylix.image = builtins.fetchurl { + url = "https://raw.githubusercontent.com/lunik1/nixos-logo-gruvbox-wallpaper/d4937c424fad79c1136a904599ba689fcf8d0fad/png/gruvbox-dark-rainbow.png"; + sha256 = "036gqhbf6s5ddgvfbgn6iqbzgizssyf7820m5815b2gd748jw8zc"; + }; + } + ]; + + config = lib.mkIf cfg.enable { + # Direnv + programs.direnv.enable = true; + programs.direnv.nix-direnv.enable = true; + # ls replacement + programs.eza.enable = true; + programs.eza.enableAliases = true; + programs.eza.git = true; + programs.eza.icons = true; + # GnuPG + programs.gpg.enable = true; + programs.gpg.homedir = "${config.xdg.dataHome}/gnupg"; + # Git + programs.git.enable = true; + programs.git.difftastic.enable = true; + programs.git.difftastic.background = "dark"; + programs.git.lfs.enable = true; + programs.git.extraConfig.init.defaultBranch = "main"; + programs.git.extraConfig.merge.conflictStyle = "zdiff3"; + programs.lazygit.enable = true; + # Mail client + programs.himalaya.enable = true; + # Another shell + programs.nushell.enable = true; + # Password manager + programs.password-store.enable = true; + programs.password-store.package = pkgs.pass-nodmenu; + programs.password-store.settings.PASSWORD_STORE_DIR = "${config.xdg.dataHome}/pass"; + # SSH + programs.ssh.enable = true; + # cd replacement + programs.zoxide.enable = true; + # Shell + programs.zsh.enable = true; + programs.zsh.enableAutosuggestions = true; + programs.zsh.enableCompletion = true; + programs.zsh.autocd = true; + programs.zsh.dotDir = ".config/zsh"; + programs.zsh.history.path = "${config.xdg.dataHome}/zsh/zsh_history"; + programs.zsh.syntaxHighlighting.enable = true; + + # GPG Agent + services.gpg-agent.enable = true; + services.gpg-agent.maxCacheTtl = 86400; + services.gpg-agent.pinentryFlavor = if config.jhome.gui.enable then "qt" else "curses"; + services.gpg-agent.extraConfig = "allow-preset-passphrase"; + # Spotifyd + services.spotifyd.enable = true; + services.spotifyd.settings.global.device_name = config.jhome.hostName; + services.spotifyd.settings.global.device_type = "computer"; + services.spotifyd.settings.global.backend = "pulseaudio"; + services.spotifyd.settings.global.zeroconf_port = 2020; + + home.stateVersion = "22.11"; + + # Extra packages + home.packages = [ + pkgs.gopass + pkgs.sshfs + pkgs.gitoxide + pkgs.xplr + ] ++ lib.optional devcfg.rust.enable pkgs.rustup; + + # Extra variables + home.sessionVariables.CARGO_HOME = "${config.xdg.dataHome}/cargo"; + home.sessionVariables.RUSTUP_HOME = "${config.xdg.dataHome}/rustup"; + home.sessionVariables.GOPATH = "${config.xdg.dataHome}/go"; + + # Verbose Commands + home.shellAliases.cp = "cp --verbose"; + home.shellAliases.ln = "ln --verbose"; + home.shellAliases.mv = "mv --verbose"; + home.shellAliases.mkdir = "mkdir --verbose"; + home.shellAliases.rename = "rename --verbose"; + # Add Color + home.shellAliases.grep = "grep --color=auto"; + home.shellAliases.ip = "ip --color=auto"; + # Use exa/eza + home.shellAliases.tree = "eza --tree"; + + # XDG directories + xdg.enable = true; + xdg.userDirs.enable = true; + xdg.userDirs.createDirectories = true; + }; +} diff --git a/home/gui/default.nix b/home/gui/default.nix new file mode 100644 index 0000000..703b459 --- /dev/null +++ b/home/gui/default.nix @@ -0,0 +1,88 @@ +{ config, lib, pkgs, osConfig ? null, ... }: +let + inherit (config) jhome; + flatpakEnabled = if osConfig != null then osConfig.services.flatpak.enable else false; + cfg = jhome.gui; + swaycfg = config.wayland.windowManager.sway.config; + cursor.package = pkgs.nordzy-cursor-theme; + cursor.name = "Nordzy-cursors"; + iconTheme.name = "Papirus-Dark"; + iconTheme.package = pkgs.papirus-icon-theme; +in +{ + config = lib.mkIf (jhome.enable && cfg.enable) { + home.packages = [ + pkgs.webcord + pkgs.ferdium + pkgs.xournalpp + pkgs.signal-desktop + pkgs.lxqt.pcmanfm-qt + pkgs.wl-clipboard + ] ++ lib.optional flatpakEnabled pkgs.flatpak; + + fonts.fontconfig.enable = true; + + # Browser + programs.firefox.enable = true; + # Dynamic Menu + programs.fuzzel.enable = true; + programs.fuzzel.settings.main.icon-theme = "Papirus-Dark"; + programs.fuzzel.settings.main.terminal = swaycfg.terminal; + programs.fuzzel.settings.main.layer = "overlay"; + # Video player + programs.mpv.enable = true; + programs.mpv.scripts = builtins.attrValues { inherit (pkgs.mpvScripts) uosc thumbfast; }; + # Status bar + programs.waybar.enable = true; + programs.waybar.systemd.enable = true; + programs.waybar.settings = import ./waybar-settings.nix { inherit config lib; }; + # Terminal + programs.wezterm.enable = true; + programs.wezterm.extraConfig = '' + config = {} + config.hide_tab_bar_if_only_one_tab = true + config.window_padding = { left = 1, right = 1, top = 1, bottom = 1 } + return config + ''; + # PDF reader + programs.zathura.enable = true; + # Auto start sway + programs.zsh.loginExtra = lib.optionalString cfg.sway.autostart '' + # Start Sway on login to TTY 1 + if [ "$TTY" = /dev/tty1 ]; then + exec sway + fi + ''; + + # Auto configure displays + services.kanshi.enable = lib.mkDefault true; + # Notifications + services.mako.enable = true; + services.mako.layer = "overlay"; + services.mako.borderRadius = 8; + services.mako.defaultTimeout = 15000; + + # Window Manager + wayland.windowManager.sway.enable = true; + wayland.windowManager.sway.config = import ./sway-config.nix { inherit config pkgs; }; + + # Set cursor style + stylix.cursor = cursor; + home.pointerCursor.gtk.enable = true; + + # Set Gtk theme + gtk.enable = true; + gtk.iconTheme = iconTheme; + gtk.gtk3.extraConfig.gtk-application-prefer-dark-theme = 1; + gtk.gtk4.extraConfig.gtk-application-prefer-dark-theme = 1; + # Set Qt theme + qt.enable = true; + qt.platformTheme = "gtk"; + + xdg.systemDirs.data = [ + "/usr/share" + "/var/lib/flatpak/exports/share" + "${config.xdg.dataHome}/flatpak/exports/share" + ]; + }; +} diff --git a/home/gui/keybindings.nix b/home/gui/keybindings.nix new file mode 100644 index 0000000..6ea70d4 --- /dev/null +++ b/home/gui/keybindings.nix @@ -0,0 +1,120 @@ +{ pkgs, config }: +let + cfg = config.jhome.gui.sway; + passmenu = "${pkgs.jpassmenu}/bin/jpassmenu"; + selectAudio = "${pkgs.audiomenu}/bin/audiomenu --menu 'fuzzel --dmenu'"; + cacheFile = '' + cache_file() { + cache_dir="''${XDG_CACHE_HOME:-$HOME/.cache}/scripts" + [ -d "$cache_dir" ] || mkdir -p "$cache_dir" + echo "$cache_dir/$1" + } + ''; + brightness-notify = pkgs.writeShellScript "birghtness-notify" '' + app='changedBrightness' + icon='brightnesssettings' + # Cache msgid + ${cacheFile} + msgid_file="$(cache_file "$app.msgid")" + [ -f "$msgid_file" ] && msgid="$(cat "$msgid_file")" + msgid="''${msgid:-0}" + # Get brightness + brightness="$(xbacklight -perceived -get)" + # Send notification + ${pkgs.libnotify}/bin/notify-send -pu low -r "$msgid" -a "$app" -i "$icon" -h int:value:"$brightness" "Brightness: $brightness%" >"$msgid_file" + ''; + audio-source-notify = pkgs.writeShellScript "audio-source-notify" '' + app='volumeChanged' + icon='audio-volume' + # Cache msgid + ${cacheFile} + msgid_file="$(cache_file "$app.msgid")" + [ -f "$msgid_file" ] && msgid="$(cat "$msgid_file")" + msgid="''${msgid:-0}" + # Process volume info + volume="$(wpctl get-volume @DEFAULT_SINK@)" + if [ "''${volume#*MUTED}" = "$volume" ]; then muted=false; else muted=true; fi + volume="''${volume#Volume: }" + int_volume="$(printf '%.0f' "$(echo "100*$volume" | "${pkgs.bc}/bin/bc")")" + if [ "$int_volume" -eq 0 ]; then muted=true; fi + # Send notification + if [ "$muted" = true ]; then + ${pkgs.libnotify}/bin/notify-send -pu low -r "$msgid" -a "$app" -i "$icon-muted" "Volume Muted" >"$msgid_file" + else + ${pkgs.libnotify}/bin/notify-send -pu low -r "$msgid" -a "$app" -i "$icon-high" -h "int:value:$int_volume" "Volume: $int_volume%" >"$msgid_file" + fi + ''; + swayconf = config.wayland.windowManager.sway.config; + mod = swayconf.modifier; + workspaces = map toString [ 1 2 3 4 5 6 7 8 9 ]; + dirs = + map + (dir: { + key = swayconf.${dir}; + arrow = dir; + direction = dir; + }) [ "up" "down" "left" "right" ]; + joinKeys = builtins.concatStringsSep "+"; + # Generate a keybind from a modifier prefix and a key + keycombo = prefix: key: joinKeys (prefix ++ [ key ]); + modKeybind = keycombo [ mod ]; + modCtrlKeybind = keycombo [ mod "Ctrl" ]; + modShiftKeybind = keycombo [ mod "Shift" ]; + modCtrlShiftKeybind = keycombo [ mod "Ctrl" "Shift" ]; + dir2resize.up = "resize grow height"; + dir2resize.down = "resize shrink height"; + dir2resize.right = "resize grow width"; + dir2resize.left = "resize shrink width"; + # Bind a key combo to an action + genKeybind = prefix: action: key: { "${prefix key}" = "${action key}"; }; + genKey = prefix: action: genKeybind ({ key, ... }: prefix key) ({ direction, ... }: action direction); + genArrow = prefix: action: genKeybind ({ arrow, ... }: prefix arrow) ({ direction, ... }: action direction); + genArrowAndKey = prefix: action: key: (genKey prefix action key) // (genArrow prefix action key); + # Move window + moveWindowKeybinds = map (genArrowAndKey modShiftKeybind (dir: "move ${dir}")) dirs; + # Focus window + focusWindowKeybinds = map (genArrowAndKey modKeybind (dir: "focus ${dir}")) dirs; + # Resize window + resizeWindowKeybinds = map (genArrowAndKey modCtrlKeybind (dir: dir2resize.${dir})) dirs; + # Move container to workspace + moveWorkspaceKeybindings = map (genKeybind modShiftKeybind (number: "move container to workspace number ${number}")) workspaces; + # Focus workspace + focusWorkspaceKeybindings = map (genKeybind modKeybind (number: "workspace number ${number}")) workspaces; + # Move container to Workspace and focus on it + moveFocusWorkspaceKeybindings = map (genKeybind modCtrlShiftKeybind (number: "move container to workspace number ${number}; workspace number ${number}")) workspaces; +in +builtins.foldl' (l: r: l // r) +{ + "${mod}+Return" = "exec ${swayconf.terminal}"; + "${mod}+D" = "exec ${swayconf.menu}"; + "${mod}+P" = "exec ${passmenu}"; + "${mod}+F2" = "exec qutebrowser"; + "${mod}+Shift+Q" = "kill"; + "${mod}+F" = "fullscreen toggle"; + # Media Controls + "${mod}+F10" = "exec ${selectAudio} select-sink"; + "${mod}+Shift+F10" = "exec ${selectAudio} select-source"; + "XF86AudioRaiseVolume" = "exec wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+ && ${audio-source-notify}"; + "XF86AudioLowerVolume" = "exec wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%- && ${audio-source-notify}"; + "XF86AudioMute" = "exec wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle && ${audio-source-notify}"; + "XF86ScreenSaver" = "exec swaylock --image ${cfg.background}"; + "XF86MonBrightnessUp" = "exec ${pkgs.light}/bin/light -A 5 && ${brightness-notify}"; + "XF86MonBrightnessDown" = "exec ${pkgs.light}/bin/light -U 5 && ${brightness-notify}"; + # Floating + "${mod}+Space" = "floating toggle"; + "${mod}+Shift+Space" = "focus mode_toggle"; + # Scratchpad + "${mod}+Minus" = "scratchpad show"; + "${mod}+Shift+Minus" = "move scratchpad"; + # Layout + "${mod}+e" = "layout toggle split"; + # Session control + "${mod}+r" = "reload"; + "${mod}+Shift+m" = "exit"; +} + (focusWindowKeybinds + ++ moveWindowKeybinds + ++ resizeWindowKeybinds + ++ focusWorkspaceKeybindings + ++ moveWorkspaceKeybindings + ++ moveFocusWorkspaceKeybindings) diff --git a/home/gui/sway-config.nix b/home/gui/sway-config.nix new file mode 100644 index 0000000..c3ce7fc --- /dev/null +++ b/home/gui/sway-config.nix @@ -0,0 +1,76 @@ +{ config, pkgs }: +let + cfg = config.jhome.gui.sway; + modifier = "Mod4"; + terminal = "wezterm"; + menu = "${pkgs.fuzzel}/bin/fuzzel --terminal 'wezterm start'"; + # currently, there is some friction between sway and gtk: + # https://github.com/swaywm/sway/wiki/GTK-3-settings-on-Wayland + # the suggested way to set gtk settings is with gsettings + # for gsettings to work, we need to tell it where the schemas are + # using the XDG_DATA_DIR environment variable + # run at the end of sway config + configure-gtk = + let + schema = pkgs.gsettings-desktop-schemas; + datadir = "${schema}/share/gsettings-schemas/${schema.name}"; + in + pkgs.writers.writeDashBin "configure-gtk" + '' + export XDG_DATA_DIRS=${datadir}:$XDG_DATA_DIRS + gnome_schema=org.gnome.desktop.interface + config="${config.xdg.configHome}/gtk-3.0/settings.ini" + if [ ! -f "$config" ]; then exit 1; fi + # Read settings from gtk3 + gtk_theme="$(${pkgs.gnugrep}/bin/grep 'gtk-theme-name' "$config" | ${pkgs.gnused}/bin/sed 's/.*\s*=\s*//')" + icon_theme="$(${pkgs.gnugrep}/bin/grep 'gtk-icon-theme-name' "$config" | ${pkgs.gnused}/bin/sed 's/.*\s*=\s*//')" + cursor_theme="$(${pkgs.gnugrep}/bin/grep 'gtk-cursor-theme-name' "$config" | ${pkgs.gnused}/bin/sed 's/.*\s*=\s*//')" + font_name="$(grep 'gtk-font-name' "$config" | sed 's/.*\s*=\s*//')" + ${pkgs.glib}/bin/gsettings set "$gnome_schema" gtk-theme "$gtk_theme" + ${pkgs.glib}/bin/gsettings set "$gnome_schema" icon-theme "$icon_theme" + ${pkgs.glib}/bin/gsettings set "$gnome_schema" cursor-theme "$cursor_theme" + ${pkgs.glib}/bin/gsettings set "$gnome_schema" font-name "$font_name" + ${pkgs.glib}/bin/gsettings set "$gnome_schema" color-scheme prefer-dark + ''; + cmdOnce = command: { inherit command; }; + cmdAlways = command: { + inherit command; + always = true; + }; +in +{ + inherit modifier terminal menu; + keybindings = import ./keybindings.nix { inherit config pkgs; }; + # Appearance + bars = [ ]; # Waybar is started as a systemd service + gaps = { + smartGaps = true; + smartBorders = "on"; + inner = 4; + }; + output."*".bg = "${cfg.background} fill"; + # Window Appearance + window.border = 2; + # Make certain windows floating + window.commands = [ + { command = "floating enable"; criteria.title = "zoom"; } + { command = "floating enable"; criteria.class = "floating"; } + { command = "floating enable"; criteria.app_id = "floating"; } + ]; + # Startup scripts + startup = + [ (cmdAlways "${configure-gtk}/bin/configure-gtk") ] + ++ (builtins.map cmdAlways cfg.exec.always) + ++ (builtins.map cmdOnce cfg.exec.once); + # Keyboard configuration + input."type:keyboard".repeat_delay = "300"; + input."type:keyboard".repeat_rate = "50"; + input."type:keyboard".xkb_options = "caps:swapescape"; + input."type:keyboard".xkb_numlock = "enabled"; + # Touchpad + input."type:touchpad".click_method = "clickfinger"; + input."type:touchpad".natural_scroll = "enabled"; + input."type:touchpad".scroll_method = "two_finger"; + input."type:touchpad".tap = "enabled"; + input."type:touchpad".tap_button_map = "lrm"; +} diff --git a/home/gui/waybar-settings.nix b/home/gui/waybar-settings.nix new file mode 100644 index 0000000..43e38f7 --- /dev/null +++ b/home/gui/waybar-settings.nix @@ -0,0 +1,68 @@ +{ config, lib }: +let cfg = config.jhome.gui; in +{ + mainBar.layer = "top"; + mainBar.position = "top"; + mainBar.margin = "2 2 2 2"; + # Choose the order of the modules + mainBar.modules-left = [ "sway/workspaces" ]; + mainBar.modules-center = [ "clock" ]; + mainBar.modules-right = [ "pulseaudio" "backlight" "battery" "sway/language" "memory" ] + ++ lib.optional (cfg.tempInfo != null) "temperature" + ++ [ "tray" ]; + mainBar."sway/workspaces".disable-scroll = true; + mainBar."sway/workspaces".persistent_workspaces."1" = [ ]; + mainBar."sway/workspaces".persistent_workspaces."2" = [ ]; + mainBar."sway/workspaces".persistent_workspaces."3" = [ ]; + mainBar."sway/workspaces".persistent_workspaces."4" = [ ]; + mainBar."sway/workspaces".persistent_workspaces."5" = [ ]; + mainBar."sway/workspaces".persistent_workspaces."6" = [ ]; + mainBar."sway/workspaces".persistent_workspaces."7" = [ ]; + mainBar."sway/workspaces".persistent_workspaces."8" = [ ]; + mainBar."sway/workspaces".persistent_workspaces."9" = [ ]; + mainBar."sway/language".format = "{} "; + mainBar."sway/language".min-length = 5; + mainBar."sway/language".tooltip = false; + mainBar.memory.format = "{used:0.1f}/{total:0.1f}GiB "; + mainBar.memory.interval = 3; + mainBar.clock.timezone = "Europe/Berlin"; + mainBar.clock.tooltip-format = "{:%Y %B}\n{calendar}"; + mainBar.clock.format = "{:%a, %d %b, %H:%M}"; + mainBar.pulseaudio.reverse-scrolling = 1; + mainBar.pulseaudio.format = "{volume}% {icon} {format_source}"; + mainBar.pulseaudio.format-bluetooth = "{volume}% {icon} {format_source}"; + mainBar.pulseaudio.format-bluetooth-muted = "{volume}% 󰖁 {icon} {format_source}"; + mainBar.pulseaudio.format-muted = "{volume}% 󰖁 {format_source}"; + mainBar.pulseaudio.format-source = "{volume}% "; + mainBar.pulseaudio.format-source-muted = "{volume}% 󰍭"; + mainBar.pulseaudio.format-icons.headphone = "󰋋"; + mainBar.pulseaudio.format-icons.hands-free = ""; + mainBar.pulseaudio.format-icons.headset = "󰋎"; + mainBar.pulseaudio.format-icons.phone = "󰘂"; + mainBar.pulseaudio.format-icons.portable = ""; + mainBar.pulseaudio.format-icons.car = ""; + mainBar.pulseaudio.format-icons.default = [ "󰕿" "󰖀" "󰕾" ]; + mainBar.pulseaudio.on-click = "pavucontrol"; + mainBar.pulseaudio.min-length = 13; + mainBar.temperature = + lib.optionalAttrs (cfg.tempInfo != null) { + inherit (cfg.tempInfo) hwmon-path; + critical-threshold = 80; + format = "{temperatureC}°C {icon}"; + format-icons = [ "" "" "" "" "" ]; + tooltip = false; + }; + mainBar.backlight.device = "intel_backlight"; + mainBar.backlight.format = "{percent}% {icon}"; + mainBar.backlight.format-icons = [ "󰃚" "󰃛" "󰃜" "󰃝" "󰃞" "󰃟" "󰃠" ]; + mainBar.backlight.min-length = 7; + mainBar.battery.states.warning = 30; + mainBar.battery.states.critical = 15; + mainBar.battery.format = "{capacity}% {icon}"; + mainBar.battery.format-charging = "{capacity}% 󰂄"; + mainBar.battery.format-plugged = "{capacity}% 󰚥"; + mainBar.battery.format-alt = "{time} {icon}"; + mainBar.battery.format-icons = [ "󰁺" "󰁻" "󰁼" "󰁽" "󰁾" "󰁿" "󰂀" "󰂁" "󰂂" "󰁹" ]; + mainBar.tray.icon-size = 16; + mainBar.tray.spacing = 0; +} diff --git a/home/options.nix b/home/options.nix new file mode 100644 index 0000000..a24641a --- /dev/null +++ b/home/options.nix @@ -0,0 +1,136 @@ +{ lib, ... }: +let + inherit (lib) types; + + identity.options = { + email = lib.mkOption { + description = "Primary email adderss"; + type = types.str; + example = "email@example.org"; + }; + name = lib.mkOption { + description = "The default name you use."; + type = types.str; + example = "John Doe"; + }; + gpgKey = lib.mkOption { + description = "The keygrip of your GPG key."; + type = types.nullOr types.str; + default = null; + example = "6F4ABB77A88E922406BCE6627AFEEE2363914B76"; + }; + }; + + user.options = { + enable = lib.mkEnableOption "Jalil's default user configuration"; + unlockGpgKeyOnLogin = lib.mkEnableOption "unlocking the gpg key on login"; + defaultIdentity = lib.mkOption { + description = "The default identity to use in things like git."; + type = types.submodule identity; + }; + }; + + tempInfo.options.hwmon-path = lib.mkOption { + description = "Path to the hardware sensor whose temperature to monitor."; + type = lib.types.str; + example = "/sys/class/hwmon/hwmon2/temp1_input"; + }; + + sway.options = { + background = lib.mkOption { + description = lib.mdDoc "The wallpaper to use."; + type = lib.types.path; + default = builtins.fetchurl { + url = "https://raw.githubusercontent.com/lunik1/nixos-logo-gruvbox-wallpaper/d4937c424fad79c1136a904599ba689fcf8d0fad/png/gruvbox-dark-rainbow.png"; + sha256 = "036gqhbf6s5ddgvfbgn6iqbzgizssyf7820m5815b2gd748jw8zc"; + }; + }; + autostart = lib.mkOption { + description = lib.mdDoc '' + Autostart Sway when logging in to /dev/tty1. + + This will make it so `exec sway` is run when logging in to TTY1, if + you want a non-graphical session (ie. your GPU drivers are broken) + you can switch TTYs when logging in by using CTRL+ALT+F2 (for TTY2, + F3 for TTY3, etc). + ''; + type = lib.types.bool; + default = true; + example = false; + }; + exec = lib.mkOption { + description = "Run commands when starting sway."; + default = { }; + type = lib.types.submodule { + options = { + once = lib.mkOption { + description = lib.mdDoc "Programs to start only once (`exec`)."; + type = lib.types.listOf lib.types.str; + default = [ ]; + example = [ "signal-desktop --start-in-tray" ]; + }; + always = lib.mkOption { + description = lib.mdDoc "Programs to start whenever the config is sourced (`exec_always`)."; + type = lib.types.listOf lib.types.str; + default = [ ]; + example = [ "signal-desktop --start-in-tray" ]; + }; + }; + }; + }; + }; + + gui.options = { + enable = lib.mkEnableOption ("GUI applications"); + tempInfo = lib.mkOption { + description = lib.mdDoc "Temperature info to display in the statusbar."; + default = null; + type = lib.types.nullOr (lib.types.submodule tempInfo); + }; + sway = lib.mkOption { + description = "Sway window manager configuration."; + default = { }; + type = lib.types.submodule sway; + }; + }; +in +{ + options.jhome = lib.mkOption { + description = lib.mdDoc "Jalil's default home-manager configuration."; + default = { }; + type = types.submodule { + options = { + enable = lib.mkEnableOption "jalil's home defaults"; + hostName = lib.mkOption { + description = lib.mdDoc "The hostname of this system."; + type = types.str; + default = "nixos"; + example = "my pc"; + }; + dev = lib.mkOption { + description = lib.mdDoc "Setup development environment for programming languages."; + default = { }; + type = types.submodule { + options.rust = lib.mkOption { + description = "Jalil's default rust configuration."; + default = { }; + type = types.submodule { + options.enable = lib.mkEnableOption "rust dev environment"; + }; + }; + }; + }; + user = lib.mkOption { + description = lib.mdDoc "User settings."; + default = null; + type = types.nullOr (types.submodule user); + }; + gui = lib.mkOption { + description = lib.mdDoc "Jalil's default GUI configuration."; + default = { }; + type = lib.types.submodule gui; + }; + }; + }; + }; +} diff --git a/home/users.nix b/home/users.nix new file mode 100644 index 0000000..32dc59e --- /dev/null +++ b/home/users.nix @@ -0,0 +1,30 @@ +{ config, lib, ... }: +let + inherit (config) jhome; + inherit (cfg.defaultIdentity) gpgKey; + + cfg = jhome.user; + hasConfig = jhome.enable && cfg != null; + hasKey = gpgKey != null; + gpgHome = config.programs.gpg.homedir; + unlockKey = hasConfig && cfg.unlockGpgKeyOnLogin && hasKey; +in +{ + config = lib.mkMerge [ + (lib.mkIf hasConfig { + programs.git.userName = cfg.defaultIdentity.name; + programs.git.userEmail = cfg.defaultIdentity.email; + programs.git.signing = lib.mkIf hasKey { + signByDefault = true; + key = gpgKey; + }; + }) + (lib.mkIf unlockKey { + xdg.configFile.pam-gnupg.text = '' + ${gpgHome} + + ${gpgKey} + ''; + }) + ]; +}