This commit is contained in:
2026-05-04 09:53:30 +02:00
commit c0aefae3fb
11 changed files with 984 additions and 0 deletions

204
GETTING_STARTED.md Normal file
View File

@@ -0,0 +1,204 @@
# Getting Started
This is a minimal development environment for Fedora Linux.
It uses GNU Stow to symlink config files into your home directory.
Everything is plain text. No magic. Read a file before you use it.
---
## What you need first
A Fedora machine with internet access and `git` installed:
```bash
sudo dnf install -y git
```
---
## Step 1 — Clone this repo
```bash
git clone git@your-gitea-instance:you/dotfiles.git ~/dotfiles
cd ~/dotfiles
```
---
## Step 2 — Read provision.sh
Before running any script, read it:
```bash
cat provision.sh
```
It installs: `stow`, `neovim`, `ripgrep`, `mise` — and symlinks the config
packages into your home directory. Nothing else.
When you are comfortable with what it does:
```bash
bash provision.sh --dry-run # see what would happen
bash provision.sh # run it
```
---
## Step 3 — Edit your git identity
The `.gitconfig` has placeholder values. Fill them in now:
```bash
nvim ~/.gitconfig
```
Change `Your Name` and `you@example.com` to your actual details.
---
## Step 4 — Install runtimes
```bash
mise install
```
This downloads Node.js (for TypeScript) and .NET (for C#/F#) into
`~/.local/share/mise/`. Nothing goes system-wide.
Check what was installed:
```bash
mise ls
```
---
## Step 5 — Open Neovim
```bash
nvim
```
On first launch, `lazy.nvim` installs all plugins automatically.
Wait for it to finish, then run:
```vim
:checkhealth
```
Fix any warnings it shows before moving on.
---
## Step 6 — Set up your notes repo
Notes are a separate private repo. Clone it to `~/notes/`:
```bash
git clone git@your-gitea-instance:you/notes.git ~/notes
```
The shell commands (`today`, `thisweek`, `inbox`, `tasks`, `decisions`)
expect `~/notes/` to exist with templates at `~/notes/templates/`.
They will not work until the notes repo is cloned.
Reload your shell so the note aliases are available:
```bash
source ~/.bashrc
```
Then try:
```bash
today # creates and opens today's daily note
inbox # opens inbox for capture
tasks # shows all open tasks across notes
```
---
## Daily workflow in 3 commands
```bash
inbox # capture anything during the day
today # open today's plan each morning
thisweek # open weekly review on Monday morning
```
---
## What is in this repo
```
dotfiles/
├── provision.sh # bootstrap script
├── GETTING_STARTED.md # this file
├── README.md # full reference
├── .gitignore
├── bash/
│ └── .bashrc # shell config, aliases, note commands
├── git/
│ └── .gitconfig # git settings (edit name/email)
├── mise/
│ └── .config/mise/
│ └── config.toml # node + dotnet versions
├── nvim/
│ └── .config/nvim/
│ └── init.lua # Neovim — read top to bottom
└── notes/ # templates only, not your actual notes
├── inbox.md
├── decisions.md
├── daily-template.md
└── weekly-template.md
```
---
## Adding a config file later
1. Create a package directory: `mkdir -p ~/dotfiles/mypackage`
2. Mirror the target path inside it — if the file belongs at
`~/.config/myapp/config`, create
`~/dotfiles/mypackage/.config/myapp/config`
3. Stow it: `stow --restow --target=$HOME --dir=~/dotfiles mypackage`
4. Commit
---
## Updating an existing config
Because stow creates symlinks, editing `~/.bashrc` is the same as editing
`~/dotfiles/bash/.bashrc`. Just open the file, save it, then commit:
```bash
cd ~/dotfiles
git add bash/.bashrc
git commit -m "bashrc: add alias for X"
git push
```
---
## Troubleshooting
**Stow says a file already exists**
The target file exists and is not a symlink. Back it up and remove it:
```bash
mv ~/.bashrc ~/.bashrc.bak
stow --restow --target=$HOME --dir=~/dotfiles bash
```
**Neovim plugins did not install**
Open nvim and run `:Lazy sync`
**mise runtimes not found after install**
Make sure your shell sourced `.bashrc`: `source ~/.bashrc`
Then check: `mise ls`

160
README.md Normal file
View File

@@ -0,0 +1,160 @@
# dotfiles
Minimal personal development environment for Fedora Linux.
**Stack:** Bash · Neovim · mise · GNU Stow
**New machine?** Start with [GETTING_STARTED.md](GETTING_STARTED.md)
---
## How stow works
Stow creates symlinks from `~` into this repo, mirroring each package's
internal directory structure.
```
dotfiles/bash/.bashrc → ~/.bashrc
dotfiles/nvim/.config/nvim/init.lua → ~/.config/nvim/init.lua
```
Editing the symlink edits the repo file. Then commit like any other change.
To stow a single package:
```bash
stow --restow --target=$HOME --dir=~/dotfiles bash
```
---
## Packages
| Package | Symlinks to | Purpose |
|---|---|---|
| `bash` | `~/.bashrc` | Shell config, aliases, note functions |
| `git` | `~/.gitconfig` | Git settings |
| `mise` | `~/.config/mise/config.toml` | Runtime versions |
| `nvim` | `~/.config/nvim/init.lua` | Neovim config |
Note commands in `.bashrc` expect templates at `~/notes/templates/`.
These come from your notes repo, not this one.
---
## Neovim
Config is a single `init.lua` — read it top to bottom before using it.
Plugins are managed by [lazy.nvim](https://github.com/folke/lazy.nvim) which
bootstraps itself on first launch.
**Installed plugins:**
| Plugin | Purpose |
|---|---|
| `nvim-treesitter` | Syntax highlighting |
| `nvim-lspconfig` + `mason` | Language servers |
| `nvim-cmp` | Completion |
| `telescope.nvim` | Fuzzy finder |
| `Comment.nvim` | `gc` to comment |
| `vim-sleuth` | Auto-detect indent |
| `kanagawa.nvim` | Colorscheme |
**Language servers installed automatically by Mason:**
- `ts_ls` — TypeScript / JavaScript
- `omnisharp` — C# and F#
- `marksman` — Markdown
- `lua_ls` — Lua (for editing this config)
**Keymaps (leader = Space):**
| Keys | Action |
|---|---|
| `Space ff` | Find files |
| `Space fg` | Search text in files |
| `Space fb` | Switch buffer |
| `Space w` | Save |
| `Space e` | File explorer |
| `Space d` | Show diagnostic |
| `Space rn` | Rename symbol |
| `Space ca` | Code action |
| `gd` | Go to definition |
| `K` | Hover docs |
| `[d` / `]d` | Prev / next diagnostic |
| `Ctrl+h/j/k/l` | Move between splits |
| `gcc` | Toggle comment |
---
## mise — runtime versions
Configured in `mise/.config/mise/config.toml`.
```bash
mise install # install all configured versions
mise ls # list installed runtimes
mise ls-remote node # list available node versions
```
To pin a version in a specific project, add a `.mise.toml` to that project
directory. The global config here is the fallback.
---
## Bash aliases
| Alias / Function | Does |
|---|---|
| `ll` | `ls -lah` with color |
| `..` / `...` | Navigate up one / two directories |
| `gs` / `ga` / `gc` / `gp` / `gl` | Git shortcuts |
| `today` | Open or create today's daily note |
| `thisweek` | Open or create this week's weekly note |
| `inbox` | Open inbox for quick capture |
| `tasks` | Grep all open tasks across notes |
| `decisions` | Open decisions log |
| `mkcd` | Create directory and cd into it |
| `bashrc` | Edit and reload `.bashrc` |
---
## Notes workflow
Notes live in `~/notes/` — a separate private git repo, not this one.
The shell commands in `.bashrc` expect this structure to exist:
```
~/notes/
├── inbox.md
├── decisions.md
├── templates/
│ ├── daily.md
│ └── weekly.md
├── daily/
└── weekly/
```
Clone your notes repo to `~/notes/` before using the note commands.
---
## Dependencies
| Tool | Install |
|---|---|
| `stow` | `dnf install stow` |
| `git` | `dnf install git` |
| `neovim` | `dnf install neovim` |
| `ripgrep` | `dnf install ripgrep` (needed by Telescope) |
| `mise` | `curl https://mise.run \| bash` |
---
## Learning resources
- `nvim +Tutor` — built-in hands-on tutor, ~30 min
- `man bash` — full bash reference
- `https://www.shellcheck.net` — paste a script, get feedback
- `https://mywiki.wooledge.org/BashGuide` — best bash guide
- `:help` in nvim — the built-in docs are good

125
bash/.bashrc Normal file
View File

@@ -0,0 +1,125 @@
# ~/.bashrc
# Loaded for interactive non-login shells.
# Keep this file readable. Each section explains what it does.
# If not running interactively, do nothing.
# This prevents issues when bash is invoked by scp or scripts.
case $- in
*i*) ;;
*) return ;;
esac
# ============================================================
# HISTORY
# ============================================================
HISTSIZE=10000
HISTFILESIZE=20000
HISTCONTROL=ignoredups:erasedups # don't store duplicate lines
shopt -s histappend # append to history, don't overwrite it
# ============================================================
# PROMPT
# ============================================================
# \u = username, \h = hostname, \w = current directory
# \e[COLORm = color code, \e[0m = reset color
# 32 = green, 34 = blue, 33 = yellow
__git_branch() {
local branch
branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
[ -n "$branch" ] && echo " ($branch)"
}
PS1='\e[32m\u@\h\e[0m:\e[34m\w\e[33m$(__git_branch)\e[0m\$ '
# ============================================================
# COMPLETION
# ============================================================
if [ -f /usr/share/bash-completion/bash_completion ]; then
. /usr/share/bash-completion/bash_completion
fi
# ============================================================
# EDITOR
# ============================================================
export EDITOR=nvim
export VISUAL=nvim
# ============================================================
# PATH
# ============================================================
# Add your personal scripts to PATH
export PATH="$HOME/.local/bin:$PATH"
# mise runtime manager — activates shims for node, dotnet, etc.
# See: ~/.config/mise/config.toml
if command -v mise &>/dev/null; then
eval "$(mise activate bash)"
fi
# ============================================================
# ALIASES
# ============================================================
# Navigation
alias ..='cd ..'
alias ...='cd ../..'
alias ll='ls -lah --color=auto'
alias la='ls -A --color=auto'
alias l='ls -CF --color=auto'
# Safety: ask before overwriting
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
# Quick edit and reload this file
alias bashrc='${EDITOR} ~/.bashrc && source ~/.bashrc'
# Git shortcuts (plain, no magic)
alias gs='git status'
alias ga='git add'
alias gc='git commit'
alias gp='git push'
alias gl='git log --oneline --graph --decorate -20'
# Notes shortcuts
# Opens inbox for quick capture
alias inbox='${EDITOR} ~/notes/inbox.md'
# Opens or creates today's daily note from template
today() {
local file=~/notes/daily/$(date +%Y-%m-%d).md
mkdir -p ~/notes/daily
if [ ! -f "$file" ]; then
sed "s/YYYY-MM-DD/$(date +%Y-%m-%d)/g" \
~/notes/templates/daily.md > "$file"
fi
${EDITOR} "$file"
}
# Opens or creates this week's weekly note from template
thisweek() {
local week=~/notes/weekly/$(date +%Y-W%V).md
mkdir -p ~/notes/weekly
if [ ! -f "$week" ]; then
sed "s/YYYY-WNN/$(date +%Y-W%V)/g" \
~/notes/templates/weekly.md > "$week"
fi
${EDITOR} "$week"
}
# Find all open tasks across all notes
alias tasks='grep -r "\- \[ \]" ~/notes/ --include="*.md"'
# Open decisions log
alias decisions='${EDITOR} ~/notes/decisions.md'
# ============================================================
# FUNCTIONS
# ============================================================
# Only add functions you can explain line by line.
# mkcd: create a directory and immediately enter it
mkcd() {
mkdir -p "$1" && cd "$1"
}

