Skip to content

Instantly share code, notes, and snippets.

@kvz
Created April 3, 2024 09:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kvz/cff4aa214fa987eb43fd0100cf1ad082 to your computer and use it in GitHub Desktop.
Save kvz/cff4aa214fa987eb43fd0100cf1ad082 to your computer and use it in GitHub Desktop.
# Inspiration, credits, references:
# - https://gist.github.com/nickrttn/28acb67356c77b838493f31a6286fc03
# - https://juliu.is/tidying-your-home-with-nix/
# - https://github.com/Arkham/dotfiles.nix/blob/ba85362abf3a442b327d0b8fbb4691de5649cf40/home.nix
# - https://github.com/nix-community/home-manager/tree/master/modules/programs
# - https://github.com/NixOS/nixpkgs/blob/master/pkgs/shells/
# - https://github.com/nix-community/home-manager/issues/1341
# - https://github.com/abiosoft/colima
# - https://jeppesen.io/git-commit-sign-nix-home-manager-ssh/
# - https://github.com/NelsonJeppesen/nix-lifestyle/blob/main/home-manager/git.nix
{ config, lib, pkgs, ... }:
let
enableTouchIDForSudo = {
text = ''
if ! grep -q "pam_tid.so" $HOME/.config/pam.d/sudo; then
echo "Touch ID not enabled for sudo. Inserting in $HOME/.config/pam.d/sudo .." >&2
mkdir -p $HOME/.config/pam.d
cp /etc/pam.d/sudo $HOME/.config/pam.d/sudo
sed -i 's/\(pam_smartcard.so\)/auth sufficient pam_tid.so\n\1/' $HOME/.config/pam.d/sudo
fi
'';
};
pathComponents = [
"$HOME/code/dotfiles/bin"
"$HOME/.npm-packages/bin"
"$HOME/.config/composer/vendor/bin"
"$HOME/.nix-profile/bin"
"/nix/var/nix/profiles/default/bin"
"/usr/local/bin"
"/System/Cryptexes/App/usr/bin"
"/usr/bin"
"/bin"
"/usr/sbin"
"/sbin"
];
in {
nixpkgs.config = {
allowUnfree = true;
input-fonts.acceptLicense = true;
};
home.username = builtins.getEnv "USER";
home.homeDirectory = builtins.getEnv "HOME";
# This value determines the Home Manager release that your configuration is
# compatible with. This helps avoid breakage when a new Home Manager release
# introduces backwards incompatible changes.
#
# You should not change this value, even if you update Home Manager. If you do
# want to update the value, then make sure to first check the Home Manager
# release notes.
home.stateVersion = "23.11"; # Please read the comment before changing.
home.sessionVariables = {
BASH_SILENCE_DEPRECATION_WARNING = "1";
EDITOR = "vim";
LC_CTYPE = "en_US.UTF-8";
NODE_PATH = "$HOME/.npm-packages/lib/node_modules";
PATH = lib.concatStringsSep ":" pathComponents;
SHELL = "${pkgs.bashInteractive}/bin/bash";
TERM = "xterm-kitty";
VISUAL = "code --wait";
};
home.packages = with pkgs;
[
# Would love to have these on macOS too:
# github-desktop
# sonos
# whatsapp
_1password
awscli
bash-completion
bashInteractive
biome
bottom
btop
colima # You can use the 'docker' client on macOS after 'colima start' with no additional setup
coreutils
curl
diffutils
dnsutils
docker
exiftool
ffmpeg
fira-code
google-cloud-sdk
html2text
htop
imagemagick
inetutils
input-fonts
ipcalc
jq
mononoki
netcat
newt
ngrok
nix-bash-completions
nixfmt
nodejs_20
nodePackages.typescript
ollama
openssh
php
php81Packages.php-codesniffer
powerline
ruby
shellcheck
shfmt
spotify
tmux
unzip
vim
vscode
watch
wget
whois
yarn-bash-completion
zoom-us
] ++ lib.optionals (stdenv.isDarwin) [
# Would love to have these on macOS too:
# reeder
# pixelmator
# sequelace
cocoapods
iterm2
m-cli
pinentry_mac
raycast
rectangle-pro
] ++ lib.optionals (stdenv.isLinux) [
# Would love to have these on macOS too (these are Linux only for now):
brave
github-desktop
signal-desktop
] ++ lib.optionals
(stdenv.isDarwin && hostPlatform.config == "x86_64-apple-darwin") [
# Would love to have these on macOS too: (vagrant is there, but fails to compile right now, virtualbox only linux)
# vagrant
# virtualbox
] ++ lib.optionals
(stdenv.isDarwin && hostPlatform.config == "aarch64-apple-darwin") [ tart ];
# Let Home Manager install and manage itself.
programs.home-manager.enable = true;
programs.bash = {
# Note that by default your terminal will still run the shell
# provided by the OS, so we need to point it to Nix.
# For Kitty, this is done in this file, for iTerm2, you need to click:
# Profiles -> General -> Command -> Command: /Users/kvz/.nix-profile/bin/bash --login
enable = true;
enableCompletion = true;
historyControl = [ "ignorespace" "ignoredups" ];
shellOptions = [
# "cdspell"
"checkwinsize"
"histappend"
"histreedit"
"histverify"
"interactive_comments"
"lithist"
"nocaseglob"
"progcomp"
"promptvars"
"sourcepath"
];
shellAliases = {
".." = "cd ..";
yarn = "corepack yarn";
grep = "grep --color=auto";
e = ''
project="$(basename "$PWD")"
if [ ! -f ".vscode/$project.code-workspace" ]; then
mkdir .vscode
echo -e '{\n "folders": [\n {\n "path": ".."\n }\n ],\n "settings": {}\n}' > ".vscode/$project.code-workspace"
fi
code ".vscode/$project.code-workspace" &
git pull || true
yarn
'';
c = "cd ~/code/content";
a = "cd ~/code/api2";
p = "yarn run up && yarn run provision";
};
bashrcExtra = ''
. ${pkgs.powerline}/share/bash/powerline.sh
# Add location to tabs in iterm via Starship:
function set_win_title(){
local pwd_with_tilde="$(echo -n "$PWD" | sed "s|$HOME|~|g")"
echo -ne "\033]0; $pwd_with_tilde \007"
}
starship_precmd_user_func="set_win_title"
'';
};
programs.kitty = {
# https://sw.kovidgoyal.net/kitty/conf/
enable = true;
font = {
name = "Menlo";
# package = pkgs.fira-code;
size = 15;
};
# theme = "Everforest Dark Medium";
theme = "Dracula";
settings = {
shell = "${pkgs.bashInteractive}/bin/bash --login";
enable_audio_bell = false;
macos_titlebar_color = "system";
notify_on_cmd_finish = "unfocused";
tab_bar_style = "powerline";
tab_powerline_style = "slanted";
term = "xterm-kitty";
text_composition_strategy = "platform";
underline_hyperlinks = "always";
background_opacity = "0.95";
include = "current-theme.conf";
};
# Can't use the same config name (like 'map') more than once above,
# so we put the repeted ones here as an alternative:
extraConfig = ''
map cmd+enter launch --cwd=current;
map cmd+shift+left move_tab_backward
map cmd+shift+right move_tab_forward
map cmd+t new_tab_with_cwd
map cmd+1 goto_tab 1
map cmd+2 goto_tab 2
map cmd+3 goto_tab 3
map cmd+4 goto_tab 4
map cmd+5 goto_tab 5
map cmd+6 goto_tab 6
map cmd+7 goto_tab 7
map cmd+8 goto_tab 8
map cmd+9 goto_tab 9
map cmd+0 goto_tab 10
# mouse_map left click ungrabbed open_url_with default
'';
# ~Noob~ProTip1: to open relative file paths and line numbers referenced in logs
# or lint output, press (by default, kitty_mod is ctrl+shift):
# - ctrl+shift+p>n
# - the number of the occurence you want to open
# To insert the path into the terminal, press:
# - ctrl+shift+p>f
# To open hyperlinks (anchors) it is:
# - ctrl+shift+p>y
#
# ~Noob~ProTip2: if you want to search like CMD+F, instead you type
# - ctrl+shift+h
# which turns the scrollback into page search mode
shellIntegration = { enableBashIntegration = true; };
};
programs.starship = {
enable = true;
enableBashIntegration = true;
settings = {
add_newline = true;
format = lib.concatStrings [
"$shlvl"
"$shell"
"$username"
"$hostname"
"$nix_shell"
"$git_branch"
"$git_commit"
"$git_state"
"$git_status"
"$directory"
"$jobs"
"$cmd_duration"
"$character"
];
command_timeout = 2000;
right_format = lib.concatStrings [
"$git_branch"
"$git_commit"
"$git_state"
"$git_status"
"$directory"
"$hostname"
"$line_break"
"$status"
];
character = {
success_symbol = "[λ](bold green)";
error_symbol = "[λ](bold red)";
};
directory = {
truncation_length = 2;
style = "fg:242";
};
git_branch = {
format = "[$symbol$branch]($style) ";
symbol = " ";
style = "green";
};
gcloud.enabled = false;
aws.enabled = false;
php.enabled = false;
};
};
programs.git = {
enable = true;
userName = "Kevin van Zonneveld";
userEmail = "kevin@vanzonneveld.net";
aliases = {
co = "checkout";
st = "status -sb";
lol = "log --pretty=oneline --abbrev-commit --graph --decorate";
down =
"! git pull && git checkout main && git pull && git checkout - && git merge main";
conflicts = "diff --name-only --diff-filter=U";
};
difftastic = { enable = true; };
extraConfig = {
core = { editor = "vim"; };
init = { defaultBranch = "main"; };
push = { autoSetupRemote = true; };
pull = { rebase = true; };
commit = { gpgsign = true; };
color = { ui = true; };
gpg = {
# We sign commits via SSH keys. Note that you need to add your
# ~/.ssh/id_rsa.pub as a "Signing Key" at https://github.com/settings/ssh/new
# see: https://jeppesen.io/git-commit-sign-nix-home-manager-ssh/
#
format = "ssh";
ssh.allowedSignersFile = "~/.ssh/allowed_signers";
};
user = { signingkey = "~/.ssh/id_rsa.pub"; };
};
lfs = { enable = true; };
};
programs.gh = {
enable = true;
gitCredentialHelper = { enable = true; };
settings = {
editor = "code --wait";
aliases = {
co = "pr checkout";
pv = "pr view";
todo-meta =
"issue create --repo=transloadit/team-internals --project='🤖 The Board' --body='n/a' --assignee='@me'";
todo-founder =
"issue create --repo=transloadit/founder-internals --project='🤖 The Board' --body='n/a' --assignee='@me'";
todo-accounting =
"issue create --repo=transloadit/accounting --project='🤖 The Board' --body='n/a' --assignee='@me'";
todo-legal =
"issue create --repo=transloadit/legal --project='🤖 The Board' --body='n/a' --assignee='@me'";
todo-website =
"issue create --repo=transloadit/content --project='🤖 The Board' --body='n/a' --assignee='@me'";
todo-content =
"issue create --repo=transloadit/content --project='🤖 The Board' --body='n/a' --assignee='@me'";
todo-nix =
"issue create --repo=transloadit/api2 --project='🤖 The Board' --body='n/a' --assignee='@me'";
todo-api2 =
"issue create --repo=transloadit/api2 --project='🤖 The Board' --body='n/a' --assignee='@me'";
todo-growth =
"issue create --repo=transloadit/growth --project='🤖 The Board' --body='n/a' --assignee='@me'";
todo-botty =
"issue create --repo=transloadit/botty --project='🤖 The Board' --body='n/a' --assignee='@me'";
};
};
};
programs.thefuck = {
enable = true;
enableBashIntegration = true;
enableZshIntegration = false;
};
# Run a 'Docker daemon' in the background. You can check the resulting
# launch file in: ~/Library/LaunchAgents/colima.plist
# and logs with: tail -f ~/.colima/_lima/colima/*log /tmp/colima*log
#
# After a macOS release upgrade, I needed to:
# launchctl unload -w ~/Library/LaunchAgents/colima.plist
# colima delete -f
# rm -rf /Users/kvz/.colima/_lima/colima/
# launchctl load -w ~/Library/LaunchAgents/colima.plist
# tail -f ~/.colima/_lima/colima/*log /tmp/colima*log
launchd.agents.colima = {
enable = true;
config = {
Label = "colima";
ProgramArguments = [ "${pkgs.colima}/bin/colima" "start" "--foreground" ];
RunAtLoad = true;
EnvironmentVariables = {
# Join all our PATH components, and replace $HOME with the actual home dir:
PATH = lib.concatStringsSep ":" (map (path:
lib.replaceStrings [ "$HOME" ] [ config.home.homeDirectory ] path)
pathComponents);
};
# We should not log into where Colima's own logs are, as it will error on:
# instance \"colima\" already exists (\"/Users/kvz/.colima/_lima/colima\")"
# and refuse to bootstrap a VM
StandardOutPath = "/tmp/colima.out.log";
StandardErrorPath = "/tmp/colima.err.log";
KeepAlive = {
Crashed = true;
SuccessfulExit = false;
};
ProcessType = "Background";
};
};
home.activation.enableTouchIDForSudo = if pkgs.stdenv.isDarwin then enableTouchIDForSudo.text else "";
# This makes graphical UI Apps findable by Spotlight / Raycast
# since they cannot follow symlinks
# See: https://github.com/nix-community/home-manager/issues/1341
home.activation.aliasApplications =
lib.hm.dag.entryAfter [ "writeBoundary" ] ''
app_folder=$(echo ~/Applications);
[ -d $genProfilePath/home-path/Applications ] && find $genProfilePath/home-path/Applications -maxdepth 1 -type l -exec readlink '{}' + | while read app; do
$DRY_RUN_CMD rm -f "$app_folder/$(basename "$app")"
$DRY_RUN_CMD /usr/bin/osascript -e "tell app \"Finder\"" -e "make new alias file at POSIX file \"$app_folder\" to POSIX file \"$app\"" -e "set name of result to \"$(basename "$app")\"" -e "end tell"
done
'';
# Clear out this config, home-manager manages it in ~/.config/git/config
# and we don't want conflicts
home.activation.legacyDefeater = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
if [ -f $HOME/.gitconfig ]; then
mv -f $HOME/.gitconfig $HOME/gitconfig.backup
fi
'';
# Generate ssh key if not exists
home.activation.generateSSHKey = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
if [ ! -f $HOME/.ssh/id_rsa ]; then
echo "Generating SSH key for ${config.home.username}@$(${pkgs.inetutils}/bin/hostname)..."
${pkgs.openssh}/bin/ssh-keygen -t rsa -b 4096 -C "${config.home.username}@$(${pkgs.inetutils}/bin/hostname)" -f $HOME/.ssh/id_rsa -N ""
echo "SSH key generated. Public key is (add the contents as a key to https://github.com/settings/keys):"
cat $HOME/.ssh/id_rsa.pub
chmod 600 $HOME/.ssh/id_rsa*
fi
if [ ! -f $HOME/.ssh/allowed_signers ]; then
echo "Creating ~/.ssh/allowed_signers file..."
echo "* $(cat $HOME/.ssh/id_rsa.pub)" > $HOME/.ssh/allowed_signers
chmod 600 $HOME/.ssh/allowed_signers
fi
'';
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment