injm
A CLI tool that injects content into marked regions in source files.
Table of Contents
Installation
Cargo
Nix
Download Binary
Download the latest binary for your platform from GitHub Releases.
Usage
injm uses subcommands. The main one is inject:
Basic Injection
Mark a region in your source file with injm begin and injm end comments:
dest.rs
Then pipe content into injm:
|
Result:
dest.rs
Running injm inject again will replace the content between the markers:
|
Inject into a Specific Region
Give a region an output ID with >id, then target it with --id:
dest.rs
Inject into a specific region:
|
Inject into multiple regions at once:
|
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
dest.rs
Then sync:
dest.rs becomes:
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.
Multiple Files and Globs
--input and --output accept multiple values and glob patterns:
# Multiple explicit files
# Sync to multiple outputs
# Glob patterns
# Multiple globs
List Markers
Preview all marker regions across files:
Output:
+-------------+----------+--------+-------+
| File | ID | Type | Lines |
+-------------+----------+--------+-------+
| src/main.rs | hello | output | 6-7 |
+-------------+----------+--------+-------+
| src/main.rs | hello | input | 23-24 |
+-------------+----------+--------+-------+
| src/cli.rs | greeting | input | 1-2 |
+-------------+----------+--------+-------+
JSON output:
Accepts positional arguments (files, globs, or directories). Falls back to current directory when no argument is given.
Dry Run
Preview the result without writing to the file:
|
To see a unified diff of what would change instead of the full file, add --diff:
|
Check
Verify that all output blocks (>id) contain the same content as their matching input blocks (<id):
If all blocks are synchronized, injm check exits 0 and prints:
all marker blocks are synchronized
If any are out of sync, it exits non-zero and lists each mismatch:
src/main.rs:12-14: output block `hello` is out of sync
To see a unified diff of what each out-of-sync block should contain, use
--diff:
Accepts files, globs, or directories as arguments. Falls back to current directory when no argument is provided.
Supported Languages
injm uses 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, including:
- Rust, C, C++
- Python, Ruby
- JavaScript, TypeScript
- Go, Java
- And 300+ more
Roadmap
See ROADMAP.md.
License
MIT
Acknowledgement
- clap-rs/clap: A full featured, fast Command Line Argument Parser for Rust.
- rust-lang/glob: Support for matching file paths against Unix shell style patterns.
- serde-rs/serde: Serialization framework for Rust.
- 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.
- zhiburt/tabled: An easy to use library for pretty print tables of Rust structs and enums.