32
git/.gitconfig Normal file
View File

@@ -0,0 +1,32 @@
[user]
name = Your Name
email = you@example.com
[core]
editor = nvim
# Treat files with these line endings consistently on Linux
autocrlf = input
[init]
defaultBranch = main
[pull]
# Fail loudly if a pull would need a merge commit — forces you to decide
rebase = false
ff = only
[push]
# Only push the current branch, not all branches
default = current
[alias]
# Short log with graph
lg = log --oneline --graph --decorate -20
# Show what changed in the last commit
last = show --stat HEAD
# Undo the last commit but keep the changes staged
undo = reset --soft HEAD~1
[diff]
# Show moved lines differently from changed lines
colorMoved = default

View File

@@ -0,0 +1,20 @@
# ~/.config/mise/config.toml
#
# mise manages language runtime versions (node, dotnet, etc.)
# so you don't install them system-wide.
#
# After stowing this file, run:
# mise install
#
# To see what's available:
# mise ls-remote node
# mise ls-remote dotnet
[tools]
node = "lts" # latest LTS release of Node.js (for TypeScript)
dotnet = "latest" # latest .NET SDK (for C# and F#)
[settings]
# mise will warn if a project directory has no .mise.toml
# Set to false if you find the warnings noisy while learning
verbose = false

