Credit: @mathiasbynens for the initial repo structure credit. I believe I used other references that I can't remember at the moment. I then added my own customizations with a lot of help from GPT/Claude to really make it my own and will continue to maintain this repo + grow it as I think of other things I want to add.
Why/what are .dotfiles
?
.dotfiles
are configuration files for OS/application/developer/etc related configurations that are useful to set if you find yourself resetting or using new computers semi-often. They allow you to set once (but also additionally over time when you change things) and benefit in the future when something happens to your computer.
If you've setup multiple computers over the span of a few years, you know how annoying it is to:
- Open Safari
- Download and install Chrome
- Proceed to download every application you had prior
- Go through your macOS preferences to enable dark-mode, invert scrolling, and all other preferences you had
- ...etc
You can automate these with .dotfiles
.
Most developers/computer affaciandos use them. @mathiasbynens is a popular repository to see a very detailed setup, but I recommend only using with settings you know of from that repository... It's very easy to enable a ton of settings that look good based on the comments in a file but then realize you made a big mistake are not able to rollback. Only take preferences you recognize and run a search on the web for the ones you need and aren't listed.
Project File Tree
├── .aliases
├── .env
├── .env.example
├── .git
├── .gitconfig
├── .gitignore
├── .macos
├── .zshrc
├── Brewfile
├── README.md
├── brewfile_work_tbd
├── install.sh
└── scripts
└── git-diff-openai.sh
Highlights from my ~/.dotfiles
The repository and its README.md
are the best source for diving in and using, but let me call out some highlights:
./install.sh
script for installing the repo + symlinking each file in~/.dotfiles
into your HOME root~/
.- Symlinking seemed to be the best route as you will probably have dotfiles specific to your
~/.dotfiles
repo and don't want these to be copied globally! You'll have to adjust the./install.sh
script accordingly to not symlink specific files.
- Symlinking seemed to be the best route as you will probably have dotfiles specific to your
.aliases
file with some handy utils that I took from that aforementioned repository.alias initialize="source ~/.zshrc"
You can runinitialize
from the command line and it will run all your dotfiles for your current command prompt. This runs automatically though within~/.zshrc
Remember, when I say
~/.zshrc
this is the same file as~/.dotfiles/.zshrc
. That./install.sh
script creates a symlink in your HOME root.
Brewfile
that lists common command line tools or applications that can be installed almost immediately when running the./install.sh
script!.gitconfig
with a ton of little git alias shortcuts. Below are some of my favorites:git rebaseBranch
this one rebases your current branch with whatever themain/dev/master
branch is for the repository. It could be named better since you might want to rebase with another branch instead though.git resetfile <file_name>
This command resets whatever file you pass to it with the counterpart on the remote'smain/dev/master
branch.git findlogs
andgit findtodos
findsconsole.logs
and#Todo: syntax
within your code.git stage-commit-push -m <commit_msg>
This command stages all, commits, and pushes all to remote. This uses the previous two commands as validation. If it finds logs or todo messages in the edited files, it will fail, but you can tack on a--no-verify
likegit stage-commit-push -m <commit_msg> --no-verify
and it will commit and not worry about those messages.git temp
quickly commits all locally without pushing to remote with a 'TEMP' commit message. I personally hate stashing code because you can't stash new files so this is my way around that.git dm
deletes branches locally that already have been merged.git open
opens up the repository on GitHub (doesn't work with other hosts). You might want to delete this one and use Paul Irish's version. Mine was inspired by his. I think I just wanted it to live in the same file as the other git config aliases so I made my own.git scpai
stands forgit stage-commit-push-AI
. I will be updating this one quite a bit as there are some little niceties that I want to add here. But this is my favorite at the moment. It uses OpenAI's API to generate a commit off thegit diff
with conventional commit terminology (you'll need an OpenAI API key to use this though...). It has an optional-m
commit flag if you need to pass something specific.
git scpai
Warning: You have unstaged changes
Here are your current changes:
M Brewfile
Would you like to stage all changes? (y/n): y
Analyzing changes and generating commit message...
-e
Proposed commit message:
feat(Brewfile): add new tap oven-sh/bun
Accept this commit message? (y/n): y
[main 93c6cff] feat(Brewfile): add new tap oven-sh/bun
1 file changed, 1 insertion(+)
Changes committed successfully
Pushing to remote...
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 14 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 331 bytes | 331.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
To github.com:benjaminmodayil/dotfiles.git
4665f25..93c6cff main -> main
Changes pushed successfully
Other defaults worth noting in ~/.gitconfig
:
[branch]
sort = -committerdate
[push]
default = current
autoSetupRemote = true
[pull]
rebase = true
.zshrc
In ~.zshrc
there are quite a few things at work, but honestly not all are needed and might be overkill.
check_tool
function that verifies if a tool that your .dotfiles
might depend on.
Example:
check_tool "brew" 'curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh | bash; echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zshrc; source ~/.zshrc'
This just verifies if a tool like brew
is installed and if not, it will prompt you with a install command. You'll want to customize these with tools your .dotfiles
depend on, but either way you'll quickly run into issues and will be able to fix them if you were to delete this function. The only purpose is to streamline things for setting up a computer.
.zshrc
file extensions
setopt NULL_GLOB # Prevents error when no matches are found
if ls "$HOME"/.zshrc.* 1> /dev/null 2>&1; then
for config in "$HOME"/.zshrc.*; do
if [ -f "$config" ] && [ "$config" != "$HOME/.zshrc.swp" ]; then
source "$config"
fi
done
fi
unsetopt NULL_GLOB # Reset to default behavior
Say you need a custom .zshrc
extension because you have a different context. For example, you're using a work computer but want to extend your base .zshrc
file. Other files in the ~/.dotfiles
folder don't support this, but if you wanted to you can create a .zshrc.work
file and that will be appended to anything in your base .zshrc
file.
.env
for sensitive variables
The other bit worth mentioning would be the .env
file that gets copied from the .env.example
after you run the ./install.sh
command. A bit self-explanatory, but great if you ever need to reference something like an API key. There's only one in there for that git scpai
command I mentioned earlier because it relies on OpenAI's API service.