diff --git a/README.md b/README.md index eef2b71..3383516 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ -# dotfiles +# Dotfiles -My dotfiles :) \ No newline at end of file +My NixOS configuration. \ No newline at end of file diff --git a/default.nix b/default.nix index 7d25bdc..d3dfb20 100644 --- a/default.nix +++ b/default.nix @@ -2,11 +2,11 @@ { imports = [ - # Temporary until it has been subdivided into modules. + # TODO: Temporary until it has been subdivided into modules. ./merged.nix - # Automation for user configuration - ./users.nix + # Modules + ./modules/default.nix # System configuration options ./system.nix @@ -15,17 +15,19 @@ ./test.nix ]; - options = { - custom.laptop = lib.mkOption { - type = lib.types.bool; - default = false; - example = true; - description = "Whether the current system is a laptop."; - }; - }; - config = { - # Set the state version - system.stateVersion = "24.05" + # Allow unfree packages + nixpkgs.config.allowUnfree = true; + + # Enable default modules + modules = { + # Greeter + tuigreet.enable = true; + }; + + # Localization settings + time.timeZone = "Europe/Amsterdam"; + i18n.defaultLocale = "en_US.UTF-8"; + console.keyMap = "us"; }; } \ No newline at end of file diff --git a/merged.nix b/merged.nix index f72769a..413f932 100644 --- a/merged.nix +++ b/merged.nix @@ -8,12 +8,12 @@ let nixvim = import (builtins.fetchGit { url = "https://github.com/nix-community/nixvim"; }); - stylix = import (pkgs.fetchFromGitHub { - owner = "danth"; - repo = "stylix"; - rev = "1ff9d37d27377bfe8994c24a8d6c6c1734ffa116"; - sha256 = "0dz8h1ga8lnfvvmvsf6iqvnbvxrvx3qxi0y8s8b72066mqgvy8y5"; - }); + # stylix = import (pkgs.fetchFromGitHub { + # owner = "danth"; + # repo = "stylix"; + # rev = "1ff9d37d27377bfe8994c24a8d6c6c1734ffa116"; + # sha256 = "0dz8h1ga8lnfvvmvsf6iqvnbvxrvx3qxi0y8s8b72066mqgvy8y5"; + # }); fontInstallPhase = '' runHook preInstall @@ -79,19 +79,19 @@ let ''; }; in { - imports = - [ - # Include home manager - - ]; + # imports = + # [ + # # Include home manager + # # + # ]; - # Enable NUR - nixpkgs.config.packageOverrides = pkgs: { - # TODO: Pin the version - nur = import (builtins.fetchTarball "https://github.com/nix-community/NUR/archive/master.tar.gz") { - inherit pkgs; - }; - }; + # # Enable NUR + # nixpkgs.config.packageOverrides = pkgs: { + # # TODO: Pin the version + # nur = import (builtins.fetchTarball "https://github.com/nix-community/NUR/archive/master.tar.gz") { + # inherit pkgs; + # }; + # }; # Use the systemd-boot EFI boot loader. boot = { @@ -126,9 +126,9 @@ in { }; # Set up console - console = { - keyMap = "us"; - }; + # console = { + # keyMap = "us"; + # }; # Set up networking networking.wireless.userControlled.enable = true; @@ -164,13 +164,13 @@ in { }; # Set time zone. - time.timeZone = "Europe/Amsterdam"; + # time.timeZone = "Europe/Amsterdam"; # Select internationalisation properties. - i18n.defaultLocale = "en_US.UTF-8"; + # i18n.defaultLocale = "en_US.UTF-8"; # Allow unfree packages - nixpkgs.config.allowUnfree = true; + # nixpkgs.config.allowUnfree = true; # Enable sound services.pipewire = { @@ -183,18 +183,18 @@ in { services.libinput.enable = true; # Display manager - services.greetd = { - enable = true; - settings = { - default_session = { - command = "${pkgs.greetd.tuigreet}/bin/tuigreet --remember --greeting \"Hewwo! >_< :3\" --time --cmd river --asterisks"; - user = "greeter"; - }; - }; - }; + # services.greetd = { + # enable = true; + # settings = { + # default_session = { + # command = "${pkgs.greetd.tuigreet}/bin/tuigreet --remember --greeting \"Hewwo! >_< :3\" --time --cmd river --asterisks"; + # user = "greeter"; + # }; + # }; + # }; # PAM setup - security.pam.services.waylock = {}; + # security.pam.services.waylock = {}; # Enable programs programs.river.enable = true; @@ -217,810 +217,7 @@ in { # extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user. # }; - home-manager.backupFileExtension = "bak"; - home-manager.users.jan = let - # Theming constants - colors = config.home-manager.users.jan.lib.stylix.colors; - fonts = config.home-manager.users.jan.stylix.fonts; - borderSize = 1; - windowPadding = 2; - - waylockOptions = "-init-color 0x${colors.base00} -input-color 0x${colors.base02} -fail-color 0x${colors.base00}"; - in { - # Extra modules - imports = [ - nixvim.homeManagerModules.nixvim - stylix.homeManagerModules.stylix - ]; - - # Packages - home.packages = with pkgs; [ - # Programs - vscode - feishin - discord - obsidian - winbox - - # Utilities - pulsemixer - wl-clipboard - pinentry-rofi - wtype - waylock - playerctl - - # Fish plugin dependencies - grc - fzf - - # Rust development - rustc - cargo - rustfmt - - # Bitwarden - rofi-rbw - - # LaTeX libraries - (pkgs.texlive.combine { - inherit (pkgs.texlive) scheme-full; - }) - ]; - - # Allow unfree - nixpkgs.config.allowUnfree = false; - - # Stylix - stylix = { - enable = true; - polarity = "dark"; - - base16Scheme = "${pkgs.base16-schemes}/share/themes/gruvbox-dark-hard.yaml"; - fonts = { - monospace = { - package = pkgs.dina-font; - name = "Dina"; - }; - - sizes = { - terminal = 9; - }; - }; - - autoEnable = false; - targets = { - foot.enable = true; - nixvim.enable = true; - qutebrowser.enable = true; - vscode.enable = true; - zathura.enable = true; - }; - }; - - # Fish shell - programs.fish = { - enable = true; - - plugins = [ - { name = "done"; src = pkgs.fishPlugins.done.src; } - { name = "fzf"; src = pkgs.fishPlugins.fzf-fish.src; } - { name = "grc"; src = pkgs.fishPlugins.grc.src; } - ]; - }; - - # Bash prompt - programs.bash = { - enable = true; - initExtra = '' - if [[ $(${pkgs.procps}/bin/ps --no-header --pid=$PPID --format=comm) != "fish" && -z ''${BASH_EXECUTION_STRING} ]] - then - shopt -q login_shell && LOGIN_OPTION='--login' || LOGIN_OPTION="" - exec ${pkgs.fish}/bin/fish $LOGIN_OPTION - fi - ''; - bashrcExtra = '' - FG_BLACK="\[$(tput setaf 0)\]" - FG_RED="\[$(tput setaf 1)\]" - FG_GREEN="\[$(tput setaf 2)\]" - FG_YELLOW="\[$(tput setaf 3)\]" - FG_BLUE="\[$(tput setaf 4)\]" - FG_MAGENTA="\[$(tput setaf 5)\]" - FG_CYAN="\[$(tput setaf 6)\]" - FG_WHITE="\[$(tput setaf 7)\]" - - RESET="\[$(tput sgr0)\]" - - export PS0="\n''${RESET}" - export PS1="''${FG_GREEN}\n│\w\n│" - export PS2="│" - ''; - }; - - # Direnv setup - programs.direnv = { - enable = true; - nix-direnv.enable = true; - }; - - # Qutebrowser - programs.qutebrowser = { - enable = true; - - extraConfig = '' - config.set("colors.webpage.darkmode.enabled", False) - config.set("colors.webpage.preferred_color_scheme", "dark") - config.set("fonts.default_family", "${fonts.monospace.name}") - config.set("fonts.default_size", "${toString fonts.sizes.terminal}pt") - ''; - }; - - # Bitwarden client - programs.rbw = { - enable = true; - settings = { - base_url = "https://keys.bulthuis.dev"; - identity_url = "https://keys.bulthuis.dev"; - email = "jan@bulthuis.dev"; - pinentry = pkgs.pinentry; - }; - }; - - # Firefox - programs.firefox = { - enable = true; - policies = { - AppAutoUpdate = false; - BlockAboutAddons = true; - BlockAboutConfig = true; - BlockAboutProfiles = true; - DisableAppUpdate = true; - DisableFeedbackCommands = true; - DisableMasterPasswordCreation = true; - DisablePocket = true; - DisableProfileImport = true; - DisableProfileRefresh = true; - DisableSetDesktopBackground = true; - DisableTelemetry = true; - DisplayBookmarksToolbar = "never"; - DisplayMenuBar = "never"; - DNSOverHTTPS = { Enabled = false; }; - DontCheckDefaultBrowser = true; - PasswordManagerEnabled = false; - TranslateEnabled = true; - UseSystemPrintDialog = true; - }; - profiles.nixos = { - search.default = "DuckDuckGo"; - - extensions = with pkgs.nur.repos.rycee.firefox-addons; [ - ublock-origin - ]; - - settings = { - "browser.tabs.inTitlebar" = 0; - "extensions.autoDisableScopes" = 0; - }; - - # Force overwriting configuration file - search.force = true; - containersForce = true; - }; - }; - - # Email setup - accounts.email.accounts = { - Personal = { - primary = true; - realName = "Jan Bulthuis"; - userName = "jan@bulthuis.dev"; - address = "jan@bulthuis.dev"; - thunderbird.enable = true; - - flavor = "plain"; - imap = { - host = "mail.bulthuis.dev"; - port = 993; - }; - smtp = { - host = "mail.bulthuis.dev"; - port = 465; - }; - }; - }; - - # Thunderbird setup - programs.thunderbird = { - enable = true; - profiles.nixos = { - isDefault = true; - }; - }; - - # Rofi setup - programs.rofi = { - enable = true; - package = pkgs.rofi-wayland; - font = "${fonts.monospace.name} ${toString fonts.sizes.terminal}"; - theme = let - inherit (config.home-manager.users.jan.lib.formats.rasi) mkLiteral; - in { - "*" = { - background-color = mkLiteral "rgba(0, 0, 0, 0%)"; - border-color = mkLiteral colors.withHashtag.base05; - text-color = mkLiteral colors.withHashtag.base05; - }; - mainbox = { - background-color = mkLiteral colors.withHashtag.base00; - border = mkLiteral "${toString borderSize}px"; - }; - element-text = { - highlight = mkLiteral colors.withHashtag.base09; - }; - inputbar = { - children = mkLiteral "[textbox-search, entry]"; - }; - listview = { - padding = mkLiteral "2px 0px"; - }; - textbox-search = { - expand = false; - content = "> "; - }; - "inputbar, message" = { - padding = mkLiteral "2px"; - }; - element = { - padding = mkLiteral "0px 2px"; - }; - "element selected" = { - background-color = mkLiteral colors.withHashtag.base02; - }; - }; - }; - - # Dark mode - dconf.settings = { - "org/gnome/desktop/interface" = { - color-scheme = "prefer-dark"; - }; - }; - qt = { - enable = true; - platformTheme.name = "adwaita"; - style.name = "adwaita-dark"; - }; - systemd.user.sessionVariables = config.home-manager.users.jan.home.sessionVariables; - - # Configure GTK - gtk = let - css = '' - headerbar.default-decoration { - margin-bottom: 50px; - margin-top: -100px; - } - - window.csd, - window.csd decoration { - box-shadow: none; - } - ''; - in { - enable = true; - - # Dark mode - theme = { - name = "Adwaita-dark"; - package = pkgs.gnome-themes-extra; - }; - - # Disable CSD - gtk3.extraCss = css; - gtk4.extraCss = css; - }; - - # Cursors - home.pointerCursor = { - gtk.enable = true; - name = lib.mkForce "BreezeX-RosePine-Linux"; - package = lib.mkForce pkgs.rose-pine-cursor; - size = lib.mkForce 24; - x11 = { - defaultCursor = lib.mkForce "BreezeX-RosePine-Linux"; - enable = true; - }; - }; - - # Neovim setup - programs.nixvim = { - enable = true; - defaultEditor = true; - viAlias = true; - vimAlias = true; - - extraPackages = with pkgs; [ - ]; - - opts = { - number = true; - relativenumber = true; - - signcolumn = "yes"; - - ignorecase = true; - smartcase = true; - - tabstop = 4; - shiftwidth = 4; - softtabstop = 0; - expandtab = true; - smarttab = true; - - list = true; - listchars = "tab:»┈«,trail:·,extends:→,precedes:←,nbsp:␣"; - }; - - diagnostics = { - enable = true; - signs = true; - underline = true; - update_in_insert = true; - }; - - extraConfigLua = '' - vim.fn.sign_define("DiagnosticSignError", - {text = "", texthl = "DiagnosticSignError"}) - vim.fn.sign_define("DiagnosticSignWarn", - {text = "", texthl = "DiagnosticSignWarn"}) - vim.fn.sign_define("DiagnosticSignInfo", - {text = "", texthl = "DiagnosticSignInfo"}) - vim.fn.sign_define("DiagnosticSignHint", - {text = "💡", texthl = "DiagnosticSignHint"}) - ''; - - keymaps = [ - # Save shortcut - { - action = ":update"; - key = ""; - mode = "n"; - } - { - action = ":update"; - key = ""; - mode = "i"; - } - - # Neo tree - { - action = ":Neotree action=focus reveal toggle"; - key = "n"; - mode = "n"; - options.silent = true; - } - ]; - - autoCmd = [ - { - desc = "Automatic formatting"; - event = "BufWritePre"; - callback = { - __raw = '' - function() - vim.lsp.buf.format { - async = false, - } - end - ''; - }; - } - ]; - - highlight = { - Comment = { - italic = true; - fg = colors.withHashtag.base03; - }; - - }; - - plugins.lsp = { - enable = true; - }; - - #plugins.treesitter = { - # enable = true; - #}; - - plugins.cmp = { - enable = true; - - settings = { - mapping = { - "" = "cmp.mapping.complete()"; - "" = "cmp.mapping.scroll_docs(-4)"; - "" = "cmp.mapping.close()"; - "" = "cmp.mapping.scroll_docs(4)"; - "" = "cmp.mapping.confirm({ select = true })"; - "" = "cmp.mapping(cmp.mapping.select_prev_item(), {'i', 's'})"; - "" = "cmp.mapping(cmp.mapping.select_next_item(), {'i', 's'})"; - }; - sources = [ - { name = "path"; } - { name = "nvim_lsp"; } - ]; - }; - }; - - plugins.neo-tree = { - enable = true; - - closeIfLastWindow = true; - window = { - width = 30; - autoExpandWidth = true; - }; - - extraOptions = { - default_component_configs.git_status.symbols = { - # Change type - added = "+"; - deleted = "✕"; - modified = "✦"; - renamed = "→"; - - # Status type - untracked = "?"; - ignored = "▫"; - unstaged = "□"; - staged = "■"; - conflict = "‼"; - }; - }; - }; - - #plugins.cmp-nvim-lsp.enable = true; - - plugins.gitsigns = { - enable = true; - settings.current_line_blame = true; - }; - - #plugins.copilot-vim = { - # enable = true; - #}; - - plugins.rust-tools = { - enable = true; - }; - - plugins.vimtex = { - enable = true; - texlivePackage = null; - settings = { - view_method = "zathura"; - }; - }; - }; - programs.neovim.defaultEditor = true; - - # Foot setup - programs.foot = { - enable = true; - settings = { - main = let - font = fonts.monospace.name; - size = toString fonts.sizes.terminal; - in { - font = lib.mkForce "${font}:style=Regular:size=${size}"; - font-bold = "${font}:style=Bold:size=${size}"; - font-italic = "${font}:style=Italic:size=${size}"; - font-bold-italic = "${font}:style=Bold Italic:size=${size}"; - }; - }; - }; - - # Fuzzel setup - #programs.fuzzel = { - # enable = true; - # settings = { - # main = { - # font = "${fonts.monospace.name}:size=${toString fonts.sizes.terminal}"; -# icons-enabled = "no"; -# horizontal-pad = borderSize; -# vertical-pad = borderSize; -# inner-pad = 2; -# dpi-aware = "no"; -# }; -# colors = { -# background = colors.base00 + "ff"; -# text = colors.base05 + "ff"; -# match = colors.base09 + "ff"; -# selection = colors.base02 + "ff"; -# selection-text = colors.base05 + "ff"; -# selection-match = colors.base09 + "ff"; -# border = colors.base05 + "ff"; -# }; -# border = { -# width = borderSize; -# radius = 0; -# }; -# }; -# }; - - # Mako notifications setup - services.mako = { - enable = true; - anchor = "top-right"; - defaultTimeout = 5000; - backgroundColor = "#${colors.base00}ff"; - textColor = "#${colors.base05}ff"; - borderColor = "#${colors.base05}ff"; - progressColor = "#${colors.base09}ff"; - borderRadius = 0; - borderSize = borderSize; - font = "${fonts.monospace.name} ${toString fonts.sizes.terminal}"; - }; - - # Waybar setup - programs.waybar = { - enable = true; - systemd = { - enable = true; - }; - settings = { - mainBar = { - layer = "top"; - spacing = 16; - modules-left = [ - "river/tags" - ]; - modules-center = [ - #"river/window" - "mpris" - ]; - modules-right = [ - "pulseaudio" - "battery" - "clock" - ]; - "river/window" = { - max-length = 50; - }; - "river/tags" = { - tag-labels = [ - "一" - "二" - "三" - "四" - "五" - "六" - "七" - "八" - "九" - ]; - disable-click = false; - }; - pulseaudio = { - tooltip = false; - format = "{icon}   {volume}%"; # Spacing achieved using "Thin Space" - #format-muted = ""; - format-muted = "{icon}  --%"; # Spacing achieved using "Thin Space" - format-icons = { - #headphone = ""; - #default = [ "" "" ]; - headphone = ""; - headphone-muted = ""; - default = [ "" "" "" ]; - }; - }; - battery = { - format = "{icon} {capacity}%"; # Spacing achieved using "Thin Space" - format-charging = " {capacity}%"; # Spacing achieved using "Thin Space" - #format-icons = [ "󰂎" "󰁺" "󰁻" "󰁼" "󰁽" "󰁾" "󰁿" "󰂀" "󰂁" "󰂂" "󰁹" ]; - format-icons = [ "" "" "" "" "" "" "" "" "" "" "" ]; - interval = 1; - }; - clock = { - #format = "󰅐 {:%H:%M}"; - #format = "   {:%H:%M}"; # Spacing achieved using "Thin Space" - format = "{:%H:%M}"; - }; - mpris = { - format = "{dynamic}"; - tooltip-format = ""; - interval = 1; - }; - }; - }; - style = '' - window#waybar { - color: #${colors.base05}; - background-color: #${colors.base00}; - border-style: none none solid none; - border-width: ${toString borderSize}px; - border-color: #${colors.base01}; - font-size: 12px; - font-family: "${fonts.monospace.name}"; - } - - .modules-right { - margin: 0 8px 0 0; - } - - #tags button { - color: #${colors.base03}; - padding: 0 5px 1px 5px; - border-radius: 0; - font-size: 16px; - font-family: "Unifont"; - } - - #tags button.occupied { - color: #${colors.base05}; - } - - #tags button.focused { - color: #${colors.base09}; - } - - #tags.button.bell { - color: #${colors.base0A}; - } - ''; - }; - - # River setup - wayland.windowManager.river = { - enable = true; - xwayland.enable = true; - settings = let - layout = "rivertile"; - layoutOptions = "-outer-padding ${toString windowPadding} -view-padding ${toString windowPadding}"; - modes = ["normal" "locked"]; - tags = [1 2 3 4 5 6 7 8 9]; - - # Quick pow function - pow2 = power: - if power != 0 - then 2 * (pow2 (power - 1)) - else 1; - - # Modifiers - main = "Super"; - ssm = "Super+Shift"; - sas = "Super+Alt+Shift"; - sam = "Super+Alt"; - scm = "Super+Control"; - scam = "Super+Control+Alt"; - ssc = "Super+Shift+Control"; - in { - default-layout = "${layout}"; - set-repeat = "50 300"; - xcursor-theme = "BreezeX-RosePine-Linux 24"; - keyboard-layout = "-options \"caps:escape\" us"; - - border-width = toString borderSize; - background-color = "0x${colors.base00}"; - border-color-focused = "0x${colors.base05}"; - border-color-unfocused = "0x${colors.base01}"; - border-color-urgent = "0x${colors.base09}"; - - spawn = [ - "\"${layout} ${layoutOptions}\"" - "\"systemctl --user restart waybar\"" - ]; - map = (lib.attrsets.recursiveUpdate ({ - normal = { - "${main} Q" = "close"; - "${ssm} E" = "spawn \"systemctl --user stop waybar && riverctl exit\""; - - # Basic utilities - "${main} X " = "spawn \"waylock -fork-on-lock ${waylockOptions}\""; - "${ssm} Return" = "spawn foot"; - "${main} P" = "spawn \"rofi -show drun\""; - "${ssm} P" = "spawn rofi-rbw"; - - # Window focus - "${main} J" = "focus-view next"; - "${main} K" = "focus-view previous"; - - # Swap windows - "${ssm} J" = "swap next"; - "${ssm} K" = "swap previous"; - "${main} Return" = "zoom"; - - # Main ratio - "${main} H" = "send-layout-cmd rivertile 'main-ratio -0.05'"; - "${main} L" = "send-layout-cmd rivertile 'main-ratio +0.05'"; - - # Main count - "${ssm} H" = "send-layout-cmd rivertile 'main-count +1'"; - "${ssm} L" = "send-layout-cmd rivertile 'main-count -1'"; - - # Tags - "${main} 0" = "set-focused-tags ${toString (pow2 32 - 1)}"; - "${ssm} 0" = "set-view-tags ${toString (pow2 32 - 1)}"; - - # Orientation - "${main} Up" = "send-layout-cmd rivertile \"main-location top\""; - "${main} Right" = "send-layout-cmd rivertile \"main-location right\""; - "${main} Down" = "send-layout-cmd rivertile \"main-location bottom\""; - "${main} Left" = "send-layout-cmd rivertile \"main-location left\""; - - # Move floating windows - "${sam} H" = "move left 100"; - "${sam} J" = "move down 100"; - "${sam} K" = "move up 100"; - "${sam} L" = "move right 100"; - - # Snap floating windows - "${scam} H" = "snap left"; - "${scam} J" = "snap down"; - "${scam} K" = "snap up"; - "${scam} L" = "snap right"; - - # Resize floating windows - "${sas} H" = "resize horizontal -100"; - "${sas} J" = "resize vertical 100"; - "${sas} K" = "resize vertical -100"; - "${sas} L" = "resize horizontal 100"; - - # Toggle modes - "${main} Space" = "toggle-float"; - "${main} F" = "toggle-fullscreen"; - } // builtins.listToAttrs (builtins.concatLists (map (tag: [ - { name = "${main} ${toString tag}"; value = "set-focused-tags ${toString (pow2 (tag - 1))}"; } - { name = "${ssm} ${toString tag}"; value = "set-view-tags ${toString (pow2 (tag - 1))}"; } - { name = "${scm} ${toString tag}"; value = "toggle-focused-tags ${toString (pow2 (tag - 1))}"; } - { name = "${ssc} ${toString tag}"; value = "toggle-view-tags ${toString (pow2 (tag - 1))}"; } - ]) tags)); - }) (builtins.listToAttrs (map (mode: { - name = "${mode}"; - value = { - # Control volume - "None XF86AudioRaiseVolume" = "spawn \"pulsemixer --change-volume +5\""; - "None XF86AudioLowerVolume" = "spawn \"pulsemixer --change-volume -5\""; - "None XF86AudioMute" = "spawn \"pulsemixer --toggle-mute\""; - - # Control brightness - "None XF86MonBrightnessUp" = "spawn \"brightnessctl set +5%\""; - "None XF86MonBrightnessDown" = "spawn \"brightnessctl set 5%-\""; - - # Control music playback - "None XF86Messenger" = "spawn \"playerctl previous\""; - "None XF86Go" = "spawn \"playerctl play-pause\""; - "None Cancel" = "spawn \"playerctl next\""; - }; - }) modes))); - map-pointer = { - normal = { - "${main} BTN_LEFT" = "move-view"; - "${main} BTN_RIGHT" = "resize-view"; - "${main} BTN_MIDDLE" = "toggle-float"; - }; - }; - input = { - "'*'" = { - accel-profile = "adaptive"; - pointer-accel = "0.5"; - scroll-factor = "0.8"; - }; - "'*Synaptics*'" = { - natural-scroll = "enabled"; - }; - }; - rule-add = { - "-app-id" = { - "'bar'" = "csd"; - "'*'" = "ssd"; - }; - }; - }; - }; - - home.stateVersion = "24.05"; - }; + # home-manager.backupFileExtension = "bak"; # Global neovim programs.neovim = { @@ -1101,7 +298,7 @@ in { # Copy the NixOS configuration file and link it from the resulting system # (/run/current-system/configuration.nix). This is useful in case you # accidentally delete configuration.nix. - system.copySystemConfiguration = true; + # system.copySystemConfiguration = true; # This option defines the first version of NixOS you have installed on this particular machine, # and is used to maintain compatibility with application data (e.g. databases) created on older NixOS versions. @@ -1120,5 +317,5 @@ in { # and migrated your data accordingly. # # For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion . - system.stateVersion = "24.05"; # Did you read the comment? -} \ No newline at end of file + # system.stateVersion = "24.05"; # Did you read the comment? +} diff --git a/modules/default.nix b/modules/default.nix new file mode 100644 index 0000000..b7ce727 --- /dev/null +++ b/modules/default.nix @@ -0,0 +1,9 @@ +{ lib, config, pkgs, ... }: + +{ + imports = [ + ./greetd/default.nix + ./tuigreet/default.nix + ./users/default.nix + ]; +} \ No newline at end of file diff --git a/modules/greetd/default.nix b/modules/greetd/default.nix new file mode 100644 index 0000000..36fe4a4 --- /dev/null +++ b/modules/greetd/default.nix @@ -0,0 +1,25 @@ +{config, lib, pkgs, ... }: + +with lib; +let + cfg = config.modules.greetd; +in { + options.modules.greetd = { + enable = mkEnableOption "greetd"; + command = mkOption { + type = types.str; + default = ""; + description = "Command to run to show greeter."; + }; + }; + + config = mkIf cfg.enable { + services.greetd = { + enable = true; + settings.default_session = { + command = cfg.command; + user = "greeter"; + }; + }; + }; +} \ No newline at end of file diff --git a/modules/silent-boot/default.nix b/modules/silent-boot/default.nix new file mode 100644 index 0000000..e69de29 diff --git a/modules/tuigreet/default.nix b/modules/tuigreet/default.nix new file mode 100644 index 0000000..6d448a2 --- /dev/null +++ b/modules/tuigreet/default.nix @@ -0,0 +1,28 @@ +{config, lib, pkgs, ... }: + +with lib; +let + cfg = config.modules.tuigreet; +in { + options.modules.tuigreet = { + enable = mkEnableOption "tuigreet"; + greeting = mkOption { + type = types.str; + default = "Hewwo! >_< :3"; + description = "Greeting message to show."; + }; + command = mkOption { + type = types.str; + default = "~/.initrc"; + description = "Command to run after logging in."; + }; + }; + + config = mkIf cfg.enable { + # Enable greetd + modules.greetd = { + enable = true; + command = "${pkgs.greetd.tuigreet}/bin/tuigreet --remember --greeting \"${cfg.greeting}\" --time --cmd \"${cfg.command}\" --asterisks"; + }; + }; +} \ No newline at end of file diff --git a/modules/users/default.nix b/modules/users/default.nix new file mode 100644 index 0000000..ef07303 --- /dev/null +++ b/modules/users/default.nix @@ -0,0 +1,82 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + # Nixvim + nixvim = import (builtins.fetchGit { + url = "https://github.com/nix-community/nixvim"; + }); + + # Stylix + stylix = import (pkgs.fetchFromGitHub { + owner = "danth"; + repo = "stylix"; + rev = "1ff9d37d27377bfe8994c24a8d6c6c1734ffa116"; + sha256 = "0dz8h1ga8lnfvvmvsf6iqvnbvxrvx3qxi0y8s8b72066mqgvy8y5"; + }); + + # User configuration + userModule = types.submodule { + options = { + sudo = mkOption { + type = types.bool; + default = false; + example = true; + description = "Whether the user is allowed sudo access."; + }; + configuration = mkOption { + type = types.path; + default = ./users/base.nix; + description = "What home manager configuration to use for this user."; + }; + desktopInit = mkOption { + type = types.lines; + default = ""; + description = "Bash script to execute after initial log in."; + }; + }; + }; +in { + imports = [ + # Import home manager + + + # Import system configuration setup + # ./system.nix + ]; + + options = { + machine.users = mkOption { + type = types.attrsOf userModule; + default = {}; + description = "Users configured on this system."; + }; + }; + + config = { + # Add required home manager modules + home-manager.sharedModules = [ + # Stylix for theming + stylix.homeManagerModules.stylix + + # Nixvim for neovim + nixvim.homeManagerModules.nixvim + + # Modules + ./modules/default.nix + ]; + + # Create users + users.users = attrsets.concatMapAttrs (name: value: { + ${name} = { + isNormalUser = true; + extraGroups = mkIf value.sudo [ "wheel" ]; + }; + }) config.machine.users; + + # Create home manager configuration for users + home-manager.users = attrsets.concatMapAttrs (name: value: { + ${name} = value.configuration; + }) config.machine.users; + }; +} diff --git a/modules/users/modules/default.nix b/modules/users/modules/default.nix new file mode 100644 index 0000000..602872d --- /dev/null +++ b/modules/users/modules/default.nix @@ -0,0 +1,19 @@ +{ input, pkgs, config, ... }: + +{ + # Set the state version + home.stateVersion = "24.05"; + + imports = [ + # Import all modules + ./desktop/default.nix + ./feishin/default.nix + ./firefox/default.nix + ./obsidian/default.nix + ./shell/bash.nix + ./shell/fish.nix + ./theming/default.nix + ./vscode/default.nix + ./zathura/default.nix + ]; +} diff --git a/modules/users/modules/desktop/default.nix b/modules/users/modules/desktop/default.nix new file mode 100644 index 0000000..b9600b8 --- /dev/null +++ b/modules/users/modules/desktop/default.nix @@ -0,0 +1,31 @@ +{ lib, pkgs, config, ... }: + +with lib; +let + cfg = config.modules.desktop; +in { + imports = [ + # Import desktop environment modules + ./lock-screen/waylock.nix + ./window-manager/river.nix + ]; + + options.modules.desktop = { + initScript = mkOption { + type = types.lines; + default = "${pkgs.bash}/bin/bash"; + description = "Bash script to execute after logging in."; + }; + }; + + config = { + home.file.".initrc" = { + enable = true; + executable = true; + text = '' + #!${pkgs.bash}/bin/bash + + '' + cfg.initScript; + }; + }; +} diff --git a/modules/users/modules/desktop/lock-screen/waylock.nix b/modules/users/modules/desktop/lock-screen/waylock.nix new file mode 100644 index 0000000..2f0f20b --- /dev/null +++ b/modules/users/modules/desktop/lock-screen/waylock.nix @@ -0,0 +1,24 @@ +{ lib, pkgs, config, ... }: + +with lib; +let + cfg = config.modules.waylock; +in { + options.modules.waylock = { + enable = mkEnableOption "waylock"; + system = mkOption { + type = types.attrsOf types.anything; + description = "System wide configuration to apply if module is enabled"; + }; + }; + + config = { + modules.waylock.system = mkForce { + security.pam.services.waylock = {}; + }; + + home.packages = mkIf cfg.enable (with pkgs; [ + waylock + ]); + }; +} \ No newline at end of file diff --git a/modules/users/modules/desktop/window-manager/river.nix b/modules/users/modules/desktop/window-manager/river.nix new file mode 100644 index 0000000..8ce95f3 --- /dev/null +++ b/modules/users/modules/desktop/window-manager/river.nix @@ -0,0 +1,171 @@ +{config, lib, pkgs, ... }: + +let + cfg = config.modules.river; +in { + options.modules.river.enable = lib.mkEnableOption "river"; + + # osConfig = lib.mkIf cfg.enable { + # programs.river.enable = true; + # }; + + config = lib.mkIf cfg.enable { + # Change desktop to execute river + modules.desktop.initScript = '' + river + ''; + + # River setup + wayland.windowManager.river = { + enable = true; + xwayland.enable = true; + settings = let + layout = "rivertile"; + layoutOptions = "-outer-padding ${toString config.theming.layout.windowPadding} -view-padding ${toString config.theming.layout.windowPadding}"; + modes = ["normal" "locked"]; + tags = [1 2 3 4 5 6 7 8 9]; + # TODO: Replace the base02 color with a named color + waylockOptions = "-init-color 0x${colors.bg} -input-color 0x${config.theming.schemeColors.base02} -fail-color 0x${colors.bg}"; + + colors = config.theming.colors; + + # Quick pow function + pow2 = power: + if power != 0 + then 2 * (pow2 (power - 1)) + else 1; + + # Modifiers + main = "Super"; + ssm = "Super+Shift"; + sas = "Super+Alt+Shift"; + sam = "Super+Alt"; + scm = "Super+Control"; + scam = "Super+Control+Alt"; + ssc = "Super+Shift+Control"; + in { + default-layout = "${layout}"; + set-repeat = "50 300"; + xcursor-theme = "BreezeX-RosePine-Linux 24"; + keyboard-layout = "-options \"caps:escape\" us"; + + border-width = toString config.theming.layout.borderSize; + background-color = "0x${colors.bg}"; + border-color-focused = "0x${colors.fg}"; + border-color-unfocused = "0x${config.theming.schemeColors.base01}"; # TODO: Change to use named color; + border-color-urgent = "0x${colors.fg}"; + + spawn = [ + "\"${layout} ${layoutOptions}\"" + "waybar" + ]; + map = (lib.attrsets.recursiveUpdate ({ + normal = { + "${main} Q" = "close"; + "${ssm} E" = "exit"; + + # Basic utilities + "${main} X " = "spawn \"waylock -fork-on-lock ${waylockOptions}\""; + "${ssm} Return" = "spawn foot"; + "${main} P" = "spawn \"rofi -show drun\""; + "${ssm} P" = "spawn rofi-rbw"; + + # Window focus + "${main} J" = "focus-view next"; + "${main} K" = "focus-view previous"; + + # Swap windows + "${ssm} J" = "swap next"; + "${ssm} K" = "swap previous"; + "${main} Return" = "zoom"; + + # Main ratio + "${main} H" = "send-layout-cmd rivertile 'main-ratio -0.05'"; + "${main} L" = "send-layout-cmd rivertile 'main-ratio +0.05'"; + + # Main count + "${ssm} H" = "send-layout-cmd rivertile 'main-count +1'"; + "${ssm} L" = "send-layout-cmd rivertile 'main-count -1'"; + + # Tags + "${main} 0" = "set-focused-tags ${toString (pow2 32 - 1)}"; + "${ssm} 0" = "set-view-tags ${toString (pow2 32 - 1)}"; + + # Orientation + "${main} Up" = "send-layout-cmd rivertile \"main-location top\""; + "${main} Right" = "send-layout-cmd rivertile \"main-location right\""; + "${main} Down" = "send-layout-cmd rivertile \"main-location bottom\""; + "${main} Left" = "send-layout-cmd rivertile \"main-location left\""; + + # Move floating windows + "${sam} H" = "move left 100"; + "${sam} J" = "move down 100"; + "${sam} K" = "move up 100"; + "${sam} L" = "move right 100"; + + # Snap floating windows + "${scam} H" = "snap left"; + "${scam} J" = "snap down"; + "${scam} K" = "snap up"; + "${scam} L" = "snap right"; + + # Resize floating windows + "${sas} H" = "resize horizontal -100"; + "${sas} J" = "resize vertical 100"; + "${sas} K" = "resize vertical -100"; + "${sas} L" = "resize horizontal 100"; + + # Toggle modes + "${main} Space" = "toggle-float"; + "${main} F" = "toggle-fullscreen"; + } // builtins.listToAttrs (builtins.concatLists (map (tag: [ + { name = "${main} ${toString tag}"; value = "set-focused-tags ${toString (pow2 (tag - 1))}"; } + { name = "${ssm} ${toString tag}"; value = "set-view-tags ${toString (pow2 (tag - 1))}"; } + { name = "${scm} ${toString tag}"; value = "toggle-focused-tags ${toString (pow2 (tag - 1))}"; } + { name = "${ssc} ${toString tag}"; value = "toggle-view-tags ${toString (pow2 (tag - 1))}"; } + ]) tags)); + }) (builtins.listToAttrs (map (mode: { + name = "${mode}"; + value = { + # Control volume + "None XF86AudioRaiseVolume" = "spawn \"pulsemixer --change-volume +5\""; + "None XF86AudioLowerVolume" = "spawn \"pulsemixer --change-volume -5\""; + "None XF86AudioMute" = "spawn \"pulsemixer --toggle-mute\""; + + # Control brightness + "None XF86MonBrightnessUp" = "spawn \"brightnessctl set +5%\""; + "None XF86MonBrightnessDown" = "spawn \"brightnessctl set 5%-\""; + + # Control music playback + "None XF86Messenger" = "spawn \"playerctl previous\""; + "None XF86Go" = "spawn \"playerctl play-pause\""; + "None Cancel" = "spawn \"playerctl next\""; + }; + }) modes))); + map-pointer = { + normal = { + "${main} BTN_LEFT" = "move-view"; + "${main} BTN_RIGHT" = "resize-view"; + "${main} BTN_MIDDLE" = "toggle-float"; + }; + }; + input = { + "'*'" = { + accel-profile = "adaptive"; + pointer-accel = "0.5"; + scroll-factor = "0.8"; + }; + "'*Synaptics*'" = { + natural-scroll = "enabled"; + }; + }; + rule-add = { + "-app-id" = { + "'bar'" = "csd"; + "'*'" = "ssd"; + }; + }; + }; + }; + }; +} diff --git a/modules/users/modules/feishin/default.nix b/modules/users/modules/feishin/default.nix new file mode 100644 index 0000000..1684002 --- /dev/null +++ b/modules/users/modules/feishin/default.nix @@ -0,0 +1,13 @@ +{config, lib, pkgs, ... }: + +let + cfg = config.modules.feishin; +in { + options.modules.feishin.enable = lib.mkEnableOption "feishin"; + + config = lib.mkIf cfg.enable { + home.packages = with pkgs; [ + feishin + ]; + }; +} \ No newline at end of file diff --git a/modules/users/modules/firefox/default.nix b/modules/users/modules/firefox/default.nix new file mode 100644 index 0000000..8487c61 --- /dev/null +++ b/modules/users/modules/firefox/default.nix @@ -0,0 +1,60 @@ +{config, lib, pkgs, ... }: + +let + cfg = config.modules.firefox; +in { + options.modules.firefox.enable = lib.mkEnableOption "firefox"; + + config = lib.mkIf cfg.enable { + # Enable NUR + nixpkgs.config.packageOverrides = pkgs: { + # TODO: Pin the version + nur = import (builtins.fetchTarball "https://github.com/nix-community/NUR/archive/master.tar.gz") { + inherit pkgs; + }; + }; + + programs.firefox = { + enable = true; + + policies = { + AppAutoUpdate = false; + BlockAboutAddons = true; + BlockAboutConfig = true; + BlockAboutProfiles = true; + DisableAppUpdate = true; + DisableFeedbackCommands = true; + DisableMasterPasswordCreation = true; + DisablePocket = true; + DisableProfileImport = true; + DisableProfileRefresh = true; + DisableSetDesktopBackground = true; + DisableTelemetry = true; + DisplayBookmarksToolbar = "never"; + DisplayMenuBar = "never"; + DNSOverHTTPS = { Enabled = false; }; + DontCheckDefaultBrowser = true; + PasswordManagerEnabled = false; + TranslateEnabled = true; + UseSystemPrintDialog = true; + }; + + profiles.nixos = { + search.default = "DuckDuckGo"; + + extensions = with pkgs.nur.repos.rycee.firefox-addons; [ + ublock-origin + ]; + + settings = { + "browser.tabs.inTitlebar" = 0; + "extensions.autoDisableScopes" = 0; + }; + + # Force overwriting configuration file + search.force = true; + containersForce = true; + }; + }; + }; +} \ No newline at end of file diff --git a/modules/users/modules/obsidian/default.nix b/modules/users/modules/obsidian/default.nix new file mode 100644 index 0000000..5971cd6 --- /dev/null +++ b/modules/users/modules/obsidian/default.nix @@ -0,0 +1,13 @@ +{config, lib, pkgs, ... }: + +let + cfg = config.modules.obsidian; +in { + options.modules.obsidian.enable = lib.mkEnableOption "obsidian"; + + config = lib.mkIf cfg.enable { + home.packages = with pkgs; [ + obsidian + ]; + }; +} \ No newline at end of file diff --git a/modules/users/modules/shell/bash.nix b/modules/users/modules/shell/bash.nix new file mode 100644 index 0000000..75e63e6 --- /dev/null +++ b/modules/users/modules/shell/bash.nix @@ -0,0 +1,12 @@ +{ lib, config, pkgs, ... }: + +with lib; +let + cfg = config.modules.bash; +in { + options.modules.bash = { + enable = mkEnableOption "bash"; + }; + + config.programs.bash.enable = cfg.enable; +} \ No newline at end of file diff --git a/modules/users/modules/shell/fish.nix b/modules/users/modules/shell/fish.nix new file mode 100644 index 0000000..4118cfd --- /dev/null +++ b/modules/users/modules/shell/fish.nix @@ -0,0 +1,46 @@ +{ lib, config, pkgs, ... }: + +with lib; +let + cfg = config.modules.fish; +in { + options.modules.fish = { + enable = mkEnableOption "fish"; + + plugins = { + done = mkEnableOption "done"; + fzf = mkEnableOption "fzf"; + grc = mkEnableOption "grc"; + }; + }; + + config = mkIf cfg.enable { + # Make bash load into fish + # Bash will remain the default shell as fish is not POSIX compliant. + modules.bash.enable = true; + programs.bash.initExtra = '' + if [[ $(${pkgs.procps}/bin/ps --no-header --pid=$PPID --format=comm) != "fish" && -z ''${BASH_EXECUTION_STRING} ]] + then + shopt -q login_shell && LOGIN_OPTION='--login' || LOGIN_OPTION="" + exec ${pkgs.fish}/bin/fish $LOGIN_OPTION + fi + ''; + + # Actual fish configuration + programs.fish = { + enable = true; + + plugins = [ + (mkIf cfg.plugins.done { name = "done"; src = pkgs.fishPlugins.done.src; }) + (mkIf cfg.plugins.fzf { name = "fzf"; src = pkgs.fishPlugins.fzf-fish.src; }) + (mkIf cfg.plugins.grc { name = "grc"; src = pkgs.fishPlugins.grc.src; }) + ]; + }; + + # Fish plugin dependencies + home.packages = with pkgs; [ + (mkIf cfg.plugins.fzf fzf) + (mkIf cfg.plugins.grc grc) + ]; + }; +} \ No newline at end of file diff --git a/modules/users/modules/theming/default.nix b/modules/users/modules/theming/default.nix new file mode 100644 index 0000000..8cc5a19 --- /dev/null +++ b/modules/users/modules/theming/default.nix @@ -0,0 +1,83 @@ +{ pkgs, lib, config, ... }: + +with lib; +let + # Stylix + stylix = pkgs.fetchFromGitHub { + owner = "danth"; + repo = "stylix"; + rev = "1ff9d37d27377bfe8994c24a8d6c6c1734ffa116"; + sha256 = "0dz8h1ga8lnfvvmvsf6iqvnbvxrvx3qxi0y8s8b72066mqgvy8y5"; + }; +in { + imports = [ + # Import all themes + ./themes/gruvbox.nix + ./themes/catppuccin.nix + ]; + + options.theming = + let + colors = config.theming.schemeColors; + in { + darkMode = mkOption { + type = types.bool; + default = false; + example = true; + description = "Whether the app should use dark mode."; + }; + + colorScheme = mkOption { + type = types.nullOr types.str; + default = null; + description = "Base 16 color scheme to use for styling. See stylix documentation for more information."; + }; + + schemeColors = mkOption { + type = types.attrsOf types.anything; + default = config.lib.stylix.colors; + description = "Generated colors from scheme"; + }; + + colors = { + bg = mkOption { + type = types.str; + default = colors.base00; + }; + fg = mkOption { + type = types.str; + default = colors.base05; + }; + }; + + layout = { + borderRadius = mkOption { + type = types.int; + default = 0; + description = "Border radius of windows."; + }; + + borderSize = mkOption { + type = types.int; + default = 1; + description = "Size of borders used throughout UI."; + }; + + windowPadding = mkOption { + type = types.int; + default = 2; + description = "Margin of each window, actual space between windows will be twice this number."; + }; + }; + }; + + config = { + stylix = { + enable = true; + autoEnable = false; + + base16Scheme = config.theming.colorScheme; + polarity = if config.theming.darkMode then "dark" else "light"; + }; + }; +} diff --git a/modules/users/modules/theming/themes/catppuccin.nix b/modules/users/modules/theming/themes/catppuccin.nix new file mode 100644 index 0000000..5c4d16f --- /dev/null +++ b/modules/users/modules/theming/themes/catppuccin.nix @@ -0,0 +1,22 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + cfg = config.theming.themes.catppuccin; +in { + options = { + theming.themes.catppuccin = { + enable = mkEnableOption "catppuccin"; + flavor = mkOption { + type = types.enum [ "latte" "frappe" "macchiato" "mocha" ]; + default = "mocha"; + description = "The flavor of catppuccin theme."; + }; + }; + }; + + config.theming = mkIf cfg.enable { + darkMode = (cfg.flavor != "latte"); + colorScheme = "${pkgs.base16-schemes}/share/themes/catppuccin-${cfg.flavor}.yaml"; + }; +} diff --git a/modules/users/modules/theming/themes/gruvbox.nix b/modules/users/modules/theming/themes/gruvbox.nix new file mode 100644 index 0000000..9bf57f2 --- /dev/null +++ b/modules/users/modules/theming/themes/gruvbox.nix @@ -0,0 +1,24 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + cfg = config.theming.themes.gruvbox; + mode = if cfg.darkMode then "dark" else "light"; +in { + options = { + theming.themes.gruvbox = { + enable = mkEnableOption "gruvbox-hard"; + darkMode = mkEnableOption "dark mode"; + contrast = mkOption { + type = types.enum [ "hard" "medium" "soft" ]; + default = "hard"; + description = "The contrast level of the theme."; + }; + }; + }; + + config.theming = mkIf cfg.enable { + darkMode = cfg.darkMode; + colorScheme = "${pkgs.base16-schemes}/share/themes/gruvbox-${mode}-${cfg.contrast}.yaml"; + }; +} diff --git a/modules/users/modules/vscode/default.nix b/modules/users/modules/vscode/default.nix new file mode 100644 index 0000000..1b27268 --- /dev/null +++ b/modules/users/modules/vscode/default.nix @@ -0,0 +1,13 @@ +{config, lib, pkgs, ... }: + +let + cfg = config.modules.vscode; +in { + options.modules.vscode.enable = lib.mkEnableOption "vscode"; + + config = lib.mkIf cfg.enable { + home.packages = with pkgs; [ + vscode + ]; + }; +} \ No newline at end of file diff --git a/users/modules/tools/zathura/default.nix b/modules/users/modules/zathura/default.nix similarity index 100% rename from users/modules/tools/zathura/default.nix rename to modules/users/modules/zathura/default.nix diff --git a/modules/users/system.nix b/modules/users/system.nix new file mode 100644 index 0000000..9708505 --- /dev/null +++ b/modules/users/system.nix @@ -0,0 +1,13 @@ +{ lib, config, pkgs, ... }: + +with lib; +let + users = config.home-manager.users; + allModules = flatten (map (user: (attrValues user.modules)) (attrValues users)); + modules = filter (module: module?system && module?enable) allModules; + configs = map (module: module.system) modules; + combined = (foldl (a: b: recursiveUpdate a b) {} configs); +in { + # Add the combined systemwide config required by the user modules. + config = combined; +} \ No newline at end of file diff --git a/system.nix b/system.nix index 316193f..4a39ac7 100644 --- a/system.nix +++ b/system.nix @@ -2,7 +2,7 @@ { options = { - custom.laptop = lib.mkOption { + machine.laptop = lib.mkOption { type = lib.types.bool; default = false; example = true; diff --git a/test.nix b/test.nix index 14d8b3e..f655d1b 100644 --- a/test.nix +++ b/test.nix @@ -2,10 +2,16 @@ { config = { - custom.users.jan = { - enable = true; + system.stateVersion = "24.05"; + + machine.users.jan = { sudo = true; configuration = ./users/jan.nix; }; + + machine.users.second = { + sudo = false; + configuration = ./users/jan.nix; + }; }; } \ No newline at end of file diff --git a/users.nix b/users.nix deleted file mode 100644 index 4a97419..0000000 --- a/users.nix +++ /dev/null @@ -1,46 +0,0 @@ -{ config, lib, pkgs, ... }: - -let - userModule = lib.types.submodule { - options = { - enable = lib.mkOption { - type = lib.types.bool; - default = false; - example = true; - description = "Whether the user is enabled."; - }; - sudo = lib.mkOption { - type = lib.types.bool; - default = false; - example = true; - description = "Whether the user is allowed sudo access."; - }; - configuration = lib.mkOption { - type = lib.types.path; - default = ./users/base.nix; - description = "What home manager configuration to use for this user."; - }; - }; - }; -in { - options = { - custom.users = lib.mkOption { - type = lib.types.attrsOf userModule; - default = {}; - description = "Users configured on this system."; - }; - }; - - config = { - users.users = lib.attrsets.concatMapAttrs (name: value: { - ${name} = { - isNormalUser = true; - extraGroups = lib.mkIf value.sudo [ "wheel" ]; - }; - }) config.custom.users; - - home-manager.users = lib.attrsets.concatMapAttrs (name: value: { - ${name} = value.configuration; - }) config.custom.users; - }; -} \ No newline at end of file diff --git a/users/base.nix b/users/base.nix deleted file mode 100644 index 5802a9a..0000000 --- a/users/base.nix +++ /dev/null @@ -1,8 +0,0 @@ -{ ... }: - -{ - imports = [ - # Import all modules - ./modules/default.nix - ]; -} \ No newline at end of file diff --git a/users/jan.nix b/users/jan.nix index f9ea0ad..bdfaa9c 100644 --- a/users/jan.nix +++ b/users/jan.nix @@ -1,12 +1,41 @@ +# How Jan likes his linux to be configured + { ... }: { imports = [ - # Import base configuration - ./base.nix + ./janMerged.nix ]; config = { - modules.zathura.enable = true; + # State version + home.stateVersion = "24.05"; + + # Allow unfree software such as vscode + nixpkgs.config.allowUnfree = true; + + modules = { + # Window manager + river.enable = true; + waylock.enable = true; + + # Programs + feishin.enable = true; + firefox.enable = true; + vscode.enable = true; + zathura.enable = true; + fish.enable = true; + }; + + theming.themes.gruvbox = { + enable = false; + darkMode = false; + contrast = "hard"; + }; + + theming.themes.catppuccin = { + enable = true; + flavor = "latte"; + }; }; -} \ No newline at end of file +} diff --git a/users/janMerged.nix b/users/janMerged.nix new file mode 100644 index 0000000..969c65a --- /dev/null +++ b/users/janMerged.nix @@ -0,0 +1,650 @@ +{ lib, pkgs, config, ... }: + +let + # Theming constants + colors = config.lib.stylix.colors; + fonts = config.stylix.fonts; + borderSize = 1; + windowPadding = 2; + + waylockOptions = "-init-color 0x${colors.base00} -input-color 0x${colors.base02} -fail-color 0x${colors.base00}"; +in { + # Extra modules + imports = [ + # nixvim.homeManagerModules.nixvim + # stylix.homeManagerModules.stylix + ]; + + # Packages + home.packages = with pkgs; [ + # Programs + vscode + feishin + discord + obsidian + winbox + + # Utilities + pulsemixer + wl-clipboard + pinentry-rofi + wtype + # waylock + playerctl + + # Fish plugin dependencies + # grc + # fzf + + # Rust development + rustc + cargo + rustfmt + + # Bitwarden + rofi-rbw + + # LaTeX libraries + (pkgs.texlive.combine { + inherit (pkgs.texlive) scheme-full; + }) + ]; + + # Stylix + stylix = { + # enable = true; + # polarity = "dark"; + + # base16Scheme = "${pkgs.base16-schemes}/share/themes/gruvbox-dark-hard.yaml"; + fonts = { + monospace = { + package = pkgs.dina-font; + name = "Dina"; + }; + + sizes = { + terminal = 9; + }; + }; + + # autoEnable = false; + targets = { + foot.enable = true; + nixvim.enable = true; + qutebrowser.enable = true; + vscode.enable = true; + # zathura.enable = true; + }; + }; + + # Fish shell + # programs.fish = { + # enable = true; + + # plugins = [ + # { name = "done"; src = pkgs.fishPlugins.done.src; } + # { name = "fzf"; src = pkgs.fishPlugins.fzf-fish.src; } + # { name = "grc"; src = pkgs.fishPlugins.grc.src; } + # ]; + # }; + + # # Bash prompt + # programs.bash = { + # enable = true; + # initExtra = '' + # if [[ $(${pkgs.procps}/bin/ps --no-header --pid=$PPID --format=comm) != "fish" && -z ''${BASH_EXECUTION_STRING} ]] + # then + # shopt -q login_shell && LOGIN_OPTION='--login' || LOGIN_OPTION="" + # exec ${pkgs.fish}/bin/fish $LOGIN_OPTION + # fi + # ''; + # bashrcExtra = '' + # FG_BLACK="\[$(tput setaf 0)\]" + # FG_RED="\[$(tput setaf 1)\]" + # FG_GREEN="\[$(tput setaf 2)\]" + # FG_YELLOW="\[$(tput setaf 3)\]" + # FG_BLUE="\[$(tput setaf 4)\]" + # FG_MAGENTA="\[$(tput setaf 5)\]" + # FG_CYAN="\[$(tput setaf 6)\]" + # FG_WHITE="\[$(tput setaf 7)\]" + + # RESET="\[$(tput sgr0)\]" + + # export PS0="\n''${RESET}" + # export PS1="''${FG_GREEN}\n│\w\n│" + # export PS2="│" + # ''; + # }; + + # Direnv setup + programs.direnv = { + enable = true; + nix-direnv.enable = true; + }; + + # Qutebrowser + programs.qutebrowser = { + enable = true; + + extraConfig = '' + config.set("colors.webpage.darkmode.enabled", False) + config.set("colors.webpage.preferred_color_scheme", "dark") + config.set("fonts.default_family", "${fonts.monospace.name}") + config.set("fonts.default_size", "${toString fonts.sizes.terminal}pt") + ''; + }; + + # Bitwarden client + programs.rbw = { + enable = true; + settings = { + base_url = "https://keys.bulthuis.dev"; + identity_url = "https://keys.bulthuis.dev"; + email = "jan@bulthuis.dev"; + pinentry = pkgs.pinentry; + }; + }; + + # Firefox + programs.firefox = { + enable = true; + policies = { + AppAutoUpdate = false; + BlockAboutAddons = true; + BlockAboutConfig = true; + BlockAboutProfiles = true; + DisableAppUpdate = true; + DisableFeedbackCommands = true; + DisableMasterPasswordCreation = true; + DisablePocket = true; + DisableProfileImport = true; + DisableProfileRefresh = true; + DisableSetDesktopBackground = true; + DisableTelemetry = true; + DisplayBookmarksToolbar = "never"; + DisplayMenuBar = "never"; + DNSOverHTTPS = { Enabled = false; }; + DontCheckDefaultBrowser = true; + PasswordManagerEnabled = false; + TranslateEnabled = true; + UseSystemPrintDialog = true; + }; + profiles.nixos = { + search.default = "DuckDuckGo"; + + extensions = with pkgs.nur.repos.rycee.firefox-addons; [ + ublock-origin + ]; + + settings = { + "browser.tabs.inTitlebar" = 0; + "extensions.autoDisableScopes" = 0; + }; + + # Force overwriting configuration file + search.force = true; + containersForce = true; + }; + }; + + # Email setup + accounts.email.accounts = { + Personal = { + primary = true; + realName = "Jan Bulthuis"; + userName = "jan@bulthuis.dev"; + address = "jan@bulthuis.dev"; + thunderbird.enable = true; + + flavor = "plain"; + imap = { + host = "mail.bulthuis.dev"; + port = 993; + }; + smtp = { + host = "mail.bulthuis.dev"; + port = 465; + }; + }; + }; + + # Thunderbird setup + programs.thunderbird = { + enable = true; + profiles.nixos = { + isDefault = true; + }; + }; + + # Rofi setup + programs.rofi = { + enable = true; + package = pkgs.rofi-wayland; + font = "${fonts.monospace.name} ${toString fonts.sizes.terminal}"; + theme = let + inherit (config.lib.formats.rasi) mkLiteral; + in { + "*" = { + background-color = mkLiteral "rgba(0, 0, 0, 0%)"; + border-color = mkLiteral colors.withHashtag.base05; + text-color = mkLiteral colors.withHashtag.base05; + }; + mainbox = { + background-color = mkLiteral colors.withHashtag.base00; + border = mkLiteral "${toString borderSize}px"; + }; + element-text = { + highlight = mkLiteral colors.withHashtag.base09; + }; + inputbar = { + children = mkLiteral "[textbox-search, entry]"; + }; + listview = { + padding = mkLiteral "2px 0px"; + }; + textbox-search = { + expand = false; + content = "> "; + }; + "inputbar, message" = { + padding = mkLiteral "2px"; + }; + element = { + padding = mkLiteral "0px 2px"; + }; + "element selected" = { + background-color = mkLiteral colors.withHashtag.base02; + }; + }; + }; + + # Dark mode + dconf.settings = { + "org/gnome/desktop/interface" = { + color-scheme = "prefer-dark"; + }; + }; + qt = { + enable = true; + platformTheme.name = "adwaita"; + style.name = "adwaita-dark"; + }; + systemd.user.sessionVariables = config.home.sessionVariables; + + # Configure GTK + gtk = let + css = '' + headerbar.default-decoration { + margin-bottom: 50px; + margin-top: -100px; + } + + window.csd, + window.csd decoration { + box-shadow: none; + } + ''; + in { + enable = true; + + # Dark mode + theme = { + name = "Adwaita-dark"; + package = pkgs.gnome-themes-extra; + }; + + # Disable CSD + gtk3.extraCss = css; + gtk4.extraCss = css; + }; + + # Cursors + home.pointerCursor = { + gtk.enable = true; + name = lib.mkForce "BreezeX-RosePine-Linux"; + package = lib.mkForce pkgs.rose-pine-cursor; + size = lib.mkForce 24; + x11 = { + defaultCursor = lib.mkForce "BreezeX-RosePine-Linux"; + enable = true; + }; + }; + + # Neovim setup + programs.nixvim = { + enable = true; + defaultEditor = true; + viAlias = true; + vimAlias = true; + + extraPackages = with pkgs; [ + ]; + + opts = { + number = true; + relativenumber = true; + + signcolumn = "yes"; + + ignorecase = true; + smartcase = true; + + tabstop = 4; + shiftwidth = 4; + softtabstop = 0; + expandtab = true; + smarttab = true; + + list = true; + listchars = "tab:»┈«,trail:·,extends:→,precedes:←,nbsp:␣"; + }; + + diagnostics = { + enable = true; + signs = true; + underline = true; + update_in_insert = true; + }; + + extraConfigLua = '' + vim.fn.sign_define("DiagnosticSignError", + {text = "", texthl = "DiagnosticSignError"}) + vim.fn.sign_define("DiagnosticSignWarn", + {text = "", texthl = "DiagnosticSignWarn"}) + vim.fn.sign_define("DiagnosticSignInfo", + {text = "", texthl = "DiagnosticSignInfo"}) + vim.fn.sign_define("DiagnosticSignHint", + {text = "💡", texthl = "DiagnosticSignHint"}) + ''; + + keymaps = [ + # Save shortcut + { + action = ":update"; + key = ""; + mode = "n"; + } + { + action = ":update"; + key = ""; + mode = "i"; + } + + # Neo tree + { + action = ":Neotree action=focus reveal toggle"; + key = "n"; + mode = "n"; + options.silent = true; + } + ]; + + autoCmd = [ + { + desc = "Automatic formatting"; + event = "BufWritePre"; + callback = { + __raw = '' + function() + vim.lsp.buf.format { + async = false, + } + end + ''; + }; + } + ]; + + highlight = { + Comment = { + italic = true; + fg = colors.withHashtag.base03; + }; + + }; + + plugins.lsp = { + enable = true; + }; + + #plugins.treesitter = { + # enable = true; + #}; + + plugins.cmp = { + enable = true; + + settings = { + mapping = { + "" = "cmp.mapping.complete()"; + "" = "cmp.mapping.scroll_docs(-4)"; + "" = "cmp.mapping.close()"; + "" = "cmp.mapping.scroll_docs(4)"; + "" = "cmp.mapping.confirm({ select = true })"; + "" = "cmp.mapping(cmp.mapping.select_prev_item(), {'i', 's'})"; + "" = "cmp.mapping(cmp.mapping.select_next_item(), {'i', 's'})"; + }; + sources = [ + { name = "path"; } + { name = "nvim_lsp"; } + ]; + }; + }; + + plugins.neo-tree = { + enable = true; + + closeIfLastWindow = true; + window = { + width = 30; + autoExpandWidth = true; + }; + + extraOptions = { + default_component_configs.git_status.symbols = { + # Change type + added = "+"; + deleted = "✕"; + modified = "✦"; + renamed = "→"; + + # Status type + untracked = "?"; + ignored = "▫"; + unstaged = "□"; + staged = "■"; + conflict = "‼"; + }; + }; + }; + + #plugins.cmp-nvim-lsp.enable = true; + + plugins.gitsigns = { + enable = true; + settings.current_line_blame = true; + }; + + #plugins.copilot-vim = { + # enable = true; + #}; + + plugins.rust-tools = { + enable = true; + }; + + plugins.vimtex = { + enable = true; + texlivePackage = null; + settings = { + view_method = "zathura"; + }; + }; + }; + programs.neovim.defaultEditor = true; + + # Foot setup + programs.foot = { + enable = true; + settings = { + main = let + font = fonts.monospace.name; + size = toString fonts.sizes.terminal; + in { + font = lib.mkForce "${font}:style=Regular:size=${size}"; + font-bold = "${font}:style=Bold:size=${size}"; + font-italic = "${font}:style=Italic:size=${size}"; + font-bold-italic = "${font}:style=Bold Italic:size=${size}"; + }; + }; + }; + + # Fuzzel setup + #programs.fuzzel = { + # enable = true; + # settings = { + # main = { + # font = "${fonts.monospace.name}:size=${toString fonts.sizes.terminal}"; +# icons-enabled = "no"; +# horizontal-pad = borderSize; +# vertical-pad = borderSize; +# inner-pad = 2; +# dpi-aware = "no"; +# }; +# colors = { +# background = colors.base00 + "ff"; +# text = colors.base05 + "ff"; +# match = colors.base09 + "ff"; +# selection = colors.base02 + "ff"; +# selection-text = colors.base05 + "ff"; +# selection-match = colors.base09 + "ff"; +# border = colors.base05 + "ff"; +# }; +# border = { +# width = borderSize; +# radius = 0; +# }; +# }; +# }; + + # Mako notifications setup + services.mako = { + enable = true; + anchor = "top-right"; + defaultTimeout = 5000; + backgroundColor = "#${colors.base00}ff"; + textColor = "#${colors.base05}ff"; + borderColor = "#${colors.base05}ff"; + progressColor = "#${colors.base09}ff"; + borderRadius = 0; + borderSize = borderSize; + font = "${fonts.monospace.name} ${toString fonts.sizes.terminal}"; + }; + + # Waybar setup + programs.waybar = { + enable = true; + settings = { + mainBar = { + layer = "top"; + spacing = 16; + modules-left = [ + "river/tags" + ]; + modules-center = [ + #"river/window" + "mpris" + ]; + modules-right = [ + "pulseaudio" + "battery" + "clock" + ]; + "river/window" = { + max-length = 50; + }; + "river/tags" = { + tag-labels = [ + "一" + "二" + "三" + "四" + "五" + "六" + "七" + "八" + "九" + ]; + disable-click = false; + }; + pulseaudio = { + tooltip = false; + format = "{icon}   {volume}%"; # Spacing achieved using "Thin Space" + #format-muted = ""; + format-muted = "{icon}  --%"; # Spacing achieved using "Thin Space" + format-icons = { + #headphone = ""; + #default = [ "" "" ]; + headphone = ""; + headphone-muted = ""; + default = [ "" "" "" ]; + }; + }; + battery = { + format = "{icon} {capacity}%"; # Spacing achieved using "Thin Space" + format-charging = " {capacity}%"; # Spacing achieved using "Thin Space" + #format-icons = [ "󰂎" "󰁺" "󰁻" "󰁼" "󰁽" "󰁾" "󰁿" "󰂀" "󰂁" "󰂂" "󰁹" ]; + format-icons = [ "" "" "" "" "" "" "" "" "" "" "" ]; + interval = 1; + }; + clock = { + #format = "󰅐 {:%H:%M}"; + #format = "   {:%H:%M}"; # Spacing achieved using "Thin Space" + format = "{:%H:%M}"; + }; + mpris = { + format = "{dynamic}"; + tooltip-format = ""; + interval = 1; + }; + }; + }; + style = '' + window#waybar { + color: #${colors.base05}; + background-color: #${colors.base00}; + border-style: none none solid none; + border-width: ${toString borderSize}px; + border-color: #${colors.base01}; + font-size: 12px; + font-family: "${fonts.monospace.name}"; + } + + .modules-right { + margin: 0 8px 0 0; + } + + #tags button { + color: #${colors.base03}; + padding: 0 5px 1px 5px; + border-radius: 0; + font-size: 16px; + font-family: "Unifont"; + } + + #tags button.occupied { + color: #${colors.base05}; + } + + #tags button.focused { + color: #${colors.base09}; + } + + #tags.button.bell { + color: #${colors.base0A}; + } + ''; + }; + + home.stateVersion = "24.05"; +} diff --git a/users/modules/default.nix b/users/modules/default.nix deleted file mode 100644 index cbf7966..0000000 --- a/users/modules/default.nix +++ /dev/null @@ -1,10 +0,0 @@ -{ input, pkgs, config, ... }: - -{ - # Set the state version - home.stateVersion = "24.05"; - - imports = [ - ./tools/zathura/default.nix - ]; -} \ No newline at end of file