Cross-platform configuration files for Neovim and WezTerm with OS-specific settings.
bash <(curl -fsSL https://raw.githubusercontent.com/ronilaukkarinen/dotfiles/master/install.sh)🎯 Modular structure - Shared configs + OS-specific overrides
🔐 Secrets management - API keys in gitignored files
🌍 Cross-platform - Works on Linux, macOS, and Windows
🎮 Gamification & stats - Code::Stats and gamify with streak tracking
🤖 Claude Code integration - Automatic XP tracking for AI-assisted coding
- Neovim - 0.10+ required
- WezTerm - Terminal emulator
- Liga SFMono Nerd Font - Ligaturized SF Mono with Nerd Font icons
- Monaspace - Monaspace Krypton NF font
- Claude Code - AI-assisted coding with Code::Stats integration
For selective updates or if you prefer manual setup:
git clone git@github.com:ronilaukkarinen/dotfiles.git ~/Projects/dotfiles# WezTerm
ln -sf ~/Projects/dotfiles/wezterm ~/.config/wezterm
# Neovim
ln -sf ~/Projects/dotfiles/nvim ~/.config/nvim
# Hammerspoon (macOS only)
ln -sf ~/Projects/dotfiles/hammerspoon ~/.hammerspoon# Clone repository
git clone git@github.com:ronilaukkarinen/dotfiles.git $env:USERPROFILE\Projects\dotfiles
# WezTerm
New-Item -ItemType SymbolicLink -Path "$env:USERPROFILE\.config\wezterm" -Target "$env:USERPROFILE\Projects\dotfiles\wezterm" -Force
# Neovim
New-Item -ItemType SymbolicLink -Path "$env:USERPROFILE\AppData\Local\nvim" -Target "$env:USERPROFILE\Projects\dotfiles\nvim" -Force# Neovim
cp ~/Projects/dotfiles/nvim/lua/secrets.lua.example ~/Projects/dotfiles/nvim/lua/secrets.lua
nvim ~/Projects/dotfiles/nvim/lua/secrets.lua
# Claude Code
cp ~/Projects/dotfiles/claude-code/secrets.sh.example ~/Projects/dotfiles/claude-code/secrets.sh
nvim ~/Projects/dotfiles/claude-code/secrets.shGet your Code::Stats API key from https://codestats.net/my/machines
With symlinks, any changes you make to your configs automatically update the repo! Just commit and push when ready.
Linter and formatter notifications appear automatically when you open files - nvim-lint will warn you if a linter is missing for that specific file type.
Track your AI-assisted coding activity with Code::Stats automatically! Every time Claude Code writes or edits a file, you earn XP (1 XP per line). A custom status line shows model, session duration, lines changed, and XP at the bottom of the Claude Code terminal.
The install script sets up symlinks automatically. For manual setup:
mkdir -p ~/.claude/hooks
ln -sf ~/Projects/dotfiles/claude-code/codestats-hook.sh ~/.claude/hooks/codestats-hook.sh
ln -sf ~/Projects/dotfiles/claude-code/statusline.sh ~/.claude/statusline.shAdd the following to your ~/.claude/settings.json (this file cannot be symlinked as it varies per machine):
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write|NotebookEdit",
"hooks": [
{
"type": "command",
"command": "~/.claude/hooks/codestats-hook.sh",
"async": true
}
]
}
]
},
"statusLine": {
"type": "command",
"command": "~/.claude/statusline.sh"
}
}The hook automatically:
- Detects file type from extension (JavaScript, Python, Markdown, Bash, etc.)
- Calculates XP based on lines written (1 XP per line)
- Sends the XP to Code::Stats API asynchronously (non-blocking)
- Displays running XP total in the status line
The status line shows: Opus 4.6 · 45m · +156 -23 · XP: 4312 +5 (Shell)
Automatically save and archive all your Claude Code conversations with searchable markdown transcripts. This uses the claude-conversation-saver plugin wrapping the conversation-logger skill. Read more at Jerad Bitner's blog post.
Run this command in Claude Code:
/plugin marketplace add https://github.com/sirkitree/claude-conversation-saver
Then restart Claude Code. The plugin will automatically save conversations after each response to ~/.claude/conversation-logs/ with markdown transcripts, JSONL raw data, and session metadata.
The plugin needs these tools (likely already installed):
git- for cloning the skilljq- JSON processor for parsing datapython3- for markdown conversion
Install missing dependencies:
Arch Linux:
sudo pacman -S git jq pythonDebian/Ubuntu:
sudo apt install git jq python3macOS:
brew install git jq python3After installation, conversations are automatically saved. Use these slash commands:
/convo-search <query>- search across all saved conversations/convo-list- list all saved conversations/convo-recent- show recent conversations
This ensures you never lose important conversations and can search through your entire Claude Code history!
On any other machine where you use Claude Code, just run the install script:
bash <(curl -fsSL https://raw.githubusercontent.com/ronilaukkarinen/dotfiles/master/install.sh)Then configure your secrets and ~/.claude/settings.json as instructed.
For remote servers where you use Claude Code via SSH, run the install script:
bash <(curl -fsSL https://raw.githubusercontent.com/ronilaukkarinen/dotfiles/master/install.sh)Or for manual Claude Code hook setup only:
# Clone dotfiles
git clone git@github.com:ronilaukkarinen/dotfiles.git ~/Projects/dotfiles
# Create secrets file with your API key
echo '#!/bin/bash
export CODESTATS_API_KEY="YOUR_API_KEY_HERE"' > ~/Projects/dotfiles/claude-code/secrets.sh
chmod +x ~/Projects/dotfiles/claude-code/secrets.sh
# Symlink the hook and status line
mkdir -p ~/.claude/hooks
ln -sf ~/Projects/dotfiles/claude-code/codestats-hook.sh ~/.claude/hooks/codestats-hook.sh
ln -sf ~/Projects/dotfiles/claude-code/statusline.sh ~/.claude/statusline.sh
# Add hooks and statusLine to ~/.claude/settings.json (see above)The install script asks which linters you want to activate. You can enable/disable individual linters for different languages. Each linter checks code quality and shows errors/warnings inline as you type.
- phpcs - PHP Code Sniffer for PHP files
- stylelint - CSS/SCSS linter
- flake8 - Python linter
- luacheck - Lua linter
- jsonlint - JSON linter
- eslint - JavaScript linter
To manually enable/disable linters after installation, edit ~/Projects/dotfiles/nvim/lua/local.lua:
return {
-- ... other settings ...
-- Linters (set to true to enable, false to disable)
enable_phpcs = true, -- PHP linter
enable_stylelint = true, -- CSS/SCSS linter
enable_flake8 = true, -- Python linter
enable_luacheck = true, -- Lua linter
enable_jsonlint = true, -- JSON linter
enable_eslint = true, -- JavaScript linter
}After editing, restart Neovim for changes to take effect.
If a linter is enabled but not installed, nvim-lint will show a notification with installation instructions when you open a file of that type.
composer global require squizlabs/php_codesniffernpm install -g stylelintpip install flake8luarocks install luachecknpm install -g jsonlintnpm install -g eslintFor JavaScript/PHP projects, nvim-lint will automatically detect and use project-local linters:
- JavaScript: Uses
node_modules/.bin/eslintif available in your project - PHP: Uses
vendor/bin/phpcsif available in your project
This ensures project-specific rules and configurations are respected.
curl -L https://github.com/ronilaukkarinen/dotfiles/archive/refs/heads/master.tar.gz | tar xz && cp -r dotfiles-master/nvim ~/.config/ && rm -rf dotfiles-master && echo "code_stats_api_key = 'SFxxxx'\ncodestats_username = 'rolle'" > ~/.config/nvim/lua/secrets.luacurl -L https://github.com/ronilaukkarinen/dotfiles/archive/refs/heads/master.tar.gz | tar xz && cp -r dotfiles-master/nvim/* ~/.config/nvim/ && rm -rf dotfiles-master- Uses
/usr/bin/python3 - nvm integration for Node.js
- Wayland clipboard workaround for WezTerm
- Uses Homebrew Python:
/opt/homebrew/bin/python3 - Background blur effects in WezTerm
- Optimized font rendering (weight 500, size 13pt)
- Uses system Python
- PowerShell as default shell - Opens with PowerShell (
powershell.exe) by default - WSL Ubuntu 22.04 - Press
Ctrl+Shift+Bto spawn WSL Ubuntu in a split pane - Launch menu - Access PowerShell, WSL Ubuntu 22.04, Git Bash, or CMD via the launcher (
Ctrl+K→ search "launcher") - Adjusted keybindings where needed
To make typing bash in PowerShell open WSL Ubuntu 22.04, add this to your PowerShell profile:
# Override bash command to use WSL Ubuntu 22.04
function bash {
wsl -d Ubuntu-22.04
}Profile location: C:\Users\YourUsername\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
Create the file if it doesn't exist, then restart PowerShell or run . $PROFILE to apply changes.
- lazy.nvim - Plugin manager
- catppuccin - Color scheme (Mocha variant)
- oklch-color-picker - OKLCH color picker with graphical interface
- dashboard - Recent projects and files in start
- lualine - Status bar with Code::Stats integration
- barbar - Buffer tabline with icons and animations
- auto-session - Auto-save and auto-restore sessions per directory
- cd-project.nvim - VSCode-like project manager
- telescope - Fuzzy finder
- telescope-frecency - Frecency algorithm for telescope
- gamify - Gamify coding with achievements and streaks
- gitsigns - Git signs in gutter, inline blame, hunk actions
- mini.files - Lightweight file explorer
- which-key - Shows keybindings in popup
- presence - Discord Rich Presence
- nvim-notify - Notification manager
- nvim-lint - Linting with contextual diagnostics
- conform - Auto-formatting on save
- indentmini - Minimal indent guides
- tiny-inline-diagnostic - Inline diagnostic messages
- trouble - Diagnostics panel
- dropbar - Context-aware breadcrumbs
- nvim-treesitter - Better syntax highlighting with Tree-sitter
- blink.cmp - Completion plugin
- minuet-ai - AI code completion with Ollama
- plenary.nvim - Lua utilities (includes custom Neovim AI helper)
- Comment.nvim - Toggle comments
- leap.nvim - Jump to any location with search labels
- hardtime - Learn better Vim motions
- mason - LSP server manager
- mason-lspconfig - Bridge between mason and lspconfig
- nvim-lspconfig - LSP configuration
- Auto-restore sessions
- Code::Stats XP in statusline
- Gamify streak tracking
- OS-specific configurations
- Contextual linter notifications (only for files you're editing)
Linux desktop uses Hyprland with the hy3 plugin for i3-like manual tiling with smart autotile.
Windows float by default. Use Super+V to tile a window. The hy3 autotile feature prevents windows from becoming too narrow or short by automatically reorganizing the layout.
| Keybind | Action |
|---|---|
| Super + V | Toggle floating/tiled |
| Super + C | Close window |
| Super + Shift + C | Center window |
| Super + T | Pin floating window |
| Keybind | Action |
|---|---|
| Super + arrows | Move focus between windows |
| Super + Shift + arrows | Move window in layout |
| Super + H | Group windows horizontally |
| Super + J | Group windows vertically |
| Super + G | Group windows as tabs |
| Super + U | Untab (convert tabs to splits) |
| Super + O | Toggle horizontal/vertical layout |
| Super + E | Expand window into parent container |
| Super + A | Focus parent container |
| Super + Z | Focus child container |
| Super + Shift + L | Lock group (prevent layout changes) |
| Keybind | Action |
|---|---|
| Super + 1-9 | Switch to workspace |
| Super + Shift + 1-9 | Move window to workspace |
| Super + Alt + left/right | Previous/next workspace |
| Super + Ctrl + left/right | Move window to prev/next workspace |
| Keybind | Action |
|---|---|
| Super + Q | Open terminal (WezTerm) |
| Super + K | App launcher (DMS spotlight) |
| Super + L | Lock screen |
| Super + Shift + E | File manager |
| Super + Tab | Window switcher |
| Screenshot area | |
| Shift + Print | Screenshot active window |
| Ctrl + Print | Screenshot full screen |
Ctrl+Shift+O- Project switcherCtrl+K- Command paletteCtrl+Shift+B- Spawn WSL Ubuntu 22.04 in split pane (Windows only)Ctrl+W- Close paneCtrl+Alt+Arrows- Navigate panesCtrl+Shift+Arrows- Resize panesCtrl+Shift+R- Reload configuration
Ctrl+P- Telescope frecencyCtrl+Shift+P- Command palette- See individual plugin docs for more keybindings
To sync your gamify streak and statistics across machines:
# Debian/Ubuntu
sudo apt install syncthing
# Arch Linux
sudo pacman -S syncthingbrew install syncthing# Enable and start Syncthing service
systemctl --user enable syncthing.service
systemctl --user start syncthing.service# Syncthing will auto-start after brew installation
brew services start syncthing- Open the web UI at
http://127.0.0.1:8384 - Set up GUI authentication (Settings → GUI → Set username and password)
- Add a new folder pointing to
~/.local/share/nvim/gamify/with Folder Label "nvim gamify" - In folder settings, go to Advanced:
- Tick Ignore Permissions
- Set Full Rescan Interval (s) to
300(5 minutes for faster sync)
- Share this folder with your other devices
- Syncthing will keep your streaks in sync automatically
To access Syncthing web UI from outside your network:
# Debian/Ubuntu
sudo apt install nginx
# Arch Linux
sudo pacman -S nginxsudo tee /etc/nginx/sites-available/syncthing > /dev/null << 'EOF'
server {
listen 0.0.0.0:8385;
listen [::]:8385;
server_name your-domain.example.com;
location / {
proxy_pass http://127.0.0.1:8384/;
proxy_http_version 1.1;
proxy_set_header Connection "upgrade";
proxy_set_header Upgrade $http_upgrade;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
# by default nginx times out connections in one minute
proxy_read_timeout 1d;
}
}
EOFReplace your-domain.example.com with your actual domain name.
sudo ln -s /etc/nginx/sites-available/syncthing /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl enable nginx
sudo systemctl start nginxSet up port forwarding in your router:
- External port:
8385 - Internal IP: Your server's local IP (e.g.,
192.168.1.100) - Internal port:
8385 - Protocol:
TCP
You can now access Syncthing from anywhere at http://your-domain.example.com:8385/
Make sure you have GUI authentication enabled (step 2 in "Set up syncing" above).
Simply pull the latest changes:
cd ~/Projects/dotfiles && git pullReload WezTerm (Ctrl+Shift+R) and restart Neovim to apply changes.
Pull and re-copy files:
cd ~/Projects/dotfiles && git pull && cp -r wezterm ~/.config/ && cp -r nvim ~/.config/cd ~/Projects/dotfiles; git pull; Copy-Item -Recurse -Force wezterm "$env:USERPROFILE\.config\"; Copy-Item -Recurse -Force nvim "$env:USERPROFILE\AppData\Local\"My .bashrc changes depending on the system I'm on, but here are some useful lines to add.
# Add trailing slash when tab-completing directories
bind 'set mark-directories on'
bind 'set mark-symlinked-directories on'