mirror of
https://github.com/davegallant/davegallant.github.io.git
synced 2025-08-05 08:13:40 +00:00
314 lines
15 KiB
HTML
314 lines
15 KiB
HTML
<!DOCTYPE html>
|
|
<html><head>
|
|
<meta charset="utf-8" />
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge"><title>Why I Threw Out My Dotfiles - davegallant</title><link rel="icon" type="image/png" href=https://davegallant.ca/favicon.ico /><meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<meta name="description" content="" />
|
|
<meta property="og:image" content=""/>
|
|
<meta property="og:title" content="Why I Threw Out My Dotfiles" />
|
|
<meta property="og:description" content="" />
|
|
<meta property="og:type" content="article" />
|
|
<meta property="og:url" content="/blog/2021/09/08/why-i-threw-out-my-dotfiles/" /><meta property="article:section" content="post" />
|
|
<meta property="article:published_time" content="2021-09-08T00:42:33-04:00" />
|
|
<meta property="article:modified_time" content="2021-09-08T00:42:33-04:00" />
|
|
|
|
<meta name="twitter:card" content="summary"/>
|
|
<meta name="twitter:title" content="Why I Threw Out My Dotfiles"/>
|
|
<meta name="twitter:description" content=""/>
|
|
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
|
|
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@1,500&display=swap" rel="stylesheet">
|
|
<link href="https://fonts.googleapis.com/css2?family=Fira+Sans&display=swap" rel="stylesheet">
|
|
<link href="https://fonts.googleapis.com/css?family=Roboto+Mono" rel="stylesheet">
|
|
|
|
|
|
<link rel="stylesheet" type="text/css" media="screen" href="/css/main.0e5aa3b634b92d61bafebfd908290cc7a034e4d50e6a0c59ce50044560179c4e.css" />
|
|
<link id="darkModeStyle" rel="stylesheet" type="text/css" href="/css/dark.b11f422ffce8151207bad84653d44cb512043f9efe93a0a049f836b9cc32b34a.css" disabled />
|
|
|
|
|
|
|
|
|
|
<script type="text/javascript"
|
|
src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
|
|
</script>
|
|
|
|
|
|
<script type="text/x-mathjax-config">
|
|
MathJax.Hub.Config({
|
|
tex2jax: {
|
|
inlineMath: [['$','$'], ['\\(','\\)']],
|
|
displayMath: [['$$','$$'], ['\[','\]']],
|
|
processEscapes: true,
|
|
processEnvironments: true,
|
|
skipTags: ['script', 'noscript', 'style', 'textarea', 'pre'],
|
|
TeX: { equationNumbers: { autoNumber: "AMS" },
|
|
extensions: ["AMSmath.js", "AMSsymbols.js"] }
|
|
}
|
|
});
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.15.2/dist/katex.min.css">
|
|
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.15.2/dist/katex.min.js"></script>
|
|
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.15.2/dist/contrib/auto-render.min.js" onload="renderMathInElement(document.body);"></script>
|
|
|
|
|
|
<script>
|
|
document.addEventListener("DOMContentLoaded", function() {
|
|
renderMathInElement(document.body, {
|
|
delimiters: [
|
|
{left: "$$", right: "$$", display: true},
|
|
{left: "$", right: "$", display: false}
|
|
]
|
|
});
|
|
});
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<link rel="stylesheet" type="text/css" href="/css/custom.2e59ff60a2d9c7e42e3c1af2aff0ba627da46f910a234867e98d178eb05c87dc.css">
|
|
|
|
</head>
|
|
<body>
|
|
<div class="content"><header>
|
|
<div class="main">
|
|
<a href="/">davegallant</a>
|
|
</div>
|
|
<nav>
|
|
|
|
<a href="/">Home</a>
|
|
|
|
<a href="/post">All posts</a>
|
|
|
|
<a href="/index.xml">RSS</a>
|
|
|
|
<a href="/tags">Tags</a>
|
|
|
|
<a href="/about">About</a>
|
|
|
|
| <span id="dark-mode-toggle" onclick="toggleTheme()"></span>
|
|
<script src="/js/themetoggle.js"></script>
|
|
|
|
</nav>
|
|
</header>
|
|
|
|
<main>
|
|
<article>
|
|
<div class="title">
|
|
<h1 class="title">Why I Threw Out My Dotfiles</h1>
|
|
<div class="meta">Posted on Sep 8, 2021</div>
|
|
</div>
|
|
|
|
|
|
<section class="body"><p>Over the years I have collected a number of dotfiles that I have shared across both Linux and macOS machines (<code>~/.zshrc</code>, <code>~/.config/git/config</code>, <code>~/.config/tmux/tmux.conf</code>, etc). I have tried several different ways to manage them, including <a href="https://www.atlassian.com/git/tutorials/dotfiles">bare git repos</a> and utilities such as <a href="https://www.gnu.org/software/stow/">GNU Stow</a>. These solutions work well enough, but I have since found what I would consider a much better solution for organizing user configuration: <a href="https://github.com/nix-community/home-manager">home-manager</a>.</p>
|
|
<h2 id="what-is-home-manager">What is home-manager?<a href="#what-is-home-manager" class="hanchor" ariaLabel="Anchor">#</a></h2>
|
|
<p>Before understanding home-manager, it is worth briefly discussing what nix is. <a href="https://nixos.org/">nix</a> is a package manager that originally spawned from a <a href="https://edolstra.github.io/pubs/phd-thesis.pdf">PhD thesis</a>. Unlike other package managers, it uses symbolic links to keep track of the currently installed packages, keeping around the old ones in case you may want to rollback.</p>
|
|
<p>For example, I have used nix to install the package <a href="https://search.nixos.org/packages?channel=unstable&show=bind&from=0&size=50&sort=relevance&type=packages&query=bind">bind</a> which includes <code>dig</code>. You can see that it is available on multiple platforms. The absolute path of <code>dig</code> can be found by running:</p>
|
|
<pre><code class="language-console">$ ls -lh $(which dig)
|
|
lrwxr-xr-x 73 root 31 Dec 1969 /run/current-system/sw/bin/dig -> /nix/store/0r4qdyprljd3dki57jn6c6a8dh2rbg9g-bind-9.16.16-dnsutils/bin/dig
|
|
</code></pre>
|
|
<p>Notice that there is a hash included in the file path? This is a nix store path and is computed by the nix package manager. This <a href="https://nixos.org/guides/nix-pills/nix-store-paths.html">nix pill</a> does a good job explaining how this hash is computed. All of the nix pills are worth a read, if you are interested in learning more about nix itself. However, using home-manager does not require extensive knowledge of nix.</p>
|
|
<p>Part of the nix ecosystem includes <a href="https://github.com/NixOS/nixpkgs">nixpkgs</a>. Many popular tools can be found already packaged in this repository. As you can see with these <a href="https://repology.org/repositories/statistics/total">stats</a>, there is a large number of existing packages that are being maintained by the community. Contributing a new package is easy, and anyone can do it!</p>
|
|
<p>home-manager leverages the nix package manager (and nixpkgs), as well the nix language so that you can declaratively define your system configuration. I store my <a href="https://github.com/davegallant/nix-config">nix-config</a> in git so that I can keep track of my packages and configurations, and retain a clean and informative git commit history so that I can understand what changed and why.</p>
|
|
<h2 id="setting-up-home-manager">Setting up home-manager<a href="#setting-up-home-manager" class="hanchor" ariaLabel="Anchor">#</a></h2>
|
|
<blockquote>
|
|
<p>⚠️ If you run this on your main machine, make sure you backup your configuration files first. home-manager is pretty good about not overwriting existing configuration, but it is better to have a backup! Alternatively, you could test this out on a VM or cloud instance.</p>
|
|
</blockquote>
|
|
<p>The first thing you should do is <a href="https://nixos.org/guides/install-nix.html">install nix</a>:</p>
|
|
<pre><code class="language-shell">curl -L https://nixos.org/nix/install | sh
|
|
</code></pre>
|
|
<p>It’s generally not a good idea to curl and execute files from the internet (without verifying integrity), so you might want to download the install script first and take a look before executing it!</p>
|
|
<p>Open up a new shell in your terminal and running <code>nix</code> <em>should</em> work. If not, run <code>. ~/.nix-profile/etc/profile.d/nix.sh</code></p>
|
|
<p>Now, <a href="https://github.com/nix-community/home-manager#installation">install home-manager</a>:</p>
|
|
<pre><code class="language-shell">nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager
|
|
nix-channel --update
|
|
nix-shell '<home-manager>' -A install
|
|
</code></pre>
|
|
<p>You should see a wave of <code>/nix/store/*</code> paths being displayed on your screen.</p>
|
|
<p>Now, to start off with a basic configuration, open up <code>~/.config/nixpkgs/home.nix</code> in the editor of your choice and paste this in (you will want to change <code>userName</code> and <code>homeDirectory</code>):</p>
|
|
<pre><code class="language-nix">{ config, pkgs, ... }:
|
|
|
|
{
|
|
programs.home-manager.enable = true;
|
|
|
|
home = {
|
|
username = "dave";
|
|
homeDirectory = "/home/dave";
|
|
stateVersion = "21.11";
|
|
packages = with pkgs; [
|
|
bind
|
|
exa
|
|
fd
|
|
ripgrep
|
|
];
|
|
};
|
|
|
|
programs = {
|
|
|
|
git = {
|
|
enable = true;
|
|
aliases = {
|
|
aa = "add -A .";
|
|
br = "branch";
|
|
c = "commit -S";
|
|
ca = "commit -S --amend";
|
|
cb = "checkout -b";
|
|
co = "checkout";
|
|
d = "diff";
|
|
l =
|
|
"log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit";
|
|
};
|
|
|
|
delta = {
|
|
enable = true;
|
|
|
|
options = {
|
|
features = "line-numbers decorations";
|
|
whitespace-error-style = "22 reverse";
|
|
plus-style = "green bold ul '#198214'";
|
|
decorations = {
|
|
commit-decoration-style = "bold yellow box ul";
|
|
file-style = "bold yellow ul";
|
|
file-decoration-style = "none";
|
|
};
|
|
};
|
|
};
|
|
|
|
extraConfig = {
|
|
push = { default = "current"; };
|
|
pull = { rebase = true; };
|
|
};
|
|
|
|
};
|
|
|
|
starship = {
|
|
enable = true;
|
|
enableZshIntegration = true;
|
|
|
|
settings = {
|
|
add_newline = false;
|
|
scan_timeout = 10;
|
|
};
|
|
};
|
|
|
|
zsh = {
|
|
enable = true;
|
|
enableAutosuggestions = true;
|
|
enableSyntaxHighlighting = true;
|
|
history.size = 1000000;
|
|
|
|
localVariables = {
|
|
CASE_SENSITIVE = "true";
|
|
DISABLE_UNTRACKED_FILES_DIRTY = "true";
|
|
RPROMPT = ""; # override because macOS defaults to filepath
|
|
ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE = "fg=#838383,underline";
|
|
ZSH_DISABLE_COMPFIX = "true";
|
|
};
|
|
|
|
initExtra = ''
|
|
export PAGER=less
|
|
'';
|
|
|
|
shellAliases = {
|
|
".." = "cd ..";
|
|
grep = "rg --smart-case";
|
|
ls = "exa -la --git";
|
|
};
|
|
|
|
"oh-my-zsh" = {
|
|
enable = true;
|
|
plugins = [
|
|
"gitfast"
|
|
"last-working-dir"
|
|
];
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
}
|
|
</code></pre>
|
|
<p>Save the file and run:</p>
|
|
<pre><code>home-manager switch
|
|
</code></pre>
|
|
<p>You should see another wave of <code>/nix/store/*</code> paths. The new configuration should now be active.</p>
|
|
<p>If you run <code>zsh</code>, you should see that you have <a href="https://starship.rs/">starship</a> and access to several other utils such as <code>rg</code>, <code>fd</code>, and <code>exa</code>.</p>
|
|
<p>This basic configuration above is also defining your <code>~/.config/git/config</code> and <code>.zshrc</code>. If you already have either of these files, home-manager will complain about them already existing.</p>
|
|
<p>If you run <code>cat ~/.zshrc</code>, you will see the way these configuration files are generated.</p>
|
|
<p>You can extend this configuration for programs such as (neo)vim, emacs, alacritty, ssh, etc. To see other programs, take a look at <a href="https://github.com/nix-community/home-manager/tree/master/modules/programs">home-manager/modules/programs</a>.</p>
|
|
<h2 id="gateway-to-nix">Gateway To Nix<a href="#gateway-to-nix" class="hanchor" ariaLabel="Anchor">#</a></h2>
|
|
<p>In ways, home-manager can be seen as a gateway to the nix ecosystem. If you have enjoyed the way you can declare user configuration with home-manager, you may be interested in expanding your configuration to include other system dependencies and configuration. For example, in Linux you can define your entire system’s configuration (including the kernel, kernel modules, networking, filesystems, etc) in nix. For macOS, there is <a href="https://github.com/LnL7/nix-darwin">nix-darwin</a> that includes nix modules for configuring launchd, dock, and other preferences and services. You may also want to check out <a href="https://nixos.wiki/wiki/Flakes">Nix Flakes</a>: a more recent feature that allows you declare dependencies, and have them automatically pinned and hashed in <code>flake.lock</code>, similar to that of many modern package managers.</p>
|
|
<h2 id="wrapping-up">Wrapping up<a href="#wrapping-up" class="hanchor" ariaLabel="Anchor">#</a></h2>
|
|
<p>The title of this post is slightly misleading, since it’s possible to retain some of your dotfiles and have them intermingle with home-manager by including them alongside nix. The idea of defining user configuration using nix can provide a clean way to maintain your configuration, and allow it to be portable across platforms. Is it worth the effort to migrate away from shell scripts and dotfiles? I’d say so.</p></section>
|
|
|
|
<div class="post-tags">
|
|
|
|
|
|
<nav class="nav tags">
|
|
<ul class="tags">
|
|
|
|
<li><a href="/tags/nix">nix</a></li>
|
|
|
|
<li><a href="/tags/dotfiles">dotfiles</a></li>
|
|
|
|
<li><a href="/tags/home-manager">home-manager</a></li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
|
|
</div>
|
|
</article>
|
|
</main>
|
|
|
|
<section id='comments' class='comments'>
|
|
<div class='container sep-before'>
|
|
<div class='comments'><script>
|
|
|
|
var getTheme = window.localStorage && window.localStorage.getItem("theme-storage");
|
|
getTheme = getTheme == null ? 'light' : getTheme;
|
|
|
|
let theme = getTheme === 'dark' ? 'github-dark' : 'github-light';
|
|
let s = document.createElement('script');
|
|
s.src = 'https://utteranc.es/client.js';
|
|
s.setAttribute('repo', 'davegallant\/davegallant.github.io');
|
|
s.setAttribute('issue-term', 'pathname');
|
|
s.setAttribute('theme', theme);
|
|
s.setAttribute('crossorigin', 'anonymous');
|
|
s.setAttribute('async', '');
|
|
document.querySelector('div.comments').innerHTML = '';
|
|
document.querySelector('div.comments').appendChild(s);
|
|
</script>
|
|
</div>
|
|
</div>
|
|
</section><footer>
|
|
<div style="display:flex"><a class="soc" href="https://github.com/davegallant" rel="me" title="GitHub"><i data-feather="github"></i></a>
|
|
<a class="border"></a><a class="soc" href="https://twitter.com/davega11ant/" rel="me" title="Twitter"><i data-feather="twitter"></i></a>
|
|
<a class="border"></a><a class="soc" href="https://mastodon.social/@davegallant" rel="me" title="Mastodon"><i data-feather="speaker"></i></a>
|
|
<a class="border"></a><a class="soc" href="https://www.linkedin.com/in/dave-gallant/" rel="me" title="LinkedIn"><i data-feather="linkedin"></i></a>
|
|
<a class="border"></a></div>
|
|
<div class="footer-info">
|
|
2023 Dave Gallant
|
|
</div>
|
|
</footer>
|
|
|
|
|
|
<script async src="https://www.googletagmanager.com/gtag/js?id=G-V8WJDERTX9"></script>
|
|
<script>
|
|
var doNotTrack = false;
|
|
if (!doNotTrack) {
|
|
window.dataLayer = window.dataLayer || [];
|
|
function gtag(){dataLayer.push(arguments);}
|
|
gtag('js', new Date());
|
|
gtag('config', 'G-V8WJDERTX9', { 'anonymize_ip': false });
|
|
}
|
|
</script>
|
|
|
|
<script>
|
|
feather.replace()
|
|
</script></div>
|
|
</body>
|
|
</html>
|