Skip to content

Commit 3a02ecd

Browse files
authored
Merge pull request #9 from SebastianMC/merge-upstream-1
Merge upstream obsidianmd/obsidian-sample-plugin + bugfix
2 parents 73440c5 + fe90df8 commit 3a02ecd

13 files changed

+176
-161
lines changed

esbuild.config.mjs

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,30 +21,20 @@ esbuild.build({
2121
'obsidian',
2222
'electron',
2323
'@codemirror/autocomplete',
24-
'@codemirror/closebrackets',
2524
'@codemirror/collab',
2625
'@codemirror/commands',
27-
'@codemirror/comment',
28-
'@codemirror/fold',
29-
'@codemirror/gutter',
30-
'@codemirror/highlight',
31-
'@codemirror/history',
3226
'@codemirror/language',
3327
'@codemirror/lint',
34-
'@codemirror/matchbrackets',
35-
'@codemirror/panel',
36-
'@codemirror/rangeset',
37-
'@codemirror/rectangular-selection',
3828
'@codemirror/search',
3929
'@codemirror/state',
40-
'@codemirror/stream-parser',
41-
'@codemirror/text',
42-
'@codemirror/tooltip',
4330
'@codemirror/view',
31+
'@lezer/common',
32+
'@lezer/highlight',
33+
'@lezer/lr',
4434
...builtins],
4535
format: 'cjs',
4636
watch: !prod,
47-
target: 'es2016',
37+
target: 'es2018',
4838
logLevel: "info",
4939
sourcemap: prod ? false : 'inline',
5040
minify: prod,

package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@
1818
"devDependencies": {
1919
"@types/jest": "^28.1.2",
2020
"@types/node": "^16.11.6",
21-
"@typescript-eslint/eslint-plugin": "^5.2.0",
22-
"@typescript-eslint/parser": "^5.2.0",
23-
"builtin-modules": "^3.2.0",
24-
"esbuild": "0.13.12",
21+
"@typescript-eslint/eslint-plugin": "5.29.0",
22+
"@typescript-eslint/parser": "5.29.0",
23+
"builtin-modules": "3.3.0",
24+
"esbuild": "0.14.47",
2525
"jest": "^28.1.1",
2626
"monkey-around": "^2.3.0",
2727
"obsidian": "^0.15.4",
2828
"ts-jest": "^28.0.5",
29-
"tslib": "2.3.1",
30-
"typescript": "4.4.4"
29+
"tslib": "2.4.0",
30+
"typescript": "4.7.4"
3131
}
3232
}

src/custom-sort/custom-sort-types.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,16 @@ export enum CustomSortOrder {
1414
byModifiedTimeReverse,
1515
byCreatedTime,
1616
byCreatedTimeReverse,
17-
standardObsidian// Let the folder sorting be in hands of Obsidian, whatever user selected in the UI
17+
standardObsidian, // Let the folder sorting be in hands of Obsidian, whatever user selected in the UI
18+
default = alphabetical
1819
}
1920

2021
export interface RecognizedOrderValue {
2122
order: CustomSortOrder
2223
secondaryOrder?: CustomSortOrder
2324
}
2425

25-
export type NormalizerFn = (s: string) => string
26+
export type NormalizerFn = (s: string) => string | null
2627

2728
export interface RegExpSpec {
2829
regex: RegExp

src/custom-sort/custom-sort.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {TFile} from 'obsidian';
1+
import {TFile, TFolder, Vault} from 'obsidian';
22
import {determineSortingGroup} from './custom-sort';
33
import {CustomSortGroupType, CustomSortSpec} from './custom-sort-types';
44
import {CompoundDashNumberNormalizerFn, CompoundDotRomanNumberNormalizerFn} from "./sorting-spec-processor";
@@ -12,10 +12,10 @@ const mockTFile = (basename: string, ext: string, size?: number, ctime?: number,
1212
},
1313
basename: basename,
1414
extension: ext,
15-
vault: null,
15+
vault: {} as Vault, // To satisfy TS typechecking
1616
path: `Some parent folder/${basename}.${ext}`,
1717
name: `${basename}.${ext}`,
18-
parent: null
18+
parent: {} as TFolder // To satisfy TS typechecking
1919
}
2020
}
2121

src/custom-sort/custom-sort.ts

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
1-
import {TFile, TFolder, requireApiVersion} from 'obsidian';
2-
import {
3-
CustomSortGroup,
4-
CustomSortGroupType,
5-
CustomSortOrder,
6-
CustomSortSpec
7-
} from "./custom-sort-types";
1+
import {requireApiVersion, TFile, TFolder} from 'obsidian';
2+
import {CustomSortGroup, CustomSortGroupType, CustomSortOrder, CustomSortSpec} from "./custom-sort-types";
83
import {isDefined} from "../utils/utils";
94

105
let Collator = new Intl.Collator(undefined, {
@@ -15,7 +10,7 @@ let Collator = new Intl.Collator(undefined, {
1510

1611
interface FolderItemForSorting {
1712
path: string
18-
groupIdx: number // the index itself represents order for groups
13+
groupIdx?: number // the index itself represents order for groups
1914
sortString: string // fragment (or full name) to be used for sorting
2015
matchGroup?: string // advanced - used for secondary sorting rule, to recognize 'same regex match'
2116
ctime: number
@@ -38,15 +33,22 @@ let Sorters: { [key in CustomSortOrder]: SorterFn } = {
3833
};
3934

4035
function compareTwoItems(itA: FolderItemForSorting, itB: FolderItemForSorting, sortSpec: CustomSortSpec) {
41-
if (itA.groupIdx === itB.groupIdx) {
42-
const group: CustomSortGroup = sortSpec.groups[itA.groupIdx]
43-
if (group.regexSpec && group.secondaryOrder && itA.matchGroup === itB.matchGroup) {
44-
return Sorters[group.secondaryOrder](itA, itB)
36+
if (itA.groupIdx != undefined && itB.groupIdx != undefined) {
37+
if (itA.groupIdx === itB.groupIdx) {
38+
const group: CustomSortGroup | undefined = sortSpec.groups[itA.groupIdx]
39+
if (group?.regexSpec && group.secondaryOrder && itA.matchGroup === itB.matchGroup) {
40+
return Sorters[group.secondaryOrder ?? CustomSortOrder.default](itA, itB)
41+
} else {
42+
return Sorters[group?.order ?? CustomSortOrder.default](itA, itB)
43+
}
4544
} else {
46-
return Sorters[group.order](itA, itB)
45+
return itA.groupIdx - itB.groupIdx;
4746
}
4847
} else {
49-
return itA.groupIdx - itB.groupIdx;
48+
// should never happen - groupIdx is not known for at least one of items to compare.
49+
// The logic of determining the index always sets some idx
50+
// Yet for sanity and to satisfy TS code analyzer a fallback to default behavior below
51+
return Sorters[CustomSortOrder.default](itA, itB)
5052
}
5153
}
5254

@@ -58,7 +60,7 @@ const isFolder = (entry: TFile | TFolder) => {
5860
export const determineSortingGroup = function (entry: TFile | TFolder, spec: CustomSortSpec): FolderItemForSorting {
5961
let groupIdx: number
6062
let determined: boolean = false
61-
let matchedGroup: string
63+
let matchedGroup: string | null | undefined
6264
const aFolder: boolean = isFolder(entry)
6365
const aFile: boolean = !aFolder
6466
const entryAsTFile: TFile = entry as TFile
@@ -77,10 +79,10 @@ export const determineSortingGroup = function (entry: TFile | TFolder, spec: Cus
7779
determined = true;
7880
}
7981
} else { // regexp is involved
80-
const match: RegExpMatchArray = group.regexSpec.regex.exec(nameForMatching);
82+
const match: RegExpMatchArray | null | undefined = group.regexSpec?.regex.exec(nameForMatching);
8183
if (match) {
8284
determined = true
83-
matchedGroup = group.regexSpec.normalizerFn(match[1]);
85+
matchedGroup = group.regexSpec?.normalizerFn(match[1]);
8486
}
8587
}
8688
break;
@@ -90,10 +92,10 @@ export const determineSortingGroup = function (entry: TFile | TFolder, spec: Cus
9092
determined = true;
9193
}
9294
} else { // regexp is involved
93-
const match: RegExpMatchArray = group.regexSpec.regex.exec(nameForMatching);
95+
const match: RegExpMatchArray | null | undefined = group.regexSpec?.regex.exec(nameForMatching);
9496
if (match) {
9597
determined = true
96-
matchedGroup = group.regexSpec.normalizerFn(match[1]);
98+
matchedGroup = group.regexSpec?.normalizerFn(match[1]);
9799
}
98100
}
99101
break;
@@ -107,10 +109,10 @@ export const determineSortingGroup = function (entry: TFile | TFolder, spec: Cus
107109
} else { // regexp is involved as the prefix or as the suffix
108110
if ((group.exactPrefix && nameForMatching.startsWith(group.exactPrefix)) ||
109111
(group.exactSuffix && nameForMatching.endsWith(group.exactSuffix))) {
110-
const match: RegExpMatchArray = group.regexSpec.regex.exec(nameForMatching);
112+
const match: RegExpMatchArray | null | undefined = group.regexSpec?.regex.exec(nameForMatching);
111113
if (match) {
112114
const fullMatch: string = match[0]
113-
matchedGroup = group.regexSpec.normalizerFn(match[1]);
115+
matchedGroup = group.regexSpec?.normalizerFn(match[1]);
114116
// check for overlapping of prefix and suffix match (not allowed)
115117
if ((fullMatch.length + (group.exactPrefix?.length ?? 0) + (group.exactSuffix?.length ?? 0)) <= nameForMatching.length) {
116118
determined = true
@@ -127,10 +129,10 @@ export const determineSortingGroup = function (entry: TFile | TFolder, spec: Cus
127129
determined = true;
128130
}
129131
} else { // regexp is involved
130-
const match: RegExpMatchArray = group.regexSpec.regex.exec(nameForMatching);
132+
const match: RegExpMatchArray | null | undefined = group.regexSpec?.regex.exec(nameForMatching);
131133
if (match) {
132134
determined = true
133-
matchedGroup = group.regexSpec.normalizerFn(match[1]);
135+
matchedGroup = group.regexSpec?.normalizerFn(match[1]);
134136
}
135137
}
136138
break;
@@ -144,7 +146,7 @@ export const determineSortingGroup = function (entry: TFile | TFolder, spec: Cus
144146
}
145147

146148
// the final groupIdx for undetermined folder entry is either the last+1 groupIdx or idx of explicitly defined outsiders group
147-
let determinedGroupIdx = groupIdx;
149+
let determinedGroupIdx: number | undefined = groupIdx;
148150

149151
if (!determined) {
150152
// Automatically assign the index to outsiders group, if relevant was configured
@@ -174,7 +176,7 @@ export const folderSort = function (sortingSpec: CustomSortSpec, order: string[]
174176

175177
const folderItems: Array<FolderItemForSorting> = (sortingSpec.itemsToHide ?
176178
this.file.children.filter((entry: TFile | TFolder) => {
177-
return !sortingSpec.itemsToHide.has(entry.name)
179+
return !sortingSpec.itemsToHide!.has(entry.name)
178180
})
179181
:
180182
this.file.children)

src/custom-sort/folder-matching-rules.spec.ts

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -58,18 +58,18 @@ describe('folderMatch', () => {
5858
['Reviews/daily/a/Tue/Early/9am', '4 Reviews/daily/a/*']
5959
])('%s should match %s', (path: string, rule: string) => {
6060
const matcher: FolderWildcardMatching<SortingSpec> = createMockMatcherRichVersion()
61-
const match: SortingSpec = matcher.folderMatch(path)
62-
const matchFromCache: SortingSpec = matcher.folderMatch(path)
61+
const match: SortingSpec | null = matcher.folderMatch(path)
62+
const matchFromCache: SortingSpec | null = matcher.folderMatch(path)
6363
expect(match).toBe(rule)
6464
expect(matchFromCache).toBe(rule)
6565
})
6666
it('should correctly handle no-root definitions', () => {
6767
const matcher: FolderWildcardMatching<SortingSpec> = createMockMatcherSimplestVersion()
68-
const match1: SortingSpec = matcher.folderMatch('/')
69-
const match2: SortingSpec = matcher.folderMatch('/Reviews')
70-
const match3: SortingSpec = matcher.folderMatch('/Reviews/daily/')
71-
const match4: SortingSpec = matcher.folderMatch('/Reviews/daily/Mon')
72-
const match5: SortingSpec = matcher.folderMatch('/Reviews/daily/Mon')
68+
const match1: SortingSpec | null = matcher.folderMatch('/')
69+
const match2: SortingSpec | null = matcher.folderMatch('/Reviews')
70+
const match3: SortingSpec | null = matcher.folderMatch('/Reviews/daily/')
71+
const match4: SortingSpec | null = matcher.folderMatch('/Reviews/daily/Mon')
72+
const match5: SortingSpec | null = matcher.folderMatch('/Reviews/daily/Mon')
7373
expect(match1).toBeNull()
7474
expect(match2).toBeNull()
7575
expect(match3).toBe('/Reviews/daily/*')
@@ -78,27 +78,27 @@ describe('folderMatch', () => {
7878
})
7979
it('should correctly handle root-only definition', () => {
8080
const matcher: FolderWildcardMatching<SortingSpec> = createMockMatcherRootOnlyVersion()
81-
const match1: SortingSpec = matcher.folderMatch('/')
82-
const match2: SortingSpec = matcher.folderMatch('/Reviews')
83-
const match3: SortingSpec = matcher.folderMatch('/Reviews/daily/')
81+
const match1: SortingSpec | null = matcher.folderMatch('/')
82+
const match2: SortingSpec | null = matcher.folderMatch('/Reviews')
83+
const match3: SortingSpec | null = matcher.folderMatch('/Reviews/daily/')
8484
expect(match1).toBe('/...')
8585
expect(match2).toBe('/...')
8686
expect(match3).toBeNull()
8787
})
8888
it('should correctly handle root-only deep definition', () => {
8989
const matcher: FolderWildcardMatching<SortingSpec> = createMockMatcherRootOnlyDeepVersion()
90-
const match1: SortingSpec = matcher.folderMatch('/')
91-
const match2: SortingSpec = matcher.folderMatch('/Reviews')
92-
const match3: SortingSpec = matcher.folderMatch('/Reviews/daily/')
90+
const match1: SortingSpec | null = matcher.folderMatch('/')
91+
const match2: SortingSpec | null = matcher.folderMatch('/Reviews')
92+
const match3: SortingSpec | null = matcher.folderMatch('/Reviews/daily/')
9393
expect(match1).toBe('/*')
9494
expect(match2).toBe('/*')
9595
expect(match3).toBe('/*')
9696
})
9797
it('should correctly handle match all and match children definitions for same path', () => {
9898
const matcher: FolderWildcardMatching<SortingSpec> = createMockMatcherSimpleVersion()
99-
const match1: SortingSpec = matcher.folderMatch('/')
100-
const match2: SortingSpec = matcher.folderMatch('/Reviews/daily/')
101-
const match3: SortingSpec = matcher.folderMatch('/Reviews/daily/1')
99+
const match1: SortingSpec | null = matcher.folderMatch('/')
100+
const match2: SortingSpec | null = matcher.folderMatch('/Reviews/daily/')
101+
const match3: SortingSpec | null = matcher.folderMatch('/Reviews/daily/1')
102102
expect(match1).toBeNull()
103103
expect(match2).toBe('/Reviews/daily/...')
104104
expect(match3).toBe('/Reviews/daily/...')

src/custom-sort/folder-matching-rules.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ export class FolderWildcardMatching<SortingSpec> {
4141
// cache
4242
determinedWildcardRules: { [key: string]: DeterminedSortingSpec<SortingSpec> } = {}
4343

44-
addWildcardDefinition = (wilcardDefinition: string, rule: SortingSpec): AddingWildcardFailure | null => {
44+
addWildcardDefinition = (wilcardDefinition: string, rule: SortingSpec): AddingWildcardFailure | null | undefined => {
4545
const pathComponents: Array<string> = splitPath(wilcardDefinition)
46-
const lastComponent: string = pathComponents.pop()
46+
const lastComponent: string | undefined = pathComponents.pop()
4747
if (lastComponent !== MATCH_ALL_PATH_TOKEN && lastComponent !== MATCH_CHILDREN_PATH_TOKEN) {
4848
return null
4949
}
@@ -82,8 +82,8 @@ export class FolderWildcardMatching<SortingSpec> {
8282
if (spec) {
8383
return spec.spec ?? null
8484
} else {
85-
let rule: SortingSpec = this.tree.matchChildren
86-
let inheritedRule: SortingSpec = this.tree.matchAll
85+
let rule: SortingSpec | null | undefined = this.tree.matchChildren
86+
let inheritedRule: SortingSpec | undefined = this.tree.matchAll
8787
const pathComponents: Array<string> = splitPath(folderPath)
8888
let parentNode: FolderMatchingTreeNode<SortingSpec> = this.tree
8989
let lastIdx: number = pathComponents.length - 1

src/custom-sort/matchers.spec.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ describe('Plain numbers regexp', () => {
2626
const match: RegExpMatchArray | null = s.match(NumberRegex)
2727
if (out) {
2828
expect(match).not.toBeNull()
29-
expect(match[1]).toBe(out)
29+
expect(match?.[1]).toBe(out)
3030
} else {
3131
expect(match).toBeNull()
3232
}
@@ -58,7 +58,7 @@ describe('Plain compound numbers regexp (dot)', () => {
5858
const match: RegExpMatchArray | null = s.match(CompoundNumberDotRegex)
5959
if (out) {
6060
expect(match).not.toBeNull()
61-
expect(match[1]).toBe(out)
61+
expect(match?.[1]).toBe(out)
6262
} else {
6363
expect(match).toBeNull()
6464
}
@@ -90,7 +90,7 @@ describe('Plain compound numbers regexp (dash)', () => {
9090
const match: RegExpMatchArray | null = s.match(CompoundNumberDashRegex)
9191
if (out) {
9292
expect(match).not.toBeNull()
93-
expect(match[1]).toBe(out)
93+
expect(match?.[1]).toBe(out)
9494
} else {
9595
expect(match).toBeNull()
9696
}
@@ -112,7 +112,7 @@ describe('Plain Roman numbers regexp', () => {
112112
const match: RegExpMatchArray | null = s.match(RomanNumberRegex)
113113
if (out) {
114114
expect(match).not.toBeNull()
115-
expect(match[1]).toBe(out)
115+
expect(match?.[1]).toBe(out)
116116
} else {
117117
expect(match).toBeNull()
118118
}
@@ -146,7 +146,7 @@ describe('Roman compound numbers regexp (dot)', () => {
146146
const match: RegExpMatchArray | null = s.match(CompoundRomanNumberDotRegex)
147147
if (out) {
148148
expect(match).not.toBeNull()
149-
expect(match[1]).toBe(out)
149+
expect(match?.[1]).toBe(out)
150150
} else {
151151
expect(match).toBeNull()
152152
}
@@ -180,7 +180,7 @@ describe('Roman compound numbers regexp (dash)', () => {
180180
const match: RegExpMatchArray | null = s.match(CompoundRomanNumberDashRegex)
181181
if (out) {
182182
expect(match).not.toBeNull()
183-
expect(match[1]).toBe(out)
183+
expect(match?.[1]).toBe(out)
184184
} else {
185185
expect(match).toBeNull()
186186
}

0 commit comments

Comments
 (0)