Here you can find my dotfiles and configurations that I use on my macOS system. I have been using these configurations for a while now, and I am quite happy with them. I have tried to keep the configurations as simple as possible, so that they can be easily understood and modified.
Note
I have recently switched to macOS, so I am still in the process of setting up my system. I will update this repository as I make changes.
This repository contains dotfiles and configuration settings for:
- Fish: My shell of choice.
- Ghostty: A fast, feature-rich, and cross-platform terminal emulator.
- Rex: Terminal multiplexer to manage sessions, tabs and panes.
- Neovim: My text editor of choice for terminal.
- Starship: A minimal, fast, and customizable prompt for any shell.
- Hammerspoon: A powerful automation tool for macOS.
- Karabiner-Elements: Keyboard customizer for macOS.
- Git: My version control of choice.
- Claude Code: Global settings, agents, commands and skills.
- ... and various other tools that boost my productivity!
To install the configurations, you need to clone the repository and follow the next steps in this README file.
On macOS I use Homebrew as my package manager, so here you can find a Brewfile that contains all taps, brews, casks & vscode extensions that I use. To install the packages, you can run the following command in the terminal.
Note
Make sure to install Homebrew before running the following commands. You can find more information about Homebrew on their website.
brew bundle --file=BrewfileAfter installing the packages, I run the following command to clean up the cache and remove old versions of the packages.
brew bundle cleanup --file=Brewfile --forceTo keep all packages up to date automatically, I use the homebrew/autoupdate tap. It runs brew upgrade and brew cleanup every 24 hours in the background via launchd. To enable it, run the following command in the terminal.
brew autoupdate start 86400 --upgrade --cleanupI use GNU Stow to manage my dotfiles. It is a simple tool that symlinks files from one directory to another. This makes it easy to manage dotfiles across multiple systems. To install GNU Stow, you can run the following command in the terminal.
Warning
Make sure that you are in the dotfiles directory before running the following command. This will create symlinks for the dotfiles in the home directory.
stow .I use Fish as my shell, and I have configured it to be as simple and efficient as possible. You can find my Fish configuration in the .config/fish directory.
Tip
Fish is not installed by default on macOS, so i have installed it using Homebrew. You can find more information about Fish on their website.
To change the default shell to Fish, you need to add the following line to the /etc/shells file.
/opt/homebrew/bin/fish
After adding the line to the /etc/shells file, you can run the following command in the terminal to change the default shell to Fish.
chsh -s /opt/homebrew/bin/fishTo update the completions for Fish, you can run the following command in the terminal. This will update the completions for all the installed packages.
fish_update_completionsThe color theme jjideenschmiede is based on the colors of the J&J Ideenschmiede logo and lives in .config/ghostty/themes. Ghostty starts the shell directly, so no multiplexer is configured here.
The Rex configuration lives in .config/rex. init.lua loads the custom actions from actions.lua, projects.lua and updates.lua and binds them in keys.lua. All actions also appear in the command palette.
| Shortcut | Action |
|---|---|
⌘W |
Close the focused pane, or the whole tab when it is the last pane. |
⌘⌥C |
Copy the output of the last command to the clipboard. |
⌘⌥⇧C |
Copy the last command together with its output. |
⌘P |
Change the focused shell to the projects directory and open Go to Directory there. |
⌘⇧K |
Start Claude Code on the left of the focused pane in the same directory. |
⌘⇧O |
Open the origin remote of the focused pane's repository in the browser. |
⌘⇧U |
Run update_all in a background tab named updates, or focus that tab when it is already open. |
⌘⇧T |
Open the YouTrack ticket named in the current git branch, such as feature/daily-627-…. |
Tabs are also named automatically. autostart.lua starts auto-label.lua in the background once per login. Whenever the focused shell changes its directory, the script names the tab after the repository or directory. While ssh runs in the foreground, the tab is named after the user and host instead, such as root@droneparts. The user comes from ssh -G, so it respects ~/.ssh/config. If the server sets a terminal title that starts with user@host, that title wins. The tab gets its project name back once the connection ends. Tabs you rename yourself keep their name. After editing the script, run Restart Automatic Tab Names from the command palette. Its log is in ~/Library/Logs/rex-auto-label.log.
The YouTrack address is internal, so it lives in .config/rex/local.lua, which git ignores. Create it on a new machine with the following content.
return {
youtrack_url = "https://youtrack.example.com",
}Rex does not watch the configuration file, so reload it after every change.
rex config reloadThe theme is not part of the Rex configuration and has to be imported once in the app. Open the command palette, run the Ghostty import and select the following file.
~/.config/ghostty/themes/jjideenschmiede
The Neovim configuration lives in .config/nvim and needs Neovim 0.12 or newer. Plugins are managed by the built-in vim.pack, so no plugin manager has to be installed. On the first start, Neovim clones the plugins and installs the Treesitter parsers, which needs tree-sitter-cli from the Brewfile.
| Plugin | Purpose |
|---|---|
nvim-lspconfig, mason.nvim, mason-lspconfig.nvim |
Language servers for Go, Zig, PHP, TypeScript, Lua, Python and Terraform. |
blink.cmp |
Autocompletion with documentation and signature help. |
nvim-treesitter |
Syntax highlighting and indentation. |
fzf-lua |
Fuzzy search for files, text, buffers, symbols and diagnostics. |
conform.nvim |
Format on save, with the language server as fallback. |
gitsigns.nvim |
Git changes in the sign column. |
Mason installs the language servers listed in lua/lsp.lua automatically. On a new machine you can also install them right away with the following command.
nvim --headless -c "MasonInstall basedpyright gopls intelephense lua-language-server terraform-ls typescript-language-server zls" -c "qa"The leader key is Space.
| Shortcut | Action |
|---|---|
<leader>f |
Find files. |
<leader>g |
Search text in the project. |
<leader>b |
Switch between open buffers. |
<leader>s |
Show symbols in the current file. |
<leader>d |
Show diagnostics of the workspace. |
<leader>r |
Resume the last search. |
<leader>l |
Open lazygit in a new tab. |
<leader>e |
Show the diagnostic under the cursor. |
gd / gD / gy |
Go to definition, declaration or type definition. |
K |
Show documentation under the cursor. |
grn / gra / grr / gri |
Rename, code action, references and implementation. |
[d / ]d |
Jump to the previous or next diagnostic. |
To update all plugins, run the following command in Neovim and write the confirmation buffer with :w.
:lua vim.pack.update()This repository is public, so a pre-commit hook blocks commits that contain an autoMode block in the Claude Code settings, tokens, private keys or passwords. Claude Code only reads autoMode from ~/.claude/settings.json, which is linked to this repository, so a git filter removes the block from every commit while the local file keeps it. To enable both after cloning the repository, run the following commands in the dotfiles directory.
git config core.hooksPath .githooks
git config filter.strip-automode.clean "jq --indent 2 'del(.autoMode)'"
git config filter.strip-automode.smudge cat
git config filter.strip-automode.required true