# injm
A CLI tool that injects content into marked regions in source files.
## Table of Contents
- [Installation](#installation)
- [Cargo](#cargo)
- [Nix](#nix)
- [Download Binary](#download-binary)
- [Usage](#usage)
- [Inject into a Specific Region](#inject-into-a-specific-region)
- [Sync Between Files](#sync-between-files)
- [Dry Run](#dry-run)
- [Supported Languages](#supported-languages)
- [Roadmap](#roadmap)
- [License](#license)
- [Acknowledgement](#acknowledgement)
## Installation
### Cargo
```bash
cargo install injm
```
### Nix
```bash
nix profile install github:Fovir-GitHub/injm
```
### Download Binary
Download the latest binary for your platform from [GitHub Releases](https://github.com/Fovir-GitHub/injm/releases/latest).
## Usage
Mark a region in your source file with `injm begin` and `injm end` comments:
`dest.rs`
```rust
fn main() {
// injm begin
// injm end
}
```
Then pipe content into `injm`:
```bash
Result:
`dest.rs`
```rust
fn main() {
// injm begin
println!("Hello, world!");
// injm end
}
```
Running `injm` again will replace the content between the markers:
```bash
### Inject into a Specific Region
Give a region an output ID with `>id`, then target it with `--id`:
`dest.rs`
```rust
fn main() {
// injm begin >greeting
// injm end
// injm begin >farewell
// injm end
}
```
Inject into a specific region:
```bash
Inject into multiple regions at once:
```bash
If `--id` is not specified, only regions **without** an ID are injected; regions with a `>id` are left untouched.
### Sync Between Files
Instead of piping from stdin, copy content between files with `--input`.
Mark the source region with `<id` (the content to read) and the destination
region with `>id` (where it goes):
`src.rs`
```rust
fn main() {
// injm begin <hello
println!("Hello, world!");
// injm end
}
```
`dest.rs`
```rust
fn main() {
// injm begin >hello
// injm end
}
```
Then sync:
```bash
injm --input src.rs --output dest.rs
```
`dest.rs` becomes:
```rust
fn main() {
// injm begin >hello
println!("Hello, world!");
// injm end
}
```
A region may read from several sources by listing multiple `<id` markers.
If a `>id` in the output has no matching `<id` in the input, `injm` reports
the missing ID and exits with an error.
### Dry Run
Preview the result without writing to the file:
```bash
## Supported Languages
`injm` uses [tree-sitter](https://tree-sitter.github.io/tree-sitter/) to parse source files, so markers are detected from actual comment nodes — not from string literals or other non-comment content.
Supports any language recognized by [tree-sitter-language-pack](https://github.com/kreuzberg-dev/tree-sitter-language-pack), including:
- Rust, C, C++
- Python, Ruby
- JavaScript, TypeScript
- Go, Java
- And [300+ more](https://github.com/kreuzberg-dev/tree-sitter-language-pack)
## Roadmap
See [ROADMAP.md](ROADMAP.md).
## License
MIT
## Acknowledgement
- [clap-rs/clap](https://github.com/clap-rs/clap): A full featured, fast Command Line Argument Parser for Rust
- [xberg-io/tree-sitter-language-pack](https://github.com/xberg-io/tree-sitter-language-pack): Comprehensive tree-sitter grammar compilation with polyglot bindings — Rust, Python, Node.js, Go, Java, Ruby, Elixir, PHP, C#, WASM, Dart, Kotlin-Android, Swift, Zig, and CLI. 306+ languages.