diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..6da5166 --- /dev/null +++ b/LICENSE @@ -0,0 +1,12 @@ +Copyright (C) 2023 by Jordan Holt + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/README.md b/README.md index 1b8e6ee..b77d220 100644 --- a/README.md +++ b/README.md @@ -1 +1,16 @@ -# nix-config \ No newline at end of file +# nix-config + +System and user configuration for NixOS-based systems. + +| | | +|-|-| +| **Shell:** | zsh | +| **DE:** | GNOME | +| **Theme:** | adwaita | +| **Terminal:** | gnome-console | + +## Quick start +1. Copy SSH keypair and `known_hosts` to `~/.ssh` +1. Import GPG keys and set ultimate trust with `echo "KEYID:6:" | gpg --import-ownertrust` +1. `git clone git@git.vimium.com:jordan/nix-config.git projects/jordan/nix-config` +1. `sudo nixos-rebuild switch --flake .#` diff --git a/flake.lock b/flake.lock index 2ee90bf..5ff5115 100644 --- a/flake.lock +++ b/flake.lock @@ -1,62 +1,63 @@ { "nodes": { + "firefox-gnome-theme": { + "flake": false, + "locked": { + "lastModified": 1686524487, + "narHash": "sha256-o53fws/jwhLfxiYfTyYpKSGi61d5LHzGgSCkt3DNGRI=", + "owner": "rafaelmardojai", + "repo": "firefox-gnome-theme", + "rev": "83b5b96b0ff5f30543b4e6137e268bcf9933c328", + "type": "github" + }, + "original": { + "owner": "rafaelmardojai", + "repo": "firefox-gnome-theme", + "type": "github" + } + }, "home-manager": { "inputs": { "nixpkgs": [ "nixpkgs" - ], - "utils": "utils" + ] }, "locked": { - "lastModified": 1672244468, - "narHash": "sha256-xaZb8AZqoXRCSqPusCk4ouf+fUNP8UJdafmMTF1Ltlw=", + "lastModified": 1687647567, + "narHash": "sha256-Ua90LZYJO7/7KW/KK/AqijhIekd+wxPwbVKXuBYzJeQ=", "owner": "nix-community", "repo": "home-manager", - "rev": "89a8ba0b5b43b3350ff2e3ef37b66736b2ef8706", + "rev": "6ca1e16eb3016c94b7ac16699e1d4158bd4e39a4", "type": "github" }, "original": { "owner": "nix-community", - "ref": "release-22.11", + "ref": "release-23.05", "repo": "home-manager", "type": "github" } }, "nixpkgs": { "locked": { - "lastModified": 1672353432, - "narHash": "sha256-oZfgp/44/o2tWiylV30cR+DLyWTJ+5dhsdWZVpzs3e4=", + "lastModified": 1687555006, + "narHash": "sha256-GD2Kqb/DXQBRJcHqkM2qFZqbVenyO7Co/80JHRMg2U0=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "913a47cd064cc06440ea84e5e0452039a85781f0", + "rev": "33223d479ffde3d05ac16c6dff04ae43cc27e577", "type": "github" }, "original": { "id": "nixpkgs", - "ref": "nixos-22.11", + "ref": "nixos-23.05", "type": "indirect" } }, "root": { "inputs": { + "firefox-gnome-theme": "firefox-gnome-theme", "home-manager": "home-manager", "nixpkgs": "nixpkgs" } - }, - "utils": { - "locked": { - "lastModified": 1667395993, - "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } } }, "root": "root", diff --git a/flake.nix b/flake.nix index b79d490..5ceda9a 100644 --- a/flake.nix +++ b/flake.nix @@ -2,23 +2,31 @@ description = "NixOS/Darwin system configuration"; inputs = { - nixpkgs.url = "nixpkgs/nixos-22.11"; + nixpkgs.url = "nixpkgs/nixos-23.05"; home-manager = { - url = "github:nix-community/home-manager/release-22.11"; + url = "github:nix-community/home-manager/release-23.05"; inputs.nixpkgs.follows = "nixpkgs"; }; + firefox-gnome-theme = { + url = "github:rafaelmardojai/firefox-gnome-theme"; + flake = false; + }; }; - outputs = inputs @ { nixpkgs, home-manager, ... }: + outputs = inputs @ { self, nixpkgs, home-manager, ... }: let inherit (lib) attrValues; inherit (lib.my) mapModules mapModulesRec; - mkPkgs = pkgs: + system = "x86_64-linux"; + + mkPkgs = pkgs: extraOverlays: import pkgs { + inherit system; config.allowUnfree = true; + overlays = extraOverlays ++ (lib.attrValues self.overlays); }; - pkgs = mkPkgs nixpkgs; + pkgs = mkPkgs nixpkgs []; lib = nixpkgs.lib.extend (self: super: { my = import ./lib { @@ -29,18 +37,43 @@ in { lib = lib.my; - nixosModules = mapModulesRec ./modules import; - nixosConfigurations = { atlas = nixpkgs.lib.nixosSystem { - system = "x86_64-linux"; modules = [ inputs.home-manager.nixosModules.home-manager + { nixpkgs.overlays = [ (import ./overlays/gnome.nix) ]; } (import ./modules) ./hosts/atlas ]; specialArgs = { inherit lib inputs; }; }; + eos = nixpkgs.lib.nixosSystem { + modules = [ + inputs.home-manager.nixosModules.home-manager + { nixpkgs.overlays = [ (import ./overlays/gnome.nix) ]; } + (import ./modules) + ./hosts/eos + ]; + specialArgs = { inherit lib inputs; }; + }; + helios = nixpkgs.lib.nixosSystem { + modules = [ + inputs.home-manager.nixosModules.home-manager + { nixpkgs.overlays = [ (import ./overlays/gnome.nix) ]; } + (import ./modules) + ./hosts/helios + ]; + specialArgs = { inherit lib inputs; }; + }; + odyssey = nixpkgs.lib.nixosSystem { + modules = [ + inputs.home-manager.nixosModules.home-manager + { nixpkgs.overlays = [ (import ./overlays/gnome.nix) ]; } + (import ./modules) + ./hosts/odyssey + ]; + specialArgs = { inherit lib inputs; }; + }; }; }; } diff --git a/hosts/atlas/README.md b/hosts/atlas/README.md index e9132cb..1a92df9 100644 --- a/hosts/atlas/README.md +++ b/hosts/atlas/README.md @@ -5,15 +5,34 @@ A general purpose mini computer used for web browsing and multimedia. ## Specs * CPU - Intel Core i7-4790K @ 4.00GHz +* Chipset - Intel Z97 * Memory - 8 GB DDR3 * Motherboard - ASRock Z97M-ITX * GPU - AMD Radeon R9 290X 4GB +* Case - SilverStone Sugo SG13 +* NIC - Intel Gigabit I218-V, Broadcom BCM4360 802.11ac ### Disks -Device | Partitions _(filesystem, usage)_ +Device | Partitions _(filesystem, size, usage)_ --- | --- -Samsung SSD 850 | `/dev/sda1` (NTFS, Windows XP) -Samsung SSD 850 | `/dev/sdb1` (EFI, NixOS Boot)
`/dev/sdb2` (ext4, NixOS Root) +Samsung SSD 850 | `/dev/sda1` (NTFS, 500 GiB, Windows XP) +Samsung SSD 850 | `/dev/sdb1` (EFI, 500 MiB, NixOS Boot)
`/dev/sdb2` (ZFS, 500 GiB, NixOS Root) + +#### ZFS pool layout +``` +rpool/ +├── local +│ ├── nix +│ └── tmp +├── system +│ ├── root +│ └── var +└── user + └── home +``` + +See [Graham Christensen's article](https://grahamc.com/blog/nixos-on-zfs/#datasets) for the motivation behind these datasets. ### Networks -DHCP on `10.0.1.0/24` subnet. +- DHCP on `10.0.1.0/24` subnet. +- Tailscale on `100.64.0.0/10` subnet. FQDN: `atlas.mesh.vimium.net`. diff --git a/hosts/atlas/default.nix b/hosts/atlas/default.nix index 2c06821..4bb6ef9 100644 --- a/hosts/atlas/default.nix +++ b/hosts/atlas/default.nix @@ -9,9 +9,9 @@ with lib.my; boot.loader.systemd-boot.enable = true; boot.loader.efi.canTouchEfiVariables = true; - boot.loader.efi.efiSysMountPoint = "/boot/efi"; networking.hostName = "atlas"; + networking.hostId = "8425e349"; networking.networkmanager.enable = true; nix.package = pkgs.nixFlakes; @@ -25,7 +25,17 @@ with lib.my; modules = { desktop = { - firefox.enable = true; + apps.qbittorrent.enable = true; + browsers = { + firefox.enable = true; + }; + media.graphics = { + raster.enable = true; + vector.enable = true; + }; + }; + dev = { + node.enable = true; }; editors = { neovim.enable = true; @@ -36,10 +46,8 @@ with lib.my; pass.enable = true; }; shell = { - fzf.enable = true; git.enable = true; - nnn.enable = true; zsh.enable = true; }; }; -} \ No newline at end of file +} diff --git a/hosts/atlas/hardware-configuration.nix b/hosts/atlas/hardware-configuration.nix index 9cdd1c4..d5cc8ee 100644 --- a/hosts/atlas/hardware-configuration.nix +++ b/hosts/atlas/hardware-configuration.nix @@ -10,22 +10,53 @@ boot.initrd.availableKernelModules = [ "xhci_pci" "ehci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ]; boot.initrd.kernelModules = [ ]; - boot.kernelModules = [ "kvm-intel" "wl" ]; - boot.extraModulePackages = [ config.boot.kernelPackages.broadcom_sta ]; + boot.initrd.supportedFilesystems = [ "zfs" ]; + boot.kernelModules = [ "kvm-intel" ]; + boot.kernelParams = [ "elevator=none" ]; + boot.extraModulePackages = [ ]; + boot.supportedFilesystems = [ "zfs" ]; fileSystems."/" = - { device = "/dev/disk/by-uuid/db92d689-50d4-4301-90f9-122aab198e38"; - fsType = "ext4"; + { device = "rpool/system/root"; + fsType = "zfs"; }; - fileSystems."/boot/efi" = - { device = "/dev/disk/by-uuid/0720-9BE0"; + fileSystems."/home" = + { device = "rpool/user/home"; + fsType = "zfs"; + }; + + fileSystems."/nix" = + { device = "rpool/local/nix"; + fsType = "zfs"; + }; + + fileSystems."/tmp" = + { device = "rpool/local/tmp"; + fsType = "zfs"; + }; + + fileSystems."/var" = + { device = "rpool/system/var"; + fsType = "zfs"; + }; + + fileSystems."/var/log" = + { device = "rpool/system/var/log"; + fsType = "zfs"; + }; + + fileSystems."/var/tmp" = + { device = "rpool/system/var/tmp"; + fsType = "zfs"; + }; + + fileSystems."/boot" = + { device = "/dev/disk/by-uuid/00B2-0384"; fsType = "vfat"; }; - swapDevices = - [ { device = "/dev/disk/by-uuid/fb217be3-c5df-4e70-8032-78bfbe7325cb"; } - ]; + swapDevices = [ ]; # 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 @@ -36,6 +67,4 @@ nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; - # high-resolution display - hardware.video.hidpi.enable = lib.mkDefault true; } diff --git a/hosts/desktop.nix b/hosts/desktop.nix index a85c66a..7fc0b0a 100644 --- a/hosts/desktop.nix +++ b/hosts/desktop.nix @@ -21,6 +21,15 @@ with lib.my; console.keyMap = "uk"; services.printing.enable = true; + services.openssh = { + enable = true; + settings = { + KbdInteractiveAuthentication = false; + PasswordAuthentication = false; + PermitRootLogin = "no"; + }; + startWhenNeeded = true; + }; sound.enable = true; hardware.pulseaudio.enable = false; @@ -32,5 +41,22 @@ with lib.my; pulse.enable = true; }; + environment.systemPackages = with pkgs; [ + git + neovim + ]; + + nix.settings = { + auto-optimise-store = true; + substituters = [ + "http://odyssey.mesh.vimium.net" + "https://cache.nixos.org" + ]; + trusted-public-keys = [ + "odyssey.mesh.vimium.net:ZhQhjscPWjoN4rlZwoMELznEiBnZ9O26iyGA27ibilQ=" + ]; + }; + modules.desktop.gnome.enable = true; -} \ No newline at end of file + modules.networking.tailscale.enable = true; +} diff --git a/hosts/eos/README.md b/hosts/eos/README.md new file mode 100644 index 0000000..f0a0490 --- /dev/null +++ b/hosts/eos/README.md @@ -0,0 +1,32 @@ +# Eos + +## Overview +ThinkPad X220 laptop. + +## Specs +* CPU - Intel Core i5-2520M @ 3.20GHz +* Memory - 8 GB DDR3 + +### Disks +Device | Partitions _(filesystem, usage)_ +--- | --- +Solid | `/dev/sda1` (EFI, NixOS Boot)
`/dev/sda2` (ZFS, NixOS Root) + +#### ZFS pool layout +``` +rpool/ +├── local +│ ├── nix +│ └── tmp +├── system +│ ├── root +│ └── var +└── user + └── home +``` + +See [Graham Christensen's article](https://grahamc.com/blog/nixos-on-zfs/#datasets) for the motivation behind these datasets. + +### Networks +- DHCP on `10.0.1.0/24` subnet. +- Tailscale on `100.64.0.0/10` subnet. FQDN: `eos.mesh.vimium.net`. diff --git a/hosts/eos/default.nix b/hosts/eos/default.nix new file mode 100644 index 0000000..e2a1ffd --- /dev/null +++ b/hosts/eos/default.nix @@ -0,0 +1,55 @@ +{ config, lib, pkgs, ... }: + +with lib.my; +{ + imports = [ + ./hardware-configuration.nix + ../desktop.nix + ]; + + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + networking.hostName = "eos"; + networking.hostId = "cc858347"; + networking.networkmanager.enable = true; + + nix.package = pkgs.nixFlakes; + nix.extraOptions = '' + experimental-features = nix-command flakes + ''; + nix.settings.auto-optimise-store = true; + + users.defaultUserShell = pkgs.zsh; + + system.stateVersion = "22.11"; + + dconf.settings = { + "org/gnome/desktop/interface" = { + show-battery-percentage = true; + }; + }; + + modules = { + desktop = { + apps.qbittorrent.enable = true; + browsers = { + firefox.enable = true; + }; + }; + dev = { + node.enable = true; + }; + editors = { + neovim.enable = true; + }; + security = { + gpg.enable = true; + pass.enable = true; + }; + shell = { + git.enable = true; + zsh.enable = true; + }; + }; +} diff --git a/hosts/eos/hardware-configuration.nix b/hosts/eos/hardware-configuration.nix new file mode 100644 index 0000000..4351673 --- /dev/null +++ b/hosts/eos/hardware-configuration.nix @@ -0,0 +1,71 @@ +# 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 = [ "ehci_pci" "ahci" "usb_storage" "sd_mod" "sdhci_pci" ]; + boot.initrd.kernelModules = [ ]; + boot.initrd.supportedFilesystems = [ "zfs" ]; + boot.kernelModules = [ ]; + boot.kernelParams = [ "elevator=none" ]; + boot.extraModulePackages = [ ]; + boot.supportedFilesystems = [ "zfs" ]; + + fileSystems."/" = + { device = "rpool/system/root"; + fsType = "zfs"; + }; + + fileSystems."/home" = + { device = "rpool/user/home"; + fsType = "zfs"; + }; + + fileSystems."/nix" = + { device = "rpool/local/nix"; + fsType = "zfs"; + }; + + fileSystems."/tmp" = + { device = "rpool/local/tmp"; + fsType = "zfs"; + }; + + fileSystems."/var" = + { device = "rpool/system/var"; + fsType = "zfs"; + }; + + fileSystems."/var/log" = + { device = "rpool/system/var/log"; + fsType = "zfs"; + }; + + fileSystems."/var/tmp" = + { device = "rpool/system/var/tmp"; + fsType = "zfs"; + }; + + fileSystems."/boot" = + { device = "/dev/disk/by-uuid/28E6-5509"; + fsType = "vfat"; + }; + + swapDevices = [ ]; + + # 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.enp0s25.useDHCP = lib.mkDefault true; + # networking.interfaces.wlp3s0.useDHCP = lib.mkDefault true; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/hosts/helios/README.md b/hosts/helios/README.md new file mode 100644 index 0000000..50d7549 --- /dev/null +++ b/hosts/helios/README.md @@ -0,0 +1,38 @@ +# Helios + +## Overview +Dell OptiPlex 980 small form factor desktop. + +## Specs +* CPU - Intel Core i7-860 @ 2.8GHz +* Chipset - Intel Q57 Express +* Memory - 8 GB DDR2 +* GPU - AMD FirePro 2460 +* NIC - Intel Gigabit 82578DM + +### Disks +Device | Partitions _(filesystem, size, usage)_ +--- | --- +SanDisk Ultra II | `/dev/sda1` (ext2, 200 MiB, NixOS Boot)
`/dev/sda2` (ZFS, 480 GiB, NixOS Root) + +> Note: The BIOS firmware on this machine only supports booting from disks with +> an MBR partition table. + +#### ZFS pool layout +``` +rpool/ +├── local +│ ├── nix +│ └── tmp +├── system +│ ├── root +│ └── var +└── user + └── home +``` + +See [Graham Christensen's article](https://grahamc.com/blog/nixos-on-zfs/#datasets) for the motivation behind these datasets. + +### Networks +- DHCP on `192.168.1.0/24` subnet. +- Tailscale on `100.64.0.0/10` subnet. FQDN: `helios.mesh.vimium.net`. diff --git a/hosts/helios/default.nix b/hosts/helios/default.nix new file mode 100644 index 0000000..9d39c89 --- /dev/null +++ b/hosts/helios/default.nix @@ -0,0 +1,50 @@ +{ config, lib, pkgs, ... }: + +with lib.my; +{ + imports = [ + ./hardware-configuration.nix + ../desktop.nix + ]; + + boot.loader.grub.enable = true; + boot.loader.grub.version = 2; + boot.loader.grub.device = "/dev/sda"; + boot.loader.grub.zfsSupport = true; + + networking.hostName = "helios"; + networking.hostId = "47d23505"; + networking.networkmanager.enable = true; + + nix.package = pkgs.nixFlakes; + nix.extraOptions = '' + experimental-features = nix-command flakes + ''; + + users.defaultUserShell = pkgs.zsh; + + system.stateVersion = "22.11"; + + modules = { + desktop = { + apps.qbittorrent.enable = true; + browsers = { + firefox.enable = true; + }; + }; + dev = { + node.enable = true; + }; + editors = { + neovim.enable = true; + }; + security = { + gpg.enable = true; + pass.enable = true; + }; + shell = { + git.enable = true; + zsh.enable = true; + }; + }; +} diff --git a/hosts/helios/hardware-configuration.nix b/hosts/helios/hardware-configuration.nix new file mode 100644 index 0000000..f8bad89 --- /dev/null +++ b/hosts/helios/hardware-configuration.nix @@ -0,0 +1,65 @@ +# 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 = [ "ehci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" "sr_mod" "zfs" ]; + boot.initrd.kernelModules = [ ]; + boot.initrd.supportedFilesystems = [ "zfs" ]; + boot.kernelModules = [ "kvm-intel" ]; + boot.kernelParams = [ "elevator=none" ]; + boot.extraModulePackages = [ ]; + boot.supportedFilesystems = [ "zfs" ]; + + fileSystems."/" = + { device = "rpool/system/root"; + fsType = "zfs"; + }; + + fileSystems."/home" = + { device = "rpool/user/home"; + fsType = "zfs"; + }; + + fileSystems."/nix" = + { device = "rpool/local/nix"; + fsType = "zfs"; + }; + + fileSystems."/tmp" = + { device = "rpool/local/tmp"; + fsType = "zfs"; + }; + + fileSystems."/var/log" = + { device = "rpool/system/var/log"; + fsType = "zfs"; + }; + + fileSystems."/var/tmp" = + { device = "rpool/system/var/tmp"; + fsType = "zfs"; + }; + + fileSystems."/boot" = + { device = "/dev/sda1"; + fsType = "ext2"; + }; + + swapDevices = [ ]; + + # 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.eno1.useDHCP = lib.mkDefault true; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/hosts/odyssey/README.md b/hosts/odyssey/README.md new file mode 100644 index 0000000..d178fb6 --- /dev/null +++ b/hosts/odyssey/README.md @@ -0,0 +1,36 @@ +# Odyssey + +## Overview +Primary workstation. + +## Specs +* CPU - Intel Core i7-5930K @ 4.10GHz +* Chipset - Intel X99 +* Memory - 64 GB DDR4 +* Motherboard - ASUS X99-A +* GPU - NVIDIA RTX 3090 +* Case - Thermaltake A500 + +### Disks +Device | Partitions _(filesystem, size, usage)_ +--- | --- +Samsung 980 Pro | `/dev/nvme0n1p1` (EFI, 512 MiB, NixOS Boot)
`/dev/nvme0n1p2` (ZFS, 2 TiB, NixOS Root) + +#### ZFS pool layout +``` +rpool/ +├── local +│ ├── nix +│ └── tmp +├── system +│ ├── root +│ └── var +└── user + └── home +``` + +See [Graham Christensen's article](https://grahamc.com/blog/nixos-on-zfs/#datasets) for the motivation behind these datasets. + +### Networks +- DHCP on `10.0.1.0/24` subnet. +- Tailscale on `100.64.0.0/10` subnet. FQDN: `odyssey.mesh.vimium.net`. diff --git a/hosts/odyssey/default.nix b/hosts/odyssey/default.nix new file mode 100644 index 0000000..a4af3f3 --- /dev/null +++ b/hosts/odyssey/default.nix @@ -0,0 +1,78 @@ +{ config, lib, pkgs, ... }: + +with lib.my; +{ + imports = [ + ./hardware-configuration.nix + ../desktop.nix + ]; + + boot.loader.systemd-boot = { + enable = true; + graceful = true; + netbootxyz.enable = true; + }; + boot.loader.efi.canTouchEfiVariables = true; + + networking.hostName = "odyssey"; + networking.hostId = "c5e68d78"; + + networking.networkmanager.enable = true; + + nix.package = pkgs.nixFlakes; + nix.extraOptions = '' + experimental-features = nix-command flakes + ''; + + virtualisation.libvirtd.enable = true; + + users.defaultUserShell = pkgs.zsh; + + system.stateVersion = "22.11"; + + services.nix-serve = { + enable = true; + secretKeyFile = "/var/cache-priv-key.pem"; + }; + + services.nginx = { + enable = true; + recommendedProxySettings = true; + virtualHosts = { + "odyssey.mesh.vimium.net" = { + locations."/".proxyPass = "http://${config.services.nix-serve.bindAddress}:${toString config.services.nix-serve.port}"; + }; + }; + }; + + modules = { + desktop = { + apps.qbittorrent.enable = true; + browsers = { + firefox.enable = true; + }; + media.graphics = { + raster.enable = true; + vector.enable = true; + }; + media.recording = { + audio.enable = true; + video.enable = true; + }; + }; + dev = { + node.enable = true; + }; + editors = { + neovim.enable = true; + }; + security = { + gpg.enable = true; + pass.enable = true; + }; + shell = { + git.enable = true; + zsh.enable = true; + }; + }; +} diff --git a/hosts/odyssey/hardware-configuration.nix b/hosts/odyssey/hardware-configuration.nix new file mode 100644 index 0000000..8c25db0 --- /dev/null +++ b/hosts/odyssey/hardware-configuration.nix @@ -0,0 +1,69 @@ +# 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 = [ "xhci_pci" "ehci_pci" "nvme" "usbhid" "usb_storage" "sd_mod" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ "kvm-intel" ]; + boot.extraModulePackages = [ ]; + boot.supportedFilesystems = [ "ntfs" ]; + + hardware.nvidia = { + modesetting.enable = true; + powerManagement.enable = true; + }; + services.xserver.videoDrivers = [ "nvidia" ]; + + fileSystems."/" = + { device = "rpool/system/root"; + fsType = "zfs"; + }; + + fileSystems."/home" = + { device = "rpool/user/home"; + fsType = "zfs"; + }; + + fileSystems."/var" = + { device = "rpool/system/var"; + fsType = "zfs"; + }; + + fileSystems."/tmp" = + { device = "rpool/local/tmp"; + fsType = "zfs"; + }; + + fileSystems."/var/log" = + { device = "rpool/system/var/log"; + fsType = "zfs"; + }; + + fileSystems."/var/tmp" = + { device = "rpool/system/var/tmp"; + fsType = "zfs"; + }; + + fileSystems."/boot" = + { device = "/dev/disk/by-uuid/E63E-8E75"; + fsType = "vfat"; + }; + + swapDevices = [ ]; + + # 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.eno1.useDHCP = lib.mkDefault true; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/hosts/server.nix b/hosts/server.nix new file mode 100644 index 0000000..054176c --- /dev/null +++ b/hosts/server.nix @@ -0,0 +1,41 @@ +{ config, lib, pkgs, ... }: + +with lib; +with lib.my; +{ + time.timeZone = "Europe/London"; + + i18n.defaultLocale = "en_GB.UTF-8"; + i18n.extraLocaleSettings = { + LC_ADDRESS = "en_GB.UTF-8"; + LC_IDENTIFICATION = "en_GB.UTF-8"; + LC_MEASUREMENT = "en_GB.UTF-8"; + LC_MONETARY = "en_GB.UTF-8"; + LC_NAME = "en_GB.UTF-8"; + LC_NUMERIC = "en_GB.UTF-8"; + LC_PAPER = "en_GB.UTF-8"; + LC_TELEPHONE = "en_GB.UTF-8"; + LC_TIME = "en_GB.UTF-8"; + }; + + console.keyMap = "uk"; + + services.openssh = { + enable = true; + settings = { + KbdInteractiveAuthentication = false; + PasswordAuthentication = false; + PermitRootLogin = "no"; + }; + }; + + environment.systemPackages = with pkgs; [ + git + neovim + ]; + + modules.networking.tailscale = { + enable = true; + restrictSSH = false; + }; +} diff --git a/modules/default.nix b/modules/default.nix index 5613449..598bd18 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -1,15 +1,32 @@ { imports = [ ./options.nix - ./desktop/firefox.nix ./desktop/gnome.nix - ./editors/neovim.nix + ./desktop/mimeapps.nix + ./desktop/apps/qbittorrent.nix + ./desktop/apps/slack.nix + ./desktop/apps/zoom.nix + ./desktop/browsers/firefox.nix + ./desktop/gaming/emulators.nix + ./desktop/gaming/lutris.nix + ./desktop/gaming/steam.nix + ./desktop/media/graphics.nix + ./desktop/media/recording.nix + ./dev/cc.nix + ./dev/java.nix + ./dev/lua.nix + ./dev/node.nix + ./dev/python.nix + ./dev/rust.nix + ./dev/scala.nix + ./dev/shell.nix + ./dev/zig.nix + ./editors/neovim ./editors/vscode.nix + ./networking/tailscale.nix ./security/gpg.nix ./security/pass.nix - ./shell/fzf.nix - ./shell/git.nix - ./shell/nnn.nix - ./shell/zsh.nix + ./shell/git + ./shell/zsh ]; -} \ No newline at end of file +} diff --git a/modules/desktop/apps/qbittorrent.nix b/modules/desktop/apps/qbittorrent.nix new file mode 100644 index 0000000..60b0c44 --- /dev/null +++ b/modules/desktop/apps/qbittorrent.nix @@ -0,0 +1,16 @@ +{ config, lib, pkgs, ... }: + +with lib; +with lib.my; +let cfg = config.modules.desktop.apps.qbittorrent; +in { + options.modules.desktop.apps.qbittorrent = { + enable = mkBoolOpt false; + }; + + config = mkIf cfg.enable { + user.packages = with pkgs; [ + qbittorrent + ]; + }; +} \ No newline at end of file diff --git a/modules/desktop/apps/slack.nix b/modules/desktop/apps/slack.nix new file mode 100644 index 0000000..86e3dfd --- /dev/null +++ b/modules/desktop/apps/slack.nix @@ -0,0 +1,16 @@ +{ config, lib, pkgs, ... }: + +with lib; +with lib.my; +let cfg = config.modules.desktop.apps.slack; +in { + options.modules.desktop.apps.slack = { + enable = mkBoolOpt false; + }; + + config = mkIf cfg.enable { + user.packages = with pkgs; [ + slack + ]; + }; +} diff --git a/modules/desktop/apps/zoom.nix b/modules/desktop/apps/zoom.nix new file mode 100644 index 0000000..3072d8d --- /dev/null +++ b/modules/desktop/apps/zoom.nix @@ -0,0 +1,16 @@ +{ config, lib, pkgs, ... }: + +with lib; +with lib.my; +let cfg = config.modules.desktop.apps.zoom; +in { + options.modules.desktop.apps.zoom = { + enable = mkBoolOpt false; + }; + + config = mkIf cfg.enable { + user.packages = with pkgs; [ + zoom-us + ]; + }; +} diff --git a/modules/desktop/browsers/firefox.nix b/modules/desktop/browsers/firefox.nix new file mode 100644 index 0000000..08735f0 --- /dev/null +++ b/modules/desktop/browsers/firefox.nix @@ -0,0 +1,132 @@ +{ config, lib, pkgs, inputs, ... }: + +with lib; +with lib.my; +let cfg = config.modules.desktop.browsers.firefox; +in { + options.modules.desktop.browsers.firefox = { + enable = mkBoolOpt false; + }; + + config = mkIf cfg.enable { + home.file.".mozilla/firefox/Default/chrome/firefox-gnome-theme".source = inputs.firefox-gnome-theme; + + home.programs.firefox = { + enable = true; + profiles.Default = { + search = { + default = "DuckDuckGo"; + force = true; + }; + userChrome = '' + @import "firefox-gnome-theme/userChrome.css"; + ''; + userContent = '' + @import "firefox-gnome-theme/userContent.css"; + ''; + settings = { + ## GNOME theme + "toolkit.legacyUserProfileCustomizations.stylesheets" = true; # Enable customChrome.cs + "browser.uidensity" = 0; # Set UI density to normal + "svg.context-properties.content.enabled" = true; # Enable SVG context-propertes + "browser.theme.dark-private-windows" = false; # Disable private window dark theme + + ## Preferences + "browser.ctrlTab.sortByRecentlyUsed" = true; + "browser.newtabpage.enabled" = false; + "browser.search.widget.inNavBar" = true; + "browser.startup.page" = 3; + "browser.startup.homepage" = "https://www.vimium.com"; + "browser.toolbars.bookmarks.visibility" = "never"; + + ## Experiments + "app.normandy.enabled" = false; + "app.normandy.api_url" = ""; + "app.normandy.user_id" = ""; + "extensions.screenshots.disabled" = true; + "extensions.screenshots.upload-disabled" = true; + "experiments.supported" = false; + "experiments.enabled" = false; + "experiments.manifest.uri" = ""; + "network.allow-experiments" = false; + "privacy.trackingprotection.enabled" = false; + + ## Geo + "geo.enabled" = false; + "geo.provider.use_gpsd" = false; + "geo.wifi.uri" = ""; + "browser.search.geoip.url" = ""; + "browser.search.geoSpecificDefaults" = false; + "browser.search.geoSpecificDefaults.url" = ""; + + ## Window meddling / popups + "dom.disable_window_open_feature.close" = true; + "dom.disable_window_open_feature.location" = true; + "dom.disable_window_open_feature.menubar" = true; + "dom.disable_window_open_feature.minimizable" = true; + "dom.disable_window_open_feature.personalbar" = true; + "dom.disable_window_open_feature.resizable" = true; + "dom.disable_window_open_feature.status" = true; + "dom.disable_window_open_feature.titlebar" = true; + "dom.disable_window_open_feature.toolbar" = true; + "dom.disable_window_move_resize" = true; + "browser.link.open_newwindow" = 3; + "browser.link.open_newwindow.restriction" = 0; + "dom.disable_open_during_load" = true; + "dom.popup_allowed_events" = "click dblclick"; + + ## Workers + # "dom.serviceWorkers.enabled" = false; + "dom.push.enabled" = false; + "dom.webnotifications.enabled" = false; + "dom.webnotifications.serviceworker.enabled" = false; + "permissions.default.desktop-notification" = 2; + + ## DOM / JavaScript + # "dom.event.clipboardevents.enabled" = false; + "middlemouse.paste" = false; + # "dom.allow_cut_copy" = false; + "dom.disable_beforeunload" = true; + "dom.vibrator.enabled" = false; + # "javascript.options.asmjs" = false; + # "javascript.options.wasm" = false; + "dom.targetBlankNoOpener.enabled" = true; + + ## Hardware fingerprinting + "dom.battery.enabled" = false; + "dom.vr.enabled" = false; + "media.navigator.enabled" = false; + "dom.webaudio.enabled" = false; + + ## Isolation + "privacy.firstparty.isolate" = true; + "privacy.firstparty.isolate.restrict_opener_access" = true; + + ## Pocket/Hello + "loop.enabled" = false; + "loop.feedback.baseUrl" = ""; + "loop.gettingStarted.url" = ""; + "loop.learnMoreUrl" = ""; + "loop.legal.ToS_url" = ""; + "loop.legal.privacy_url" = ""; + "loop.oauth.google.redirect_uri" = ""; + "loop.oauth.google.scope" = ""; + "loop.server" = ""; + "loop.soft_start_hostname" = ""; + "loop.support_url" = ""; + "loop.throttled2" = false; + "loop.logDomains" = false; + "browser.pocket.enabled" = false; + "browser.pocket.api" = ""; + "browser.pocket.site" = ""; + "browser.pocket.oAuthConsumerKey" = ""; + "browser.pocket.useLocaleList" = false; + "brwoser.pocket.enabledLocales" = ""; + + ## Misc + "browser.selfsupport.url" = ""; + }; + }; + }; + }; +} diff --git a/modules/desktop/firefox.nix b/modules/desktop/firefox.nix deleted file mode 100644 index b79e909..0000000 --- a/modules/desktop/firefox.nix +++ /dev/null @@ -1,16 +0,0 @@ -{ config, lib, pkgs, ... }: - -with lib; -with lib.my; -let cfg = config.modules.desktop.firefox; -in { - options.modules.desktop.firefox = { - enable = mkBoolOpt false; - }; - - config = mkIf cfg.enable { - home.programs.firefox = { - enable = true; - }; - }; -} \ No newline at end of file diff --git a/modules/desktop/gaming/emulators.nix b/modules/desktop/gaming/emulators.nix new file mode 100644 index 0000000..d06a89a --- /dev/null +++ b/modules/desktop/gaming/emulators.nix @@ -0,0 +1,34 @@ +{ config, lib, pkgs, ... }: + +with lib; +with lib.my; +let cfg = config.modules.desktop.gaming.emulators; +in { + options.modules.desktop.gaming.emulators = { + ds.enable = mkBoolOpt false; + gb.enable = mkBoolOpt false; + gba.enable = mkBoolOpt false; + gamecube.enable = mkBoolOpt false; + ps2.enable = mkBoolOpt false; + ps3.enable = mkBoolOpt false; + psp.enable = mkBoolOpt false; + snes.enable = mkBoolOpt false; + wii.enable = mkBoolOpt false; + }; + + config = { + user.packages = with pkgs; [ + (mkIf cfg.ps2.enable pcsx2) + (mkIf cfg.ps3.enable rpcs3) + (mkIf cfg.psp.enable ppsspp) + (mkIf cfg.ds.enable desmume) + (mkIf (cfg.gba.enable || + cfg.gb.enable || + cfg.snes.enable) + higan) + (mkIf (cfg.wii.enable || + cfg.gamecube.enable) + dolphin-emu) + ]; + }; +} \ No newline at end of file diff --git a/modules/desktop/gaming/lutris.nix b/modules/desktop/gaming/lutris.nix new file mode 100644 index 0000000..dffc93f --- /dev/null +++ b/modules/desktop/gaming/lutris.nix @@ -0,0 +1,24 @@ +{ config, lib, pkgs, ... }: + +with lib; +with lib.my; +let cfg = config.modules.desktop.gaming.lutris; +in { + options.modules.desktop.gaming.lutris = { + enable = mkBoolOpt false; + }; + + config = mkIf cfg.enable { + user.packages = with pkgs; [ + lutris + vulkan-loader + vulkan-tools + ]; + + hardware.opengl = { + enable = true; + driSupport = true; + driSupport32Bit = true; + }; + }; +} diff --git a/modules/desktop/gaming/steam.nix b/modules/desktop/gaming/steam.nix new file mode 100644 index 0000000..262089a --- /dev/null +++ b/modules/desktop/gaming/steam.nix @@ -0,0 +1,16 @@ +{ config, lib, pkgs, ... }: + +with lib; +with lib.my; +let cfg = config.modules.desktop.gaming.steam; +in { + options.modules.desktop.gaming.steam = { + enable = mkBoolOpt false; + }; + + config = mkIf cfg.enable { + programs.steam.enable = true; + + systemd.extraConfig = "DefaultLimitNOFILE=1048576"; + }; +} \ No newline at end of file diff --git a/modules/desktop/gnome.nix b/modules/desktop/gnome.nix index 7d20962..c8a1b6c 100644 --- a/modules/desktop/gnome.nix +++ b/modules/desktop/gnome.nix @@ -15,16 +15,166 @@ in { desktopManager.gnome.enable = true; }; + programs.dconf.enable = true; + dconf.settings = { + "org/gnome/shell" = { + disable-user-extensions = false; + enabled-extensions = [ + "another-window-session-manager@gmail.com" + "blur-my-shell@aunetx" + "burn-my-windows@schneegans.github.com" + "desktop-cube@schneegans.github.com" + "desktop-zoom@colin.kinlo.ch" + "espresso@coadmunkee.github.com" + # "forge@jmmaranan.com" + "hue-lights@chlumskyvaclav@gmail.com" + "just-perfection-desktop@just-perfection" + "space-bar@luchrioh" + # "smart-auto-move@khimaros.com" + # "systemd-manager@hardpixel.eu" + # "tailscale-status@maxgallup.github.com" + "tiling-assistant@leleat-on-github" + # "wsmatrix@martin.zurowietz.de" + ]; + favorite-apps = [ + "firefox.desktop" + "org.gnome.Nautilus.desktop" + "org.gnome.Console.desktop" + ]; + }; + "org/gnome/shell/extensions/another-window-session-manager" = { + enable-autorestore-sessions = true; + }; + "org/gnome/shell/extensions/blur-my-shell/panel" = { + static-blur = true; + }; + "org/gnome/shell/extensions/blur-my-shell/applications" = { + blur = false; + }; + "org/gnome/shell/extensions/burn-my-windows" = { + fire-close-effect = false; + glide-open-effect = true; + glide-close-effect = true; + }; + "org/gnome/shell/extensions/desktop-zoom" = { + mag-factor-delta = 0.07; + }; + "org/gnome/shell/extensions/espresso" = { + enable-fullscreen = true; + show-indicator = true; + show-notifications = false; + inhibit-apps = [ + "com.obsproject.Studio.desktop" + ]; + }; + "org/gnome/shell/extensions/forge" = { + window-gap-size = 8; + window-gap-hidden-on-single = false; + }; + "org/gnome/shell/extensions/just-perfection" = { + activities-button = false; + window-demands-attention-focus = true; + workspace-wrap-around = true; + }; + "org/gnome/shell/extensions/space-bar/behavior" = { + enable-activate-workspace-shortcuts = true; + show-empty-workspaces = true; + smart-workspace-names = false; + }; + "org/gnome/shell/extensions/tiling-assistant" = { + screen-top-gap = 8; + screen-right-gap = 8; + screen-bottom-gap = 8; + screen-left-gap = 8; + window-gap = 8; + }; + "org/gnome/desktop/background" = { + picture-uri = "file://${pkgs.gnome.gnome-backgrounds}/share/backgrounds/gnome/adwaita-l.webp"; + picture-uri-dark = "file://${pkgs.gnome.gnome-backgrounds}/share/backgrounds/gnome/adwaita-d.webp"; + }; + "org/gtk/settings/file-chooser" = { + show-hidden = true; + sort-directories-first = true; + }; + "org/gtk/gtk4/settings/file-chooser" = { + show-hidden = true; + sort-directories-first = true; + }; + "org/gnome/settings-daemon/plugins/media-keys" = { + volume-up = [ + "F12" + "XF86AudioRaiseVolume" + ]; + volume-down = [ + "F11" + "XF86AudioLowerVolume" + ]; + }; + "org/gnome/gnome-session" = { + auto-save-session = true; + }; + "org/gnome/gnome-system-monitor" = { + show-dependencies = true; + }; + "org/gnome/Console" = { + font-scale = 1.4; + }; + "org/gnome/mutter" = { + center-new-windows = true; + experimental-features = [ "scale-monitor-framebuffer" ]; + }; + "org/gnome/desktop/interface" = { + color-scheme = "prefer-dark"; + enable-hot-corners = false; + monospace-font-name = "Ubuntu Mono 11"; + }; + "org/gnome/desktop/wm/keybindings" = { + switch-group = [ "grave" ]; + switch-group-backward = [ "grave" ]; + }; + "io/github/celluloid-player/celluloid" = { + draggable-video-area-enable = true; + }; + }; + fonts.fonts = with pkgs; [ noto-fonts ubuntu_font_family ]; + user.packages = with pkgs; [ + celluloid + ]; + environment.systemPackages = with pkgs; [ bind bmon fd ffmpeg + gnome.gnome-boxes + gnomeExtensions.another-window-session-manager + # gnomeExtensions.bifocals + gnomeExtensions.blur-my-shell + gnomeExtensions.browser-tabs + gnomeExtensions.burn-my-windows + gnomeExtensions.desktop-cube + gnomeExtensions.desktop-zoom + gnomeExtensions.espresso + # gnomeExtensions.forge + # gnomeExtensions.gsnap + gnomeExtensions.hue-lights + gnomeExtensions.just-perfection + # gnomeExtensions.mutter-primary-gpu + # gnomeExtensions.pip-on-top + gnomeExtensions.smart-auto-move + gnomeExtensions.space-bar + gnomeExtensions.systemd-manager + gnomeExtensions.tailscale-status + gnomeExtensions.tiling-assistant + # gnomeExtensions.todotxt + # gnomeExtensions.window-is-ready-remover + # gnomeExtensions.worksets + # gnomeExtensions.workspace-matrix iotop ripgrep rsync @@ -33,5 +183,7 @@ in { tree wl-clipboard ]; + + home.services.gpg-agent.pinentryFlavor = "gnome3"; }; -} \ No newline at end of file +} diff --git a/modules/desktop/media/graphics.nix b/modules/desktop/media/graphics.nix new file mode 100644 index 0000000..800e7b7 --- /dev/null +++ b/modules/desktop/media/graphics.nix @@ -0,0 +1,21 @@ +{ config, lib, pkgs, ... }: + +with lib; +with lib.my; +let cfg = config.modules.desktop.media.graphics; +in { + options.modules.desktop.media.graphics = { + modeling.enable = mkBoolOpt false; + raster.enable = mkBoolOpt false; + vector.enable = mkBoolOpt false; + }; + + config = { + user.packages = with pkgs; [ + (mkIf cfg.modeling.enable blender) + (mkIf cfg.raster.enable gimp) + (mkIf cfg.raster.enable krita) + (mkIf cfg.vector.enable inkscape) + ]; + }; +} \ No newline at end of file diff --git a/modules/desktop/media/recording.nix b/modules/desktop/media/recording.nix new file mode 100644 index 0000000..556fc2f --- /dev/null +++ b/modules/desktop/media/recording.nix @@ -0,0 +1,24 @@ +{ config, lib, pkgs, ... }: + +with lib; +with lib.my; +let cfg = config.modules.desktop.media.recording; +in { + options.modules.desktop.media.recording = { + audio.enable = mkBoolOpt false; + video.enable = mkBoolOpt false; + }; + + config = { + user.packages = with pkgs; + (if cfg.audio.enable then [ + ardour + audacity + ] else []) ++ + (if cfg.video.enable then [ + handbrake + mkvtoolnix + obs-studio + ] else []); + }; +} \ No newline at end of file diff --git a/modules/desktop/mimeapps.nix b/modules/desktop/mimeapps.nix new file mode 100644 index 0000000..55fc1f9 --- /dev/null +++ b/modules/desktop/mimeapps.nix @@ -0,0 +1,145 @@ +{ config, lib, pkgs, ... }: + +with lib; +with lib.my; +let + cfg = config.modules.desktop.mimeapps; + avApp = "io.github.celluloid_player.Celluloid.desktop"; + imageApp = "org.gnome.eog.desktop"; +in { + options.modules.desktop.mimeapps = { + enable = mkBoolOpt false; + }; + + config = mkIf cfg.enable { + xdg.mime.defaultApplications = { + # Audio/video + "audio/x-vorbis+ogg" = avApp; + "audio/3gpp" = avApp; + "audio/3gpp2" = avApp; + "audio/aac" = avApp; + "audio/ac3" = avApp; + "audio/amr" = avApp; + "audio/amr-wb" = avApp; + "audio/basic" = avApp; + "audio/dv" = avApp; + "audio/eac3" = avApp; + "audio/flac" = avApp; + "audio/m4a" = avApp; + "audio/midi" = avApp; + "audio/mp1" = avApp; + "audio/mp2" = avApp; + "audio/mp3" = avApp; + "audio/mp4" = avApp; + "audio/mpeg" = avApp; + "audio/mpegurl" = avApp; + "audio/mpg" = avApp; + "audio/ogg" = avApp; + "audio/opus" = avApp; + "audio/scpls" = avApp; + "audio/vnd.dolby.heaac.1" = avApp; + "audio/vnd.dolby.heaac.2" = avApp; + "audio/vnd.dolby.mlp" = avApp; + "audio/vnd.dts" = avApp; + "audio/vnd.dts.hd" = avApp; + "audio/vnd.rn-realaudio" = avApp; + "audio/wav" = avApp; + "audio/webm" = avApp; + "audio/x-aac" = avApp; + "audio/x-aiff" = avApp; + "audio/x-ape" = avApp; + "audio/x-flac" = avApp; + "audio/x-gsm" = avApp; + "audio/x-it" = avApp; + "audio/x-m4a" = avApp; + "audio/x-matroska" = avApp; + "audio/x-mod" = avApp; + "audio/x-mp1" = avApp; + "audio/x-mp2" = avApp; + "audio/x-mp3" = avApp; + "audio/x-mpeg" = avApp; + "audio/x-mpegurl" = avApp; + "audio/x-mpg" = avApp; + "audio/x-ms-asf" = avApp; + "audio/x-ms-wma" = avApp; + "audio/x-musepack" = avApp; + "audio/x-pn-aiff" = avApp; + "audio/x-pn-au" = avApp; + "audio/x-pn-realaudio" = avApp; + "audio/x-pn-wav" = avApp; + "audio/x-real-audio" = avApp; + "audio/x-realaudio" = avApp; + "audio/x-s3m" = avApp; + "audio/x-scpls" = avApp; + "audio/x-shorten" = avApp; + "audio/x-speex" = avApp; + "audio/x-tta" = avApp; + "audio/x-vorbis" = avApp; + "audio/x-wav" = avApp; + "audio/x-wavpack" = avApp; + "audio/x-xm" = avApp; + "video/x-ogm+ogg" = avApp; + "video/3gp" = avApp; + "video/3gpp" = avApp; + "video/3gpp2" = avApp; + "video/divx" = avApp; + "video/dv" = avApp; + "video/fli" = avApp; + "video/flv" = avApp; + "video/mp2t" = avApp; + "video/mp4" = avApp; + "video/mp4v-es" = avApp; + "video/mpeg" = avApp; + "video/mpeg-system" = avApp; + "video/msvideo" = avApp; + "video/ogg" = avApp; + "video/quicktime" = avApp; + "video/vnd.mpegurl" = avApp; + "video/vnd.rn-realvideo" = avApp; + "video/webm" = avApp; + "video/x-avi" = avApp; + "video/x-flc" = avApp; + "video/x-fli" = avApp; + "video/x-flv" = avApp; + "video/x-m4v" = avApp; + "video/x-matroska" = avApp; + "video/x-mpeg" = avApp; + "video/x-mpeg-system" = avApp; + "video/x-mpeg2" = avApp; + "video/x-ms-asf" = avApp; + "video/x-ms-wm" = avApp; + "video/x-ms-wmv" = avApp; + "video/x-ms-wmx" = avApp; + "video/x-msvideo" = avApp; + "video/x-nsv" = avApp; + "video/x-theora" = avApp; + "video/x-theora+ogg" = avApp; + + # Images + "image/jpeg" = imageApp; + "image/bmp" = imageApp; + "image/gif" = imageApp; + "image/jpg" = imageApp; + "image/pjpeg" = imageApp; + "image/png" = imageApp; + "image/tiff" = imageApp; + "image/webp" = imageApp; + "image/x-bmp" = imageApp; + "image/x-gray" = imageApp; + "image/x-icb" = imageApp; + "image/x-ico" = imageApp; + "image/x-png" = imageApp; + "image/x-portable-anymap" = imageApp; + "image/x-portable-bitmap" = imageApp; + "image/x-portable-graymap" = imageApp; + "image/x-portable-pixmap" = imageApp; + "image/x-xbitmap" = imageApp; + "image/x-xpixmap" = imageApp; + "image/x-pcx" = imageApp; + "image/svg+xml" = imageApp; + "image/svg+xml-compressed" = imageApp; + "image/vnd.wap.wbmp" = imageApp; + "image/x-icns" = imageApp; + }; + }; +} diff --git a/modules/dev/cc.nix b/modules/dev/cc.nix new file mode 100644 index 0000000..b711ad0 --- /dev/null +++ b/modules/dev/cc.nix @@ -0,0 +1,20 @@ +{ config, lib, pkgs, ... }: + +with lib; +with lib.my; +let cfg = config.modules.dev.cc; +in { + options.modules.dev.cc = { + enable = mkBoolOpt false; + }; + + config = mkIf cfg.enable { + user.packages = with pkgs; [ + clang + gcc + gdb + cmake + llvmPackages.libcxx + ]; + }; +} \ No newline at end of file diff --git a/modules/shell/nnn.nix b/modules/dev/java.nix similarity index 51% rename from modules/shell/nnn.nix rename to modules/dev/java.nix index 3268c3c..1ec11a7 100644 --- a/modules/shell/nnn.nix +++ b/modules/dev/java.nix @@ -2,15 +2,15 @@ with lib; with lib.my; -let cfg = config.modules.shell.nnn; +let cfg = config.modules.dev.java; in { - options.modules.shell.nnn = { + options.modules.dev.java = { enable = mkBoolOpt false; }; config = mkIf cfg.enable { - home.programs.nnn = { - enable = true; - }; + user.packages = with pkgs; [ + jdk + ]; }; } \ No newline at end of file diff --git a/modules/dev/lua.nix b/modules/dev/lua.nix new file mode 100644 index 0000000..db7f5d0 --- /dev/null +++ b/modules/dev/lua.nix @@ -0,0 +1,16 @@ +{ config, lib, pkgs, ... }: + +with lib; +with lib.my; +let cfg = config.modules.dev.lua; +in { + options.modules.dev.lua = { + enable = mkBoolOpt false; + }; + + config = mkIf cfg.enable { + user.packages = with pkgs; [ + lua + ]; + }; +} \ No newline at end of file diff --git a/modules/dev/node.nix b/modules/dev/node.nix new file mode 100644 index 0000000..42ad34d --- /dev/null +++ b/modules/dev/node.nix @@ -0,0 +1,16 @@ +{ config, lib, pkgs, ... }: + +with lib; +with lib.my; +let cfg = config.modules.dev.node; +in { + options.modules.dev.node = { + enable = mkBoolOpt false; + }; + + config = mkIf cfg.enable { + user.packages = with pkgs; [ + nodejs_latest + ]; + }; +} \ No newline at end of file diff --git a/modules/dev/python.nix b/modules/dev/python.nix new file mode 100644 index 0000000..5ba84b0 --- /dev/null +++ b/modules/dev/python.nix @@ -0,0 +1,16 @@ +{ config, lib, pkgs, ... }: + +with lib; +with lib.my; +let cfg = config.modules.dev.python; +in { + options.modules.dev.python = { + enable = mkBoolOpt false; + }; + + config = mkIf cfg.enable { + user.packages = with pkgs; [ + python310 + ]; + }; +} \ No newline at end of file diff --git a/modules/dev/rust.nix b/modules/dev/rust.nix new file mode 100644 index 0000000..556eb35 --- /dev/null +++ b/modules/dev/rust.nix @@ -0,0 +1,19 @@ +{ config, lib, pkgs, ... }: + +with lib; +with lib.my; +let cfg = config.modules.dev.rust; +in { + options.modules.dev.rust = { + enable = mkBoolOpt false; + }; + + config = mkIf cfg.enable { + user.packages = with pkgs; [ + rustc + rustup + rustfmt + rust-bindgen + ]; + }; +} \ No newline at end of file diff --git a/modules/dev/scala.nix b/modules/dev/scala.nix new file mode 100644 index 0000000..08b1425 --- /dev/null +++ b/modules/dev/scala.nix @@ -0,0 +1,18 @@ +{ config, lib, pkgs, ... }: + +with lib; +with lib.my; +let cfg = config.modules.dev.scala; +in { + options.modules.dev.scala = { + enable = mkBoolOpt false; + }; + + config = mkIf cfg.enable { + user.packages = with pkgs; [ + jdk + sbt + scala + ]; + }; +} \ No newline at end of file diff --git a/modules/dev/shell.nix b/modules/dev/shell.nix new file mode 100644 index 0000000..7fc8687 --- /dev/null +++ b/modules/dev/shell.nix @@ -0,0 +1,16 @@ +{ config, lib, pkgs, ... }: + +with lib; +with lib.my; +let cfg = config.modules.dev.shell; +in { + options.modules.dev.shell = { + enable = mkBoolOpt false; + }; + + config = mkIf cfg.enable { + user.packages = with pkgs; [ + shellcheck + ]; + }; +} \ No newline at end of file diff --git a/modules/dev/zig.nix b/modules/dev/zig.nix new file mode 100644 index 0000000..eaef914 --- /dev/null +++ b/modules/dev/zig.nix @@ -0,0 +1,16 @@ +{ config, lib, pkgs, ... }: + +with lib; +with lib.my; +let cfg = config.modules.dev.zig; +in { + options.modules.dev.zig = { + enable = mkBoolOpt false; + }; + + config = mkIf cfg.enable { + user.packages = with pkgs; [ + zig + ]; + }; +} \ No newline at end of file diff --git a/modules/editors/neovim.nix b/modules/editors/neovim.nix deleted file mode 100644 index 15b761a..0000000 --- a/modules/editors/neovim.nix +++ /dev/null @@ -1,18 +0,0 @@ -{ config, lib, pkgs, ... }: - -with lib; -with lib.my; -let cfg = config.modules.editors.neovim; -in { - options.modules.editors.neovim = { - enable = mkBoolOpt false; - }; - - config = mkIf cfg.enable { - home.programs.neovim = { - enable = true; - vimAlias = true; - vimdiffAlias = true; - }; - }; -} \ No newline at end of file diff --git a/modules/editors/neovim/default.nix b/modules/editors/neovim/default.nix new file mode 100644 index 0000000..98c5f55 --- /dev/null +++ b/modules/editors/neovim/default.nix @@ -0,0 +1,134 @@ +{ config, lib, pkgs, ... }: + +with lib; +with lib.my; +let + cfg = config.modules.editors.neovim; + dev = config.modules.dev; +in { + options.modules.editors.neovim = { + enable = mkBoolOpt false; + }; + + config = mkIf cfg.enable { + user.packages = with pkgs; [ + (neovim.override { + configure = { + customRC = '' + luafile ~/.config/nvim/init.lua + ''; + packages.myPlugins = with pkgs.vimPlugins; { + start = [ + (nvim-treesitter.withPlugins ( + plugins: with plugins; [ + bash + c + cmake + cpp + css + dockerfile + elm + glsl + graphql + haskell + http + html + java + javascript + jsdoc + json + json5 + latex + lua + markdown + ninja + nix + org + perl + php + pug + python + regex + rst + ruby + rust + scala + scss + toml + tsx + typescript + vim + yaml + zig + ] + )) + nvim-treesitter-context + nvim-treesitter-textobjects + nvim-lspconfig + ]; + }; + }; + }) + ] ++ + + # Install appropriate language servers + (if dev.cc.enable then [ + ccls # C/C++ + ] else []) ++ + (if dev.java.enable then [ + java-language-server # Java + ltex-ls # LaTeX + ] else []) ++ + (if dev.lua.enable then [ + sumneko-lua-language-server # Lua + ] else []) ++ + (if dev.node.enable then [ + nodePackages.bash-language-server # Bash + nodePackages.dockerfile-language-server-nodejs # Dockerfile + nodePackages.graphql-language-service-cli # GraphQL + nodePackages.purescript-language-server # PureScript + nodePackages.svelte-language-server # Svelte + nodePackages.typescript-language-server # JavaScript/TypeScript + nodePackages.vim-language-server # Vim + nodePackages.vscode-langservers-extracted # HTML, CSS, JSON, ESLint + nodePackages.vue-language-server # Vue.js + nodePackages.yaml-language-server # YAML + ] else []) ++ + (if dev.python.enable then [ + cmake-language-server # CMake + python310Packages.python-lsp-server # Python + ] else []) ++ + (if dev.rust.enable then [ + rust-analyzer # Rust + ] else []) ++ + (if dev.scala.enable then [ + metals # Scala + ] else []) ++ + (if dev.zig.enable then [ + zls # Zig + ] else []); + + home.configFile = { + "nvim/init.lua".source = ./init.lua; + "nvim/lua" = { source = ./lua; recursive = true; }; + "nvim/lua/config/lsp.lua".text = '' + -- This file is autogenerated, do not edit. + ${if dev.cc.enable then "require('config.lsp.cc')\n" else ""} + ${if dev.java.enable then "require('config.lsp.java')\n" else ""} + ${if dev.lua.enable then "require('config.lsp.lua')\n" else ""} + ${if dev.node.enable then "require('config.lsp.node')\n" else ""} + ${if dev.python.enable then "require('config.lsp.python')\n" else ""} + ${if dev.rust.enable then "require('config.lsp.rust')\n" else ""} + ${if dev.scala.enable then "require('config.lsp.scala')\n" else ""} + ${if dev.zig.enable then "require('config.lsp.zig')\n" else ""} + ''; + }; + + env.EDITOR = "nvim"; + + environment.shellAliases = { + vim = "nvim"; + v = "nvim"; + }; + }; +} diff --git a/modules/editors/neovim/init.lua b/modules/editors/neovim/init.lua new file mode 100644 index 0000000..fe172e6 --- /dev/null +++ b/modules/editors/neovim/init.lua @@ -0,0 +1,6 @@ +require("config.core") +require("config.keymap") +require("config.treesitter") +require("config.plugins") +require("config.lsp") + diff --git a/modules/editors/neovim/lua/config/core.lua b/modules/editors/neovim/lua/config/core.lua new file mode 100644 index 0000000..85a75cd --- /dev/null +++ b/modules/editors/neovim/lua/config/core.lua @@ -0,0 +1,36 @@ +local o = vim.opt +local wo = vim.wo +local bo = vim.bo + +-- Global dirs +local cachedir = os.getenv("XDG_CACHE_HOME") +o.backupdir = cachedir .. "/nvim/backup/" +o.directory = cachedir .. "/nvim/swap/" +o.undodir = cachedir .. "/nvim/undo/" + +-- Global +o.breakindent = true +o.clipboard = "unnamedplus" +o.compatible = false +o.encoding = "utf-8" +o.expandtab = true +o.foldlevel = 99 +o.hidden = true +o.hlsearch = false +o.ignorecase = true +o.laststatus = 2 +o.listchars = { eol = '↲', tab = '▸ ', trail = '·' } +o.relativenumber = true +o.shiftwidth = 2 +o.showmode = false +o.smartcase = true +o.smarttab = true +o.softtabstop = 2 +o.synmaxcol = 150 +o.tabstop = 4 +o.undofile = true +o.wildmenu = true + +-- Window + +-- Buffer diff --git a/modules/editors/neovim/lua/config/keymap.lua b/modules/editors/neovim/lua/config/keymap.lua new file mode 100644 index 0000000..9d42fca --- /dev/null +++ b/modules/editors/neovim/lua/config/keymap.lua @@ -0,0 +1,35 @@ +local keymap = vim.keymap.set +local opts = { noremap = true, silent = true } + +vim.g.mapleader = "," + +-- Modes +-- Normal = "n", +-- Insert = "i", +-- Visual = "v", +-- Visual Block = "x", +-- Term = "t", +-- Command = "c" + +keymap("n", "", "", opts) +keymap("n", "", "", opts) +keymap("n", "", "", opts) +keymap("n", "", "", opts) + +keymap("n", "", "h", { noremap = true }) +keymap("n", "", "j", { noremap = true }) +keymap("n", "", "k", { noremap = true }) +keymap("n", "", "l", { noremap = true }) + +keymap("n", "gV", "`[v`]", opts) + +keymap("n", ";", ":", { noremap = true }) + +-- Bubble single lines with vim-unimpaired +keymap("n", "", "[e", opts) +keymap("n", "", "]e", opts) + +-- Bubble multiple lines with vim-unimpaired +keymap("v", "", "[egv", opts) +keymap("v", "", "]egv", opts) + diff --git a/modules/editors/neovim/lua/config/lsp/cc.lua b/modules/editors/neovim/lua/config/lsp/cc.lua new file mode 100644 index 0000000..9e344ac --- /dev/null +++ b/modules/editors/neovim/lua/config/lsp/cc.lua @@ -0,0 +1,5 @@ +lspconfig = require('lspconfig') + +-- Requires C/C++ +lspconfig.ccls.setup{} + diff --git a/modules/editors/neovim/lua/config/lsp/java.lua b/modules/editors/neovim/lua/config/lsp/java.lua new file mode 100644 index 0000000..2d5c17b --- /dev/null +++ b/modules/editors/neovim/lua/config/lsp/java.lua @@ -0,0 +1,6 @@ +lspconfig = require('lspconfig') + +-- Requires Java +lspconfig.java_language_server.setup{} +lspconfig.ltex.setup{} + diff --git a/modules/editors/neovim/lua/config/lsp/lua.lua b/modules/editors/neovim/lua/config/lsp/lua.lua new file mode 100644 index 0000000..71bef6e --- /dev/null +++ b/modules/editors/neovim/lua/config/lsp/lua.lua @@ -0,0 +1,22 @@ +lspconfig = require('lspconfig') + +-- Requires Lua +lspconfig.sumneko_lua.setup { + settings = { + Lua = { + runtime = { + -- Tell the language server which version of Lua you're using (most likely LuaJIT in the case of Neovim) + version = 'LuaJIT', + }, + diagnostics = { + -- Get the language server to recognize the `vim` global + globals = {'vim'}, + }, + -- Do not send telemetry data containing a randomized but unique identifier + telemetry = { + enable = false, + }, + }, + }, +} + diff --git a/modules/editors/neovim/lua/config/lsp/node.lua b/modules/editors/neovim/lua/config/lsp/node.lua new file mode 100644 index 0000000..5d46bbe --- /dev/null +++ b/modules/editors/neovim/lua/config/lsp/node.lua @@ -0,0 +1,17 @@ +lspconfig = require('lspconfig') + +-- Requires Node.js +lspconfig.bashls.setup{} +lspconfig.cssls.setup{} +lspconfig.dockerls.setup{} +lspconfig.eslint.setup{} +lspconfig.graphql.setup{} +lspconfig.html.setup{} +lspconfig.jsonls.setup{} +lspconfig.purescriptls.setup{} +lspconfig.svelte.setup{} +lspconfig.tsserver.setup{} +lspconfig.vimls.setup{} +lspconfig.vuels.setup{} +lspconfig.yamlls.setup{} + diff --git a/modules/editors/neovim/lua/config/lsp/python.lua b/modules/editors/neovim/lua/config/lsp/python.lua new file mode 100644 index 0000000..dce7699 --- /dev/null +++ b/modules/editors/neovim/lua/config/lsp/python.lua @@ -0,0 +1,6 @@ +lspconfig = require('lspconfig') + +-- Requires Python +lspconfig.cmake.setup{} +lspconfig.pylsp.setup{} + diff --git a/modules/editors/neovim/lua/config/lsp/rust.lua b/modules/editors/neovim/lua/config/lsp/rust.lua new file mode 100644 index 0000000..bedf56a --- /dev/null +++ b/modules/editors/neovim/lua/config/lsp/rust.lua @@ -0,0 +1,5 @@ +lspconfig = require('lspconfig') + +-- Requires Rust +lspconfig.rls.setup{} + diff --git a/modules/editors/neovim/lua/config/lsp/scala.lua b/modules/editors/neovim/lua/config/lsp/scala.lua new file mode 100644 index 0000000..a8efb60 --- /dev/null +++ b/modules/editors/neovim/lua/config/lsp/scala.lua @@ -0,0 +1,5 @@ +lspconfig = require('lspconfig') + +-- Requires Scala +lspconfig.metals.setup{} + diff --git a/modules/editors/neovim/lua/config/lsp/zig.lua b/modules/editors/neovim/lua/config/lsp/zig.lua new file mode 100644 index 0000000..d55155f --- /dev/null +++ b/modules/editors/neovim/lua/config/lsp/zig.lua @@ -0,0 +1,5 @@ +lspconfig = require('lspconfig') + +-- Requires Zig +lspconfig.zls.setup{} + diff --git a/modules/editors/neovim/lua/config/plugins.lua b/modules/editors/neovim/lua/config/plugins.lua new file mode 100644 index 0000000..9784989 --- /dev/null +++ b/modules/editors/neovim/lua/config/plugins.lua @@ -0,0 +1,77 @@ +local fn = vim.fn + +local install_path = fn.stdpath "data" .. "/site/pack/packer/start/packer.nvim" +if fn.empty(fn.glob(install_path)) > 0 then + PACKER_BOOTSTRAP = fn.system { + "git", + "clone", + "--depth", + "1", + "https://github.com/wbthomason/packer.nvim", + install_path, + } + print "Installing packer close and reopen Neovim..." + vim.cmd [[packadd packer.nvim]] +end + +vim.cmd [[ + augroup packer_user_config + autocmd! + autocmd BufWritePost plugins.lua source | PackerSync + augroup end +]] + +local status_ok, packer = pcall(require, "packer") +if not status_ok then + return +end + +packer.init { + display = { + open_fn = function() + return require("packer.util").float { border = "rounded" } + end, + }, +} + +return packer.startup(function(use) + -- Utilities + use { "wbthomason/packer.nvim", opt = true } + use { "mbbill/undotree" } + use { "nvim-lua/plenary.nvim" } + use { "tpope/vim-fugitive", event = "User InGitRepo" } + + -- Editing + use { "andymass/vim-matchup" } + use { "godlygeek/tabular" } + use { "JoosepAlviste/nvim-ts-context-commentstring" } + use { "kana/vim-textobj-user" } + use { "mg979/vim-visual-multi", branch = "master" } + use { "p00f/nvim-ts-rainbow" } + use { "terryma/vim-expand-region" } + use { "tommcdo/vim-exchange", event = "VimEnter" } + use { "tpope/vim-abolish" } + use { "tpope/vim-commentary", event = "VimEnter" } + use { "tpope/vim-repeat", event = "VimEnter" } + use { "tpope/vim-surround", event = "VimEnter" } + use { "windwp/nvim-autopairs" } + use { "windwp/nvim-ts-autotag" } + + -- UI + use { "junegunn/goyo.vim" } + use { "junegunn/limelight.vim" } + use { "markonm/traces.vim" } + + -- Searching + use { "nvim-telescope/telescope.nvim", config = [[require('config.telescope')]] } + use { "cljoly/telescope-repo.nvim", requires = "telescope.nvim" } + use { "dyng/ctrlsf.vim" } + + -- LSP + use { "jose-elias-alvarez/null-ls.nvim" } + + if PACKER_BOOTSTRAP then + require("packer").sync() + end +end) + diff --git a/modules/editors/neovim/lua/config/telescope.lua b/modules/editors/neovim/lua/config/telescope.lua new file mode 100644 index 0000000..bbd5f03 --- /dev/null +++ b/modules/editors/neovim/lua/config/telescope.lua @@ -0,0 +1,46 @@ +local status_ok, telescope = pcall(require, "telescope") +if not status_ok then + return +end + +local actions = require("telescope.actions") + +telescope.setup({ + defaults = { + file_ignore_patterns = { ".git/", "node_modules" }, + }, + mappings = { + i = { + [""] = actions.cycle_history_next, + [""] = actions.cycle_history_prev, + [""] = actions.move_selection_next, + [""] = actions.move_selection_previous, + }, + }, + extensions = { + repo = { + list = { + fd_opts = { + "--no-ignore-vcs", + }, + search_dirs = { + "~/projects", + "~/repos", + "~/workspace", + }, + }, + }, + }, +}) + +telescope.load_extension("repo") + +local keymap = vim.keymap.set +local opts = { noremap = true, silent = true } + +keymap("n", "ff", "Telescope find_files", opts) +keymap("n", "fg", "Telescope live_grep", opts) +keymap("n", "fb", "Telescope buffers", opts) +keymap("n", "fh", "Telescope help_tags", opts) +keymap("n", "fr", "Telescope repo list", opts) + diff --git a/modules/editors/neovim/lua/config/treesitter.lua b/modules/editors/neovim/lua/config/treesitter.lua new file mode 100644 index 0000000..a95ee64 --- /dev/null +++ b/modules/editors/neovim/lua/config/treesitter.lua @@ -0,0 +1,35 @@ +require("nvim-treesitter.configs").setup({ + ignore_install = {}, + highlight = { + enable = true, + disable = {}, + }, + indent = { enable = true }, + incremental_selection = { + enable = true, + keymaps = { + init_selection = "gnn", + node_incremental = "grn", + scope_incremental = "grc", + node_decremental = "grm", + }, + }, + -- Extensions + autotag = { enable = true }, + context_commentstring = { enable = true }, + matchup = { enable = true }, + rainbow = { enable = true }, + textobjects = { + select = { + enable = true, + keymaps = { + ["af"] = "@function.outer", + ["if"] = "@function.inner", + }, + }, + }, +}) + +vim.opt.foldmethod = "expr" +vim.opt.foldexpr = "nvim_treesitter#foldexpr()" + diff --git a/modules/networking/tailscale.nix b/modules/networking/tailscale.nix new file mode 100644 index 0000000..fafd533 --- /dev/null +++ b/modules/networking/tailscale.nix @@ -0,0 +1,21 @@ +{ config, lib, pkgs, ... }: + +with lib; +with lib.my; +let cfg = config.modules.networking.tailscale; +in { + options.modules.networking.tailscale = { + enable = mkBoolOpt false; + restrictSSH = mkBoolOpt true; + }; + + config = mkIf cfg.enable { + services.tailscale.enable = true; + services.openssh.openFirewall = !cfg.restrictSSH; + networking.firewall = { + checkReversePath = "loose"; + trustedInterfaces = [ "tailscale0" ]; + allowedUDPPorts = [ config.services.tailscale.port ]; + }; + }; +} diff --git a/modules/options.nix b/modules/options.nix index 8c61e15..5a7b16e 100644 --- a/modules/options.nix +++ b/modules/options.nix @@ -15,6 +15,8 @@ with lib.my; services = mkOpt' attrs { } "Services managed directly from home-manager"; }; + dconf.settings = mkOpt' attrs { } "dconf settings to enable"; + env = mkOption { type = attrsOf (oneOf [ str path (listOf (either str path)) ]); apply = mapAttrs (n: v: @@ -37,11 +39,14 @@ with lib.my; extraGroups = [ "networkmanager" "wheel" ]; description = "Jordan Holt"; useDefaultShell = true; + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILVHTjsyMIV4THNw6yz0OxAxGnC+41gX72UrPqTzR+OS jordan@vimium.com" + ]; home = "/home/${name}"; group = "users"; uid = 1000; }; - + home-manager = { useGlobalPkgs = true; useUserPackages = true; @@ -51,7 +56,6 @@ with lib.my; file = mkAliasDefinitions options.home.file; stateVersion = config.system.stateVersion; }; - home.packages = mkAliasDefinitions options.home.packages; programs = mkAliasDefinitions options.home.programs; services = mkAliasDefinitions options.home.services; xdg = { @@ -59,11 +63,16 @@ with lib.my; configFile = mkAliasDefinitions options.home.configFile; dataFile = mkAliasDefinitions options.home.dataFile; }; + dconf.settings = mkAliasDefinitions options.dconf.settings; }; }; users.users.${config.user.name} = mkAliasDefinitions options.user; nixpkgs.config.allowUnfree = true; + + environment.extraInit = + concatStringsSep "\n" + (mapAttrsToList (n: v: "export ${n}=\"${v}\"") config.env); }; -} \ No newline at end of file +} diff --git a/modules/shell/fzf.nix b/modules/shell/fzf.nix deleted file mode 100644 index e821166..0000000 --- a/modules/shell/fzf.nix +++ /dev/null @@ -1,21 +0,0 @@ -{ config, lib, pkgs, ... }: - -with lib; -with lib.my; -let cfg = config.modules.shell.fzf; -in { - options.modules.shell.fzf = { - enable = mkBoolOpt false; - }; - - config = mkIf cfg.enable { - home.packages = with pkgs; [ - bind - ]; - home.programs.fzf = { - enable = true; - enableZshIntegration = true; - defaultCommand = "fd --type f --hidden --follow --exclude .git"; - }; - }; -} \ No newline at end of file diff --git a/modules/shell/git.nix b/modules/shell/git/default.nix similarity index 91% rename from modules/shell/git.nix rename to modules/shell/git/default.nix index ac1c883..e8e129f 100644 --- a/modules/shell/git.nix +++ b/modules/shell/git/default.nix @@ -30,5 +30,9 @@ in { pull.rebase = true; }; }; + + home.configFile = { + "git/ignore".source = ./ignore; + }; }; } \ No newline at end of file diff --git a/modules/shell/git/ignore b/modules/shell/git/ignore new file mode 100644 index 0000000..d9f2575 --- /dev/null +++ b/modules/shell/git/ignore @@ -0,0 +1,24 @@ +# CMake +cmake-build-*/ + +# Linux trash folder +.Trash-* + +# Swap +[._]*.s[a-v][a-z] +[._]*.sw[a-p] +[._]s[a-rt-v][a-z] +[._]ss[a-gi-z] +[._]sw[a-p] + +# Session +Session.vim +Sessionx.vim + +# Temporary +.netrwhist +*~ +# Auto-generated tag files +tags +# Persistent undo +[._]*.un~ diff --git a/modules/shell/zsh.nix b/modules/shell/zsh.nix deleted file mode 100644 index 0d60e10..0000000 --- a/modules/shell/zsh.nix +++ /dev/null @@ -1,35 +0,0 @@ -{ config, lib, pkgs, ... }: - -with lib; -with lib.my; -let cfg = config.modules.shell.zsh; -in { - options.modules.shell.zsh = { - enable = mkBoolOpt false; - }; - - config = mkIf cfg.enable { - home.packages = with pkgs; [ - zsh-autosuggestions - zsh-fast-syntax-highlighting - zsh-history-substring-search - ]; - - home.programs.zsh = { - enable = true; - enableCompletion = true; - shellAliases = { - cp = "cp -iv"; - mv = "mv -iv"; - rm = "rm -v"; - mkdir = "mkdir -v"; - ls = "ls -h --color=auto --group-directories-first"; - e = "nvim"; - f = "nnn"; - g = "git"; - n = "nnn"; - v = "nvim"; - }; - }; - }; -} \ No newline at end of file diff --git a/modules/shell/zsh/.zshrc b/modules/shell/zsh/.zshrc new file mode 100644 index 0000000..271c341 --- /dev/null +++ b/modules/shell/zsh/.zshrc @@ -0,0 +1,34 @@ +source $ZDOTDIR/config.zsh + +if [ ! -d "$ZGEN_DIR" ]; then + echo "Installing jandamm/zgenom" + git clone https://github.com/jandamm/zgenom "$ZGEN_DIR" +fi +source $ZGEN_DIR/zgenom.zsh + +zgenom autoupdate + +if ! zgenom saved; then + echo "Initializing zgenom" + rm -f $ZDOTDIR/*.zwc(N) \ + $XDG_CACHE_HOME/zsh/*(N) \ + $ZGEN_INIT.zwc + + zgenom load junegunn/fzf shell + zgenom load zdharma-continuum/fast-syntax-highlighting + zgenom load zsh-users/zsh-completions src + zgenom load zsh-users/zsh-history-substring-search + zgenom load softmoth/zsh-vim-mode + + zgenom save + zgenom compile $ZDOTDIR +fi + +## Bootstrap interactive sessions +if [[ $TERM != dumb ]]; then + autoload -Uz compinit && compinit -u -d $ZSH_CACHE/zcompdump + + source $ZDOTDIR/keybinds.zsh + source $ZDOTDIR/completion.zsh + source $ZDOTDIR/aliases.zsh +fi diff --git a/modules/shell/zsh/aliases.zsh b/modules/shell/zsh/aliases.zsh new file mode 100644 index 0000000..a9cb32b --- /dev/null +++ b/modules/shell/zsh/aliases.zsh @@ -0,0 +1,25 @@ +#!/bin/sh + +# Verbose file operations +alias \ + cp="cp -iv" \ + mv="mv -iv" \ + rm="rm -v" \ + mkdir="mkdir -v" + +# Colorize commands +alias \ + ls="ls -h --color=auto --group-directories-first" + +# Abbreviations +alias \ + e="$EDITOR" \ + f="$FILE" \ + g="git" \ + m="neomutt" \ + n="$FILE" \ + v="$EDITOR" + +# XDG fixes +alias \ + mbsync="mbsync -c $XDG_CONFIG_HOME/isync/mbsyncrc -a" diff --git a/modules/shell/zsh/completion.zsh b/modules/shell/zsh/completion.zsh new file mode 100644 index 0000000..1915bf8 --- /dev/null +++ b/modules/shell/zsh/completion.zsh @@ -0,0 +1,6 @@ +fpath+=( $ZDOTDIR/completions ) + +# Don't offer history completion; we have fzf, C-r, and +# zsh-history-substring-search for that. +ZSH_AUTOSUGGEST_STRATEGY=(completion) +ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE=30 diff --git a/modules/shell/zsh/config.zsh b/modules/shell/zsh/config.zsh new file mode 100644 index 0000000..08835d1 --- /dev/null +++ b/modules/shell/zsh/config.zsh @@ -0,0 +1,99 @@ +#### +## zsh configuration +#### + +## Colors +autoload -U colors && colors + +## Completion +setopt HASH_LIST_ALL +unsetopt AUTO_NAME_DIRS +autoload -Uz compinit +zstyle ':completion:*' menu select +zmodload zsh/complist +compinit +_comp_options+=(globdots) # Include hidden files + +## Directories +setopt AUTO_PUSHD +setopt CDABLE_VARS +setopt PUSHD_IGNORE_DUPS +setopt PUSHD_SILENT +setopt PUSHD_TO_HOME +unsetopt AUTO_CD + +## Expansion and globbing +setopt EXTENDED_GLOB +unsetopt GLOB_DOTS +unsetopt NOMATCH + +## History +HISTFILE="${XDG_DATA_HOME:-${HOME}/.local/share}/zsh/history" +HISTSIZE=1000000 +SAVEHIST=1000000 +[[ !( -f "${HISTFILE}" ) ]] && mkdir -p $(dirname ${HISTFILE}) + +setopt APPEND_HISTORY +setopt BANG_HIST +setopt EXTENDED_HISTORY +setopt HIST_IGNORE_ALL_DUPS +setopt HIST_IGNORE_DUPS +setopt HIST_IGNORE_SPACE +setopt HIST_SAVE_NO_DUPS +setopt HIST_VERIFY +setopt INC_APPEND_HISTORY_TIME +setopt SHARE_HISTORY + +## I/O +setopt INTERACTIVE_COMMENTS +setopt MULTIOS +unsetopt CLOBBER + +## Jobs +setopt LONG_LIST_JOBS +setopt AUTO_RESUME +unsetopt BG_NICE +unsetopt NOTIFY +unsetopt HUP +unsetopt CHECK_JOBS + +## Shell emulation +setopt APPEND_CREATE + +## Prompt +PS1="%B%{$fg[magenta]%}%~%{$reset_color%} $%b " + +## Window title +precmd () { print -Pn "\e]0;%n@%m: %~\a" } +preexec () { print -Pn "\e]0;%n@%m: $1\a" } + +## Vi mode +bindkey -v +export KEYTIMEOUT=1 + +## Zsh line editor +unsetopt BEEP + + +#### +## Plugins +#### + +export ZGEN_AUTOLOAD_COMPINIT=0 + +# zsh-vim-mode +export MODE_INDICATOR="" +export MODE_CURSOR_VIINS="#b77ee0 blinking bar" +export MODE_CURSOR_REPLACE="$MODE_CURSOR_VIINS #ff3334" +export MODE_CURSOR_VICMD="#b77ee0 block" +export MODE_CURSOR_SEARCH="#e7c547 steady underline" +export MODE_CURSOR_VISUAL="$MODE_CURSOR_VICMD steady bar" +export MODE_CURSOR_VLINE="$MODE_CURSOR_VISUAL #54ced6" + +# fzf +if (( $+commands[fd] )); then + export FZF_DEFAULT_OPTS="--reverse --ansi" + export FZF_DEFAULT_COMMAND="fd ." + export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND" + export FZF_ALT_C_COMMAND="fd -t d . $HOME" +fi diff --git a/modules/shell/zsh/default.nix b/modules/shell/zsh/default.nix new file mode 100644 index 0000000..a7f6f14 --- /dev/null +++ b/modules/shell/zsh/default.nix @@ -0,0 +1,52 @@ +{ config, lib, pkgs, ... }: + +with lib; +with lib.my; +let cfg = config.modules.shell.zsh; +in { + options.modules.shell.zsh = { + enable = mkBoolOpt false; + }; + + config = mkIf cfg.enable { + users.defaultUserShell = pkgs.zsh; + + programs.zsh = { + enable = true; + enableCompletion = true; + enableGlobalCompInit = false; + promptInit = ""; + }; + + user.packages = with pkgs; [ + fd + fzf + jq + nix-zsh-completions + nnn + ripgrep + zsh + ]; + + env = { + ZDOTDIR = "$XDG_CONFIG_HOME/zsh"; + ZSH_CACHE = "$XDG_CACHE_HOME/zsh"; + ZGEN_DIR = "$XDG_DATA_HOME/zgenom"; + }; + + home.configFile = { + "zsh/.zshrc".source = ./.zshrc; + "zsh/aliases.zsh".source = ./aliases.zsh; + "zsh/completion.zsh".source = ./completion.zsh; + "zsh/config.zsh".source = ./config.zsh; + "zsh/keybinds.zsh".source = ./keybinds.zsh; + }; + + system.userActivationScripts.cleanupZgen = '' + rm -rf $ZDOTDIR/.*.zwc + rm -f $ZDOTDIR/.zcompdump + rm -rf $ZSH_CACHE + rm -fv $ZGEN_DIR/init.zsh{,.zwc} + ''; + }; +} diff --git a/modules/shell/zsh/keybinds.zsh b/modules/shell/zsh/keybinds.zsh new file mode 100644 index 0000000..7617fe4 --- /dev/null +++ b/modules/shell/zsh/keybinds.zsh @@ -0,0 +1,12 @@ +#### +## Keybindings +#### +stty stop undef +bindkey -s '^f' 'cd "$(dirname "$(fzf)")"\n' + +bindkey -M vicmd 'k' history-substring-search-up +bindkey -M vicmd 'j' history-substring-search-down + +if (( $+commands[fzf] )); then + bindkey '^R' fzf-history-widget +fi diff --git a/overlays/gnome.nix b/overlays/gnome.nix new file mode 100644 index 0000000..4970c35 --- /dev/null +++ b/overlays/gnome.nix @@ -0,0 +1,11 @@ +self: super: +{ + gnome = super.gnome.overrideScope' (gself: gsuper: { + mutter = gsuper.mutter.overrideAttrs (oldAttrs: { + src = super.fetchurl { + url = "https://gitlab.gnome.org/Community/Ubuntu/mutter/-/archive/triple-buffering-v4-44/mutter-triple-buffering-v4-44.tar.gz"; + sha256 = "Xgiu1ifgPijXPq6rYfPX81Nq97jw9m/hoWTKAgC3aeI="; + }; + }); + }); +}