Skip to content

Lesson 11 — Dev & Code

Tools for writing code, managing projects, and working with dev environments. Configured in vendor/nixproject/modules/home/cli.nix and vendor/nixproject/modules/home/editors.nix.


git + delta

git is configured with delta as the diff viewer. Delta gives you side-by-side diffs with syntax highlighting instead of the raw +/- line output.

What delta changes

Running git diff or git show now routes through delta automatically. You don't invoke delta directly — it hooks into git's pager.

git diff                      # side-by-side highlighted diff
git diff HEAD~1               # diff against one commit ago
git show abc123               # show a commit with delta output
git log -p                    # log with diffs, all delta-formatted

Your config sets side-by-side = true, so the old and new versions appear in columns instead of interleaved:

───────────────────────────────────────────┬────────────────────────────────────────────
 home.packages = with pkgs; [              │  home.packages = with pkgs; [
   ripgrep                                 │    ripgrep
-  bat                                     │
+                                          │    bat
+                                          │    fd
 ];                                        │  ];
───────────────────────────────────────────┴────────────────────────────────────────────

Everyday git workflow

git status                    # what's changed
git add -p                    # interactively stage hunks (review before committing)
git commit -m "message"       # commit
git log --oneline --graph     # compact history with branch graph
git log -p filename           # history of a specific file with diffs
git stash                     # temporarily shelve changes
git stash pop                 # bring them back

Useful git aliases worth knowing

git diff --cached             # diff of what's staged (about to be committed)
git diff HEAD                 # diff of everything since last commit (staged + unstaged)
git show --stat HEAD          # files changed in last commit
git blame filename            # who wrote each line

direnv + nix-direnv

direnv watches for .envrc files. When you cd into a directory that has one, it automatically activates the environment defined there. When you leave, it deactivates.

nix-direnv extends this to understand flake.nix — so entering a project directory automatically puts you in the right Nix dev shell with all the project's tools available.

How it works in practice

You navigate into a project:

$ cd ~/Developer/nixlessons
direnv: loading ~/Developer/nixlessons/.envrc
direnv: using flake
direnv: nix-direnv: using cached dev shell
$

Now mkdocs is in your PATH because flake.nix includes it in the dev shell. Leave the directory and it's gone again.

Setting up a project

For a project with a flake.nix, create a .envrc:

echo "use flake" > .envrc
direnv allow              # must approve each new .envrc

For a project without a flake, you can still use an .envrc to load packages:

# .envrc — load some packages from nixpkgs for this project
use nix

Or set environment variables:

# .envrc
export DATABASE_URL="postgres://localhost/mydb"
export NODE_ENV="development"

Common direnv commands

direnv allow              # approve .envrc in current directory
direnv deny               # revoke approval
direnv reload             # force reload of current .envrc
direnv status             # show what's loaded

Why nix-direnv specifically

Plain direnv with use flake works but re-evaluates the flake on every shell entry (slow). nix-direnv caches the result, so after the first load it's instant. Your Home Manager config already enables nix-direnv.enable = true.


micro — friendly terminal editor

micro is your "I just need to quickly edit this file" editor. It uses familiar keyboard shortcuts (Ctrl-S to save, Ctrl-Z to undo, Ctrl-C/V for copy/paste) — no modal editing to think about.

micro file.txt            # open a file
micro                     # open empty buffer

Key shortcuts:

Shortcut Action
Ctrl-S Save
Ctrl-Q Quit
Ctrl-Z Undo
Ctrl-Y Redo
Ctrl-F Find
Ctrl-H Find and replace
Ctrl-A Select all
Ctrl-C Copy
Ctrl-V Paste
Ctrl-X Cut
Ctrl-G Go to line number
Ctrl-E Command bar (for ex-style commands)

Good for: editing config files quickly, writing short notes in the terminal, anything where you don't want to think about your editor.


helix — zero-config modal editor

Helix is a modal editor (like Vim) but with modern defaults out of the box: built-in LSP support, tree-sitter syntax highlighting, and multiple cursors. No plugin system needed — it works well without configuration.

hx file.txt               # open a file
hx .                      # open current directory (file picker)

The modal model

Helix has modes. The mode you're in determines what keys do:

Mode How to enter What keys do
Normal Start here / press Esc Navigate, run commands
Insert Press i Type text
Select Press v Select text, extend selections

Core Normal mode keys

Motion:

h j k l         ← ↓ ↑ →
w / b           next / previous word
e               end of word
0 / $           start / end of line
gg / G          top / bottom of file
Ctrl-d / Ctrl-u half-page down / up

Edit:

i               insert before cursor
a               insert after cursor (append)
o / O           open new line below / above
d               delete selection
c               change selection (delete and enter insert)
y               yank (copy) selection
p               paste after
u               undo
Ctrl-r          redo

Selection first (Helix's key difference from Vim):

Helix uses a selection-action model. You select what you want to act on, then do the action. This is the opposite of Vim's verb-motion model.

v               start selection
x               select current line
%               select whole file
;               collapse selection to cursor

Search:

/               search forward
?               search backward
n / N           next / previous match

Commands (press : to enter command mode):

:w              save
:q              quit
:wq             save and quit
:q!             quit without saving

Useful Helix features

Space menu — press Space in Normal mode for context-sensitive actions (code actions, diagnostics, file picker):

Space-f         file picker
Space-b         buffer picker
Space-s         symbol picker (LSP)
Space-d         diagnostics

LSP is automatic — if a language server for the file type is installed, Helix uses it. For Nix files, install nil or nixd:

home.packages = [ pkgs.nil ];  # Nix LSP


neovim — your $EDITOR

Neovim is set as the default editor ($EDITOR=nvim) with vi and vim aliased to it. Your config enables it via Home Manager with no further plugins — a clean starting point.

nvim file.txt             # open file
nvim .                    # open directory browser (netrw)

Since Neovim has a large learning curve and Ian's dotfiles have a full nixvim config you can study (vendor/dotfiles-main/home-manager/nixvim.nix), this lesson covers just the essentials for daily survival.

Essential Normal mode

i               insert mode
Esc             back to Normal
:w              save
:q              quit
:wq             save and quit
:q!             force quit without saving

Navigation:

h j k l         ← ↓ ↑ →
gg              top of file
G               bottom of file
Ctrl-d          half page down
Ctrl-u          half page up
/               search
n               next match

Edit:

dd              delete line
yy              yank (copy) line
p               paste below
u               undo
Ctrl-r          redo
.               repeat last change

The most important survival skill: If you're stuck and don't know what mode you're in, press Esc a couple of times to get back to Normal mode, then :q! to exit without saving.

When to use which editor

Situation Use
Quick edit, unfamiliar file micro — familiar shortcuts, no thinking required
Code editing with LSP hx — zero-config, built-in language server
Extended editing session nvim — once you've learned it, fastest for heavy editing
Nix config files hx or nvim — both handle Nix syntax well