Skip to content

Commit f93222d

Browse files
authored
Merge pull request #76 from mkantor/drop-kleur
Drop `kleur` dependency in favor of `node:util`'s `styleText`
2 parents 3d2cd18 + 070b6fb commit f93222d

File tree

9 files changed

+48
-53
lines changed

9 files changed

+48
-53
lines changed

package-lock.json

Lines changed: 2 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@
2323
"dependencies": {
2424
"@matt.kantor/either": "^1.2.0",
2525
"@matt.kantor/option": "^1.0.0",
26-
"@matt.kantor/parsing": "^2.0.0",
27-
"kleur": "^4.1.5"
26+
"@matt.kantor/parsing": "^2.0.0"
2827
},
2928
"engines": {
3029
"node": ">=22.18"

src/language/cli/output.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import either, { type Either } from '@matt.kantor/either'
2-
import kleur from 'kleur'
32
import { parseArgs } from 'node:util'
43
import { type SyntaxTree } from '../parsing/syntax-tree.js'
54
import {
@@ -27,7 +26,10 @@ export const handleOutput = async (
2726
if (typeof noColorArg !== 'boolean') {
2827
throw new Error('Unsupported value for --no-color')
2928
} else if (noColorArg === true) {
30-
kleur.enabled = false
29+
// Warning: the global state mutation here means that we can't style text in static contexts!
30+
// Functions like `node:util`'s `styleText` shouldn't be called from the top level of modules.
31+
delete process.env['FORCE_COLOR']
32+
process.env['NO_COLOR'] = 'true'
3133
}
3234

3335
const outputFormatArg = args.values['output-format']

src/language/unparsing/inline-plz.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import either from '@matt.kantor/either'
2-
import kleur from 'kleur'
2+
import { styleText } from 'node:util'
33
import type { Atom, Molecule } from '../parsing.js'
44
import {
55
moleculeAsKeyValuePairStrings,
@@ -9,7 +9,7 @@ import {
99
import { punctuation, type Notation } from './unparsing-utilities.js'
1010

1111
const unparseSugarFreeMolecule = (value: Molecule) => {
12-
const { comma, closeBrace, openBrace } = punctuation(kleur)
12+
const { comma, closeBrace, openBrace } = punctuation(styleText)
1313
if (Object.keys(value).length === 0) {
1414
return either.makeRight(openBrace + closeBrace)
1515
} else {

src/language/unparsing/plz-utilities.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import either, { type Either, type Right } from '@matt.kantor/either'
22
import parsing from '@matt.kantor/parsing'
3-
import kleur from 'kleur'
3+
import { styleText } from 'node:util'
44
import type { UnserializableValueError } from '../errors.js'
55
import type { Atom, Molecule } from '../parsing.js'
66
import { unquotedAtomParser } from '../parsing/atom.js'
@@ -76,7 +76,7 @@ export const moleculeAsKeyValuePairStrings = (
7676
unparseAtomOrMolecule: UnparseAtomOrMolecule,
7777
options: { readonly ordinalKeys: 'omit' | 'preserve' },
7878
): Either<UnserializableValueError, readonly string[]> => {
79-
const { colon } = punctuation(kleur)
79+
const { colon } = punctuation(styleText)
8080
const entries = Object.entries(value)
8181

8282
const keyValuePairsAsStrings: string[] = []
@@ -96,8 +96,7 @@ export const moleculeAsKeyValuePairStrings = (
9696
ordinalPropertyKeyCounter += 1n
9797
} else {
9898
keyValuePairsAsStrings.push(
99-
kleur
100-
.cyan(quoteAtomIfNecessary(propertyKey).concat(colon))
99+
styleText('cyan', quoteAtomIfNecessary(propertyKey).concat(colon))
101100
.concat(' ')
102101
.concat(valueAsStringResult.value),
103102
)
@@ -109,15 +108,15 @@ export const moleculeAsKeyValuePairStrings = (
109108
export const unparseAtom = (atom: string): Right<string> =>
110109
either.makeRight(
111110
/^@[^@]/.test(atom)
112-
? kleur.bold(kleur.underline(quoteAtomIfNecessary(atom)))
111+
? styleText(['bold', 'underline'], quoteAtomIfNecessary(atom))
113112
: quoteAtomIfNecessary(atom),
114113
)
115114

116115
const requiresQuotation = (atom: string): boolean =>
117116
either.isLeft(parsing.parse(unquotedAtomParser, atom))
118117

119118
const quoteAtomIfNecessary = (value: string): string => {
120-
const { quote } = punctuation(kleur)
119+
const { quote } = punctuation(styleText)
121120
if (requiresQuotation(value)) {
122121
return quote.concat(escapeStringContents(value)).concat(quote)
123122
} else {
@@ -126,7 +125,7 @@ const quoteAtomIfNecessary = (value: string): string => {
126125
}
127126

128127
const quoteKeyPathComponentIfNecessary = (value: string): string => {
129-
const { quote } = punctuation(kleur)
128+
const { quote } = punctuation(styleText)
130129
const unquotedAtomResult = parsing.parse(unquotedAtomParser, value)
131130
if (either.isLeft(unquotedAtomResult) || value.includes('.')) {
132131
return quote.concat(escapeStringContents(value)).concat(quote)
@@ -153,7 +152,7 @@ const unparseSugaredApply = (
153152
expression: ApplyExpression,
154153
unparseAtomOrMolecule: UnparseAtomOrMolecule,
155154
) => {
156-
const { closeParenthesis, openParenthesis } = punctuation(kleur)
155+
const { closeParenthesis, openParenthesis } = punctuation(styleText)
157156
return either.flatMap(
158157
either.map(
159158
either.flatMap(
@@ -188,8 +187,8 @@ const unparseSugaredFunction = (
188187
either.flatMap(serializeIfNeeded(expression[1].body), serializedBody =>
189188
either.map(unparseAtomOrMolecule(serializedBody), bodyAsString =>
190189
[
191-
kleur.cyan(expression[1].parameter),
192-
punctuation(kleur).arrow,
190+
styleText('cyan', expression[1].parameter),
191+
punctuation(styleText).arrow,
193192
bodyAsString,
194193
].join(' '),
195194
),
@@ -238,7 +237,7 @@ const unparseSugaredIndex = (
238237
message: 'invalid key path',
239238
})
240239
} else {
241-
const { dot } = punctuation(kleur)
240+
const { dot } = punctuation(styleText)
242241
return either.makeRight(
243242
unparsedObject
244243
.concat(dot)
@@ -254,8 +253,9 @@ const unparseSugaredLookup = (
254253
_unparseAtomOrMolecule: UnparseAtomOrMolecule,
255254
) =>
256255
either.makeRight(
257-
kleur.cyan(
258-
punctuation(kleur).colon.concat(
256+
styleText(
257+
'cyan',
258+
punctuation(styleText).colon.concat(
259259
quoteKeyPathComponentIfNecessary(expression[1].key),
260260
),
261261
),
@@ -280,7 +280,7 @@ const unparseSugaredGeneralizedKeywordExpression = (
280280
'expression cannot be faithfully represented using generalized keyword expression sugar',
281281
})
282282
} else {
283-
const unparsedKeyword = kleur.bold(kleur.underline(expression['0']))
283+
const unparsedKeyword = styleText(['bold', 'underline'], expression['0'])
284284
if ('1' in expression) {
285285
return either.map(
286286
either.flatMap(

src/language/unparsing/pretty-json.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,33 @@
11
import type { Right } from '@matt.kantor/either'
22
import either from '@matt.kantor/either'
3-
import kleur from 'kleur'
3+
import { styleText } from 'node:util'
44
import type { Atom, Molecule } from '../parsing.js'
55
import { indent, punctuation, type Notation } from './unparsing-utilities.js'
66

77
const escapeStringContents = (value: string) =>
88
value.replace('\\', '\\\\').replace('"', '\\"')
99

1010
const key = (value: Atom): string => {
11-
const { quote } = punctuation(kleur)
12-
return quote.concat(kleur.bold(escapeStringContents(value))).concat(quote)
11+
const { quote } = punctuation(styleText)
12+
return quote
13+
.concat(styleText('bold', escapeStringContents(value)))
14+
.concat(quote)
1315
}
1416

1517
const unparseAtom = (value: Atom): Right<string> => {
16-
const { quote } = punctuation(kleur)
18+
const { quote } = punctuation(styleText)
1719
return either.makeRight(
1820
quote.concat(
1921
escapeStringContents(
20-
/^@[^@]/.test(value) ? kleur.bold(kleur.underline(value)) : value,
22+
/^@[^@]/.test(value) ? styleText(['bold', 'underline'], value) : value,
2123
),
2224
quote,
2325
),
2426
)
2527
}
2628

2729
const unparseMolecule = (value: Molecule): Right<string> => {
28-
const { closeBrace, colon, comma, openBrace } = punctuation(kleur)
30+
const { closeBrace, colon, comma, openBrace } = punctuation(styleText)
2931
const entries = Object.entries(value)
3032
if (entries.length === 0) {
3133
return either.makeRight(openBrace.concat(closeBrace))

src/language/unparsing/pretty-plz.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import either from '@matt.kantor/either'
2-
import kleur from 'kleur'
2+
import { styleText } from 'node:util'
33
import type { Atom, Molecule } from '../parsing.js'
44
import {
55
moleculeAsKeyValuePairStrings,
@@ -9,7 +9,7 @@ import {
99
import { indent, punctuation, type Notation } from './unparsing-utilities.js'
1010

1111
const unparseSugarFreeMolecule = (value: Molecule) => {
12-
const { closeBrace, openBrace } = punctuation(kleur)
12+
const { closeBrace, openBrace } = punctuation(styleText)
1313
if (Object.keys(value).length === 0) {
1414
return either.makeRight(openBrace + closeBrace)
1515
} else {

src/language/unparsing/sugar-free-pretty-plz.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import either from '@matt.kantor/either'
2-
import kleur from 'kleur'
2+
import { styleText } from 'node:util'
33
import type { Atom, Molecule } from '../parsing.js'
44
import { moleculeAsKeyValuePairStrings, unparseAtom } from './plz-utilities.js'
55
import { indent, punctuation, type Notation } from './unparsing-utilities.js'
66

77
const unparseMolecule = (value: Molecule) => {
8-
const { closeBrace, openBrace } = punctuation(kleur)
8+
const { closeBrace, openBrace } = punctuation(styleText)
99
if (Object.keys(value).length === 0) {
1010
return either.makeRight(openBrace + closeBrace)
1111
} else {
Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { type Either } from '@matt.kantor/either'
2-
import type { Kleur } from 'kleur'
2+
import * as util from 'node:util'
33
import type { UnserializableValueError } from '../errors.js'
44
import type { Atom, Molecule } from '../parsing.js'
55

@@ -18,14 +18,16 @@ export const indent = (spaces: number, textToIndent: string) => {
1818
.replace(/(\r?\n)/g, `$1${indentation}`)
1919
}
2020

21-
export const punctuation = (kleur: Kleur) => ({
22-
dot: kleur.dim('.'),
23-
quote: kleur.dim('"'),
24-
colon: kleur.dim(':'),
25-
comma: kleur.dim(','),
26-
openBrace: kleur.dim('{'),
27-
closeBrace: kleur.dim('}'),
28-
openParenthesis: kleur.dim('('),
29-
closeParenthesis: kleur.dim(')'),
30-
arrow: kleur.dim('=>'),
21+
// Note that `node:util`'s `styleText` changes behavior based on the current global state of
22+
// `process.env`, which may be mutated at runtime (e.g. to handle `--no-color`).
23+
export const punctuation = (styleText: typeof util.styleText) => ({
24+
dot: styleText('dim', '.'),
25+
quote: styleText('dim', '"'),
26+
colon: styleText('dim', ':'),
27+
comma: styleText('dim', ','),
28+
openBrace: styleText('dim', '{'),
29+
closeBrace: styleText('dim', '}'),
30+
openParenthesis: styleText('dim', '('),
31+
closeParenthesis: styleText('dim', ')'),
32+
arrow: styleText('dim', '=>'),
3133
})

0 commit comments

Comments
 (0)