27
notes/daily-template.md Normal file
View File

@@ -0,0 +1,27 @@
# YYYY-MM-DD — Daily
## Today's focus
Three things that would make today a success:
1.
2.
3.
## Tasks
Pulled from inbox. Only commit to what is realistic today.
- [ ]
## Log
Running notes during the day. Decisions, context, things that came up.
---
## End of day
What got done, what didn't, anything to carry forward.
Undone tasks: move back to inbox or forward to tomorrow explicitly.

17
notes/decisions.md Normal file
View File

@@ -0,0 +1,17 @@
# Decisions
Append-only. Never edit past entries.
Add new decisions at the bottom with a date and context.
Format:
## YYYY-MM-DD — Short title
**Decision:** What was decided.
**Why:** The reason or constraint behind it.
**Who:** Who made or owns this decision.
---
## YYYY-MM-DD — Example entry
**Decision:** Use SSH keys for git commit signing instead of GPG.
**Why:** Avoids GPG keychain complexity, same key used for auth and signing.
**Who:** Edwin

8
notes/inbox.md Normal file
View File

@@ -0,0 +1,8 @@
# Inbox
Everything lands here. Do not organise while capturing.
Process during your daily or weekly review.
---
- [ ]

30
notes/weekly-template.md Normal file
View File

