Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

macOS rice

My keyboard-first macOS setup: Yabai BSP tiling, skhd hotkeys, a floating SketchyBar, JankyBorders, Ghostty, and a modular Neovim IDE. The entire desktop switches between Nordfox dark and Xcode Light with one shortcut.

Tested on Apple Silicon with macOS Tahoe 26.5, Yabai 7.1, SketchyBar 2.24, skhd 0.3.9, JankyBorders 1.9, Ghostty 1.3, and Neovim 0.12. The scripts use /opt/homebrew, so Intel Mac users should replace it with /usr/local.

Light desktop with SketchyBar, Ghostty, JankyBorders, and Neovim

Xcode Light Nordfox dark
Neovim Xcode Light theme Neovim Nordfox dark theme

What is included

Component Purpose Main config
Yabai BSP tiling, Spaces, displays, stacking .config/yabai/yabairc
skhd Global keyboard shortcuts .config/skhd/skhdrc
SketchyBar Spaces, app, media, CPU, RAM, network, audio, battery, clock .config/sketchybar/sketchybarrc
JankyBorders Rounded focused-window glow .config/borders/bordersrc
Ghostty Fast terminal with synchronized themes .config/ghostty/config.ghostty
Neovim LSP, completion, formatting, linting, tests, DAP, Git, tasks, sessions .config/nvim/

The SketchyBar is intentionally useful, not decorative:

  • semantic numbered Spaces that keep their number when moved between displays;
  • application icons for every Space and a stack-size indicator;
  • a clickable Apple control center with system, display, network, VPN, battery, and volume details;
  • currently playing media with click-to-play/pause;
  • CPU graph, memory, live network throughput, volume, battery, and clock;
  • event-driven updates where possible, with lightweight polling only for live telemetry.

Install

Read the scripts before running them. These are personal dotfiles and the setup changes window-management behavior across macOS.

1. Install Homebrew and packages

Install Homebrew, then:

git clone https://github.com/deniserdogan/dotfiles.git ~/dotfiles
cd ~/dotfiles
brew bundle

The Brewfile installs the desktop tools, Ghostty, Neovim, jq, nowplaying-cli, common picker tools, and JetBrainsMono Nerd Font. Neovim installs its language-specific editor tooling through Mason on first launch.

SketchyBar uses the sketchybar-app-font for application ligatures. Download the latest sketchybar-app-font.ttf release asset into ~/Library/Fonts/, then log out and back in if macOS does not notice the font immediately.

mkdir -p ~/Library/Fonts
font_url="$(
  curl -fsSL https://api.github.com/repos/kvndrsslr/sketchybar-app-font/releases/latest |
    jq -r '.assets[] | select(.name == "sketchybar-app-font.ttf") | .browser_download_url'
)"
curl -fL "$font_url" -o ~/Library/Fonts/sketchybar-app-font.ttf

2. Configure macOS

In System Settings → Desktop & Dock:

  • enable Displays have separate Spaces;
  • disable Automatically rearrange Spaces based on most recent use;
  • enable Show Items On Desktop;
  • set Click wallpaper to reveal Desktop to Only in Stage Manager.

In System Settings → Control Center, set Automatically hide and show the menu bar to Always. SketchyBar replaces it.

On first launch, allow both Yabai and skhd under Privacy & Security → Accessibility. Restart each service after granting access.

3. Link the configs

Back up any existing configuration first:

mkdir -p ~/.config
stamp="$(date +%Y%m%d-%H%M%S)"

for name in borders ghostty nvim sketchybar skhd yabai; do
  if [ -e "$HOME/.config/$name" ] || [ -L "$HOME/.config/$name" ]; then
    mv "$HOME/.config/$name" "$HOME/.config/$name.backup-$stamp"
  fi
  ln -s "$HOME/dotfiles/.config/$name" "$HOME/.config/$name"
done

