alejandr0angul0.dev/content/posts/dotfiles.md
alejandro-angulo c35a6fdfe5
Some checks failed
CI / lint (push) Failing after 5s
CI / build (push) Has been skipped
CI / deploy (push) Has been skipped
Updated github links to instead link to personal git server
2024-11-15 17:52:41 -08:00

176 lines
6.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

+++
title = "Dotfiles"
date = "2022-01-05T11:36:47-08:00"
author = "alejandro"
tags = ["info-dump"]
keywords = ["dotfiles"]
showFullContent = false
+++
Not too long ago I had completely different configurations across different
computers. Terminal color schemes between computers weren't consistent. Git was
configured slightly differently between all computers. Lucky for me, there's a
program that's well suited for this task:
[stow](https://www.gnu.org/software/stow/).
Special thanks to [Brandon Invergo](http://brandon.invergo.net/) for [his blog
post](http://brandon.invergo.net/news/2012-05-26-using-gnu-stow-to-manage-your-dotfiles.html)
documenting how he uses stow to manage dotfiles.
## Git & Stow
Before I found stow I was using a [purely git-based
workflow](https://git.alejandr0angul0.dev/alejandro-angulo/dotfiles-bak). It
worked but it was a little clunky keeping a git repo at the root of my home
directory. One minor annoyance was that the repo's README would show up in my
home directory whenever I ran `ls` (minor, I know, but it didn't feel _right_ to
me). I was always a little paranoid that I would accidentally commit some secret
inside of `~/.cache` too.
My [updated
workflow](https://git.alejandr0angul0.dev/alejandro-angulo/dotfiles/tree/0af75c92fdbf908f9445bfbaf5e07b0e223db97d)
still uses git but I no longer maintain a repo at the root of my home folder.
Instead, I use stow to manage symlinks for me. My directory structure is cleaner
now with a directory for each set of configuration files (below are my git and
[terminal emulator](https://alacritty.org/) configurations).
```zsh
tree -a git alacritty
git
└── .config
└── git
├── config
└── global_ignore
alacritty
└── .config
└── alacritty
└── alacritty.yml
4 directories, 3 files
```
Installing the configurations for those two programs is as easy as running `stow
-t ~ alacritty && stow -t ~ git`.
## Handling Plugins (and Plugin Managers)
There are some utilities ([vundle](https://github.com/VundleVim/Vundle.vim),
[base16-shell](https://github.com/chriskempson/base16-shell), [Oh My
ZSH](https://github.com/ohmyzsh/ohmyzsh), etc) that I want to have available
regardless of my underlying system's environment. I set up submodules in my git
repo for these utilities so that I have those utilities available without having
to go through my system's package manager (brew, apt, yay, etc).
As an added bonus, I can rely on plugin managers to pull in the bulk of my
dependencies without cluttering up my git repo with a bunch of submodules.
```zsh tree -a -L 3 vim
vim
├── .vim
│   ├── bundle
│   │   ├── ale
│   │   ├── base16-vim
│   │   ├── fzf
│   │   ├── fzf.vim
│   │   ├── nerdcommenter
│   │   ├── nerdtree
│   │   ├── tmuxline.vim
│   │   ├── vim-airline
│   │   ├── vim-airline-themes
│   │   ├── vim-devicons
│   │   ├── vim-fugitive
│   │   ├── vim-gitgutter
│   │   ├── vimspector
│   │   ├── vim-tmux-navigator
│   │   ├── vim-toml
│   │   └── Vundle.vim
│   └── ftplugin
│   ├── css.vim
│   ├── go.vim
│   ├── javascript.vim
│   ├── python.vim
│   ├── rust.vim
│   └── yaml.vim
├── .vimrc
└── .vimrc_background
19 directories, 8 files
git ls-files vim/.vim/bundle/
vim/.vim/bundle/Vundle.vim
```
Instead of setting up submodules for each individual vim plugin I only have a
submodule for vundle (a vim plugin manager) and then I run `vim +PluginInstall
+qall` to pull in my vim plugins.
## Special Snowflake Configurations
There are some cases where I don't want to use the exact same configuration
across all my devices. I've found that this situation comes up in one of two
cases:
- device-specific configuration
- environment-specific configuration
### Device-Specific Configurations
I have certain configurations that are device-specific. For example, I have a
`sway` configuration but there are slight differences between my laptop and
desktop because the output configuration isn't the same (one display vs multiple
displays). To handle this I have `sway-carbon` and `sway-gospel` directories in
my dotfiles repo.
```zsh
tree -a sway*
sway
└── .config
├── sway
│   ├── config
│   └── status
└── waybar
├── config
└── style.css
sway-carbon
└── .config
└── sway
└── includes
└── carbon
sway-gospel
└── .config
└── sway
└── includes
└── gospel
9 directories, 6 files
```
My main sway configuration has this line `include ~/.config/sway/includes/*`
which loads all files inside of `~/.config/sway/includes/`. My `sway-carbon` and
`sway-gospel` configurations will place the correct device-specific
configuration once stowed.
### Environment-Specific Configurations
I don't use the same set of programs on all my devices. Sometimes there's no
need to install something everywhere (I wouldn't use my sway configuration on a
device running OS X). Sometimes I just want to play around with a new program
first before deciding it's something that I want to install everywhere.
For example, I wanted to try out [delta](https://github.com/dandavison/delta)
for pretty git output on a personal device. The configuration for delta requires
changes to git's configuration file which depend on having `delta` in `$PATH`.
To prevent breaking things on devices, like my work computer or one of my
raspberry pi's, I updated git's configuration so that there would be fallback.
```ini
[pager]
diff = "$(which delta 2>/dev/null) | less"
log = "$(which delta 2>/dev/null) | less"
reflog = "$(which delta 2>/dev/null) | less"
show = "$(which delta 2>/dev/null) | less"
```
So now on devices with delta installed that'll be used, otherwise less will be
used.