···11-# sdiff
11+# adiff
2233A semantic, side-by-side diff viewer for the terminal with `$EDITOR` support.
4455-Unlike traditional diff tools, sdiff uses [tree-sitter](https://tree-sitter.github.io/tree-sitter/) to parse source files into ASTs and diffs at the token level. This means pure formatting changes — re-indented blocks, reformatted function signatures, whitespace normalization — are shown as equal, while genuine logic changes are clearly highlighted.
55+Unlike traditional diff tools, adiff uses [tree-sitter](https://tree-sitter.github.io/tree-sitter/) to parse source files into ASTs and diffs at the token level. This means pure formatting changes — re-indented blocks, reformatted function signatures, whitespace normalization — are shown as equal, while genuine logic changes are clearly highlighted.
6677-
77+
8899## Features
10101111- **Semantic diff** — tree-sitter token-level diffing ignores style-only changes
1212- **Syntax highlighting** — per-language color via [Chroma](https://github.com/alecthomas/chroma)
1313-- **Live file watching** — press `e` to open the new file in `$EDITOR`; sdiff watches for saves and reloads automatically
1313+- **Live file watching** — press `e` to open the new file in `$EDITOR`; adiff watches for saves and reloads automatically
1414- **Vim keybindings** — `j`/`k`, `g`/`G`, `n`/`p` for change navigation
1515- **Themeable** — TOML theme files with full colour control; `nord` built-in
1616···2727### Nix (flake)
28282929```nix
3030-inputs.sdiff.url = "git+https://tangled.org/adriano.tngl.sh/sdiff";
3030+inputs.adiff.url = "git+https://tangled.org/adriano.tngl.sh/adiff";
3131```
32323333-Then add `inputs.sdiff.packages.${system}.default` to your packages, or use the provided overlay.
3333+Then add `inputs.adiff.packages.${system}.default` to your packages, or use the provided overlay.
34343535**Direct package reference** (home-manager / NixOS `environment.systemPackages`):
36363737```nix
3838-home.packages = [ inputs.sdiff.packages.${pkgs.system}.default ];
3838+home.packages = [ inputs.adiff.packages.${pkgs.system}.default ];
3939```
40404141-**Overlay** — adds `pkgs.sdiff` to your package set:
4141+**Overlay** — adds `pkgs.adiff` to your package set:
42424343```nix
4444-nixpkgs.overlays = [ inputs.sdiff.overlays.default ];
4444+nixpkgs.overlays = [ inputs.adiff.overlays.default ];
45454646# Then reference it like any nixpkgs package:
4747-home.packages = [ pkgs.sdiff ];
4747+home.packages = [ pkgs.adiff ];
4848```
49495050In a NixOS or home-manager flake this typically looks like:
···5454 inputs = {
5555 nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
5656 home-manager.url = "github:nix-community/home-manager";
5757- sdiff.url = "git+https://tangled.org/adriano.tngl.sh/sdiff";
5757+ adiff.url = "git+https://tangled.org/adriano.tngl.sh/adiff";
5858 };
59596060- outputs = { nixpkgs, home-manager, sdiff, ... }: {
6060+ outputs = { nixpkgs, home-manager, adiff, ... }: {
6161 homeConfigurations.yourname = home-manager.lib.homeManagerConfiguration {
6262 pkgs = import nixpkgs {
6363 system = "x86_64-linux";
6464- overlays = [ sdiff.overlays.default ];
6464+ overlays = [ adiff.overlays.default ];
6565 };
6666 modules = [
6767- ({ pkgs, ... }: { home.packages = [ pkgs.sdiff ]; })
6767+ ({ pkgs, ... }: { home.packages = [ pkgs.adiff ]; })
6868 ];
6969 };
7070 };
···7474## Usage
75757676```
7777-sdiff [flags] <old-file> <new-file>
7777+adiff [flags] <old-file> <new-file>
7878```
79798080| Flag | Default | Description |
···100100101101## Themes
102102103103-Themes are TOML files. sdiff searches for themes in this order:
103103+Themes are TOML files. adiff searches for themes in this order:
1041041051051. Literal path (if the value contains `/` or ends in `.toml`)
106106-2. `~/.config/sdiff/themes/<name>.toml`
106106+2. `~/.config/adiff/themes/<name>.toml`
1071073. Built-in `nord`
108108109109### Theme format
···130130cursor_symbol = "▶"
131131```
132132133133-Place custom themes at `~/.config/sdiff/themes/<name>.toml` and reference them with `-theme <name>`.
133133+Place custom themes at `~/.config/adiff/themes/<name>.toml` and reference them with `-theme <name>`.
134134135135## hookable integration
136136137137-[hookable](https://tangled.org/adriano.tngl.sh/hookable) is a Claude Code hook runner that exposes tool call inputs as environment variables and forwards them to an arbitrary command. sdiff reads these variables natively, so it can be dropped in as the `--cmd` to preview file changes before Claude applies them.
137137+[hookable](https://tangled.org/adriano.tngl.sh/hookable) is a Claude Code hook runner that exposes tool call inputs as environment variables and forwards them to an arbitrary command. adiff reads these variables natively, so it can be dropped in as the `--cmd` to preview file changes before Claude applies them.
138138139139-When invoked with no file arguments and `HOOKABLE_TOOL_NAME` is set, sdiff constructs the before/after diff automatically:
139139+When invoked with no file arguments and `HOOKABLE_TOOL_NAME` is set, adiff constructs the before/after diff automatically:
140140141141| Tool | Before | After |
142142|------|--------|-------|
···153153 "PreToolUse": [
154154 {
155155 "matcher": "Edit",
156156- "hooks": [{"type": "command", "command": "hookable --interactive --no-exit-code --cmd 'sdiff -i'"}]
156156+ "hooks": [{"type": "command", "command": "hookable --interactive --no-exit-code --cmd 'adiff -i'"}]
157157 },
158158 {
159159 "matcher": "Write",
160160- "hooks": [{"type": "command", "command": "hookable --interactive --no-exit-code --cmd 'sdiff -i'"}]
160160+ "hooks": [{"type": "command", "command": "hookable --interactive --no-exit-code --cmd 'adiff -i'"}]
161161 }
162162 ]
163163 }
164164}
165165```
166166167167-`--interactive` runs sdiff under a PTY so the full TUI renders. `--no-exit-code` tells hookable to ignore sdiff's exit code and always wait for a keypress — press `y` to allow the change or `n` to deny it.
167167+`--interactive` runs adiff under a PTY so the full TUI renders. `--no-exit-code` tells hookable to ignore adiff's exit code and always wait for a keypress — press `y` to allow the change or `n` to deny it.
168168169169## Development
170170171171```sh
172172nix develop # CGO-aware dev shell
173173go test ./... # run tests
174174-nix build # hermetic build → ./result/bin/sdiff
174174+nix build # hermetic build → ./result/bin/adiff
175175```
+1-1
docs/demo_new.go
···1111// processRequest handles an incoming HTTP request.
1212//
1313// The signature below is reformatted across multiple lines in the new
1414-// version. sdiff recognises the tokens are identical and shows those
1414+// version. adiff recognises the tokens are identical and shows those
1515// lines as equal — no highlight despite the whitespace change.
1616func processRequest(
1717 w http.ResponseWriter,
+1-1
docs/demo_old.go
···1010// processRequest handles an incoming HTTP request.
1111//
1212// The signature below is reformatted across multiple lines in the new
1313-// version. sdiff recognises the tokens are identical and shows those
1313+// version. adiff recognises the tokens are identical and shows those
1414// lines as equal — no highlight despite the whitespace change.
1515func processRequest(w http.ResponseWriter, r *http.Request) {
1616 name := r.URL.Query().Get("name")