chmod +x ~/.config/borders/bordersrc
chmod +x ~/.config/yabai/yabairc ~/.config/yabai/scripts/*.sh
chmod +x ~/.config/sketchybar/sketchybarrc ~/.config/sketchybar/plugins/*.sh
chmod +x ~/.config/skhd/scripts/*.sh

If you cloned somewhere other than ~/dotfiles, change the symlink source. Using whole-directory symlinks keeps edits in the repository automatically.

4. Decide whether to enable Yabai's scripting addition

Basic window tiling works with normal Accessibility permission. This rice also uses advanced Space operations—create, destroy, focus, and move Spaces—which require Yabai's scripting addition and therefore a partial reduction of System Integrity Protection.

This is a real security tradeoff. Read Yabai's current SIP instructions and scripting-addition setup before deciding.

After following the official SIP instructions, generate a sudoers rule tied to your username, Yabai path, and the exact hash of the installed binary:

echo "$(whoami) ALL=(root) NOPASSWD: sha256:$(shasum -a 256 "$(which yabai)" | cut -d ' ' -f 1) $(which yabai) --load-sa" \
  | sudo tee /private/etc/sudoers.d/yabai

Regenerate that rule every time Yabai is upgraded. The repository deliberately does not ship a yabai.sudoers file because another user's username, binary path, and hash would be wrong.

5. Start everything

yabai --start-service
skhd --start-service
brew services start sketchybar

JankyBorders starts from yabairc, so do not also start it as a separate service. Open Ghostty and then Neovim:

nvim

On the first Neovim launch, lazy.nvim installs plugins and Mason installs the configured editor tools. Let both finish, restart Neovim, then run:

:checkhealth
:ConfigHealth

Yabai and macOS shortcuts

Alt means the left Option key (lalt). Directions follow Vim: H left, J down, K up, L right.

Focus, move, and resize windows

Shortcut Action
Alt H/J/K/L Focus the window left/down/up/right
Shift Alt H/J/K/L Warp the focused window left/down/up/right in the BSP tree
Ctrl Alt H/J/K/L Resize the focused edge by 40 px
Alt F Toggle native-looking zoom fullscreen
Alt Space Toggle floating
Alt S Toggle the next split orientation
Alt + left mouse drag Move a window
Alt + right mouse drag Resize a window

Directional focus is smarter than a plain Yabai command: it handles zoomed windows, stacks, and wraparound candidates without leaving the keyboard.

Stacks and layout

Shortcut Action
Shift Alt S Add the focused window to a stack, or pull it back into BSP
Alt [ Focus the previous member of the current stack, wrapping around
Alt ] Focus the next member of the current stack, wrapping around
Alt R Rotate the current BSP tree 90°
Alt B Balance the current BSP tree
Shift Alt X Mirror the current layout on the x-axis
Shift Alt Y Mirror the current layout on the y-axis

Displays

Shortcut Action
Cmd Alt H/J/K/L Focus the display left/down/up/right
Cmd Alt M Cycle focus through connected displays
Shift Cmd Alt H/J/K/L Move the current Space to the display in that direction
Shift Cmd Alt B Move the current Space to the built-in display
Shift Alt M Cycle the current Space through every display

The entire Space moves, not just one window. Its semantic number follows it, and SketchyBar rebuilds the Space pills after topology changes.

Semantic Spaces

Shortcut Action
Cmd 1Cmd 9 Focus semantic Space 1 … 9
Shift Cmd 1Shift Cmd 9 Move the focused window to semantic Space 1 … 9
Shift Alt N Create a Space on the focused display
Shift Alt Backspace Destroy the focused Space

The first run creates .config/yabai/space_roles.tsv. It maps stable Space identities to slot.N labels and is intentionally ignored by Git because it is machine state. When a Space moves to another display, Cmd N still follows the role instead of its temporary Mission Control index.

Reload and theme

Shortcut Action
Ctrl Alt Cmd R Restart Yabai
Ctrl Alt Cmd S Reload SketchyBar
Ctrl Alt Cmd T Toggle macOS, Ghostty, Neovim, and SketchyBar light/dark themes

The theme switch is serialized and debounced, so repeated key presses settle on one final theme without leaving the bar and Neovim out of sync.

SketchyBar mouse actions

Item Click behavior
Apple logo Toggle the custom control-center popup
Space number Focus that semantic Space
Media island Play/pause current media
CPU or memory Open Activity Monitor
Volume Toggle mute
Volume slider Set output volume
Clock Open Calendar
Control-center rows Open their matching system panel or application where configured

Neovim shortcuts

<leader> and <localleader> are both Space. Press <leader>? for buffer-local mappings or pause after Space to let which-key show the available groups.

The hierarchy is: b buffers, c code/LSP, d debugger, f find, g Git, p projects/sessions, r tasks, s search/symbols, t tests/toggles, u UI, v windows, and x diagnostics/Trouble.

Editing and navigation

Mapping Modes Action
J normal Join lines without moving the cursor
Y normal Yank to end of line
n / N normal Next/previous search result, open folds, center
<C-d> / <C-u> normal Half-page down/up and center
< / > visual Indent and keep the selection
J / K visual Move selected lines down/up
p visual Paste without replacing the unnamed register
, / . / ; insert Insert punctuation with an undo breakpoint
q selected utility buffers Close the utility window

Files, projects, buffers, windows, and terminals

Mapping Action
<leader>w / <leader>W Save current file / all files
<leader>q / <leader>Q Quit current window / save all and quit Neovim
<leader><space> Smart project file picker
<leader>ff / <leader>fg Find files / live grep in the project root
<leader>fb / <leader>bl Buffer picker
<leader>fr / <leader>fp Recent files / projects
<leader>fc / <leader>fh Command history / help tags
<leader>e Project-root explorer
<leader>bd / <leader>bo Delete current / all other buffers without destroying layouts
<leader>bn / <leader>bp Next / previous buffer
<C-h/j/k/l> Move across splits in normal and terminal modes
<Esc><Esc> Leave terminal mode
<leader>v= Equalize splits
<leader>v+ / <leader>v- Increase / decrease height by four
<leader>v> / <leader>v< Increase / decrease width by four
<leader>vr Rotate windows
<leader>vH/J/K/L Move the window to the far left/bottom/top/right
<leader>ut / <leader>uT Toggle project float / open project bottom terminal

LSP, code, formatting, and linting

These mappings appear for buffers with an attached LSP server.

Mapping Action
gd / gD Definition / declaration
gri / grr / grt Implementation / references / type definition
K / gK Hover / signature help
<leader>ca Code action in normal or visual mode
<leader>cA All source actions
<leader>cO / <leader>cF / <leader>cU Organize imports / fix all / remove unused imports
<leader>cr Rename symbol
<leader>cs / <leader>cS Document / workspace symbols
<leader>ci / <leader>co Incoming / outgoing calls
<leader>ck Signature help
<leader>cwa / <leader>cwr / <leader>cwl Add / remove / list workspace folders
<leader>cI / <leader>cR Inspect / restart LSP clients
<leader>cm Open Mason
<leader>cf Asynchronous format in normal or visual mode
<leader>cl Run the selected linter
<leader>cE Fix the current file with project ESLint
<leader>th / <leader>ts Toggle buffer inlay hints / semantic tokens
<leader>cn / <leader>cN Swap with next / previous argument

Diagnostics, lists, and Trouble

Mapping Action
]d / [d Next / previous diagnostic
]e / [e Next / previous error
]w / [w Next / previous warning
<leader>cd Diagnostic under the cursor
<leader>cD Current-buffer diagnostics in the location list
<leader>td Toggle diagnostics globally
<leader>tv Toggle current-line diagnostic virtual lines
<leader>uD Toggle diagnostic signs
]q / [q Next / previous quickfix item, wrapping
]l / [l Next / previous location-list item, wrapping
<leader>xx / <leader>xX Workspace / current-buffer diagnostics in Trouble
<leader>xq / <leader>xl Quickfix / location list in Trouble
<leader>xs / <leader>xr Document symbols / LSP references in Trouble

Git

Mapping Action
]h / [h Next / previous hunk
<leader>gs Stage/unstage hunk; stage selection in visual mode
<leader>gr Reset hunk; reset selection in visual mode
<leader>gS / <leader>gp Stage buffer / preview hunk
<leader>gb / <leader>gB Full line blame / toggle current-line blame
<leader>gd / <leader>gq Diff current file / repository hunks in quickfix
ih Select hunk in operator-pending or visual mode
<leader>gD / <leader>gC Open / close Diffview
<leader>gh / <leader>gH File / repository history
<leader>gg Lazygit at the Git or project root
]x / [x Next / previous conflict in Diffview
<leader>gco/gct/gcb/gca/gcn Choose ours/theirs/base/all/none for a conflict

Testing

Mapping Action
<leader>tn Run nearest test
<leader>tf / <leader>tp Run current file / package or directory
<leader>ta Run all project tests
<leader>tl Run last test
<leader>tD Debug nearest test through DAP
<leader>to / <leader>tO Open last output / toggle output panel
<leader>tu Toggle test summary
<leader>tS Stop test interactively
]T / [T Next / previous failed test and center

Debugging

Mapping Action
<leader>dc Start or continue
<leader>db / <leader>dB / <leader>dl Breakpoint / conditional breakpoint / log point
<leader>do / <leader>di / <leader>dO Step over / into / out
<leader>dC / <leader>dR Run to cursor / restart frame
<leader>dL / <leader>dp Run last configuration / pause
<leader>dt Terminate
<leader>dr / <leader>du Toggle REPL / DAP UI
<leader>ds / <leader>de Inspect scopes / evaluate normal or visual selection
<leader>dk / <leader>dj Move up / down the stack
]b / [b Next / previous breakpoint across buffers

Tasks and sessions

Mapping Action
<leader>rr Choose an Overseer template
<leader>rb/rt/rl/rf Detected build/test/lint/format task
<leader>rp Choose a package script
<leader>rR / <leader>ro Rerun / open output of latest task
<leader>rh / <leader>ra Task history / task action
<leader>pr / <leader>pc Restore project / current-directory session
<leader>pl / <leader>ps Restore last / select session
<leader>pw / <leader>pd Save session / stop persistence

Task detection supports Make, Go, Python, npm, pnpm, Yarn, and Bun. Sessions are scoped to the project root and Git branch.

Treesitter, TODOs, UI, and completion

Mapping Modes Action
<C-Space> / <BS> normal/visual / visual Select parent / child syntax node
af / if visual, operator Around / inside function
ac / ic visual, operator Around / inside class
aa / ia visual, operator Around / inside argument
]m / [m normal, visual, operator Next / previous function start
]M / [M normal, visual, operator Next / previous function end
]] / [[ normal, visual, operator Next / previous class start
]t / [t normal Next / previous TODO comment
<leader>st / <leader>sT normal All TODOs / TODO-FIX-FIXME picker
<leader>un normal Notification history
<leader>? normal Buffer-local which-key view

Blink completion never preselects or auto-inserts an item:

Mapping Action
<C-Space> Show completion or toggle documentation
<C-n> / <C-p> Select next / previous item, otherwise fall back
<Tab> / <S-Tab> Select item, jump snippet forward/backward, or fall back
<CR> Explicitly accept the selected completion; otherwise normal Enter
<C-e> Cancel completion
<C-b> / <C-f> Scroll documentation up / down

The same completion navigation works on the command line. In : and @, the first Enter accepts a visible suggestion and the next Enter executes.

For the language manifest, plugin architecture, maintenance commands, formatting/lint policy, large-file behavior, and instructions for adding a language, read the Neovim guide.

Make it yours

Colors and themes

  • Edit both palettes in .config/sketchybar/colors.sh.
  • Change Ghostty's pair in .config/ghostty/config.ghostty.
  • Change Neovim's dark/light schemes in .config/nvim/lua/plugins/colorscheme.lua.
  • Match border colors in .config/yabai/yabairc and .config/borders/bordersrc.

Keep the dark and light names aligned if you want Ctrl Alt Cmd T to switch everything together.

Layout and spacing

Edit .config/yabai/yabairc:

  • split_ratio controls the initial 50/50 split;
  • top_padding, bottom_padding, left_padding, and right_padding control the outer gap;
  • window_gap controls space between tiled windows;
  • external_bar all:46:0 reserves room for SketchyBar;
  • the rule --add lines decide which applications float.

Edit .config/sketchybar/sketchybarrc to change bar height, margin, offset, corner radius, blur, fonts, widget order, or update rates.

Shortcuts

All global bindings are in .config/skhd/skhdrc. Change the left side of a binding while leaving its command intact. skhd hotloads changes; if it does not, run:

skhd --reload

On non-US keyboard layouts, the 0x21, 0x1E, and 0x33 keycodes for [, ], and Backspace may need adjustment. Run skhd -o to observe keycodes.

Bar applications

  • Add application ligatures in .config/sketchybar/plugins/icon_map.sh.
  • Remove or replace the AmneziaVPN popup row if you use another VPN.
  • Remove the media item if you do not want nowplaying-cli.
  • System telemetry uses standard macOS tools and does not send data anywhere.

Neovim languages

.config/nvim/lua/config/languages.lua is the source of truth for LSP servers, formatters, linters, Treesitter parsers, debuggers, test adapters, and Mason tools. Change one language definition there instead of maintaining duplicate lists across plugins.

Troubleshooting

Symptom Check
Hotkeys do nothing Accessibility permission for skhd; Secure Keyboard Entry must be off
Windows do not tile Accessibility permission for Yabai; restart with yabai --restart-service
Space move/create fails Scripting addition, partial SIP setup, and current sudoers hash
Bar is missing Run sketchybar in a terminal and inspect the first script error
Space numbers are stale Run ~/.config/yabai/scripts/sync_space_roles.sh and sketchybar --reload
App icons are boxes Install JetBrainsMono Nerd Font and sketchybar-app-font, then log out/in
Media island never appears Install nowplaying-cli and start playing supported system media
Theme is out of sync Press Ctrl Alt Cmd T once, wait a second, then reload SketchyBar
Neovim tool is missing Run :ConfigHealth, :MasonToolsInstall, and :checkhealth

Useful logs:

tail -f /tmp/yabai_$USER.err.log
tail -f /tmp/skhd_$USER.err.log

Repository layout

.
├── .config
│   ├── borders
│   ├── ghostty
│   ├── nvim
│   ├── sketchybar
│   ├── skhd
│   └── yabai
├── screenshots
├── Brewfile
├── LICENSE
└── README.md

Machine-only files—OAuth data, logs, backups, Yabai Space UUID state, and the sudoers hash—are intentionally excluded.

Acknowledgements

Built on the excellent work of Yabai and skhd, FelixKratz's SketchyBar and JankyBorders, Ghostty, Neovim, and the plugin authors listed in .config/nvim/lazy-lock.json.

Released under the MIT License.

About

A polished macOS rice featuring Yabai, skhd, SketchyBar, JankyBorders, Ghostty, and Neovim—with documented shortcuts, installation steps, screenshots, and easy customization.

Topics

Resources

Stars

26 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages