@peteanderson/ansi 0.3.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ansi.d.ts +28 -37
- package/dist/ansi.d.ts.map +1 -0
- package/dist/ansi.js +29 -52
- package/dist/ansi.js.map +1 -0
- package/dist/caret.d.ts +5 -3
- package/dist/caret.d.ts.map +1 -0
- package/dist/caret.js +6 -8
- package/dist/caret.js.map +1 -0
- package/dist/erase.d.ts +5 -1
- package/dist/erase.d.ts.map +1 -0
- package/dist/erase.js +4 -2
- package/dist/erase.js.map +1 -0
- package/dist/features/build.d.ts +7 -11
- package/dist/features/build.d.ts.map +1 -0
- package/dist/features/build.js +12 -25
- package/dist/features/build.js.map +1 -0
- package/dist/features/detect.d.ts +4 -4
- package/dist/features/detect.d.ts.map +1 -0
- package/dist/features/detect.js +5 -6
- package/dist/features/detect.js.map +1 -0
- package/dist/features/features.d.ts +4 -4
- package/dist/features/features.d.ts.map +1 -0
- package/dist/features/features.js +24 -34
- package/dist/features/features.js.map +1 -0
- package/dist/features/index.d.ts +2 -2
- package/dist/features/index.d.ts.map +1 -0
- package/dist/features/index.js +17 -1
- package/dist/features/index.js.map +1 -0
- package/dist/features/types.d.ts +10 -0
- package/dist/features/types.d.ts.map +1 -0
- package/dist/features/types.js +3 -0
- package/dist/features/types.js.map +1 -0
- package/dist/index.d.ts +3 -81
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -1
- package/dist/index.js.map +1 -0
- package/dist/pad.d.ts +3 -12
- package/dist/pad.d.ts.map +1 -0
- package/dist/pad.js +8 -14
- package/dist/pad.js.map +1 -0
- package/dist/patterns.d.ts +4 -3
- package/dist/patterns.d.ts.map +1 -0
- package/dist/patterns.js +6 -4
- package/dist/patterns.js.map +1 -0
- package/dist/scroll.d.ts +5 -3
- package/dist/scroll.d.ts.map +1 -0
- package/dist/scroll.js +6 -6
- package/dist/scroll.js.map +1 -0
- package/dist/sgr/color/color.d.ts +5 -9
- package/dist/sgr/color/color.d.ts.map +1 -0
- package/dist/sgr/color/color.js +22 -29
- package/dist/sgr/color/color.js.map +1 -0
- package/dist/sgr/color/index.d.ts +2 -2
- package/dist/sgr/color/index.d.ts.map +1 -0
- package/dist/sgr/color/index.js +17 -1
- package/dist/sgr/color/index.js.map +1 -0
- package/dist/sgr/color/test-rgb.d.ts +3 -0
- package/dist/sgr/color/test-rgb.d.ts.map +1 -0
- package/dist/sgr/color/test-rgb.js +149 -0
- package/dist/sgr/color/test-rgb.js.map +1 -0
- package/dist/sgr/color/types.d.ts +30 -0
- package/dist/sgr/color/types.d.ts.map +1 -0
- package/dist/sgr/color/types.js +3 -0
- package/dist/sgr/color/types.js.map +1 -0
- package/dist/sgr/color/utils.d.ts +7 -27
- package/dist/sgr/color/utils.d.ts.map +1 -0
- package/dist/sgr/color/utils.js +17 -32
- package/dist/sgr/color/utils.js.map +1 -0
- package/dist/sgr/index.d.ts +4 -9
- package/dist/sgr/index.d.ts.map +1 -0
- package/dist/sgr/index.js +18 -4
- package/dist/sgr/index.js.map +1 -0
- package/dist/sgr/reset.d.ts +2 -1
- package/dist/sgr/reset.d.ts.map +1 -0
- package/dist/sgr/reset.js +4 -1
- package/dist/sgr/reset.js.map +1 -0
- package/dist/sgr/sgr.d.ts +4 -3
- package/dist/sgr/sgr.d.ts.map +1 -0
- package/dist/sgr/sgr.js +8 -22
- package/dist/sgr/sgr.js.map +1 -0
- package/dist/sgr/style.d.ts +3 -1
- package/dist/sgr/style.d.ts.map +1 -0
- package/dist/sgr/style.js +5 -3
- package/dist/sgr/style.js.map +1 -0
- package/dist/sgr/utils.d.ts +3 -2
- package/dist/sgr/utils.d.ts.map +1 -0
- package/dist/sgr/utils.js +3 -3
- package/dist/sgr/utils.js.map +1 -0
- package/dist/simplify/atom.d.ts +4 -3
- package/dist/simplify/atom.d.ts.map +1 -0
- package/dist/simplify/atom.js +12 -9
- package/dist/simplify/atom.js.map +1 -0
- package/dist/simplify/index.d.ts +2 -2
- package/dist/simplify/index.d.ts.map +1 -0
- package/dist/simplify/index.js +17 -1
- package/dist/simplify/index.js.map +1 -0
- package/dist/simplify/lookup.d.ts +3 -5
- package/dist/simplify/lookup.d.ts.map +1 -0
- package/dist/simplify/lookup.js +9 -13
- package/dist/simplify/lookup.js.map +1 -0
- package/dist/simplify/simplify.d.ts +2 -1
- package/dist/simplify/simplify.d.ts.map +1 -0
- package/dist/simplify/simplify.js +7 -7
- package/dist/simplify/simplify.js.map +1 -0
- package/dist/simplify/state.d.ts +3 -8
- package/dist/simplify/state.d.ts.map +1 -0
- package/dist/simplify/state.js +9 -13
- package/dist/simplify/state.js.map +1 -0
- package/dist/simplify/test.d.ts +2 -0
- package/dist/simplify/test.d.ts.map +1 -0
- package/dist/simplify/test.js +64 -0
- package/dist/simplify/test.js.map +1 -0
- package/dist/simplify/types.d.ts +9 -0
- package/dist/simplify/types.d.ts.map +1 -0
- package/dist/simplify/types.js +3 -0
- package/dist/simplify/types.js.map +1 -0
- package/dist/simplify/utils.d.ts +3 -2
- package/dist/simplify/utils.d.ts.map +1 -0
- package/dist/simplify/utils.js +4 -3
- package/dist/simplify/utils.js.map +1 -0
- package/dist/slice.d.ts +21 -1
- package/dist/slice.d.ts.map +1 -0
- package/dist/slice.js +10 -22
- package/dist/slice.js.map +1 -0
- package/dist/strip.d.ts +4 -15
- package/dist/strip.d.ts.map +1 -0
- package/dist/strip.js +10 -17
- package/dist/strip.js.map +1 -0
- package/dist/terminal.d.ts +5 -1
- package/dist/terminal.d.ts.map +1 -0
- package/dist/terminal.js +4 -2
- package/dist/terminal.js.map +1 -0
- package/package.json +9 -22
- package/src/ansi.ts +71 -0
- package/src/{caret.js → caret.ts} +9 -15
- package/src/{erase.js → erase.ts} +7 -10
- package/src/features/build.ts +52 -0
- package/src/features/detect.ts +33 -0
- package/src/features/features.ts +48 -0
- package/src/features/index.ts +1 -0
- package/src/features/{types.d.ts → types.ts} +1 -1
- package/src/index.ts +2 -0
- package/src/pad.ts +7 -0
- package/src/{patterns.js → patterns.ts} +3 -5
- package/src/scroll.ts +13 -0
- package/src/sgr/color/{color.js → color.ts} +26 -35
- package/src/sgr/color/index.ts +1 -0
- package/src/sgr/color/{types.d.ts → types.ts} +6 -2
- package/src/sgr/color/utils.ts +58 -0
- package/src/sgr/index.ts +3 -0
- package/src/sgr/reset.ts +1 -0
- package/src/sgr/sgr.ts +68 -0
- package/src/sgr/{style.js → style.ts} +3 -5
- package/src/sgr/{utils.js → utils.ts} +3 -6
- package/src/simplify/{atom.js → atom.ts} +11 -13
- package/src/simplify/index.ts +1 -0
- package/src/simplify/{lookup.js → lookup.ts} +5 -14
- package/src/simplify/{simplify.js → simplify.ts} +4 -10
- package/src/simplify/state.ts +63 -0
- package/src/simplify/{types.d.ts → types.ts} +5 -5
- package/src/simplify/{utils.js → utils.ts} +4 -10
- package/src/{slice.js → slice.ts} +12 -26
- package/src/strip.ts +5 -0
- package/src/{terminal.js → terminal.ts} +4 -7
- package/LICENSE +0 -7
- package/README.md +0 -174
- package/src/ansi.js +0 -70
- package/src/features/build.js +0 -68
- package/src/features/detect.js +0 -40
- package/src/features/features.js +0 -53
- package/src/features/index.js +0 -1
- package/src/index.js +0 -1
- package/src/pad.js +0 -21
- package/src/scroll.js +0 -18
- package/src/sgr/color/index.js +0 -1
- package/src/sgr/color/utils.js +0 -81
- package/src/sgr/index.js +0 -5
- package/src/sgr/reset.js +0 -3
- package/src/sgr/sgr.js +0 -77
- package/src/simplify/index.js +0 -1
- package/src/simplify/state.js +0 -73
- package/src/strip.js +0 -23
|
@@ -12,7 +12,7 @@ export type Attribute =
|
|
|
12
12
|
| "reset"
|
|
13
13
|
| number;
|
|
14
14
|
|
|
15
|
-
type AttributeMap = Map<Attribute, number[]>;
|
|
15
|
+
export type AttributeMap = Map<Attribute, number[]>;
|
|
16
16
|
|
|
17
17
|
export interface Atom {
|
|
18
18
|
attribute : Attribute;
|
|
@@ -21,8 +21,8 @@ export interface Atom {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
export type BuildAtom = (
|
|
24
|
-
attribute: Attribute,
|
|
25
|
-
codes
|
|
26
|
-
index
|
|
27
|
-
state
|
|
24
|
+
attribute : Attribute,
|
|
25
|
+
codes : number[],
|
|
26
|
+
index : number,
|
|
27
|
+
state : AttributeMap,
|
|
28
28
|
) => Atom;
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
/** @type {<T>(a: T[] | undefined, b: T[] | undefined) => boolean} */
|
|
4
|
-
function arraysEqual(a, b) {
|
|
1
|
+
export function arraysEqual<T>(a: T[] | undefined, b: T[] | undefined): boolean {
|
|
5
2
|
if (a === b)
|
|
6
3
|
return true;
|
|
7
4
|
|
|
@@ -16,8 +13,7 @@ function arraysEqual(a, b) {
|
|
|
16
13
|
return true;
|
|
17
14
|
}
|
|
18
15
|
|
|
19
|
-
|
|
20
|
-
function transitionIntensity(previous, current) {
|
|
16
|
+
export function transitionIntensity(previous: number[] | undefined, current: number[]): number[] {
|
|
21
17
|
if (!previous || previous[0] === 22 || current[0] === 22)
|
|
22
18
|
return current;
|
|
23
19
|
|
|
@@ -26,7 +22,7 @@ function transitionIntensity(previous, current) {
|
|
|
26
22
|
const oldDim = previous[previous.length - 1] === 2;
|
|
27
23
|
const newDim = current[current.length - 1] === 2;
|
|
28
24
|
|
|
29
|
-
const result = [];
|
|
25
|
+
const result: number[] = [];
|
|
30
26
|
|
|
31
27
|
if (oldBold && !newBold || oldDim && !newDim)
|
|
32
28
|
result.push(22);
|
|
@@ -36,6 +32,4 @@ function transitionIntensity(previous, current) {
|
|
|
36
32
|
result.push(2);
|
|
37
33
|
|
|
38
34
|
return result;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
module.exports = {arraysEqual, transitionIntensity};
|
|
35
|
+
}
|
|
@@ -1,19 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
import {rxCSI, rxSGR} from "./patterns";
|
|
2
|
+
import {simplify} from "./simplify";
|
|
3
|
+
import {visibleLength} from "./strip";
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
@type {
|
|
9
|
-
(
|
|
10
|
-
text : string,
|
|
11
|
-
fromStringIndex : number,
|
|
12
|
-
visibleCount : number,
|
|
13
|
-
) => {index: number, length: number}
|
|
14
|
-
}
|
|
15
|
-
*/
|
|
16
|
-
function scanCSI(text, fromStringIndex, visibleCount) {
|
|
5
|
+
function scanCSI(
|
|
6
|
+
text : string,
|
|
7
|
+
fromStringIndex : number,
|
|
8
|
+
visibleCount : number,
|
|
9
|
+
): {index: number; length: number} {
|
|
17
10
|
// We intentionally mutate `lastIndex` here, so we need a clone.
|
|
18
11
|
const rx = new RegExp(rxCSI);
|
|
19
12
|
|
|
@@ -37,8 +30,7 @@ function scanCSI(text, fromStringIndex, visibleCount) {
|
|
|
37
30
|
return {index, length};
|
|
38
31
|
}
|
|
39
32
|
|
|
40
|
-
|
|
41
|
-
function skippedSequences(text, start, end) {
|
|
33
|
+
function skippedSequences(text: string, start: number, end?: number): string {
|
|
42
34
|
const sequences = text.slice(start, end).match(new RegExp(rxSGR));
|
|
43
35
|
return sequences ? simplify(sequences.join("")) : "";
|
|
44
36
|
}
|
|
@@ -61,12 +53,9 @@ function skippedSequences(text, start, end) {
|
|
|
61
53
|
* length of the slice, and that the terminal state may not be exactly the same at the start and end
|
|
62
54
|
* of the slice as it would be if the whole string were printed. This function is intended mostly
|
|
63
55
|
* for text that contains SGR codes, but no other ANSI codes or control characters.
|
|
64
|
-
*
|
|
65
|
-
* @type {(text: string, start: number, end: number) => string}
|
|
66
56
|
*/
|
|
67
|
-
function slice(text, start, end) {
|
|
68
|
-
|
|
69
|
-
let textVisibleLength;
|
|
57
|
+
export function slice(text: string, start: number, end: number): string {
|
|
58
|
+
let textVisibleLength: number | undefined;
|
|
70
59
|
const getVisibleLength = () => textVisibleLength ??= visibleLength(text);
|
|
71
60
|
|
|
72
61
|
if (start < 0 || end < 0) {
|
|
@@ -89,11 +78,8 @@ function slice(text, start, end) {
|
|
|
89
78
|
? scanCSI(text, startIndex, end - visibleSkipped).index
|
|
90
79
|
: text.length;
|
|
91
80
|
|
|
92
|
-
// Start and end the string in the same terminal state it would be in if the string weren't sliced.
|
|
93
81
|
const leadingSequences = skippedSequences(text, 0, startIndex);
|
|
94
82
|
const trailingSequences = skippedSequences(text, endIndex);
|
|
95
83
|
|
|
96
84
|
return leadingSequences + text.slice(startIndex, endIndex) + trailingSequences;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
module.exports = {slice};
|
|
85
|
+
}
|
package/src/strip.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import {rxCSI, rxUnsafe} from "./patterns";
|
|
2
|
+
|
|
3
|
+
export const strip = (text: string): string => text.replace(new RegExp(rxCSI), "");
|
|
4
|
+
export const visibleLength = (text: string): number => strip(text).length;
|
|
5
|
+
export const sanitize = (text: string): string => text.replace(new RegExp(rxUnsafe), "");
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
1
|
const terminal = {
|
|
4
2
|
focusReporting: {
|
|
5
3
|
enable : "\x1b[?1004h",
|
|
@@ -26,8 +24,9 @@ const terminal = {
|
|
|
26
24
|
},
|
|
27
25
|
};
|
|
28
26
|
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
export type Terminal = typeof terminal;
|
|
28
|
+
|
|
29
|
+
const disabled: Terminal = {
|
|
31
30
|
focusReporting: {
|
|
32
31
|
enable : "",
|
|
33
32
|
disable : "",
|
|
@@ -53,6 +52,4 @@ const disabled = {
|
|
|
53
52
|
},
|
|
54
53
|
};
|
|
55
54
|
|
|
56
|
-
const makeTerminal = (enabled = true) => enabled ? terminal : disabled;
|
|
57
|
-
|
|
58
|
-
module.exports = {makeTerminal};
|
|
55
|
+
export const makeTerminal = (enabled = true): Terminal => enabled ? terminal : disabled;
|
package/LICENSE
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
Copyright 2026 Pete Anderson
|
|
2
|
-
|
|
3
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
-
|
|
5
|
-
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
-
|
|
7
|
-
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
DELETED
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
# @peteanderson/ansi
|
|
2
|
-
|
|
3
|
-
ANSI escape sequence helpers for Node.js terminal output. Automatically detects terminal
|
|
4
|
-
capabilities and adapts output accordingly.
|
|
5
|
-
|
|
6
|
-
## Installation
|
|
7
|
-
|
|
8
|
-
```sh
|
|
9
|
-
npm install @peteanderson/ansi
|
|
10
|
-
```
|
|
11
|
-
|
|
12
|
-
## Usage
|
|
13
|
-
|
|
14
|
-
```js
|
|
15
|
-
const ansi = require("@peteanderson/ansi");
|
|
16
|
-
|
|
17
|
-
console.log(ansi.fg.red("error: something went wrong"));
|
|
18
|
-
console.log(ansi.bg.blue.combine(ansi.fg.white)("highlighted"));
|
|
19
|
-
console.log(ansi.style.bold("important"));
|
|
20
|
-
console.log(ansi.fg.rgb(5, 2, 0)("custom color"));
|
|
21
|
-
|
|
22
|
-
// Disable colors for a specific stream
|
|
23
|
-
const ansiNoColor = ansi(1); // force 1-bit (no color)
|
|
24
|
-
console.log(ansiNoColor.fg.red("this won't be colored"));
|
|
25
|
-
|
|
26
|
-
// Override specific features
|
|
27
|
-
const customAnsi = ansi({colorDepth: 8, caret: false});
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## Feature Detection
|
|
31
|
-
|
|
32
|
-
The module automatically detects:
|
|
33
|
-
|
|
34
|
-
- **Color depth**: 1 (none), 4 (16 colors), 8 (256 colors), 24 (true color)
|
|
35
|
-
- **Style support**: enabled if color depth > 1
|
|
36
|
-
- **Other features**: caret, erase, scroll — enabled if output is a TTY and `TERM` is not `dumb`
|
|
37
|
-
|
|
38
|
-
When disabled, features output empty strings. Color outputs plain text. This can be overridden:
|
|
39
|
-
|
|
40
|
-
- Pass a boolean to force color on/off
|
|
41
|
-
- Pass a number to set specific color depth (1, 3, 4, 8, or 24)
|
|
42
|
-
- Pass a stream to use for detection
|
|
43
|
-
- Pass a partial features object to override individual features
|
|
44
|
-
|
|
45
|
-
## API
|
|
46
|
-
|
|
47
|
-
### Default Export
|
|
48
|
-
|
|
49
|
-
The module exports a callable function with detection-based properties:
|
|
50
|
-
|
|
51
|
-
```js
|
|
52
|
-
const ansi = require("@peteanderson/ansi");
|
|
53
|
-
const customAnsi = ansi(options); // returns configured instance
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
### `fg` — foreground colors
|
|
57
|
-
|
|
58
|
-
Functions that wrap text with color codes (or plain text if disabled):
|
|
59
|
-
|
|
60
|
-
- Basic colors: `black` `red` `green` `yellow` `blue` `magenta` `cyan` `white` `default`
|
|
61
|
-
- Bright colors: `brightBlack` `brightRed` `brightGreen` `brightYellow` `brightBlue` `brightMagenta`
|
|
62
|
-
`brightCyan` `brightWhite`
|
|
63
|
-
- `fg.rgb(r, g, b)(text)` - 24-bit RGB color, downscaled for lower color depths
|
|
64
|
-
- `fg.x256(code)(text)` or `fg.x256(r, g, b)(text)` - 256-color palette, downscaled as needed
|
|
65
|
-
|
|
66
|
-
All return functions with `open` and `close` properties for raw sequences.
|
|
67
|
-
|
|
68
|
-
### `bg` — background colors
|
|
69
|
-
|
|
70
|
-
Functions that wrap text with color codes (or plain text if disabled):
|
|
71
|
-
|
|
72
|
-
- Basic colors: `black` `red` `green` `yellow` `blue` `magenta` `cyan` `white` `default`
|
|
73
|
-
- Bright colors: `brightBlack` `brightRed` `brightGreen` `brightYellow` `brightBlue` `brightMagenta`
|
|
74
|
-
`brightCyan` `brightWhite`
|
|
75
|
-
- `bg.rgb(r, g, b)(text)` - 24-bit RGB color, downscaled for lower color depths
|
|
76
|
-
- `bg.x256(code)(text)` or `bg.x256(r, g, b)(text)` - 256-color palette, downscaled as needed
|
|
77
|
-
|
|
78
|
-
### `style`
|
|
79
|
-
|
|
80
|
-
Functions that wrap text with style codes (disabled if color depth = 1):
|
|
81
|
-
|
|
82
|
-
`bold` `dim` `italic` `underline` `inverse` `hidden` `strikethrough` `doubleUnderline` `framed`
|
|
83
|
-
`encircled` `overline`
|
|
84
|
-
|
|
85
|
-
All return functions with `open` and `close` properties for raw sequences.
|
|
86
|
-
|
|
87
|
-
### `reset`
|
|
88
|
-
|
|
89
|
-
The SGR reset sequence. Empty string if color is disabled.
|
|
90
|
-
|
|
91
|
-
### `caret`
|
|
92
|
-
|
|
93
|
-
Available if feature is enabled:
|
|
94
|
-
|
|
95
|
-
- `caret.show` / `caret.hide` - show or hide the cursor
|
|
96
|
-
- `caret.position.get` - get the current cursor position (terminal sends position to stdin)
|
|
97
|
-
- `caret.position.set(row, col)` - set cursor position (1-based indexing)
|
|
98
|
-
- `caret.shape.block` / `caret.shape.underline` / `caret.shape.bar` - change cursor shape
|
|
99
|
-
- `caret.up(n)` / `caret.down(n)` / `caret.forward(n)` / `caret.backward(n)` - move cursor
|
|
100
|
-
- `caret.nextLine(n)` / `caret.prevLine(n)` - move cursor to next/previous line
|
|
101
|
-
- `caret.x(col)` - move cursor to column (1-based)
|
|
102
|
-
- `caret.save` / `caret.restore` - save/restore cursor position (VT100)
|
|
103
|
-
|
|
104
|
-
### `terminal`
|
|
105
|
-
|
|
106
|
-
Terminal control features (available if feature is enabled):
|
|
107
|
-
|
|
108
|
-
- `terminal.focusReporting.enable` / `terminal.focusReporting.disable` - enable/disable focus
|
|
109
|
-
reporting
|
|
110
|
-
- `terminal.alternateBuffer.on` / `terminal.alternateBuffer.off` - switch to/from alternate buffer
|
|
111
|
-
- `terminal.alternateBuffer.legacy.on` / `terminal.alternateBuffer.legacy.off` - use legacy
|
|
112
|
-
alternate buffer sequences
|
|
113
|
-
- `terminal.bracketedPasteMode.enable` / `terminal.bracketedPasteMode.disable` - enable/disable
|
|
114
|
-
bracketed paste mode
|
|
115
|
-
|
|
116
|
-
### `erase`
|
|
117
|
-
|
|
118
|
-
Available if feature is enabled:
|
|
119
|
-
|
|
120
|
-
- `erase.line.toStart` / `erase.line.toEnd` / `erase.line.full` - erase line
|
|
121
|
-
- `erase.screen.toStart` / `erase.screen.toEnd` / `erase.screen.full` - erase screen
|
|
122
|
-
- `erase.screen.scrollback` - erase screen and scrollback buffer
|
|
123
|
-
|
|
124
|
-
### `scroll`
|
|
125
|
-
|
|
126
|
-
Available if feature is enabled:
|
|
127
|
-
|
|
128
|
-
- `scroll.up(lines)` - scroll up (default 1 line)
|
|
129
|
-
- `scroll.down(lines)` - scroll down (default 1 line)
|
|
130
|
-
|
|
131
|
-
### `strip(text)`
|
|
132
|
-
|
|
133
|
-
Removes all ANSI CSI sequences from a string (always available).
|
|
134
|
-
|
|
135
|
-
### `slice(text, start, end)`
|
|
136
|
-
|
|
137
|
-
Slices a string by visible characters, ignoring ANSI sequences (always available).
|
|
138
|
-
|
|
139
|
-
### `sanitize(text)`
|
|
140
|
-
|
|
141
|
-
Removes "unsafe" CSI sequences, leaving only color and style codes (always available).
|
|
142
|
-
|
|
143
|
-
### `simplify(text)`
|
|
144
|
-
|
|
145
|
-
Simplifies ANSI SGR sequences by combining adjacent sequences and removing redundant codes (always
|
|
146
|
-
available).
|
|
147
|
-
|
|
148
|
-
### `visibleLength(text)`
|
|
149
|
-
|
|
150
|
-
Returns the visible length of a string with all ANSI sequences removed (always available).
|
|
151
|
-
|
|
152
|
-
### `padStart(text, targetLength)` and `padEnd(text, targetLength)`
|
|
153
|
-
|
|
154
|
-
Pads a string to a target visible length using spaces. Accounts for ANSI sequences when calculating
|
|
155
|
-
length.
|
|
156
|
-
|
|
157
|
-
### `features`
|
|
158
|
-
|
|
159
|
-
Object containing the detected feature configuration:
|
|
160
|
-
|
|
161
|
-
```ts
|
|
162
|
-
{
|
|
163
|
-
colorDepth : 1 | 3 | 4 | 8 | 24;
|
|
164
|
-
style : boolean;
|
|
165
|
-
caret : boolean;
|
|
166
|
-
erase : boolean;
|
|
167
|
-
scroll : boolean;
|
|
168
|
-
terminal : boolean;
|
|
169
|
-
}
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
## License
|
|
173
|
-
|
|
174
|
-
MIT
|
package/src/ansi.js
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
const {makeCaret} = require("./caret");
|
|
4
|
-
const {makeErase} = require("./erase");
|
|
5
|
-
const {getFeatures} = require("./features");
|
|
6
|
-
const {padEnd, padStart} = require("./pad");
|
|
7
|
-
const {makeScroll} = require("./scroll");
|
|
8
|
-
const {makeColor, makeReset, makeStyle} = require("./sgr");
|
|
9
|
-
const {simplify} = require("./simplify");
|
|
10
|
-
const {slice} = require("./slice");
|
|
11
|
-
const {sanitize, strip, visibleLength} = require("./strip");
|
|
12
|
-
const {makeTerminal} = require("./terminal");
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
@typedef {import("./features/features").Args} Args
|
|
16
|
-
|
|
17
|
-
@typedef {ReturnType<typeof makeColor> & {
|
|
18
|
-
caret : ReturnType<typeof makeCaret>;
|
|
19
|
-
erase : ReturnType<typeof makeErase>;
|
|
20
|
-
scroll : ReturnType<typeof makeScroll>;
|
|
21
|
-
|
|
22
|
-
reset : string;
|
|
23
|
-
style : ReturnType<typeof makeStyle>;
|
|
24
|
-
|
|
25
|
-
terminal : ReturnType<typeof makeTerminal>;
|
|
26
|
-
|
|
27
|
-
padEnd : typeof padEnd;
|
|
28
|
-
padStart : typeof padStart;
|
|
29
|
-
|
|
30
|
-
strip : typeof strip;
|
|
31
|
-
visibleLength : typeof visibleLength;
|
|
32
|
-
sanitize : typeof sanitize;
|
|
33
|
-
slice : typeof slice;
|
|
34
|
-
simplify : typeof simplify;
|
|
35
|
-
|
|
36
|
-
features : ReturnType<typeof getFeatures>;
|
|
37
|
-
}} Ansi
|
|
38
|
-
*/
|
|
39
|
-
|
|
40
|
-
/** @type {(...args: Args) => Ansi}*/
|
|
41
|
-
function makeAnsi(...args) {
|
|
42
|
-
const features = getFeatures(...args);
|
|
43
|
-
|
|
44
|
-
return {
|
|
45
|
-
caret : makeCaret(features.caret),
|
|
46
|
-
erase : makeErase(features.erase),
|
|
47
|
-
scroll : makeScroll(features.scroll),
|
|
48
|
-
|
|
49
|
-
reset : makeReset(features.colorDepth > 1),
|
|
50
|
-
style : makeStyle(features.style),
|
|
51
|
-
...makeColor(features.colorDepth),
|
|
52
|
-
|
|
53
|
-
terminal: makeTerminal(features.terminal),
|
|
54
|
-
|
|
55
|
-
padEnd,
|
|
56
|
-
padStart,
|
|
57
|
-
|
|
58
|
-
strip,
|
|
59
|
-
visibleLength,
|
|
60
|
-
sanitize,
|
|
61
|
-
slice,
|
|
62
|
-
simplify,
|
|
63
|
-
|
|
64
|
-
features,
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const ansi = Object.assign(makeAnsi, makeAnsi());
|
|
69
|
-
|
|
70
|
-
module.exports = ansi;
|
package/src/features/build.js
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
const {getColorDepth, detectFeatureSupport} = require("./detect");
|
|
4
|
-
|
|
5
|
-
/** @typedef {import("./types").ColorDepth} ColorDepth */
|
|
6
|
-
/** @typedef {import("./types").Features} Features */
|
|
7
|
-
|
|
8
|
-
/** @type {(colorDepth: number) => ColorDepth} */
|
|
9
|
-
function normalizeColorDepth(colorDepth) {
|
|
10
|
-
colorDepth = Math.floor(colorDepth);
|
|
11
|
-
if (colorDepth >= 24)
|
|
12
|
-
return 24;
|
|
13
|
-
if (colorDepth >= 8)
|
|
14
|
-
return 8;
|
|
15
|
-
if (colorDepth >= 4)
|
|
16
|
-
return 4;
|
|
17
|
-
if (colorDepth === 3)
|
|
18
|
-
return 3;
|
|
19
|
-
return 1;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
@type {
|
|
24
|
-
(
|
|
25
|
-
isTTY : boolean,
|
|
26
|
-
colorDepth : ColorDepth,
|
|
27
|
-
style? : boolean,
|
|
28
|
-
caret? : boolean,
|
|
29
|
-
erase? : boolean,
|
|
30
|
-
scroll? : boolean,
|
|
31
|
-
terminal? : boolean,
|
|
32
|
-
) => Features
|
|
33
|
-
}
|
|
34
|
-
*/
|
|
35
|
-
function build(isTTY, colorDepth, style, caret, erase, scroll, terminal) {
|
|
36
|
-
if (
|
|
37
|
-
style !== undefined &&
|
|
38
|
-
caret !== undefined &&
|
|
39
|
-
erase !== undefined &&
|
|
40
|
-
scroll !== undefined &&
|
|
41
|
-
terminal !== undefined
|
|
42
|
-
)
|
|
43
|
-
return {colorDepth: normalizeColorDepth(colorDepth), style, caret, erase, scroll, terminal};
|
|
44
|
-
|
|
45
|
-
const support = detectFeatureSupport(isTTY, colorDepth);
|
|
46
|
-
return {
|
|
47
|
-
colorDepth : normalizeColorDepth(colorDepth),
|
|
48
|
-
style : style ?? support.style,
|
|
49
|
-
caret : caret ?? support.caret,
|
|
50
|
-
erase : erase ?? support.erase,
|
|
51
|
-
scroll : scroll ?? support.scroll,
|
|
52
|
-
terminal : terminal ?? support.terminal,
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/** @type {(isTTY: boolean, enabled: boolean) => Features} */
|
|
57
|
-
const boolean = (isTTY, enabled) => build(isTTY, enabled ? 4 : 1);
|
|
58
|
-
|
|
59
|
-
/** @type {(isTTY: boolean, colorDepth: ColorDepth) => Features} */
|
|
60
|
-
const number = (isTTY, colorDepth) => build(isTTY, colorDepth);
|
|
61
|
-
|
|
62
|
-
/** @type {(stream: NodeJS.WriteStream) => Features} */
|
|
63
|
-
const tty = stream => build(true, getColorDepth(stream));
|
|
64
|
-
|
|
65
|
-
/** @type {() => Features} */
|
|
66
|
-
const pipe = () => build(false, getColorDepth());
|
|
67
|
-
|
|
68
|
-
module.exports = {build, boolean, number, tty, pipe};
|
package/src/features/detect.js
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/** @typedef {import("./types").ColorDepth} ColorDepth */
|
|
4
|
-
/** @typedef {import("./types").Features} Features */
|
|
5
|
-
|
|
6
|
-
/** @type {(stream?: NodeJS.WriteStream) => ColorDepth} */
|
|
7
|
-
function getColorDepth(stream) {
|
|
8
|
-
if (stream?.isTTY)
|
|
9
|
-
return /** @type {ColorDepth} */(stream.getColorDepth());
|
|
10
|
-
|
|
11
|
-
if (process.env.NO_COLOR || process.env.NODE_DISABLE_COLORS)
|
|
12
|
-
return 1;
|
|
13
|
-
|
|
14
|
-
switch (process.env.FORCE_COLOR) {
|
|
15
|
-
case "":
|
|
16
|
-
case "true":
|
|
17
|
-
case "1":
|
|
18
|
-
return 4;
|
|
19
|
-
case "2":
|
|
20
|
-
return 8;
|
|
21
|
-
case "3":
|
|
22
|
-
return 24;
|
|
23
|
-
default:
|
|
24
|
-
return 1;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/** @type {(isTTY: boolean, colorDepth: ColorDepth) => Omit<Features, "colorDepth">} */
|
|
29
|
-
function detectFeatureSupport(isTTY, colorDepth) {
|
|
30
|
-
const enabled = process.env.TERM !== "dumb" && isTTY;
|
|
31
|
-
return {
|
|
32
|
-
style : colorDepth > 1,
|
|
33
|
-
caret : enabled,
|
|
34
|
-
erase : enabled,
|
|
35
|
-
scroll : enabled,
|
|
36
|
-
terminal : enabled,
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
module.exports = {detectFeatureSupport, getColorDepth}
|
package/src/features/features.js
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
const {Socket} = require("node:net");
|
|
4
|
-
const {WriteStream} = require("node:tty");
|
|
5
|
-
const {build, boolean, number, tty, pipe} = require("./build");
|
|
6
|
-
const {getColorDepth} = require("./detect");
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
@typedef {import("./types").ColorDepth} ColorDepth
|
|
10
|
-
@typedef {import("./types").Features} Features
|
|
11
|
-
|
|
12
|
-
@typedef {
|
|
13
|
-
| [enabled : boolean, stream?: NodeJS.WriteStream]
|
|
14
|
-
| [colorDepth : ColorDepth, stream?: NodeJS.WriteStream]
|
|
15
|
-
| [features : Partial<Features>, stream?: NodeJS.WriteStream]
|
|
16
|
-
| [socket : Socket]
|
|
17
|
-
| [stream? : NodeJS.WriteStream]
|
|
18
|
-
} Args
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
/** @type {(...args: Args) => Features} */
|
|
22
|
-
function getFeatures(...args) {
|
|
23
|
-
let [features, stream] = args;
|
|
24
|
-
|
|
25
|
-
if (typeof features === "boolean")
|
|
26
|
-
return boolean((stream ?? process.stdout).isTTY, features);
|
|
27
|
-
|
|
28
|
-
if (typeof features === "number")
|
|
29
|
-
return number((stream ?? process.stdout).isTTY, features);
|
|
30
|
-
|
|
31
|
-
if (!features || typeof features !== "object")
|
|
32
|
-
features = (stream ?? process.stdout);
|
|
33
|
-
|
|
34
|
-
if (features instanceof WriteStream)
|
|
35
|
-
return tty(features);
|
|
36
|
-
|
|
37
|
-
if (features instanceof Socket)
|
|
38
|
-
return pipe();
|
|
39
|
-
|
|
40
|
-
const {colorDepth, style, caret, erase, scroll, terminal} = features;
|
|
41
|
-
|
|
42
|
-
stream ??= process.stdout;
|
|
43
|
-
|
|
44
|
-
if (colorDepth)
|
|
45
|
-
build(stream.isTTY, colorDepth, style, caret, erase, scroll, terminal);
|
|
46
|
-
|
|
47
|
-
if (stream.isTTY)
|
|
48
|
-
return build(true, getColorDepth(stream), style, caret, erase, scroll, terminal);
|
|
49
|
-
|
|
50
|
-
return build(false, getColorDepth(), style, caret, erase, scroll, terminal);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
module.exports = {getFeatures};
|
package/src/features/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require("./features");
|
package/src/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require("./ansi");
|
package/src/pad.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
const {visibleLength} = require("./strip");
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Pad the given text at the end with the specified fill string to the target visible length without
|
|
7
|
-
* counting ANSI escape codes.
|
|
8
|
-
* @type {(text: string, targetLength: number, fillString?: string) => string}
|
|
9
|
-
*/
|
|
10
|
-
const padEnd = (text, targetLength, fillString = " ") =>
|
|
11
|
-
text + fillString.repeat(Math.max(0, targetLength - visibleLength(text)) / fillString.length);
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Pad the given text at the start with the specified fill string to the target visible length
|
|
15
|
-
* without counting ANSI escape codes.
|
|
16
|
-
* @type {(text: string, targetLength: number, fillString?: string) => string}
|
|
17
|
-
*/
|
|
18
|
-
const padStart = (text, targetLength, fillString = " ") =>
|
|
19
|
-
fillString.repeat(Math.max(0, targetLength - visibleLength(text)) / fillString.length) + text;
|
|
20
|
-
|
|
21
|
-
module.exports = {padEnd, padStart};
|
package/src/scroll.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
const scroll = {
|
|
4
|
-
/** @type {(lines?: number) => string} */
|
|
5
|
-
up : lines => `\x1b[${lines ?? 1}S`,
|
|
6
|
-
/** @type {(lines?: number) => string} */
|
|
7
|
-
down : lines => `\x1b[${lines ?? 1}T`,
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
/** @type {typeof scroll} */
|
|
11
|
-
const disabled = {
|
|
12
|
-
up : () => "",
|
|
13
|
-
down : () => "",
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
const makeScroll = (enabled = true) => enabled ? scroll : disabled;
|
|
17
|
-
|
|
18
|
-
module.exports = {makeScroll};
|
package/src/sgr/color/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require("./color");
|