Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(sort-enums): add partition-by-comment option #116

Merged
merged 2 commits into from
Mar 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions docs/rules/sort-enums.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ interface Options {
type?: 'alphabetical' | 'natural' | 'line-length'
order?: 'asc' | 'desc'
'ignore-case'?: boolean
'partition-by-comment'?: string[] | string | boolean
}
```

Expand All @@ -95,6 +96,14 @@ interface Options {

Only affects alphabetical and natural sorting. When `true` the rule ignores the case-sensitivity of the order.

### partition-by-comment

<sub>(default: `false`)</sub>

You can set comments that would separate the members of enums into logical parts. If set to `true`, all enum member comments will be treated as delimiters.

The [minimatch](https://github.com/isaacs/minimatch) library is used for pattern matching.

## ⚙️ Usage

::: code-group
Expand Down
88 changes: 60 additions & 28 deletions rules/sort-enums.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import type { SortingNode } from '../typings'
import type { PartitionComment, SortingNode } from '../typings'

import { isPartitionComment } from '../utils/is-partition-comment'
import { createEslintRule } from '../utils/create-eslint-rule'
import { getCommentBefore } from '../utils/get-comment-before'
import { toSingleLine } from '../utils/to-single-line'
import { rangeToDiff } from '../utils/range-to-diff'
import { isPositive } from '../utils/is-positive'
Expand All @@ -15,6 +17,7 @@ type MESSAGE_ID = 'unexpectedEnumsOrder'

type Options = [
Partial<{
'partition-by-comment': PartitionComment
'ignore-case': boolean
order: SortOrder
type: SortType
Expand All @@ -35,6 +38,10 @@ export default createEslintRule<Options, MESSAGE_ID>({
{
type: 'object',
properties: {
'partition-by-comment': {
default: false,
type: ['boolean', 'string', 'array'],
},
type: {
enum: [
SortType.alphabetical,
Expand Down Expand Up @@ -77,36 +84,61 @@ export default createEslintRule<Options, MESSAGE_ID>({
type: SortType.alphabetical,
order: SortOrder.asc,
'ignore-case': false,
'partition-by-comment': false,
})

let nodes: SortingNode[] = node.members.map(member => ({
name:
member.id.type === 'Literal'
? `${member.id.value}`
: `${context.sourceCode.text.slice(...member.id.range)}`,
size: rangeToDiff(member.range),
node: member,
}))
let partitionComment = options['partition-by-comment']

pairwise(nodes, (left, right) => {
if (isPositive(compare(left, right, options))) {
context.report({
messageId: 'unexpectedEnumsOrder',
data: {
left: toSingleLine(left.name),
right: toSingleLine(right.name),
},
node: right.node,
fix: fixer =>
makeFixes(
fixer,
nodes,
sortNodes(nodes, options),
context.sourceCode,
),
})
}
})
let formattedMembers: SortingNode[][] = node.members.reduce(
(accumulator: SortingNode[][], member) => {
let comment = getCommentBefore(member, context.sourceCode)

if (
partitionComment &&
comment &&
isPartitionComment(partitionComment, comment.value)
) {
accumulator.push([])
}

let name =
member.id.type === 'Literal'
? `${member.id.value}`
: `${context.sourceCode.text.slice(...member.id.range)}`

let sortingNode = {
name,
node: member,
size: rangeToDiff(member.range),
}
accumulator.at(-1)!.push(sortingNode)
return accumulator
},
[[]],
)

for (let nodes of formattedMembers) {
pairwise(nodes, (left, right) => {
if (isPositive(compare(left, right, options))) {
context.report({
messageId: 'unexpectedEnumsOrder',
data: {
left: toSingleLine(left.name),
right: toSingleLine(right.name),
},
node: right.node,
fix: fixer =>
makeFixes(
fixer,
nodes,
sortNodes(nodes, options),
context.sourceCode,
{ partitionComment },
),
})
}
})
}
}
},
}),
Expand Down
Loading
Loading