User Tools

Site Tools


configuration.nix

This is an old revision of the document!


My Nix Configuration

In order to edit the configuration without root permissions, it is convenient to symlink configuration.nix to my user's home directory, like this:

mkdir ~/etc
sudo mv /etc/nixos/ ~/etc/
sudo chown -R $(id -un):users ~/etc/nixos/
sudo ln -s ~/etc/nixos/ /etc/

The Configuration

# Edit this configuration file to define what should be installed on
# your system.  Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running ‘nixos-help’).

{ config, pkgs, lib, ... }:

let
  home-manager = builtins.fetchTarball https://github.com/nix-community/home-manager/archive/release-26.05.tar.gz;

  # Given a list of attribute sets, union them into a single attribute
  # set, preferring keys earlier in the list.
  unionsAttrs = lib.foldAttrs lib.const {};
in
{
  imports =
    [ # Include the results of the hardware scan.
      ./hardware-configuration.nix
      (import "${home-manager}/nixos")
    ];

  # Bootloader.
  boot.loader.systemd-boot.enable = true;
  boot.loader.efi.canTouchEfiVariables = true;

  networking.hostName = "xps"; # Define your hostname.
  networking.wireless.enable = true;  # Enables wireless support via wpa_supplicant.

  # Configure network proxy if necessary
  # networking.proxy.default = "http://user:password@proxy:port/";
  # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";

  # Enable networking
  networking.networkmanager.enable = true;

  # Set your time zone.
  time.timeZone = "America/Chicago";

  # Select internationalisation properties.
  i18n.defaultLocale = "en_US.UTF-8";

  i18n.extraLocaleSettings = {
    LC_ADDRESS = "en_US.UTF-8";
    LC_IDENTIFICATION = "en_US.UTF-8";
    LC_MEASUREMENT = "en_US.UTF-8";
    LC_MONETARY = "en_US.UTF-8";
    LC_NAME = "en_US.UTF-8";
    LC_NUMERIC = "en_US.UTF-8";
    LC_PAPER = "en_US.UTF-8";
    LC_TELEPHONE = "en_US.UTF-8";
    LC_TIME = "en_US.UTF-8";
  };

  # Add swap
  swapDevices = [{
    device = "/var/lib/swapfile";
    size = 16*1024; # 16 GiB
  }];

  # Define a user account. Don't forget to set a password with ‘passwd’.
  users.users."sam" = {
    isNormalUser = true;
    description = "Sam Cohen";
    extraGroups = [ "networkmanager" "wheel" "video" ];
    packages = with pkgs; [];
  };

  # Necessary for sway
  security.polkit.enable = true;

  # Keyring for wayland applications
  services.gnome.gnome-keyring.enable = true;
  security.pam.services = {
    greetd.enableGnomeKeyring = true;
    # Necessary for swaylock to work correctly.
    swaylock = {};
  };

  # Launches sway on login
  services.greetd = {
    enable = true;
    settings = {
      default_session = {
        command = "${pkgs.tuigreet}/bin/tuigreet --time --cmd sway";
        user = "greeter";
      };
    };
  };

  services.logind.settings.Login = {
    # don’t shutdown when power button is short-pressed. We want sway
    # to handle that key instead.
    HandlePowerKey = "ignore";
  };

  # CPU frequency scaling. This is meant to extend battery life.
  services.auto-cpufreq = {
    enable = true;
    settings = {
      battery = {
        governor = "powersave";
        turbo = "never";
      };
      charger = {
        governor = "performance";
        turbo = "auto";
      };
    };
  };
  # Tries to keep the CPU at a reasonable temperature by throttling
  # when necessary.
  services.thermald.enable = true;

  ## Printing ##########

  # NOTE: see http://localhost:631 to configure printers.
  services.printing.enable = true;

  # The below is for automatic discovery of network printers using
  # the IPP Everywhere protocol.
  services.avahi = {
    enable = true;
    nssmdns4 = true;
    openFirewall = true;
  };

  # Fonts
  fonts.packages = with pkgs; [
    hack-font
  ];

  home-manager.users."sam" = { config, pkgs, lib, ... }:
    let
      # Permits adjustment of display brightness
      brightnessctl = "${pkgs.brightnessctl}/bin/brightnessctl";
      # Permits adjustment of audio volume via pactl
      pactl = "${pkgs.pulseaudio}/bin/pactl";
      # Permits locking the screen
      swaylock = "${pkgs.swaylock}/bin/swaylock";
    in {
      home.packages = with pkgs; [
        # For keeping track of passwords:
        pass

        # For reading mail:
        mu

        # For syncing with mail servers:
        isync
        # For sending email:
        msmtp
        # For communicating with exchange servers. See below, usually
        # we will start this program as a systemd service.
        davmail

        # dokoff (locally defined)
        (callPackage /home/sam/Projects/dokoff/dokoff.nix { })

        # For taking screenshots
        grim
      ];

      programs.bash = {
        enable = true;
        enableCompletion = true;
        bashrcExtra = "eval \"$(direnv hook bash)\"";
      };

      programs.git = {
        enable = true;
        signing = {
          key = "E2FE54A52DF79398";
          format = "openpgp";
          signByDefault = true;
        };
        settings = {
          init.defaultBranch = "main";
          user.useConfigOnly = true;
          user.name = "Sam Cohen";
          user.email = "sbcohen2000@gmail.com";
          rebase.autoSquash = true;
        };
      };

      ## GPG ##########

      programs.gpg = {
        enable = true;
      };
      services.gpg-agent = {
        enable = true;
        pinentry.package = pkgs.pinentry-qt;
        defaultCacheTtl = 1800; # Only ask for a password half an hour after inactivity
      };

      ## Sway/GUI ##########

      programs.kitty = {
        enable = true;
        themeFile = "AtomOneLight";
        font.name = "Hack";
        font.size = 10;
        # Make the text render a lot thicker, more similar to emacs
        # text rendering:
        extraConfig = "text_composition_strategy 1.5 15";
      };

      services.emacs.enable = true;
      programs.emacs = {
        enable = true;
      };
      home.sessionVariables = {
        # Put the location of mu4e on the path so that emacs can find
        # it later.
        MU4E = "${pkgs.mu.mu4e}";
      };

      wayland.windowManager.sway = {
        enable = true;
        wrapperFeatures.gtk = true; # Fixes common issues with gtk3 apps
        checkConfig = true;
        config = rec {
          terminal = "kitty";
          startup = [
            # Launch emacs on start
            { command = "emacsclient -c"; }
          ];
          modifier = "Mod4";
          keybindings = let
            workspaces = [1 2 3 4];

            # Setup two bindings for each workspace, one which moves
            # to the workspace, and one which moves the current
            # container to the workspace:
            bindings = lib.listToAttrs
              (lib.concatMap (n:
                let
                  ns = toString n;
                in [
                  { "name" = "${modifier}+${ns}";       value = "workspace number ${ns}"; }
                  { "name" = "${modifier}+Shift+${ns}"; value = "move container to workspace number ${ns}"; }
                ]) workspaces);
          in
            unionsAttrs [
              bindings
              {
                "${modifier}+Left" = "focus left";
                "${modifier}+Right" = "focus right";
                "${modifier}+Up" = "focus up";
                "${modifier}+Down" = "focus down";
                "${modifier}+Shift+Left" = "move left";
                "${modifier}+Shift+Right" = "move right";
                "${modifier}+Shift+Up" = "move up";
                "${modifier}+Shift+Down" = "move down";

                "${modifier}+r" = "mode resize";
                "${modifier}+q" = "kill";
                "${modifier}+a" = "focus parent";
                "${modifier}+f" = "fullscreen toggle";
                "${modifier}+space" = "layout toggle split";
                "${modifier}+Shift+space" = "floating toggle";

                # Brightness Controls
                "XF86MonBrightnessDown" = "exec ${brightnessctl} s 5%-";
                "XF86MonBrightnessUp" = "exec ${brightnessctl} s +5%";

                # Volume Controls
                "XF86AudioRaiseVolume" = "exec ${pactl} set-sink-volume @DEFAULT_SINK@ +5%";
                "XF86AudioLowerVolume" = "exec ${pactl} set-sink-volume @DEFAULT_SINK@ -5%";
                "XF86AudioMute" = "exec ${pactl} set-sink-mute @DEFAULT_SINK@ toggle";

                # Launching
                "${modifier}+Return" = "exec kitty";
                "${modifier}+e" = "exec emacsclient -c";
                "${modifier}+b" = "exec firefox";

                # Locking
                "XF86PowerOff" = "exec ${swaylock}";
              }
            ];

          input = {
            "type:keyboard" = {
              xkb_options = "ctrl:nocaps";
              repeat_delay = "250";
              repeat_rate = "30";
            };
            "type:touchpad" = {
              tap = "enabled";
              # Prevent an odd feature where after tapping you can drag
              # the mouse to create a selection.
              drag = "disabled";
              drag_lock = "disabled";

              # Change scroll direction.
              natural_scroll = "enabled";

              # Disable trackpad while typing.
              dwt = "enabled";
            };
          };
        };
      };

      # Turns off the display, then suspends the computer after a period
      # of inactivity.
      services.swayidle = {
        enable = true;
        timeouts = [
          {
            timeout = 1 * 60;
            command = "${brightnessctl} -s s 5%"; # Set the brightness, saving the old value to a tmpfile.
            resumeCommand = "${brightnessctl} -r"; # Restore the previous brightness.
          }
          {
            timeout = 5 * 60;
            command = "${pkgs.systemd}/bin/systemctl suspend";
          }
        ];
        events = {
          # Lock the screen, and restore the previously saved brightness.
          "after-resume" = "${swaylock}; ${brightnessctl} -r";
        };
      };

      # Locks the screen when power button is pressed.
      programs.swaylock = {
        enable = true;
      };

      # Displays notifications when called upon.
      services.mako = {
        enable = true;
        settings = {
          default-timeout = 5000; # 5 seconds.
        };
      };

      programs.firefox = {
        enable = true;
      };

      ## Mail ##########

      # We use a davmail server to proxy Exchange mail servers as
      # local SMTP/IMAP servers.
      systemd.user.services.davmail = {
        Unit = {
          Description = "Proxy Exchange servers through local SMTP/IMAP.";
        };
        Install = {
          WantedBy = [ "default.target" ];
        };
        Service = {
          ExecStart = "${pkgs.davmail}/bin/davmail ${config.home.homeDirectory}/.davmail.properties";
        };
      };

      # Restart user services when we perform a configuration switch.
      systemd.user.startServices = "sd-switch";

      home.stateVersion = "26.05";
    };

  # List packages installed in system profile. To search, run:
  # $ nix search wget
  environment.systemPackages = with pkgs; [
    libnotify          # Send notifications to the notification daemon.
    wl-clipboard       # Copy/Paste from the terminal (`wl-copy/paste`).
    direnv
    kdePackages.okular # A PDF viewer

    ## In Service of Emacs ##########

    # Ghostscript is necessary to interpret PDF files in emacs'
    # document viewer.
    ghostscript
    ispell             # A spell-checking program.
    ripgrep            # A better grep.
  ];

  # This value determines the NixOS release from which the default
  # settings for stateful data, like file locations and database versions
  # on your system were taken. It‘s perfectly fine and recommended to leave
  # this value at the release version of the first install of this system.
  # Before changing this value read the documentation for this option
  # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
  system.stateVersion = "26.05"; # Did you read the comment?
}
configuration.nix.1782339263.txt.gz · Last modified: by sam