Here, you'll find my dotfiles configuration for fish shell on macOS managed using GNU Stow. You'll also find files for provisioning a new machine and setting up my environment. Again, this is my personal setup and changes often, so don't blindly fork and run the install.sh
script without reading it first. But get inspired, take what you want, and leave the rest to make it your own.
Table of Contents:
Prerequisites ↑
Install with a single line...
I have not tested this on a fresh install, so this could break your setup. I'd suggest you read through the bootstrap.sh
and install.sh
scripts and the Makefile
before running this command.
In theory, this will clone the repository and install everything outlined below. Again, In theory.
bash -c "`curl -fsSL https://raw.githubusercontent.com/edheltzel/dotfiles/master/bootstrap.sh`"
Resources & Inspiration for the help
Below are the resources I used to get to this point in my setup.
Caveats for non-Apple Silicon (Intel)
If you are on any version of macOS that uses AFPS, you'll need to disable the SIP. First check to see if SIP is enabled or not.csrutil status
output should read:
System Integrity Protection status: enabled.
If your SIP is enabled, then follow the next steps to disable it – Assuming that you know what you're doing, here is how to turn off System Integrity Protection on your Mac.
- Turn off your Mac (Apple > Shut Down).
- Hold down Command-R and press the Power button. Keep holding Command-R until the Apple logo appears.
- Wait for OS X to boot into the OS X Utilities window.
- Choose Utilities > Terminal.
- Enter csrutil disable.
- Enter reboot.
csrutil status
-> should readSystem Integrity Protection status: disabled.
👋 For future Mr EdHeltzel↑
Since we have a bad habit of forgetting things - see Troubleshooting:
-
Installing Xcode Command Line Tools
sudo softwardupdate -i -a && xcode-select --install
This will installgit
andmake
if not already installed.
-
Generate a new SSH key and add to GitHub
- Generate a new ssh keys
eval "$(ssh-agent -s)" && ssh-add --apple-use-keychain ~/.ssh/id_ed25519
-
Clone repo
git clone https://github.com/edheltzel/dotfiles.git ~/.dotfiles
-
Use the
Makefile
for the rest of the setupcd ~/.dotfiles && make install
- Alternatively, run install script
cd ~/.dotfiles && ./install.sh
-
After the setup is complete, run
upp
to execute topgrade and update everything.upp
is an alias fortopgrade
which is Update Packages (this is what I say to myself).- The
topgrade.toml
includes[post_commands]
for additional Brew and Node updates.
-
Optional steps for DX and nice to haves:
- Disable Gatekeeper when installing apps:
sudo spctl --master-disable
(in macos/security.sh) - Make sure to run
fnm env --use-on-cd | source
to enable auto-switching of Node versions. (in fish)
- Disable Gatekeeper when installing apps:
The Nitty Gritty ↑
Originally, I used a series of custom scripts to create symlinks, and it worked, but I've since switched to using GNU Stow. This is way easier to manage.
So, with the addition of GNU Stow, I added a makefile
– I treat this like NPM scripts. You need to be in the root of ~/.dotfiles
to execute any of the make
tasks.
The following are available:
help Show this help message (default)
install Bootstraps a new machine
run Symlink all dotfiles w/Stow
stow Add individual packages w/Stow
unstow Remove individual packages w/Stow
delete Delete all dotfiles w/Stow
update Sync & clean dead symlinks w/Stow
Bootstrapping
make install
task, it will execute thebootstrap.sh
script. This script, is for setting up a brand new machine, it will install the necessary package managers, packages with dependencies, applications, clone the necessary repositories, configure the~/.gitconfig.local
and symlink dotfiles using GNU Stow.
Stowing/Unstowing (add/remove)
There are two options for managing packages with GNU Stow:
- Just use Stow:
stow nvim
/stow --restow nvim
orstow -D nvim
(unstow) - Use the Makefile:
make stow pkg=nvim
ormake unstow pkg=nvim
- The
pkg=
variable must be specified.
- The
- dots (dots/)
- misc dotfiles that are stored in the $HOME directory
- git (git/)
- git configuration
- zsh (zsh/)
- Zsh configuration files (this kind of sort of mimics fish - WIP)
- fish (fish/)
- XDG Base Directory – Reference: XDG Base Directory for more information. To edit/set the XDG Base Directory variables, you can edit the
~/fish/.config/fish/conf.d/paths.fish
file. Hopefully, this will keep the$HOME
directory clean and organized.
- XDG Base Directory – Reference: XDG Base Directory for more information. To edit/set the XDG Base Directory variables, you can edit the
- nvim (nvim/)
- When I need Vim, I use LazyVim - lightly customized.
- config (config/)
- Configuration files for various applications, instead of adding them to root of the repo.
- local (local/)
- User-specific data not configuration-related. ie: dictionaries, wallpapers, misc items that mean nothing, etc.
Scripts ↑
Any of the scripts can be run individually at any time to update/reset as needed. ie: cd ~/.dotfiles && ./duti/duti.sh
- macObS (macos/)
macos.sh
- Executes a long list of commands pertaining to macOS Preferences – DO NOT blindly run this script - it is a WIP with each macOS update things change.
- packages (packages/)
packages.sh
- Installs the Brewfile and each package manager's packages based on the.txt
files.
- repositories (repos/)
repos.sh
- Clones the repositories in the.txt
files at the corresponding locations
- private (private/)
private.sh
- Left empty on purpose
- duti (duti/)
duti.sh
- Sets the default applications for file types- run
./duti/duti.sh
to reset the default applications for file types
- run
- Helper Scripts (scripts/)
functions.sh
- Contains helper functions for for the scripts
MacOS Mods ↑
Aerospace Window Manager ↑
Sketchybar ↑
Karabiner Elements ↑
Troubleshooting ↑
Dotfiles↑
Fish: Fisher Plugin Manager
In the past, Fisher (fish plugin manager) would do something weird or introduce a breaking change - just reinstall Fisher.curl -sL https://raw.githubusercontent.com/jorgebucaran/fisher/main/functions/fisher.fish | source && fisher install jorgebucaran/fisher
Node Development: FNM
Node Version switching for Node development, takes advantage of fnm for managing Node versions, which supports both .nvmrc
and .node-version
files.
- If not already installed from the Brewfile, install
fnm
:
brew install fnm
fnm env --use-on-cd | source
For Fish Completions run:
fnm completions --shell fish
Make sure you run:
make update #updates all stow packages
OR
make stow pkg=fish
Enable auto switch of Node versions with .node-version
or .nvmrc
files
# auto runs: fnm use
fnm env --use-on-cd | source
Which each Node version change, enabling corepack
is necessary to ensure that pnpm
and yarn
are available.
npm install --global $(cat node_packages.txt)
Git: Commit and Tag Signing
SSH Signing
I use SSH commit signing over GPG. GPG is there if I need it, but I prefer SSH. For a few resources to help get this setup:
The .gitconfig
includes .gitconfig.local
[meta]
isLocalConfig = true
[user]
signingkey = PATH_TO_YOUR_KEY
[gpg "ssh"]
allowedSignersFile = PATH_TO_YOUR_ALLOWED_SIGNERS_FILE
If you choose to use this, make sure you look at that ./git/git.sh
; this script is where the provisioning of .gitconfig.local
happens.
GPG Commit Signing - optional
GPG signing is set to TRUE
by default. If you rather not enable GPG then execute: git config --global commit.gpgsign false
and remove the GPG packages from the Brewfile.
Generate new key and assign to global git config
main take away:
gpg --list-secret-keys --keyid-format=long
- Copy key
- set key for your git user
git config --global user.signingkey <your key>
- If you need help setting this up GPG:
- follow the Github article for Signing Commits to set up you GPG key(s).
- I found this GIST helpful
- To get VSCode setup follow this article
- Please Note if you used the Brewfile, Cask installed the macOS GPG Suite via
cask 'gpg-suite-no-mail'
-- (alternatively) update the Brewfile with `cask 'gpg-suite' to include GPGMail.
Rust and Cargo
From time to time, `cargo` will fail to update/upgrade using `topgrade`. This is generally due to something changing inside of the Rust system that doesn't allow `cargo install cargo-update` to work.The solution:
Uninstall and reinstall rust
and rustup-init
along with cargo
using brew
.
brew uninstall rustup-init;
and brew reinstall rust;
and cargo uninstall cargo;
cargo install cargo-update --force;
topgrade --only cargo
SSH Agent
In the even when restarting macOS, the SSH agent will not be running, even though it is configured to run on login. A result of this is that Git will keep asking for your SSH Passphrase, to resolve this you will need to execute the following:eval ssh-agent;
and ssh-add --apple-use-keychain
What this does: Starts the SSH agent and adds the SSH key to the keychain.
Since we are using danhper/fish-ssh-agent to manage the SSH agent, we only have to run this once.
MacOS↑
I include this website in 01-preferences.sh
- it's a great resource to see what the default key repeat rate will be. fs
WindowServer RAM Leak
As of `2024-07` there is a known bug/issue with macOS where the WindowServer will consume CPU and/or Memory. It is annoying. From my experience, this is related to more than one external monitor. My current workaround is to kill the WindowServer on macOS, which logs you out. Once you log back in the WindowServer will be restarted and your RAM usage will be back in normal ranges. This is a workaround until Apple fixes the issue, which will probably never happen. Usage:- Open your Terminal
- run `killws` (work for both Fish and Zsh)
- Log back into your account
Media Control Keys
From time to time some of the "nice-to-have" features of MacOS break. An example of this is when the media keys stop working for one reason or another; Google Chrome/WhatsApp/ can and generally hijack the media keys.To resolve this just run the following command in the terminal:
launchctl load -w /System/Library/LaunchAgents/com.apple.rcd.plist
This luanchctl
will reenable media key, which in turn will control Spotify 🙂
Ethernet Backhaul
Run the `flashEthernet` function to "flush" the Ethernet backhaul.flashEthernet; and echo 'Ethernet backhaul flushed'
speedtest
TODOs ↑
- Consider using Home Manager for package management.
- Convert fish functions to zsh functions - WIP
- zsh completions seem to be broken issue #40
- Look into zsh-completions vs autocomplete
- include zsh abbreviations
- Create a single-line install script to execute bootstrap.sh
- use makefile to execute bootstrap.sh and install.sh
- update make unstow to include only the available stow package or all
- add customizations to lazyvim
- Add vscode settings and symlink to dotfiles
- Add XDG Base Directory support
- update README
- include XDG info
- include Stow info
- include Make info
- include New bootstrap process
- include New install process (makefile)