dotfiles/flake.nix

600 lines
23 KiB
Nix
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

{
inputs = {
# Principle inputs (updated by `nix run .#update`)
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
nix-darwin.url = "github:lnl7/nix-darwin/master";
nix-darwin.inputs.nixpkgs.follows = "nixpkgs";
home-manager.url = "github:nix-community/home-manager";
home-manager.inputs.nixpkgs.follows = "nixpkgs";
flake-parts.url = "github:hercules-ci/flake-parts";
nixos-flake.url = "github:srid/nixos-flake";
# Neovim
nixvim = {
url = "github:nix-community/nixvim";
# nixvim has a lot of inputs we are using, so pin them to same version
inputs = {
nixpkgs.follows = "nixpkgs";
nix-darwin.follows = "nix-darwin";
home-manager.follows = "home-manager";
flake-parts.follows = "flake-parts";
treefmt-nix.follows = "treefmt-nix";
};
};
# https://developer.1password.com/docs/cli/shell-plugins/nix/
_1password-shell-plugins = {
url = "github:1Password/shell-plugins";
inputs.nixpkgs.follows = "nixpkgs";
inputs.flake-utils.follows = "nixvim/devshell/flake-utils";
};
nix-index-database.url = "github:nix-community/nix-index-database";
nix-index-database.inputs.nixpkgs.follows = "nixpkgs";
treefmt-nix.url = "github:numtide/treefmt-nix";
treefmt-nix.inputs.nixpkgs.follows = "nixpkgs";
nil = {
url = "github:oxalica/nil";
inputs.nixpkgs.follows = "nixpkgs";
inputs.flake-utils.follows = "nixvim/devshell/flake-utils";
};
};
outputs = inputs@{ self, ... }:
inputs.flake-parts.lib.mkFlake { inherit inputs; }
(
let
myUsername = "bjeanes";
in
{
systems = [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" ];
imports = [
inputs.nixos-flake.flakeModule
inputs.treefmt-nix.flakeModule
];
# flake-parts will export this wholesale as the flakes' `outputs`, with no per-system transposition. See `perSystem` below for this.
flake = {
# Configurations for Linux (NixOS) machines
nixosConfigurations = { };
# Configurations for macOS machines
darwinConfigurations = {
# Work M3 Max MBP
Jabberwocky = self.darwinConfigurations.Bandersnatch;
# Personal M1 Max MBP
Bandersnatch = self.nixos-flake.lib.mkMacosSystem {
nixpkgs.hostPlatform = "aarch64-darwin";
imports = [
self.nixosModules.common # See below for "nixosModules"!
self.nixosModules.darwin
# Your machine's configuration.nix goes here
({ pkgs, ... }: {
# Used for backwards compatibility, please read the changelog before changing.
# $ darwin-rebuild changelog
system.stateVersion = 4;
})
# Your home-manager configuration
self.darwinModules_.home-manager
{
home-manager.users.${myUsername} = {
imports = [
self.homeModules.common # See below for "homeModules"!
self.homeModules.darwin
];
home.stateVersion = "24.05";
};
}
];
};
};
# All nixos/nix-darwin configurations are kept here.
nixosModules = {
# Common nixos/nix-darwin configuration shared between Linux and macOS.
common = { pkgs, ... }:
{
home-manager.backupFileExtension = "bak-hm";
home-manager.useUserPackages = true;
# home-manager.verbose = true;
nixpkgs.config.allowUnfree = true;
environment.variables = { };
environment.systemPackages = with pkgs; [
git
bat
# In system packages so VSCode more reliably finds these
direnv
nil
nixpkgs-fmt
];
};
# NixOS specific configuration
linux = { pkgs, ... }: {
imports = [
inputs.nixvim.nixosModules.nixvim
];
users.users.${myUsername}.isNormalUser = true;
};
# nix-darwin specific configuration
darwin = { pkgs, ... }: {
imports = [
inputs.nixvim.nixDarwinModules.nixvim
];
nix.useDaemon = true;
services.nix-daemon.enable = true;
services.nix-daemon.enableSocketListener = true;
nix = {
configureBuildUsers = true;
## Control the version of Nix that nix-darwin uses. At time of writing, it defaults to 2.18.x, but latest is 2.23.3.
## Commented out because versions after 2.18.x are apparently pretty buggy
# package = pkgs.nixVersions.latest;
# Use Lix (a Nix-compatible lang -- https://lix.systems)
package = pkgs.lix;
settings = {
trusted-users = [ "root" myUsername ];
allowed-users = [ "root" myUsername "@nixbld" ];
auto-optimise-store = true; # https://daiderd.com/nix-darwin/manual/index.html#opt-nix.settings.auto-optimise-store
substituters = [
"https://nix-community.cachix.org"
];
trusted-public-keys = [
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
];
};
extraOptions = ''
extra-nix-path = "nixpkgs=flake:nixpkgs"
experimental-features = nix-command flakes
'';
};
launchd.user.agents.gc-downloads =
let
find = "${pkgs.findutils}/bin/find";
downloads = "/Users/${myUsername}/Downloads";
in
{
serviceConfig = {
ProcessType = "Background";
RunAtLoad = true;
StartInterval = 6 * 60 * 60; # every 6 hours
};
script = ''
${find} ${downloads} -type f -mtime +30 -print -delete
${find} ${downloads} -type d -not -wholename "${downloads}" -empty -print -delete
'';
};
homebrew.enable = true;
homebrew.taps = [
"exoscale/tap"
"terrastruct/tap"
];
homebrew.brews = [
"exoscale/tap/exoscale-cli"
"terrastruct/tap/tala" # proprietary layout engine for D2
];
# This needs to be here in addition to the home-manager configuration below in order to write /etc/zshenv to correctly configure ZSH. This is confusing, but...
# https://github.com/LnL7/nix-darwin/issues/1003
# https://github.com/LnL7/nix-darwin/issues/922#issuecomment-2041430035
programs.zsh.enable = true;
programs.bash.enable = true;
security.pam.enableSudoTouchIdAuth = true;
users.users.${myUsername}.home = "/Users/${myUsername}";
system.keyboard.enableKeyMapping = true;
system.keyboard.remapCapsLockToControl = true;
# https://archive.is/KBa2w
system.activationScripts.postUserActivation.text = ''
# Following line should allow us to avoid a logout/login cycle
/System/Library/PrivateFrameworks/SystemAdministration.framework/Resources/activateSettings -u
'';
system.defaults = {
# Show file extensions in Finder
finder.AppleShowAllExtensions = true;
# Default to column view in Finder
finder.FXPreferredViewStyle = "clmv";
# Allow quitting Finder from the menu
finder.QuitMenuItem = true;
finder.ShowPathbar = true;
finder.ShowStatusBar = true;
# Disable guest logins
loginwindow.GuestEnabled = false;
loginwindow.autoLoginUser = myUsername;
menuExtraClock.ShowDayOfMonth = true;
menuExtraClock.ShowDayOfWeek = true;
# Disable quarantine for downloaded files
LaunchServices.LSQuarantine = false;
# Disable swiping for backwards/forwards
NSGlobalDomain.AppleEnableSwipeNavigateWithScrolls = false;
NSGlobalDomain.AppleEnableMouseSwipeNavigateWithScrolls = false;
# Switch light/dark style of OS automatically based on time
NSGlobalDomain.AppleInterfaceStyleSwitchesAutomatically = true;
NSGlobalDomain.AppleMetricUnits = 1;
# Disable press-and-hold keyboard for alt characters; this messes with key repeat and I am already used to Option+key for special characters
NSGlobalDomain.ApplePressAndHoldEnabled = false;
NSGlobalDomain.InitialKeyRepeat = 15;
NSGlobalDomain.KeyRepeat = 5;
# Disable certain text substitutions
NSGlobalDomain.NSAutomaticQuoteSubstitutionEnabled = false; # smart quotes
NSGlobalDomain.NSAutomaticPeriodSubstitutionEnabled = false; # period after double-space
NSGlobalDomain.NSAutomaticCapitalizationEnabled = false;
NSGlobalDomain.NSAutomaticSpellingCorrectionEnabled = false;
NSGlobalDomain.NSAutomaticDashSubstitutionEnabled = true;
# Jump to the spot thats clicked on the scroll bar
NSGlobalDomain.AppleScrollerPagingBehavior = true;
# use expanded save panel by default
NSGlobalDomain.NSNavPanelExpandedStateForSaveMode = true;
NSGlobalDomain.NSNavPanelExpandedStateForSaveMode2 = true;
CustomSystemPreferences = {
"io.tailscale.ipn.macos"."FileSharingConfiguration" = "show";
};
};
};
};
# All home-manager configurations are kept here; they are evaluated in the context of the user's home-manager profile.
# i.e. `foo = true` is equivalent to `home-manager.users.bjeanes.foo = true`.
homeModules = {
# Common home-manager configuration shared between Linux and macOS.
common = { pkgs, ... }:
let
code-font = "MesloLGMDZ Nerd Font Mono";
nerdfonts = (pkgs.nerdfonts.override {
fonts = [
"BitstreamVeraSansMono"
"Meslo"
"SourceCodePro"
"Monaspace" # Monaspace Argon, specifically
"FiraCode"
];
});
in
{
imports = [
inputs.nixvim.homeManagerModules.nixvim
inputs._1password-shell-plugins.hmModules.default
];
home.shellAliases = {
g = "git";
l = "ls";
ll = "ls -la";
arst = "asdf"; # Colemak home row
cat = "bat";
lg = "lazygit";
cd = "z";
};
programs.nixvim = {
enable = true;
defaultEditor = true;
viAlias = true;
vimAlias = true;
};
programs.git = {
enable = true;
aliases = {
br = "branch --format='%(color:red)%(committerdate:iso8601)%(color:reset) %(align:8)(%(ahead-behind:HEAD))%(end) %(color:blue)%(align:40)%(refname:short)%(end)%(color:reset) %(color:white)%(contents:subject) %(color:yellow)(%(committerdate:relative))%(color:reset)' --sort=-creatordate";
oldestb = "br --sort=committerdate";
newestb = "br --sort=-committerdate";
c = "commit -v";
co = "checkout";
commit = "commit -v";
lg = "log --decorate --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset' --abbrev-commit --date=relative";
st = "status";
unadd = "reset HEAD";
me = "!sh -c 'echo `git config user.name` \\<`git config user.email`\\>'";
mine = "!sh -c 'git lg --author=\"`git me`\"'";
};
extraConfig = {
apply.whitespace = "fix";
init.defaultbranch = "main";
color = {
ui = "auto";
branch = "auto";
diff = "auto";
status = "auto";
};
branch = {
autosetupmerge = "always";
autosetuprebase = "local";
};
rebase.autostash = true;
pull.rebase = true;
push.default = "current";
remote.pushDefault = "origin";
status = {
short = true;
branch = true;
showUntrackedFiles = "all";
};
commit.gpgsign = true;
gpg.format = "ssh";
user.signingkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJykg+5TulcwmeKFYSjZmnrL5/Fo4kWmOV1fAyt41Evh";
};
ignores = [
"*.swp"
];
};
# difftastic will show syntactical/structural changes in diffs
# programs.git.difftastic.enable = true;
# delta will show diffs with language-aware syntax highlighting
programs.git.delta.enable = true;
programs.git.delta.package = pkgs.delta;
programs.bash.initExtra = /* bash */ ''
eval "$(${pkgs.delta}/bin/delta --generate-completion bash)"
'';
programs.zsh.initExtra = /* zsh */ ''
eval "$(${pkgs.delta}/bin/delta --generate-completion zsh)"
'';
programs.lazygit.enable = true;
programs.lazygit.settings = {
# lazygit can pull the pager out of Git's config, but `programs.git.delta.enable = true` sets
# the pager to `delta` directly, wheras `lazygit` requires `delta` to be called with
# `--paging=never` due to rendering issues.
#
# https://github.com/jesseduffield/lazygit/blob/master/docs/Custom_Pagers.md
git.paging.pager = "${pkgs.delta}/bin/delta --paging=never";
update.method = "never"; # we will manage it here
disableStartupPopups = true;
os.editPreset = "nvim";
};
programs.gh.enable = true;
programs.gh.settings.aliases = {
# https://cli.github.com/manual/gh_alias_set
configure-repo-squash = "api repos/{owner}/{repo} --method PATCH -f allow_squash_merge=true -f squash_merge_commit_title=PR_TITLE -f squash_merge_commit_message=PR_BODY";
configure-repo-delete-merged = "api repos/{owner}/{repo} --method PATCH -f delete_branch_on_merge=true";
configure-repo = "!gh configure-repo-squash && gh configure-repo-delete-merged";
};
programs.zsh = {
enable = true;
enableCompletion = true;
autocd = true;
syntaxHighlighting.enable = true;
autosuggestion.enable = true;
};
programs.bash = {
enable = true;
enableCompletion = true;
enableVteIntegration = true;
};
programs.starship.enable = true;
programs.direnv = {
enable = true;
config.global.hide_env_diff = true;
enableZshIntegration = true;
enableBashIntegration = true;
nix-direnv.enable = true;
};
programs.bat.enable = true;
programs.bat.config = {
map-syntax = [
"flake.lock:JSON"
];
};
# By default, this integration also hooks into shell ^R for history search, but atuin is better
# and fortunately appears to take precedence when both are enabled
programs.fzf.enable = true;
programs.fzf.enableZshIntegration = true;
programs.fzf.enableBashIntegration = true;
programs.fzf.fileWidgetOptions = [
"--preview '${pkgs.bat}/bin/bat --color=always --style=numbers --line-range :500 {}'"
];
# Shell history recording + UI
programs.atuin.enable = true;
programs.atuin.enableZshIntegration = true;
programs.atuin.enableBashIntegration = true;
programs.atuin.settings = {
dialect = "uk";
filter_mode_shell_up_key_binding = "session";
workspaces = true;
style = "compact";
inline_height = 20;
enter_accept = false;
ctrl_n_shortcuts = true;
stats.common_prefix = [
"sudo"
"time"
];
};
programs.zoxide = {
enable = true;
enableBashIntegration = true;
enableZshIntegration = true;
};
programs.eza = {
enable = true;
git = true;
icons = true;
enableBashIntegration = true;
enableZshIntegration = true;
};
programs.kitty = {
enable = true;
extraConfig = ''
background_opacity 0.8
background_blur 10
enable_audio_bell no
'';
theme = "Tomorrow Night Eighties";
font = {
package = nerdfonts;
name = code-font;
size = 13;
};
};
# TODO: https://news.ycombinator.com/item?id=31010090 for wiring together `rg`+`fzf`+`bat`
programs.ripgrep.enable = true;
programs._1password-shell-plugins = {
enable = true;
plugins = with pkgs; [
gh # github
cargo
heroku
tea # gitea
glab # gitlab
];
};
fonts.fontconfig.enable = true;
fonts.fontconfig.defaultFonts.monospace = [
code-font
];
home.packages = with pkgs; [
nerdfonts
# TODO: https://gist.github.com/axelbdt/0de9f5f9ba8a2100326b793f7bfb8658?permalink_comment_id=4977667#gistcomment-4977667
asdf-vm
git-absorb # https://github.com/tummychow/git-absorb
mkcert
# d2 # does not include proprietary Tala layout engine, and installing it with brew auto-installs brew's version of d2
];
};
# home-manager config specific to Linux / NixOS
linux = { };
# home-manager config specific to Darwin
darwin = { pkgs, ... }: {
# Yank/paste in Neovim to/from macOS clipboard by default
programs.nixvim.clipboard.register = "unnamedplus";
programs.git.extraConfig."gpg \"ssh\"".program = "/Applications/1Password.app/Contents/MacOS/op-ssh-sign";
home.shellAliases =
{
# https://github.com/tailscale/tailscale/issues/3805#issuecomment-1707050952
tailscale = "/Applications/Tailscale.app/Contents/MacOS/Tailscale";
};
home.sessionVariables =
let
brewPrefix =
if pkgs.stdenv.hostPlatform.isAarch64
then "/opt/homebrew"
else "/usr/local";
in
{
PATH = "${brewPrefix}/bin:${brewPrefix}/sbin:$PATH";
};
};
};
};
perSystem = { self', inputs', pkgs, system, config, ... }: {
# Non-NixOS Linux machine TumTum
legacyPackages.homeConfigurations."${myUsername}@tumtum" =
self.nixos-flake.lib.mkHomeConfiguration pkgs {
imports = [
self.homeModules.common
self.homeModules.linux
];
};
# Make `nix run` equivalent to `nix run .#activate`
packages.default = self'.packages.activate;
treefmt.config = {
projectRootFile = "flake.lock";
programs.nixpkgs-fmt.enable = true;
programs.nixpkgs-fmt.package = pkgs.nixpkgs-fmt;
};
devShells.default = pkgs.mkShell {
nativeBuildInputs = with pkgs; [
inputs.nil.packages.${system}.nil
nixpkgs-fmt
];
};
};
}
);
nixConfig = {
extra-substituters = [
"https://nix-community.cachix.org"
];
extra-trusted-public-keys = [
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
];
};
}