# Splice Manual
**Version**: 0.1.0
**Status**: MVP / Proof of Concept
---
## Overview
Splice is a span-safe refactoring tool for Rust code that performs byte-accurate, AST-validated replacements.
### Core Philosophy
1. **Span Safety**: All operations work with exact byte spans
2. **Validation Gates**: Every patch passes tree-sitter reparse + cargo check
3. **Atomic Rollback**: Any failure triggers automatic rollback
4. **No Magic**: Explicit parameters only
### What Splice Does
- Replace function bodies, struct definitions, enum variants, trait definitions, impl blocks
- Validate syntax with tree-sitter after every patch
- Validate semantics with cargo check after every patch
- Rollback atomically if validation fails
- Orchestrate multi-step refactors with JSON plans
### What Splice Does NOT Do
- Cross-file reference tracking
- Automatic symbol discovery
- Smart refactoring (no "rename all references")
- Configuration files
- Persistent databases
---
## Installation
```bash
git clone https://github.com/oldnordic/splice.git
cd splice
cargo build --release
sudo cp target/release/splice /usr/local/bin/splice
```
---
## Quick Start
### Single Patch
```bash
splice patch \
--file src/lib.rs \
--symbol foo \
--kind function \
--with new_foo.rs
```
### Multi-Step Plan
Create `plan.json`:
```json
{
"steps": [
{
"file": "src/lib.rs",
"symbol": "foo",
"kind": "function",
"with": "patches/foo.rs"
},
{
"file": "src/lib.rs",
"symbol": "bar",
"kind": "function",
"with": "patches/bar.rs"
}
]
}
```
Execute:
```bash
splice plan --file plan.json
```
---
## Command Reference
### splice patch
Apply a single patch to a symbol's span.
```bash
splice patch \
--file <PATH> \
--symbol <NAME> \
[--kind <KIND>] \
--with <FILE>
```
**Required Arguments:**
- `--file <PATH>`: Path to source file
- `--symbol <NAME>`: Symbol name to patch
- `--with <FILE>`: Path to replacement file
**Optional Arguments:**
- `--kind <KIND>`: Symbol kind (function, struct, enum, trait, impl)
- `--analyzer <MODE>`: rust-analyzer mode (off, os)
- `-v, --verbose`: Enable verbose logging
**Symbol Kinds:**
| `function` | `pub fn foo() {}` |
| `struct` | `pub struct Foo;` |
| `enum` | `pub enum Bar {}` |
| `trait` | `pub trait Baz {}` |
| `impl` | `impl Foo {}` |
### splice plan
Execute a multi-step refactoring plan.
```bash
splice plan --file <PLAN.json>
```
**Execution Behavior:**
1. Steps execute sequentially
2. Stops on first failure
3. Previous successful steps remain applied
4. Each step has atomic rollback
---
## Patch File Format
### Function Replacement
**Original** (`src/lib.rs`):
```rust
pub fn greet(name: &str) -> String {
format!("Hello, {}!", name)
}
```
**Patch** (`new_greet.rs`):
```rust
pub fn greet(name: &str) -> String {
format!("Greetings, {}!", name)
}
```
**Command:**
```bash
splice patch --file src/lib.rs --symbol greet --kind function --with new_greet.rs
```
---
## Error Handling
### Common Errors
**Symbol Not Found:**
```
Error: Symbol not found: nonexistent
```
Check symbol name and verify `--file` path.
**Ambiguous Symbol:**
```
Error: Ambiguous symbol 'foo': found in multiple files
```
Add `--file` to disambiguate.
**Parse Validation Failed:**
```
Error: Parse validation failed - Tree-sitter detected syntax errors
```
Check patch file for syntax errors.
**Cargo Check Failed:**
```
Error: Cargo check failed - mismatched types
```
Fix type errors in patch file.
---
## Validation Gates
Every patch passes:
1. UTF-8 boundary validation
2. Tree-sitter reparse
3. Cargo check
**Rollback Behavior:**
- Automatic on any failure
- Atomic (temp + fsync + rename)
- No partial patch states
---
## Workflows
### Safe Function Rename
1. Create new function with desired name
2. Run splice to replace old function
3. Manually update call sites with IDE or `rg`
### Stub Implementation
1. Create stub with `todo!()` macro
2. Replace real implementation with splice
3. Implement later
### Multi-File Refactor
1. Create `plan.json` with all steps
2. Create patch files for each step
3. Execute plan
4. If step N fails, steps 1..N-1 remain applied
---
## Best Practices
**DO:**
- Run `cargo check` on patch files before using splice
- Use `--kind` to disambiguate when needed
- Test patches in git repos
- Use verbose mode for debugging
- Create backup branches
**DON'T:**
- Manually edit files after splice starts
- Skip `cargo check` on patch files
- Use patch files with syntax errors
- Assume splice will find all references
- Create plans with 100+ steps (no resume mode)
---
## Limitations
**Current Limitations:**
1. No cross-file reference tracking
2. No resume mode for failed plans
3. No auto-discovery of symbols
4. No persistent database
5. No dry-run mode
6. Single-file symbols only
---
## Technical Details
**How Splice Works:**
1. Extract symbols via tree-sitter
2. Resolve symbol byte span
3. Read replacement file
4. Replace span with ropey
5. Validate with tree-sitter + cargo check
6. Commit or rollback atomically
**Why Byte Spans:**
- Deterministic (independent of line endings)
- Exact (no ambiguity)
- Fast (no conversion overhead)
---
## License
GPL-3.0-or-later
---
**End of Manual**
For quick help:
```bash
splice --help
splice patch --help
splice plan --help
```