Skip to content

Commit 52f162c

Browse files
committed
feat: detab before wrapping
Signed-off-by: Lexus Drumgold <[email protected]>
1 parent a169fa3 commit 52f162c

File tree

11 files changed

+87
-8
lines changed

11 files changed

+87
-8
lines changed

.dictionary.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ chunker
44
commandoptst
55
commitlintrc
66
dedupe
7+
detab
78
devlop
89
fbca
910
gpgsign

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ Options for wrapping a string (`interface`).
280280
— convert a value to a string
281281
- `stripAnsi?` ([`StripAnsi`](#stripansi) | `boolean` | `null` | `undefined`, optional)
282282
— whether to remove ANSI escape codes before wrapping, or a function to remove ANSI escape codes
283-
- `tabSize?` (`number` | `null` | `undefined`, optional)
283+
- `tabSize?` (`number` | `string` | `undefined`, optional)
284284
— the number of spaces a tab is equivalent to
285285
- default: `2`
286286
- `trim?` (`boolean` | `null` | `undefined`, optional)

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@
141141
"@flex-development/ansi-regex": "1.0.0",
142142
"@flex-development/fsm-tokenizer": "1.0.0-alpha.1",
143143
"@flex-development/strip-ansi": "1.0.0",
144+
"detab": "3.0.2",
144145
"devlop": "1.1.0",
145146
"grapheme-splitter": "1.0.4",
146147
"micromark-util-character": "2.1.1",

src/interfaces/__tests__/options.spec-d.mts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,10 @@ describe('unit-d:interfaces/Options', () => {
6060
.toEqualTypeOf<Nilable<StripAnsi | boolean>>()
6161
})
6262

63-
it('should match [tabSize?: number | null | undefined]', () => {
63+
it('should match [tabSize?: number | string | null | undefined]', () => {
6464
expectTypeOf<TestSubject>()
6565
.toHaveProperty('tabSize')
66-
.toEqualTypeOf<Nilable<number>>()
66+
.toEqualTypeOf<Nilable<number | string>>()
6767
})
6868

6969
it('should match [trim?: boolean | null | undefined]', () => {

src/interfaces/options.mts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ interface Options {
8080
*
8181
* @default 2
8282
*/
83-
tabSize?: number | null | undefined
83+
tabSize?: number | string | null | undefined
8484

8585
/**
8686
* Whether to remove whitespace from the beginning and end of each line.

src/internal/__snapshots__/happy-dom/tokenize.functional.snap

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3423,6 +3423,19 @@ exports[`functional:internal/tokenize > options.stripAnsi > should remove ansi e
34233423
}
34243424
`;
34253425
3426+
exports[`functional:internal/tokenize > options.tabSize > should replace tabs with equivalent number of spaces 1`] = `
3427+
{
3428+
"candidate": ""\\t\\t\\t\\ttestingtesting"",
3429+
"hard": true,
3430+
"lines": [
3431+
" testing",
3432+
"testing",
3433+
],
3434+
"tabSize": 1,
3435+
"trim": false,
3436+
}
3437+
`;
3438+
34263439
exports[`functional:internal/tokenize > options.trim > should not trim lines if disabled (0) 1`] = `
34273440
{
34283441
"candidate": "" "",

src/internal/__snapshots__/node/tokenize.functional.snap

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3423,6 +3423,19 @@ exports[`functional:internal/tokenize > options.stripAnsi > should remove ansi e
34233423
}
34243424
`;
34253425
3426+
exports[`functional:internal/tokenize > options.tabSize > should replace tabs with equivalent number of spaces 1`] = `
3427+
{
3428+
"candidate": ""\\t\\t\\t\\ttestingtesting"",
3429+
"hard": true,
3430+
"lines": [
3431+
" testing",
3432+
"testing",
3433+
],
3434+
"tabSize": 1,
3435+
"trim": false,
3436+
}
3437+
`;
3438+
34263439
exports[`functional:internal/tokenize > options.trim > should not trim lines if disabled (0) 1`] = `
34273440
{
34283441
"candidate": "" "",

src/internal/__tests__/tokenize.functional.spec.mts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ describe('functional:internal/tokenize', () => {
9292
'string',
9393
'stringify',
9494
'stripAnsi',
95+
'tabSize',
9596
'token',
9697
'trim',
9798
'write'
@@ -541,6 +542,27 @@ describe('functional:internal/tokenize', () => {
541542
})
542543
})
543544

545+
describe('options.tabSize', () => {
546+
it('should replace tabs with equivalent number of spaces', () => {
547+
// Arrange
548+
const tabSize: string = chars.digit1
549+
const thing: string = chars.ht.repeat(4) + 'testingtesting'
550+
551+
// Act
552+
const result = testSubject(thing, 11, {
553+
hard: true,
554+
tabSize,
555+
trim: false
556+
})
557+
558+
// Expect
559+
expect(result).to.have.keys(keys)
560+
expect(result).to.have.property('tabSize', +tabSize)
561+
expect(result.lines).to.satisfyColumns(result.columns)
562+
expect(snapshot(result, ['hard', 'tabSize', 'trim'])).toMatchSnapshot()
563+
})
564+
})
565+
544566
describe('options.stringify', () => {
545567
let options: Options
546568
let stringify: MockInstance<ToString>

src/internal/tokenize.mts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import type {
2626
SpacerFunction
2727
} from '@flex-development/string-wrap'
2828
import stripAnsi from '@flex-development/strip-ansi'
29+
import { detab } from 'detab'
2930
import { ok } from 'devlop'
3031

3132
export default tokenize
@@ -133,12 +134,23 @@ function tokenize(
133134
[codes.vcr]: eol,
134135
[codes.vlf]: eol,
135136
null: [sequence, eoc]
136-
}),
137-
tabSize: config.tabSize ?? +chars.digit2
137+
})
138138
})
139139

140-
void chunks(context.trim ? trimEnd(context.string) : context.string, / /g)
141-
return context
140+
/**
141+
* The string to wrap.
142+
*
143+
* @var {string} string
144+
*/
145+
let string: string = context.string
146+
147+
// remove tabs.
148+
string = detab(string, context.tabSize)
149+
150+
// trim string.
151+
if (context.trim) string = trimEnd(string)
152+
153+
return void chunks(string, / /g), context
142154

143155
/**
144156
* Write chunks to the tokenizer.
@@ -255,6 +267,7 @@ function tokenize(
255267
self.lines = []
256268
self.padLeft = spacing(config.padLeft)
257269
self.padRight = spacing(config.padRight)
270+
self.tabSize = number(config.tabSize ?? chars.digit2)
258271
self.stringify = config.stringify ?? String
259272
self.trim = config.trim ?? true
260273

typings/@flex-development/fsm-tokenizer/index.d.mts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,5 +136,13 @@ declare module '@flex-development/fsm-tokenizer' {
136136
* @override
137137
*/
138138
stripAnsi: StripAnsi
139+
140+
/**
141+
* The number of spaces a tab is equivalent to.
142+
*
143+
* @internal
144+
* @override
145+
*/
146+
tabSize: number
139147
}
140148
}

0 commit comments

Comments
 (0)