@@ -0,0 +1,30 @@
# YYYY-WNN — Weekly
## Review last week
Open last week's note. For each undone task, decide:
- [ ] Still relevant → move to inbox
- [ ] No longer relevant → mark with ~~strikethrough~~ and a note why
What went well:
What got in the way:
## This week's focus
Three things that would make this week a success:
1.
2.
3.
## Tasks
Pulled from inbox after review. Not everything — only what fits a week.
- [ ]
## Notes
Context, blockers, decisions made this week.
For decisions that should be permanent, copy to decisions.md.

284
nvim/.config/nvim/init.lua Normal file
View File

@@ -0,0 +1,284 @@
-- init.lua — minimal Neovim config based on kickstart.nvim
-- https://github.com/nvim-lua/kickstart.nvim
--
-- Read this file top to bottom. Every section explains what it does.
-- Remove anything you don't understand yet — a smaller config you own
-- is better than a large one you don't.
-- ============================================================
-- LEADER KEY
-- ============================================================
-- Must be set before plugins load. Space is the most common choice.
-- <leader> is used as a prefix for your custom keymaps below.
vim.g.mapleader = ' '
vim.g.maplocalleader = ' '
-- ============================================================
-- OPTIONS
-- ============================================================
-- vim.opt is how you set Neovim options from Lua.
-- :help option-name shows docs for any option.
vim.opt.number = true -- show line numbers
vim.opt.relativenumber = true -- relative numbers make motions easier (5j, 3k)
vim.opt.mouse = 'a' -- allow mouse in all modes (useful at first)
vim.opt.showmode = false -- mode shown in statusline instead
vim.opt.clipboard = 'unnamedplus' -- sync with system clipboard
vim.opt.breakindent = true -- wrapped lines indent visually
vim.opt.undofile = true -- persist undo history across sessions
vim.opt.ignorecase = true -- case-insensitive search ...
vim.opt.smartcase = true -- ... unless you type a capital
vim.opt.signcolumn = 'yes' -- always show sign column (avoids layout shifts)
vim.opt.updatetime = 250 -- faster completion and diagnostics
vim.opt.splitright = true -- new vertical splits open right
vim.opt.splitbelow = true -- new horizontal splits open below
vim.opt.list = true -- show whitespace characters
vim.opt.listchars = { tab = '» ', trail = '·', nbsp = '' }
vim.opt.scrolloff = 8 -- keep 8 lines visible above/below cursor
vim.opt.tabstop = 2 -- tabs display as 2 spaces
vim.opt.shiftwidth = 2 -- indent size
vim.opt.expandtab = true -- use spaces instead of tabs
vim.opt.wrap = false -- don't wrap long lines by default
-- ============================================================
-- KEYMAPS
-- ============================================================
-- vim.keymap.set(mode, keys, action, opts)
-- mode: 'n' normal, 'i' insert, 'v' visual, 'x' visual block
-- Clear search highlights with Escape
vim.keymap.set('n', '<Esc>', '<cmd>nohlsearch<CR>')
-- Move between windows with Ctrl+direction (no need for Ctrl+W first)
vim.keymap.set('n', '<C-h>', '<C-w><C-h>', { desc = 'Move to left window' })
vim.keymap.set('n', '<C-l>', '<C-w><C-l>', { desc = 'Move to right window' })
vim.keymap.set('n', '<C-j>', '<C-w><C-j>', { desc = 'Move to lower window' })
vim.keymap.set('n', '<C-k>', '<C-w><C-k>', { desc = 'Move to upper window' })
-- Quick save
vim.keymap.set('n', '<leader>w', '<cmd>write<CR>', { desc = 'Save file' })
-- Open netrw file explorer (built-in, no plugin needed)
vim.keymap.set('n', '<leader>e', '<cmd>Ex<CR>', { desc = 'Open file explorer' })
-- Diagnostic keymaps (errors from LSP)
vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, { desc = 'Previous diagnostic' })
vim.keymap.set('n', ']d', vim.diagnostic.goto_next, { desc = 'Next diagnostic' })
vim.keymap.set('n', '<leader>d', vim.diagnostic.open_float, { desc = 'Show diagnostic' })
-- ============================================================
-- AUTOCOMMANDS
-- ============================================================
-- These run automatically on specific events.
-- Highlight text briefly when you yank (copy)
vim.api.nvim_create_autocmd('TextYankPost', {
desc = 'Highlight on yank',
callback = function()
vim.highlight.on_yank()
end,
})
-- Markdown-specific settings
vim.api.nvim_create_autocmd('FileType', {
pattern = 'markdown',
callback = function()
vim.opt_local.wrap = true -- wrap lines in markdown
vim.opt_local.spell = true -- enable spellcheck
vim.opt_local.spelllang = 'en'
vim.opt_local.conceallevel = 1 -- hide markdown syntax slightly
end,
})
-- ============================================================
-- PLUGIN MANAGER: lazy.nvim
-- ============================================================
-- lazy.nvim bootstraps itself if not installed.
-- It clones from GitHub the first time you open Neovim.
local lazypath = vim.fn.stdpath 'data' .. '/lazy/lazy.nvim'
if not vim.loop.fs_stat(lazypath) then
vim.fn.system {
'git', 'clone', '--filter=blob:none',
'https://github.com/folke/lazy.nvim.git',
'--branch=stable',
lazypath,
}
end
vim.opt.rtp:prepend(lazypath)
-- ============================================================
-- PLUGINS
-- ============================================================
-- Each table is one plugin. 'keys' means the plugin only loads
-- when you press that key (lazy loading). This keeps startup fast.
require('lazy').setup({
-- Detect indent settings from file (tabs vs spaces, width)
-- No config needed — it just works.
'tpope/vim-sleuth',
-- Comment lines with gc (gcc for one line, gc in visual mode)
{ 'numToStr/Comment.nvim', opts = {} },
-- --------------------------------------------------------
-- TELESCOPE: fuzzy finder
-- --------------------------------------------------------
-- Requires ripgrep for live_grep: dnf install ripgrep
{
'nvim-telescope/telescope.nvim',
branch = '0.1.x',
dependencies = { 'nvim-lua/plenary.nvim' },
config = function()
require('telescope').setup {}
local builtin = require 'telescope.builtin'
-- <leader>f prefix for "find"
vim.keymap.set('n', '<leader>ff', builtin.find_files, { desc = 'Find files' })
vim.keymap.set('n', '<leader>fg', builtin.live_grep, { desc = 'Find in files' })
vim.keymap.set('n', '<leader>fb', builtin.buffers, { desc = 'Find open buffers' })
vim.keymap.set('n', '<leader>fh', builtin.help_tags, { desc = 'Find help' })
vim.keymap.set('n', '<leader>fd', builtin.diagnostics, { desc = 'Find diagnostics' })
end,
},
-- --------------------------------------------------------
-- TREESITTER: syntax highlighting and indentation
-- --------------------------------------------------------
{
'nvim-treesitter/nvim-treesitter',
build = ':TSUpdate',
config = function()
require('nvim-treesitter.configs').setup {
-- Install these parsers automatically
ensure_installed = {
'bash', 'lua', 'markdown', 'markdown_inline',
'typescript', 'javascript', 'c_sharp',
},
auto_install = true,
highlight = { enable = true },
indent = { enable = true },
}
end,
},
-- --------------------------------------------------------
-- LSP: language server protocol
-- --------------------------------------------------------
-- mason installs language servers for you.
-- mason-lspconfig bridges mason and nvim-lspconfig.
{
'neovim/nvim-lspconfig',
dependencies = {
'williamboman/mason.nvim',
'williamboman/mason-lspconfig.nvim',
},
config = function()
-- mason must be set up first
require('mason').setup()
require('mason-lspconfig').setup {
-- These servers are installed automatically
ensure_installed = {
'ts_ls', -- TypeScript / JavaScript
'omnisharp', -- C# and F#
'marksman', -- Markdown
'lua_ls', -- Lua (for editing this config)
},
}
-- Keymaps that only activate when an LSP attaches to a buffer
vim.api.nvim_create_autocmd('LspAttach', {
callback = function(event)
local map = function(keys, func, desc)
vim.keymap.set('n', keys, func, { buffer = event.buf, desc = desc })
end
map('gd', vim.lsp.buf.definition, 'Go to definition')
map('gD', vim.lsp.buf.declaration, 'Go to declaration')
map('gr', vim.lsp.buf.references, 'Go to references')
map('K', vim.lsp.buf.hover, 'Hover documentation')
map('<leader>rn', vim.lsp.buf.rename, 'Rename symbol')
map('<leader>ca', vim.lsp.buf.code_action, 'Code action')
end,
})
-- Server-specific settings
local lspconfig = require 'lspconfig'
lspconfig.ts_ls.setup {}
lspconfig.omnisharp.setup {
-- Point to your solution file if needed
-- cmd = { 'omnisharp', '--solution-path', 'YourSolution.sln' },
}
lspconfig.marksman.setup {}
lspconfig.lua_ls.setup {
settings = {
Lua = {
-- Teach the Lua LSP about Neovim's globals
diagnostics = { globals = { 'vim' } },
},
},
}
end,
},
-- --------------------------------------------------------
-- COMPLETION: nvim-cmp
-- --------------------------------------------------------
{
'hrsh7th/nvim-cmp',
dependencies = {
'hrsh7th/cmp-nvim-lsp', -- LSP completions
'hrsh7th/cmp-buffer', -- completions from current buffer
'hrsh7th/cmp-path', -- file path completions
'L3MON4D3/LuaSnip', -- snippet engine (required by cmp)
'saadparwaiz1/cmp_luasnip',
},
config = function()
local cmp = require 'cmp'
local luasnip = require 'luasnip'
cmp.setup {
snippet = {
expand = function(args)
luasnip.lsp_expand(args.body)
end,
},
mapping = cmp.mapping.preset.insert {
['<C-n>'] = cmp.mapping.select_next_item(),
['<C-p>'] = cmp.mapping.select_prev_item(),
['<C-y>'] = cmp.mapping.confirm { select = true }, -- confirm
['<C-Space>'] = cmp.mapping.complete(), -- open manually
},
sources = {
{ name = 'nvim_lsp' },
{ name = 'luasnip' },
{ name = 'buffer' },
{ name = 'path' },
},
}
end,
},
-- --------------------------------------------------------
-- COLORSCHEME
-- --------------------------------------------------------
-- A clean, low-distraction theme. Change to any you prefer.
{
'rebelot/kanagawa.nvim',
priority = 1000, -- load before other plugins
config = function()
vim.cmd.colorscheme 'kanagawa'
end,
},
}, {
-- lazy.nvim options
ui = {
-- Use ascii borders if your terminal font lacks nerdfont icons
border = 'rounded',
},
})

