magic_string
String editing by byte offset, with a source map as a byproduct.
Keep the original source, record overwrite/remove/insert edits keyed by
UTF-8 byte offset, then to_string and generate_map replay the log.
Surviving slices of the original produce mapping segments; inserted text
does not.
Types
A concatenation of edited sources. Materializes to the joined output text and a single Source Map v3 spanning every source.
pub opaque type Bundle
Why an edit was rejected.
pub type EditError {
Overlap(existing: #(Int, Int), attempted: #(Int, Int))
SwallowedInsert(at: Int, range: #(Int, Int))
OutOfBounds(offset: Int, source_length: Int)
InvertedRange(start: Int, end: Int)
}
Constructors
-
Overlap(existing: #(Int, Int), attempted: #(Int, Int))attemptedshares at least one byte with anexistingrange. -
SwallowedInsert(at: Int, range: #(Int, Int))An insert at
atfalls strictly insiderange(range.0 < at < range.1). Boundaries are fine. -
OutOfBounds(offset: Int, source_length: Int)offsetis outside[0, source_length]. -
InvertedRange(start: Int, end: Int)end < start.
Immutable string editor. Keeps the original source plus a sorted edit log
and is materialized lazily by to_string / generate_map.
intro/outroaccumulateprepend/appendcontent wrapping the whole string.editsmaps an edit’s start offset to the overwrite/remove at that point.left_inserts/right_insertsmap a byte offset to text inserted just left of (after the preceding content) or right of (before the following content) that offset.
pub opaque type MagicString
Options shared by generate_map and bundle_generate_map.
pub type MapOptions {
MapOptions(
file: option.Option(String),
source_root: option.Option(String),
include_content: Bool,
)
}
Constructors
-
MapOptions( file: option.Option(String), source_root: option.Option(String), include_content: Bool, )
Values
pub fn add_source(
b: Bundle,
filename: String,
content: String,
ms: MagicString,
) -> Bundle
Append a source to the bundle. filename is the name recorded in the map’s
sources; content is the original text; ms is its edit log.
pub fn append(ms: MagicString, content: String) -> MagicString
Append content to the very end of the output.
pub fn append_left(
ms: MagicString,
index: Int,
content: String,
) -> Result(MagicString, EditError)
Insert content just LEFT of index: after the content that ends at
index, before anything inserted to the right of index. Repeated calls
at the same index append in call order.
Returns Error(SwallowedInsert) if index falls strictly inside an
existing overwrite/remove range (the insert would never be visited and so
would be silently dropped), or Error(OutOfBounds) if index is outside
the source.
pub fn append_right(
ms: MagicString,
index: Int,
content: String,
) -> Result(MagicString, EditError)
Insert content just RIGHT of index: before the content that starts at
index, after anything inserted to the left of index. Repeated calls at
the same index append in call order.
Returns Error for the same reasons as append_left.
pub fn bundle_generate_map(
b: Bundle,
opts: MapOptions,
) -> codec.SourceMap
Generate one Source Map v3 spanning every source in output order.
Walks each source’s pieces, offsetting their segments into chunk-space: the
generated line/column accumulates across the whole output, and the newline
joining each source to the next advances the generated line by one (and
resets the column). Each source is assigned its index in sources.
pub fn bundle_to_string(b: Bundle) -> String
Materialize the bundle output: each source’s edited text, joined by newlines (one line break between sources).
pub fn default_map_options() -> MapOptions
Sensible defaults: no file, no sourceRoot, embed original content.
pub fn describe_error(err: EditError) -> String
Human-readable description of an EditError.
pub fn generate_map(
ms: MagicString,
filename: String,
opts: MapOptions,
) -> codec.SourceMap
Generate a Source Map v3 for a single edited source. filename is recorded
as the sole entry of sources; include_content controls whether the
original text is embedded in sourcesContent.
pub fn overwrite(
ms: MagicString,
start: Int,
end: Int,
with content: String,
) -> Result(MagicString, EditError)
Replace the original byte range [start, end) with with. The
replacement is inserted text and produces no mapping segment.
Returns Error if [start, end) overlaps an existing range, would
swallow an existing insert, or is out of bounds. Same-start is
last-write-wins; adjacent ranges that only share a boundary are fine.
pub fn prepend(ms: MagicString, content: String) -> MagicString
Prepend content to the very start of the output. Repeated calls stack so
the most recent prepend ends up first.
pub fn remove(
ms: MagicString,
start: Int,
end: Int,
) -> Result(MagicString, EditError)
Delete the original byte range [start, end). Returns Error for the
same reasons as overwrite (it is overwrite with an empty replacement).
pub fn to_string(ms: MagicString) -> String
Materialize the edited output as a string.