Coming from slice-ansi
A slice-ansi alternative with a drop-in path: import sliceAnsi from linegauge/slice, graded 15 / 15 by slice-ansi's own test suite, including the OSC 8 hyperlink case slice-ansi marks as failing — then zero dependencies, grapheme clusters never halved, and one style stack shared with wrap.
linegauge is a slice-ansi alternative you adopt by changing one import.
linegauge/slice's default export is slice, call-compatible with slice-ansi's default, and
slice-ansi's own test suite is the grade.
Migrate from slice-ansi in one import
- import sliceAnsi from 'slice-ansi';
+ import sliceAnsi from 'linegauge/slice';The call is slice-ansi's — sliceAnsi(string, start, end), in display columns, end
optional. The same function is also the named export slice, from linegauge/slice or from
linegauge.
It also answers the questions slice-ansi's neighbours do, one subpath each:
| Incumbent | linegauge path |
|---|---|
string-width | linegauge (the default export) |
strip-ansi | linegauge/strip |
wrap-ansi | linegauge/wrap |
slice-ansi | linegauge/slice |
Is linegauge compatible with slice-ansi?
Graded, not claimed. slice-ansi's own suite, vendored at 7.1.2 and unmodified apart from the
import specifier, runs against linegauge/slice beside a control that runs it against the
real slice-ansi:
| passing | rate | |
|---|---|---|
linegauge/slice | 15 / 15 | 100.0% |
| slice-ansi itself (control) | 15 / 15 | 100.0% |
From Compatibility, which npm run compat:page generates from the
oracle's last run; that page is the authority. One of the fifteen, slice links, is marked
test.failing() in slice-ansi's own suite — the incumbent cannot round-trip an OSC 8
hyperlink and says so. linegauge can, so the assertion passes; the runner reports an
unexpected pass as not ok, and the grader counts it as the pass it is and marks it on the
page rather than letting it look like the fourteen beside it.
The suite is pinned at 7.1.2, not at slice-ansi's current major: the control grades against the slice-ansi this workspace installs, which is 7, and grading 9's suite against a 7 control would publish the gap between two of the incumbent's own majors as linegauge's.
The same page grades linegauge against string-width (229 / 229), linegauge/strip against
strip-ansi (8 / 8) and linegauge/wrap against wrap-ansi (80 / 80).
What you gain over slice-ansi
slice-ansi 7.1.2 depends on ansi-styles and is-fullwidth-code-point. linegauge/slice
depends on nothing, and it is pure: nothing in linegauge reads process, so the same input
slices the same way on a pipe, under --json and in a test.
- Hyperlinks survive the cut. An
OSC 8link open atstartis re-emitted at the front of the slice and closed at its end — the case slice-ansi's own suite marks as one it fails. - A cluster is never halved. Columns come from the same
widththat passes string-width's suite 229 / 229, and cluster boundaries from the platform's ownIntl.Segmenter. A cluster that straddles the boundary is included whole, so a slice can be one column wider than asked but never returns half a family emoji or one letter of a flag. - One style stack, not two. slice-ansi and wrap-ansi each carry their own copy of
open/close/reopen, and they disagree at the edges.
linegauge/sliceandlinegauge/wrapshare one, so slicing and wrapping the same styled string agree. - The family measures with it. burgee, caique and flagstaff build on linegauge, so what they write for a pipe or an agent is cut the same way.
When to switch from slice-ansi
- Your output carries terminal hyperlinks, and a slice of it has to keep them.
- Your dependency tree carries slice-ansi beside string-width, strip-ansi or wrap-ansi, and you would rather it carried one package with no dependencies.
The API and the design notes are on linegauge; the width path is on Coming from string-width.