77
provision.sh Normal file
View File

@@ -0,0 +1,77 @@
#!/usr/bin/env bash
# provision.sh — set up a new machine from this dotfiles repo
#
# What this does:
# 1. Installs system dependencies (stow, git, neovim, mise, ripgrep)
# 2. Uses stow to symlink each config package into your home directory
#
# What this does NOT do:
# - Set your git name/email (edit git/.gitconfig yourself)
# - Run mise install (do that manually after review)
#
# Usage:
# bash provision.sh # normal run
# bash provision.sh --dry-run # show what would happen, do nothing
set -euo pipefail
DRY_RUN=false
if [[ "${1:-}" == "--dry-run" ]]; then
DRY_RUN=true
echo "[dry-run] No changes will be made."
fi
run() {
if $DRY_RUN; then
echo "[dry-run] $*"
else
"$@"
fi
}
DOTFILES_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
echo "Dotfiles directory: $DOTFILES_DIR"
# ============================================================
# SYSTEM PACKAGES
# ============================================================
echo "==> Installing system packages..."
run sudo dnf install -y \
stow \
git \
neovim \
ripgrep \
curl
# Install mise if not already present
if ! command -v mise &>/dev/null; then
echo "==> Installing mise..."
run curl https://mise.run | bash
else
echo "==> mise already installed, skipping."
fi
# ============================================================
# STOW PACKAGES
# ============================================================
# Each directory in dotfiles/ is a stow "package".
# stow creates symlinks in ~ that mirror the package directory structure.
#
# Example: bash/.bashrc → ~/.bashrc
PACKAGES=(bash git mise nvim)
echo "==> Stowing config packages..."
for pkg in "${PACKAGES[@]}"; do
echo " stow $pkg"
# --restow removes and recreates links (handles updates)
# --target=$HOME is explicit about where links go
run stow --restow --target="$HOME" --dir="$DOTFILES_DIR" "$pkg"
done
echo ""
echo "Done. Next steps:"
echo " 1. Edit ~/gitconfig — set your name and email"
echo " 2. Run: mise install"
echo " 3. Open nvim — plugins will install automatically on first launch"
echo " 4. In nvim, run :checkhealth to verify your setup"