Refactoring of internal processing context plus support for implicit sorting specs
- !!! NO UNIT TESTS ADDED - remember to do it
This commit is contained in:
parent
45f5918598
commit
3cc58f69b9
|
@ -79,10 +79,7 @@ export interface CustomSortSpec {
|
||||||
outsidersFoldersGroupIdx?: number
|
outsidersFoldersGroupIdx?: number
|
||||||
itemsToHide?: Set<string>
|
itemsToHide?: Set<string>
|
||||||
priorityOrder?: Array<number> // Indexes of groups in evaluation order
|
priorityOrder?: Array<number> // Indexes of groups in evaluation order
|
||||||
|
implicit?: boolean // spec applied automatically (e.g. auto integration with a plugin)
|
||||||
// For internal transient use
|
|
||||||
plugin?: Plugin // to hand over the access to App instance to the sorting engine
|
|
||||||
_mCache?: MetadataCache
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DEFAULT_METADATA_FIELD_FOR_SORTING: string = 'sort-index-value'
|
export const DEFAULT_METADATA_FIELD_FOR_SORTING: string = 'sort-index-value'
|
||||||
|
|
|
@ -9,7 +9,7 @@ import {
|
||||||
sorterByMetadataField,
|
sorterByMetadataField,
|
||||||
SorterFn,
|
SorterFn,
|
||||||
getSorterFnFor,
|
getSorterFnFor,
|
||||||
Sorters
|
ProcessingContext
|
||||||
} from './custom-sort';
|
} from './custom-sort';
|
||||||
import {CustomSortGroupType, CustomSortOrder, CustomSortSpec, RegExpSpec} from './custom-sort-types';
|
import {CustomSortGroupType, CustomSortOrder, CustomSortSpec, RegExpSpec} from './custom-sort-types';
|
||||||
import {CompoundDashNumberNormalizerFn, CompoundDotRomanNumberNormalizerFn} from "./sorting-spec-processor";
|
import {CompoundDashNumberNormalizerFn, CompoundDotRomanNumberNormalizerFn} from "./sorting-spec-processor";
|
||||||
|
@ -744,7 +744,9 @@ describe('determineSortingGroup', () => {
|
||||||
type: CustomSortGroupType.HasMetadataField,
|
type: CustomSortGroupType.HasMetadataField,
|
||||||
withMetadataFieldName: "metadataField1",
|
withMetadataFieldName: "metadataField1",
|
||||||
exactPrefix: 'Ref'
|
exactPrefix: 'Ref'
|
||||||
}],
|
}]
|
||||||
|
}
|
||||||
|
const ctx: Partial<ProcessingContext> = {
|
||||||
_mCache: {
|
_mCache: {
|
||||||
getCache: function (path: string): CachedMetadata | undefined {
|
getCache: function (path: string): CachedMetadata | undefined {
|
||||||
return {
|
return {
|
||||||
|
@ -760,7 +762,7 @@ describe('determineSortingGroup', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const result = determineSortingGroup(file, sortSpec)
|
const result = determineSortingGroup(file, sortSpec, ctx as ProcessingContext)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
|
@ -781,7 +783,9 @@ describe('determineSortingGroup', () => {
|
||||||
type: CustomSortGroupType.HasMetadataField,
|
type: CustomSortGroupType.HasMetadataField,
|
||||||
withMetadataFieldName: "metadataField1",
|
withMetadataFieldName: "metadataField1",
|
||||||
exactPrefix: 'Ref'
|
exactPrefix: 'Ref'
|
||||||
}],
|
}]
|
||||||
|
}
|
||||||
|
const ctx: Partial<ProcessingContext> = {
|
||||||
_mCache: {
|
_mCache: {
|
||||||
getCache: function (path: string): CachedMetadata | undefined {
|
getCache: function (path: string): CachedMetadata | undefined {
|
||||||
return {
|
return {
|
||||||
|
@ -797,7 +801,7 @@ describe('determineSortingGroup', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const result = determineSortingGroup(file, sortSpec)
|
const result = determineSortingGroup(file, sortSpec, ctx as ProcessingContext)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
|
@ -818,7 +822,9 @@ describe('determineSortingGroup', () => {
|
||||||
type: CustomSortGroupType.HasMetadataField,
|
type: CustomSortGroupType.HasMetadataField,
|
||||||
withMetadataFieldName: "metadataField1",
|
withMetadataFieldName: "metadataField1",
|
||||||
exactPrefix: 'Ref'
|
exactPrefix: 'Ref'
|
||||||
}],
|
}]
|
||||||
|
}
|
||||||
|
const ctx: Partial<ProcessingContext> = {
|
||||||
_mCache: {
|
_mCache: {
|
||||||
getCache: function (path: string): CachedMetadata | undefined {
|
getCache: function (path: string): CachedMetadata | undefined {
|
||||||
return {
|
return {
|
||||||
|
@ -834,7 +840,7 @@ describe('determineSortingGroup', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const result = determineSortingGroup(file, sortSpec)
|
const result = determineSortingGroup(file, sortSpec, ctx as ProcessingContext)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
|
@ -855,7 +861,9 @@ describe('determineSortingGroup', () => {
|
||||||
type: CustomSortGroupType.HasMetadataField,
|
type: CustomSortGroupType.HasMetadataField,
|
||||||
withMetadataFieldName: "metadataField1",
|
withMetadataFieldName: "metadataField1",
|
||||||
exactPrefix: 'Ref'
|
exactPrefix: 'Ref'
|
||||||
}],
|
}]
|
||||||
|
}
|
||||||
|
const ctx: Partial<ProcessingContext> = {
|
||||||
_mCache: {
|
_mCache: {
|
||||||
getCache: function (path: string): CachedMetadata | undefined {
|
getCache: function (path: string): CachedMetadata | undefined {
|
||||||
return {
|
return {
|
||||||
|
@ -871,7 +879,7 @@ describe('determineSortingGroup', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const result = determineSortingGroup(folder, sortSpec)
|
const result = determineSortingGroup(folder, sortSpec, ctx as ProcessingContext)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
|
@ -904,7 +912,7 @@ describe('determineSortingGroup', () => {
|
||||||
// when
|
// when
|
||||||
const result = determineSortingGroup(file, sortSpec, {
|
const result = determineSortingGroup(file, sortSpec, {
|
||||||
starredPluginInstance: starredPluginInstance as Starred_PluginInstance
|
starredPluginInstance: starredPluginInstance as Starred_PluginInstance
|
||||||
})
|
} as ProcessingContext)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
|
@ -935,7 +943,7 @@ describe('determineSortingGroup', () => {
|
||||||
// when
|
// when
|
||||||
const result = determineSortingGroup(file, sortSpec, {
|
const result = determineSortingGroup(file, sortSpec, {
|
||||||
starredPluginInstance: starredPluginInstance as Starred_PluginInstance
|
starredPluginInstance: starredPluginInstance as Starred_PluginInstance
|
||||||
})
|
} as ProcessingContext)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
|
@ -966,7 +974,7 @@ describe('determineSortingGroup', () => {
|
||||||
// when
|
// when
|
||||||
const result = determineSortingGroup(folder, sortSpec, {
|
const result = determineSortingGroup(folder, sortSpec, {
|
||||||
starredPluginInstance: starredPluginInstance as Starred_PluginInstance
|
starredPluginInstance: starredPluginInstance as Starred_PluginInstance
|
||||||
})
|
} as ProcessingContext)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
|
@ -1005,7 +1013,7 @@ describe('determineSortingGroup', () => {
|
||||||
// when
|
// when
|
||||||
const result = determineSortingGroup(folder, sortSpec, {
|
const result = determineSortingGroup(folder, sortSpec, {
|
||||||
starredPluginInstance: starredPluginInstance as Starred_PluginInstance
|
starredPluginInstance: starredPluginInstance as Starred_PluginInstance
|
||||||
})
|
} as ProcessingContext)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
|
@ -1044,7 +1052,7 @@ describe('determineSortingGroup', () => {
|
||||||
// when
|
// when
|
||||||
const result = determineSortingGroup(folder, sortSpec, {
|
const result = determineSortingGroup(folder, sortSpec, {
|
||||||
starredPluginInstance: starredPluginInstance as Starred_PluginInstance
|
starredPluginInstance: starredPluginInstance as Starred_PluginInstance
|
||||||
})
|
} as ProcessingContext)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
|
@ -1086,7 +1094,7 @@ describe('determineSortingGroup', () => {
|
||||||
// when
|
// when
|
||||||
const result = determineSortingGroup(file, sortSpec, {
|
const result = determineSortingGroup(file, sortSpec, {
|
||||||
iconFolderPluginInstance: obsidianIconFolderPluginInstance as ObsidianIconFolder_PluginInstance
|
iconFolderPluginInstance: obsidianIconFolderPluginInstance as ObsidianIconFolder_PluginInstance
|
||||||
})
|
} as ProcessingContext)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
|
@ -1121,7 +1129,7 @@ describe('determineSortingGroup', () => {
|
||||||
// when
|
// when
|
||||||
const result = determineSortingGroup(file, sortSpec, {
|
const result = determineSortingGroup(file, sortSpec, {
|
||||||
iconFolderPluginInstance: obsidianIconFolderPluginInstance as ObsidianIconFolder_PluginInstance
|
iconFolderPluginInstance: obsidianIconFolderPluginInstance as ObsidianIconFolder_PluginInstance
|
||||||
})
|
} as ProcessingContext)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
|
@ -1155,7 +1163,7 @@ describe('determineSortingGroup', () => {
|
||||||
// when
|
// when
|
||||||
const result = determineSortingGroup(file, sortSpec, {
|
const result = determineSortingGroup(file, sortSpec, {
|
||||||
iconFolderPluginInstance: obsidianIconFolderPluginInstance as ObsidianIconFolder_PluginInstance
|
iconFolderPluginInstance: obsidianIconFolderPluginInstance as ObsidianIconFolder_PluginInstance
|
||||||
})
|
} as ProcessingContext)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
|
@ -1190,7 +1198,7 @@ describe('determineSortingGroup', () => {
|
||||||
// when
|
// when
|
||||||
const result = determineSortingGroup(file, sortSpec, {
|
const result = determineSortingGroup(file, sortSpec, {
|
||||||
iconFolderPluginInstance: obsidianIconFolderPluginInstance as ObsidianIconFolder_PluginInstance
|
iconFolderPluginInstance: obsidianIconFolderPluginInstance as ObsidianIconFolder_PluginInstance
|
||||||
})
|
} as ProcessingContext)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
|
@ -1221,7 +1229,7 @@ describe('determineSortingGroup', () => {
|
||||||
// when
|
// when
|
||||||
const result = determineSortingGroup(folder, sortSpec, {
|
const result = determineSortingGroup(folder, sortSpec, {
|
||||||
iconFolderPluginInstance: obsidianIconFolderPluginInstance as ObsidianIconFolder_PluginInstance
|
iconFolderPluginInstance: obsidianIconFolderPluginInstance as ObsidianIconFolder_PluginInstance
|
||||||
})
|
} as ProcessingContext)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
|
@ -1263,7 +1271,7 @@ describe('determineSortingGroup', () => {
|
||||||
// when
|
// when
|
||||||
const result = determineSortingGroup(folder, sortSpec, {
|
const result = determineSortingGroup(folder, sortSpec, {
|
||||||
iconFolderPluginInstance: obsidianIconFolderPluginInstance as ObsidianIconFolder_PluginInstance
|
iconFolderPluginInstance: obsidianIconFolderPluginInstance as ObsidianIconFolder_PluginInstance
|
||||||
})
|
} as ProcessingContext)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
|
@ -1308,7 +1316,7 @@ describe('determineSortingGroup', () => {
|
||||||
// when
|
// when
|
||||||
const result = determineSortingGroup(folder, sortSpec, {
|
const result = determineSortingGroup(folder, sortSpec, {
|
||||||
iconFolderPluginInstance: obsidianIconFolderPluginInstance as ObsidianIconFolder_PluginInstance
|
iconFolderPluginInstance: obsidianIconFolderPluginInstance as ObsidianIconFolder_PluginInstance
|
||||||
})
|
} as ProcessingContext)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
|
@ -1351,7 +1359,7 @@ describe('determineSortingGroup', () => {
|
||||||
// when
|
// when
|
||||||
const result = determineSortingGroup(folder, sortSpec, {
|
const result = determineSortingGroup(folder, sortSpec, {
|
||||||
iconFolderPluginInstance: obsidianIconFolderPluginInstance as ObsidianIconFolder_PluginInstance
|
iconFolderPluginInstance: obsidianIconFolderPluginInstance as ObsidianIconFolder_PluginInstance
|
||||||
})
|
} as ProcessingContext)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
|
@ -1397,7 +1405,7 @@ describe('determineSortingGroup', () => {
|
||||||
// when
|
// when
|
||||||
const result = determineSortingGroup(folder, sortSpec, {
|
const result = determineSortingGroup(folder, sortSpec, {
|
||||||
iconFolderPluginInstance: obsidianIconFolderPluginInstance as ObsidianIconFolder_PluginInstance
|
iconFolderPluginInstance: obsidianIconFolderPluginInstance as ObsidianIconFolder_PluginInstance
|
||||||
})
|
} as ProcessingContext)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
|
@ -1440,7 +1448,7 @@ describe('determineSortingGroup', () => {
|
||||||
// when
|
// when
|
||||||
const result = determineSortingGroup(folder, sortSpec, {
|
const result = determineSortingGroup(folder, sortSpec, {
|
||||||
iconFolderPluginInstance: obsidianIconFolderPluginInstance as ObsidianIconFolder_PluginInstance
|
iconFolderPluginInstance: obsidianIconFolderPluginInstance as ObsidianIconFolder_PluginInstance
|
||||||
})
|
} as ProcessingContext)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
|
@ -1486,7 +1494,7 @@ describe('determineSortingGroup', () => {
|
||||||
// when
|
// when
|
||||||
const result = determineSortingGroup(folder, sortSpec, {
|
const result = determineSortingGroup(folder, sortSpec, {
|
||||||
iconFolderPluginInstance: obsidianIconFolderPluginInstance as ObsidianIconFolder_PluginInstance
|
iconFolderPluginInstance: obsidianIconFolderPluginInstance as ObsidianIconFolder_PluginInstance
|
||||||
})
|
} as ProcessingContext)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
|
@ -1519,7 +1527,9 @@ describe('determineSortingGroup', () => {
|
||||||
byMetadataField: 'metadata-field-for-sorting',
|
byMetadataField: 'metadata-field-for-sorting',
|
||||||
exactPrefix: 'Ref',
|
exactPrefix: 'Ref',
|
||||||
order: CustomSortOrder.byMetadataFieldAlphabetical
|
order: CustomSortOrder.byMetadataFieldAlphabetical
|
||||||
}],
|
}]
|
||||||
|
}
|
||||||
|
const ctx: Partial<ProcessingContext> = {
|
||||||
_mCache: {
|
_mCache: {
|
||||||
getCache: function (path: string): CachedMetadata | undefined {
|
getCache: function (path: string): CachedMetadata | undefined {
|
||||||
return {
|
return {
|
||||||
|
@ -1535,7 +1545,7 @@ describe('determineSortingGroup', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const result = determineSortingGroup(file, sortSpec)
|
const result = determineSortingGroup(file, sortSpec, ctx as ProcessingContext)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
|
@ -1558,7 +1568,9 @@ describe('determineSortingGroup', () => {
|
||||||
byMetadataField: 'metadata-field-for-sorting',
|
byMetadataField: 'metadata-field-for-sorting',
|
||||||
exactPrefix: 'Ref',
|
exactPrefix: 'Ref',
|
||||||
order: CustomSortOrder.byMetadataFieldAlphabeticalReverse
|
order: CustomSortOrder.byMetadataFieldAlphabeticalReverse
|
||||||
}],
|
}]
|
||||||
|
}
|
||||||
|
const ctx: Partial<ProcessingContext> = {
|
||||||
_mCache: {
|
_mCache: {
|
||||||
getCache: function (path: string): CachedMetadata | undefined {
|
getCache: function (path: string): CachedMetadata | undefined {
|
||||||
return {
|
return {
|
||||||
|
@ -1574,7 +1586,7 @@ describe('determineSortingGroup', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const result = determineSortingGroup(file, sortSpec)
|
const result = determineSortingGroup(file, sortSpec, ctx as ProcessingContext)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
|
@ -1597,7 +1609,9 @@ describe('determineSortingGroup', () => {
|
||||||
byMetadataField: 'metadata-field-for-sorting',
|
byMetadataField: 'metadata-field-for-sorting',
|
||||||
exactPrefix: 'Ref',
|
exactPrefix: 'Ref',
|
||||||
order: CustomSortOrder.byMetadataFieldTrueAlphabetical
|
order: CustomSortOrder.byMetadataFieldTrueAlphabetical
|
||||||
}],
|
}]
|
||||||
|
}
|
||||||
|
const ctx: Partial<ProcessingContext> = {
|
||||||
_mCache: {
|
_mCache: {
|
||||||
getCache: function (path: string): CachedMetadata | undefined {
|
getCache: function (path: string): CachedMetadata | undefined {
|
||||||
return {
|
return {
|
||||||
|
@ -1613,7 +1627,7 @@ describe('determineSortingGroup', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const result = determineSortingGroup(file, sortSpec)
|
const result = determineSortingGroup(file, sortSpec, ctx as ProcessingContext)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
|
@ -1636,7 +1650,9 @@ describe('determineSortingGroup', () => {
|
||||||
byMetadataField: 'metadata-field-for-sorting',
|
byMetadataField: 'metadata-field-for-sorting',
|
||||||
exactPrefix: 'Ref',
|
exactPrefix: 'Ref',
|
||||||
order: CustomSortOrder.byMetadataFieldTrueAlphabeticalReverse
|
order: CustomSortOrder.byMetadataFieldTrueAlphabeticalReverse
|
||||||
}],
|
}]
|
||||||
|
}
|
||||||
|
const ctx: Partial<ProcessingContext> = {
|
||||||
_mCache: {
|
_mCache: {
|
||||||
getCache: function (path: string): CachedMetadata | undefined {
|
getCache: function (path: string): CachedMetadata | undefined {
|
||||||
return {
|
return {
|
||||||
|
@ -1652,7 +1668,7 @@ describe('determineSortingGroup', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const result = determineSortingGroup(file, sortSpec)
|
const result = determineSortingGroup(file, sortSpec, ctx as ProcessingContext)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
|
@ -1675,7 +1691,9 @@ describe('determineSortingGroup', () => {
|
||||||
exactPrefix: 'Ref',
|
exactPrefix: 'Ref',
|
||||||
byMetadataField: 'metadata-field-for-sorting',
|
byMetadataField: 'metadata-field-for-sorting',
|
||||||
order: CustomSortOrder.byMetadataFieldAlphabeticalReverse
|
order: CustomSortOrder.byMetadataFieldAlphabeticalReverse
|
||||||
}],
|
}]
|
||||||
|
}
|
||||||
|
const ctx: Partial<ProcessingContext> = {
|
||||||
_mCache: {
|
_mCache: {
|
||||||
getCache: function (path: string): CachedMetadata | undefined {
|
getCache: function (path: string): CachedMetadata | undefined {
|
||||||
return {
|
return {
|
||||||
|
@ -1691,7 +1709,7 @@ describe('determineSortingGroup', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const result = determineSortingGroup(folder, sortSpec)
|
const result = determineSortingGroup(folder, sortSpec, ctx as ProcessingContext)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
|
@ -1715,6 +1733,10 @@ describe('determineSortingGroup', () => {
|
||||||
exactPrefix: 'Ref',
|
exactPrefix: 'Ref',
|
||||||
order: CustomSortOrder.byMetadataFieldAlphabetical
|
order: CustomSortOrder.byMetadataFieldAlphabetical
|
||||||
}],
|
}],
|
||||||
|
defaultOrder: CustomSortOrder.byMetadataFieldAlphabeticalReverse,
|
||||||
|
byMetadataField: 'metadata-field-for-sorting-specified-on-target-folder'
|
||||||
|
}
|
||||||
|
const ctx: Partial<ProcessingContext> = {
|
||||||
_mCache: {
|
_mCache: {
|
||||||
getCache: function (path: string): CachedMetadata | undefined {
|
getCache: function (path: string): CachedMetadata | undefined {
|
||||||
return {
|
return {
|
||||||
|
@ -1726,13 +1748,11 @@ describe('determineSortingGroup', () => {
|
||||||
}
|
}
|
||||||
}[path]
|
}[path]
|
||||||
}
|
}
|
||||||
} as MetadataCache,
|
} as MetadataCache
|
||||||
defaultOrder: CustomSortOrder.byMetadataFieldAlphabeticalReverse,
|
|
||||||
byMetadataField: 'metadata-field-for-sorting-specified-on-target-folder',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const result = determineSortingGroup(file, sortSpec)
|
const result = determineSortingGroup(file, sortSpec, ctx as ProcessingContext)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
|
@ -1754,7 +1774,9 @@ describe('determineSortingGroup', () => {
|
||||||
type: CustomSortGroupType.HasMetadataField,
|
type: CustomSortGroupType.HasMetadataField,
|
||||||
order: CustomSortOrder.byMetadataFieldAlphabetical,
|
order: CustomSortOrder.byMetadataFieldAlphabetical,
|
||||||
withMetadataFieldName: 'field-used-with-with-metadata-syntax'
|
withMetadataFieldName: 'field-used-with-with-metadata-syntax'
|
||||||
}],
|
}]
|
||||||
|
}
|
||||||
|
const ctx: Partial<ProcessingContext> = {
|
||||||
_mCache: {
|
_mCache: {
|
||||||
getCache: function (path: string): CachedMetadata | undefined {
|
getCache: function (path: string): CachedMetadata | undefined {
|
||||||
return {
|
return {
|
||||||
|
@ -1770,7 +1792,7 @@ describe('determineSortingGroup', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const result = determineSortingGroup(file, sortSpec)
|
const result = determineSortingGroup(file, sortSpec, ctx as ProcessingContext)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
|
@ -1792,7 +1814,9 @@ describe('determineSortingGroup', () => {
|
||||||
type: CustomSortGroupType.ExactPrefix,
|
type: CustomSortGroupType.ExactPrefix,
|
||||||
exactPrefix: 'Ref',
|
exactPrefix: 'Ref',
|
||||||
order: CustomSortOrder.byMetadataFieldAlphabetical
|
order: CustomSortOrder.byMetadataFieldAlphabetical
|
||||||
}],
|
}]
|
||||||
|
}
|
||||||
|
const ctx: Partial<ProcessingContext> = {
|
||||||
_mCache: {
|
_mCache: {
|
||||||
getCache: function (path: string): CachedMetadata | undefined {
|
getCache: function (path: string): CachedMetadata | undefined {
|
||||||
return {
|
return {
|
||||||
|
@ -1808,7 +1832,7 @@ describe('determineSortingGroup', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const result = determineSortingGroup(file, sortSpec)
|
const result = determineSortingGroup(file, sortSpec, ctx as ProcessingContext)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
|
@ -2122,7 +2146,7 @@ describe('CustomSortOrder.byMetadataFieldAlphabetical', () => {
|
||||||
const itemB: Partial<FolderItemForSorting> = {
|
const itemB: Partial<FolderItemForSorting> = {
|
||||||
metadataFieldValue: 'B'
|
metadataFieldValue: 'B'
|
||||||
}
|
}
|
||||||
const sorter: SorterFn = Sorters[CustomSortOrder.byMetadataFieldAlphabetical]
|
const sorter: SorterFn = getSorterFnFor(CustomSortOrder.byMetadataFieldAlphabetical)
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const result1: number = sorter(itemA as FolderItemForSorting, itemB as FolderItemForSorting)
|
const result1: number = sorter(itemA as FolderItemForSorting, itemB as FolderItemForSorting)
|
||||||
|
@ -2142,7 +2166,7 @@ describe('CustomSortOrder.byMetadataFieldAlphabetical', () => {
|
||||||
metadataFieldValue: 'Aaa',
|
metadataFieldValue: 'Aaa',
|
||||||
sortString: 'a123'
|
sortString: 'a123'
|
||||||
}
|
}
|
||||||
const sorter: SorterFn = Sorters[CustomSortOrder.byMetadataFieldAlphabetical]
|
const sorter: SorterFn = getSorterFnFor(CustomSortOrder.byMetadataFieldAlphabetical)
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const result1: number = sorter(itemA as FolderItemForSorting, itemB as FolderItemForSorting)
|
const result1: number = sorter(itemA as FolderItemForSorting, itemB as FolderItemForSorting)
|
||||||
|
@ -2163,7 +2187,7 @@ describe('CustomSortOrder.byMetadataFieldAlphabetical', () => {
|
||||||
const itemB: Partial<FolderItemForSorting> = {
|
const itemB: Partial<FolderItemForSorting> = {
|
||||||
sortString: 'n123'
|
sortString: 'n123'
|
||||||
}
|
}
|
||||||
const sorter: SorterFn = Sorters[CustomSortOrder.byMetadataFieldAlphabetical]
|
const sorter: SorterFn = getSorterFnFor(CustomSortOrder.byMetadataFieldAlphabetical)
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const result1: number = sorter(itemA as FolderItemForSorting, itemB as FolderItemForSorting)
|
const result1: number = sorter(itemA as FolderItemForSorting, itemB as FolderItemForSorting)
|
||||||
|
@ -2181,7 +2205,7 @@ describe('CustomSortOrder.byMetadataFieldAlphabetical', () => {
|
||||||
const itemB: Partial<FolderItemForSorting> = {
|
const itemB: Partial<FolderItemForSorting> = {
|
||||||
sortString: 'ccc '
|
sortString: 'ccc '
|
||||||
}
|
}
|
||||||
const sorter: SorterFn = Sorters[CustomSortOrder.byMetadataFieldAlphabetical]
|
const sorter: SorterFn = getSorterFnFor(CustomSortOrder.byMetadataFieldAlphabetical)
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const result1: number = sorter(itemA as FolderItemForSorting, itemB as FolderItemForSorting)
|
const result1: number = sorter(itemA as FolderItemForSorting, itemB as FolderItemForSorting)
|
||||||
|
@ -2204,7 +2228,7 @@ describe('CustomSortOrder.byMetadataFieldAlphabeticalReverse', () => {
|
||||||
const itemB: Partial<FolderItemForSorting> = {
|
const itemB: Partial<FolderItemForSorting> = {
|
||||||
metadataFieldValue: 'B'
|
metadataFieldValue: 'B'
|
||||||
}
|
}
|
||||||
const sorter: SorterFn = Sorters[CustomSortOrder.byMetadataFieldAlphabeticalReverse]
|
const sorter: SorterFn = getSorterFnFor(CustomSortOrder.byMetadataFieldAlphabeticalReverse)
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const result1: number = sorter(itemA as FolderItemForSorting, itemB as FolderItemForSorting)
|
const result1: number = sorter(itemA as FolderItemForSorting, itemB as FolderItemForSorting)
|
||||||
|
@ -2224,7 +2248,7 @@ describe('CustomSortOrder.byMetadataFieldAlphabeticalReverse', () => {
|
||||||
metadataFieldValue: 'Aaa',
|
metadataFieldValue: 'Aaa',
|
||||||
sortString: 'a123'
|
sortString: 'a123'
|
||||||
}
|
}
|
||||||
const sorter: SorterFn = Sorters[CustomSortOrder.byMetadataFieldAlphabeticalReverse]
|
const sorter: SorterFn = getSorterFnFor(CustomSortOrder.byMetadataFieldAlphabeticalReverse)
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const result1: number = sorter(itemA as FolderItemForSorting, itemB as FolderItemForSorting)
|
const result1: number = sorter(itemA as FolderItemForSorting, itemB as FolderItemForSorting)
|
||||||
|
@ -2236,25 +2260,6 @@ describe('CustomSortOrder.byMetadataFieldAlphabeticalReverse', () => {
|
||||||
expect(result2).toBe(SORT_FIRST_GOES_LATER)
|
expect(result2).toBe(SORT_FIRST_GOES_LATER)
|
||||||
expect(result3).toBe(SORT_ITEMS_ARE_EQUAL)
|
expect(result3).toBe(SORT_ITEMS_ARE_EQUAL)
|
||||||
})
|
})
|
||||||
it('should put the item with metadata below the second one w/o metadata (this is reverse order)', () => {
|
|
||||||
// given
|
|
||||||
const itemA: Partial<FolderItemForSorting> = {
|
|
||||||
metadataFieldValue: '15',
|
|
||||||
sortString: 'n123'
|
|
||||||
}
|
|
||||||
const itemB: Partial<FolderItemForSorting> = {
|
|
||||||
sortString: 'n123'
|
|
||||||
}
|
|
||||||
const sorter: SorterFn = Sorters[CustomSortOrder.byMetadataFieldAlphabeticalReverse]
|
|
||||||
|
|
||||||
// when
|
|
||||||
const result1: number = sorter(itemA as FolderItemForSorting, itemB as FolderItemForSorting)
|
|
||||||
const result2: number = sorter(itemB as FolderItemForSorting, itemA as FolderItemForSorting)
|
|
||||||
|
|
||||||
// then
|
|
||||||
expect(result1).toBe(SORT_FIRST_GOES_LATER)
|
|
||||||
expect(result2).toBe(SORT_FIRST_GOES_EARLIER)
|
|
||||||
})
|
|
||||||
it('should put the item with metadata later if the second one has no metadata (reverse order)', () => {
|
it('should put the item with metadata later if the second one has no metadata (reverse order)', () => {
|
||||||
// given
|
// given
|
||||||
const itemA: Partial<FolderItemForSorting> = {
|
const itemA: Partial<FolderItemForSorting> = {
|
||||||
|
@ -2264,7 +2269,7 @@ describe('CustomSortOrder.byMetadataFieldAlphabeticalReverse', () => {
|
||||||
const itemB: Partial<FolderItemForSorting> = {
|
const itemB: Partial<FolderItemForSorting> = {
|
||||||
sortString: 'n123'
|
sortString: 'n123'
|
||||||
}
|
}
|
||||||
const sorter: SorterFn = Sorters[CustomSortOrder.byMetadataFieldAlphabeticalReverse]
|
const sorter: SorterFn = getSorterFnFor(CustomSortOrder.byMetadataFieldAlphabeticalReverse)
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const result1: number = sorter(itemA as FolderItemForSorting, itemB as FolderItemForSorting)
|
const result1: number = sorter(itemA as FolderItemForSorting, itemB as FolderItemForSorting)
|
||||||
|
@ -2282,7 +2287,7 @@ describe('CustomSortOrder.byMetadataFieldAlphabeticalReverse', () => {
|
||||||
const itemB: Partial<FolderItemForSorting> = {
|
const itemB: Partial<FolderItemForSorting> = {
|
||||||
sortString: 'ccc '
|
sortString: 'ccc '
|
||||||
}
|
}
|
||||||
const sorter: SorterFn = Sorters[CustomSortOrder.byMetadataFieldAlphabeticalReverse]
|
const sorter: SorterFn = getSorterFnFor(CustomSortOrder.byMetadataFieldAlphabeticalReverse)
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const result1: number = sorter(itemA as FolderItemForSorting, itemB as FolderItemForSorting)
|
const result1: number = sorter(itemA as FolderItemForSorting, itemB as FolderItemForSorting)
|
||||||
|
|
|
@ -3,6 +3,7 @@ import {
|
||||||
CommunityPlugin,
|
CommunityPlugin,
|
||||||
FrontMatterCache,
|
FrontMatterCache,
|
||||||
InstalledPlugin,
|
InstalledPlugin,
|
||||||
|
MetadataCache,
|
||||||
requireApiVersion,
|
requireApiVersion,
|
||||||
TAbstractFile,
|
TAbstractFile,
|
||||||
TFile,
|
TFile,
|
||||||
|
@ -39,6 +40,15 @@ import {
|
||||||
} from "./macros";
|
} from "./macros";
|
||||||
import {Obj} from "tern";
|
import {Obj} from "tern";
|
||||||
|
|
||||||
|
export interface ProcessingContext {
|
||||||
|
// For internal transient use
|
||||||
|
plugin?: Plugin // to hand over the access to App instance to the sorting engine
|
||||||
|
_mCache?: MetadataCache
|
||||||
|
starredPluginInstance?: Starred_PluginInstance
|
||||||
|
|
||||||
|
iconFolderPluginInstance?: ObsidianIconFolder_PluginInstance
|
||||||
|
}
|
||||||
|
|
||||||
let CollatorCompare = new Intl.Collator(undefined, {
|
let CollatorCompare = new Intl.Collator(undefined, {
|
||||||
usage: "sort",
|
usage: "sort",
|
||||||
sensitivity: "base",
|
sensitivity: "base",
|
||||||
|
@ -96,7 +106,7 @@ export const sorterByMetadataField:(reverseOrder?: boolean, trueAlphabetical?: b
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export let Sorters: { [key in CustomSortOrder]: SorterFn } = {
|
let Sorters: { [key in CustomSortOrder]: SorterFn } = {
|
||||||
[CustomSortOrder.alphabetical]: (a: FolderItemForSorting, b: FolderItemForSorting) => CollatorCompare(a.sortString, b.sortString),
|
[CustomSortOrder.alphabetical]: (a: FolderItemForSorting, b: FolderItemForSorting) => CollatorCompare(a.sortString, b.sortString),
|
||||||
[CustomSortOrder.trueAlphabetical]: (a: FolderItemForSorting, b: FolderItemForSorting) => CollatorTrueAlphabeticalCompare(a.sortString, b.sortString),
|
[CustomSortOrder.trueAlphabetical]: (a: FolderItemForSorting, b: FolderItemForSorting) => CollatorTrueAlphabeticalCompare(a.sortString, b.sortString),
|
||||||
[CustomSortOrder.alphabeticalReverse]: (a: FolderItemForSorting, b: FolderItemForSorting) => CollatorCompare(b.sortString, a.sortString),
|
[CustomSortOrder.alphabeticalReverse]: (a: FolderItemForSorting, b: FolderItemForSorting) => CollatorCompare(b.sortString, a.sortString),
|
||||||
|
@ -236,12 +246,7 @@ export const matchGroupRegex = (theRegex: RegExpSpec, nameForMatching: string):
|
||||||
return [false, undefined, undefined]
|
return [false, undefined, undefined]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Context {
|
export const determineSortingGroup = function (entry: TFile | TFolder, spec: CustomSortSpec, ctx?: ProcessingContext): FolderItemForSorting {
|
||||||
starredPluginInstance?: Starred_PluginInstance
|
|
||||||
iconFolderPluginInstance?: ObsidianIconFolder_PluginInstance
|
|
||||||
}
|
|
||||||
|
|
||||||
export const determineSortingGroup = function (entry: TFile | TFolder, spec: CustomSortSpec, ctx?: Context): FolderItemForSorting {
|
|
||||||
let groupIdx: number
|
let groupIdx: number
|
||||||
let determined: boolean = false
|
let determined: boolean = false
|
||||||
let matchedGroup: string | null | undefined
|
let matchedGroup: string | null | undefined
|
||||||
|
@ -324,10 +329,10 @@ export const determineSortingGroup = function (entry: TFile | TFolder, spec: Cus
|
||||||
break
|
break
|
||||||
case CustomSortGroupType.HasMetadataField:
|
case CustomSortGroupType.HasMetadataField:
|
||||||
if (group.withMetadataFieldName) {
|
if (group.withMetadataFieldName) {
|
||||||
if (spec._mCache) {
|
if (ctx?._mCache) {
|
||||||
// For folders - scan metadata of 'folder note'
|
// For folders - scan metadata of 'folder note'
|
||||||
const notePathToScan: string = aFile ? entry.path : `${entry.path}/${entry.name}.md`
|
const notePathToScan: string = aFile ? entry.path : `${entry.path}/${entry.name}.md`
|
||||||
const frontMatterCache: FrontMatterCache | undefined = spec._mCache.getCache(notePathToScan)?.frontmatter
|
const frontMatterCache: FrontMatterCache | undefined = ctx._mCache.getCache(notePathToScan)?.frontmatter
|
||||||
const hasMetadata: boolean | undefined = frontMatterCache?.hasOwnProperty(group.withMetadataFieldName)
|
const hasMetadata: boolean | undefined = frontMatterCache?.hasOwnProperty(group.withMetadataFieldName)
|
||||||
|
|
||||||
if (hasMetadata) {
|
if (hasMetadata) {
|
||||||
|
@ -417,10 +422,10 @@ export const determineSortingGroup = function (entry: TFile | TFolder, spec: Cus
|
||||||
metadataFieldName = DEFAULT_METADATA_FIELD_FOR_SORTING
|
metadataFieldName = DEFAULT_METADATA_FIELD_FOR_SORTING
|
||||||
}
|
}
|
||||||
if (metadataFieldName) {
|
if (metadataFieldName) {
|
||||||
if (spec._mCache) {
|
if (ctx?._mCache) {
|
||||||
// For folders - scan metadata of 'folder note'
|
// For folders - scan metadata of 'folder note'
|
||||||
const notePathToScan: string = aFile ? entry.path : `${entry.path}/${entry.name}.md`
|
const notePathToScan: string = aFile ? entry.path : `${entry.path}/${entry.name}.md`
|
||||||
const frontMatterCache: FrontMatterCache | undefined = spec._mCache.getCache(notePathToScan)?.frontmatter
|
const frontMatterCache: FrontMatterCache | undefined = ctx._mCache.getCache(notePathToScan)?.frontmatter
|
||||||
metadataValueToSortBy = frontMatterCache?.[metadataFieldName]
|
metadataValueToSortBy = frontMatterCache?.[metadataFieldName]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -496,11 +501,8 @@ export const determineFolderDatesIfNeeded = (folderItems: Array<FolderItemForSor
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const folderSort = function (sortingSpec: CustomSortSpec, order: string[]) {
|
export const folderSort = function (sortingSpec: CustomSortSpec, ctx: ProcessingContext) {
|
||||||
let fileExplorer = this.fileExplorer
|
let fileExplorer = this.fileExplorer
|
||||||
sortingSpec._mCache = sortingSpec.plugin?.app.metadataCache
|
|
||||||
const starredPluginInstance: Starred_PluginInstance | undefined = getStarredPlugin()
|
|
||||||
const iconFolderPluginInstance: ObsidianIconFolder_PluginInstance | undefined = getIconFolderPlugin()
|
|
||||||
|
|
||||||
// shallow copy of groups
|
// shallow copy of groups
|
||||||
sortingSpec.groupsShadow = sortingSpec.groups?.map((group) => Object.assign({} as CustomSortGroup, group))
|
sortingSpec.groupsShadow = sortingSpec.groups?.map((group) => Object.assign({} as CustomSortGroup, group))
|
||||||
|
@ -516,10 +518,7 @@ export const folderSort = function (sortingSpec: CustomSortSpec, order: string[]
|
||||||
:
|
:
|
||||||
this.file.children)
|
this.file.children)
|
||||||
.map((entry: TFile | TFolder) => {
|
.map((entry: TFile | TFolder) => {
|
||||||
const itemForSorting: FolderItemForSorting = determineSortingGroup(entry, sortingSpec, {
|
const itemForSorting: FolderItemForSorting = determineSortingGroup(entry, sortingSpec, ctx)
|
||||||
starredPluginInstance: starredPluginInstance,
|
|
||||||
iconFolderPluginInstance: iconFolderPluginInstance
|
|
||||||
})
|
|
||||||
return itemForSorting
|
return itemForSorting
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -538,8 +537,4 @@ export const folderSort = function (sortingSpec: CustomSortSpec, order: string[]
|
||||||
} else {
|
} else {
|
||||||
this.children = items;
|
this.children = items;
|
||||||
}
|
}
|
||||||
|
|
||||||
// release risky references
|
|
||||||
sortingSpec._mCache = undefined
|
|
||||||
sortingSpec.plugin = undefined
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,8 +2,10 @@ import {FolderWildcardMatching} from './folder-matching-rules'
|
||||||
|
|
||||||
type SortingSpec = string
|
type SortingSpec = string
|
||||||
|
|
||||||
|
const checkIfImplicitSpec = (s: SortingSpec) => false
|
||||||
|
|
||||||
const createMockMatcherRichVersion = (): FolderWildcardMatching<SortingSpec> => {
|
const createMockMatcherRichVersion = (): FolderWildcardMatching<SortingSpec> => {
|
||||||
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching()
|
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching(checkIfImplicitSpec)
|
||||||
let p: string
|
let p: string
|
||||||
p = '/...'; matcher.addWildcardDefinition(p, `00 ${p}`)
|
p = '/...'; matcher.addWildcardDefinition(p, `00 ${p}`)
|
||||||
p = '/*'; matcher.addWildcardDefinition(p, `0 ${p}`)
|
p = '/*'; matcher.addWildcardDefinition(p, `0 ${p}`)
|
||||||
|
@ -19,25 +21,25 @@ const PRIO2 = 2
|
||||||
const PRIO3 = 3
|
const PRIO3 = 3
|
||||||
|
|
||||||
const createMockMatcherSimplestVersion = (): FolderWildcardMatching<SortingSpec> => {
|
const createMockMatcherSimplestVersion = (): FolderWildcardMatching<SortingSpec> => {
|
||||||
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching()
|
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching(checkIfImplicitSpec)
|
||||||
matcher.addWildcardDefinition('/Reviews/daily/*', '/Reviews/daily/*')
|
matcher.addWildcardDefinition('/Reviews/daily/*', '/Reviews/daily/*')
|
||||||
return matcher
|
return matcher
|
||||||
}
|
}
|
||||||
|
|
||||||
const createMockMatcherRootOnlyVersion = (): FolderWildcardMatching<SortingSpec> => {
|
const createMockMatcherRootOnlyVersion = (): FolderWildcardMatching<SortingSpec> => {
|
||||||
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching()
|
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching(checkIfImplicitSpec)
|
||||||
matcher.addWildcardDefinition('/...', '/...')
|
matcher.addWildcardDefinition('/...', '/...')
|
||||||
return matcher
|
return matcher
|
||||||
}
|
}
|
||||||
|
|
||||||
const createMockMatcherRootOnlyDeepVersion = (): FolderWildcardMatching<SortingSpec> => {
|
const createMockMatcherRootOnlyDeepVersion = (): FolderWildcardMatching<SortingSpec> => {
|
||||||
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching()
|
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching(checkIfImplicitSpec)
|
||||||
matcher.addWildcardDefinition('/*', '/*')
|
matcher.addWildcardDefinition('/*', '/*')
|
||||||
return matcher
|
return matcher
|
||||||
}
|
}
|
||||||
|
|
||||||
const createMockMatcherSimpleVersion = (): FolderWildcardMatching<SortingSpec> => {
|
const createMockMatcherSimpleVersion = (): FolderWildcardMatching<SortingSpec> => {
|
||||||
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching()
|
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching(checkIfImplicitSpec)
|
||||||
matcher.addWildcardDefinition('/Reviews/daily/*', '/Reviews/daily/*')
|
matcher.addWildcardDefinition('/Reviews/daily/*', '/Reviews/daily/*')
|
||||||
matcher.addWildcardDefinition('/Reviews/daily/...', '/Reviews/daily/...')
|
matcher.addWildcardDefinition('/Reviews/daily/...', '/Reviews/daily/...')
|
||||||
return matcher
|
return matcher
|
||||||
|
@ -108,21 +110,21 @@ describe('folderMatch', () => {
|
||||||
expect(match3).toBe('/Reviews/daily/...')
|
expect(match3).toBe('/Reviews/daily/...')
|
||||||
})
|
})
|
||||||
it('should detect duplicate match children definitions for same path', () => {
|
it('should detect duplicate match children definitions for same path', () => {
|
||||||
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching()
|
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching(checkIfImplicitSpec)
|
||||||
matcher.addWildcardDefinition('Archive/2020/...', 'First occurrence')
|
matcher.addWildcardDefinition('Archive/2020/...', 'First occurrence')
|
||||||
const result = matcher.addWildcardDefinition('/Archive/2020/.../', 'Duplicate')
|
const result = matcher.addWildcardDefinition('/Archive/2020/.../', 'Duplicate')
|
||||||
|
|
||||||
expect(result).toEqual({errorMsg: "Duplicate wildcard '...' specification for /Archive/2020/.../"})
|
expect(result).toEqual({errorMsg: "Duplicate wildcard '...' specification for /Archive/2020/.../"})
|
||||||
})
|
})
|
||||||
it('should detect duplicate match all definitions for same path', () => {
|
it('should detect duplicate match all definitions for same path', () => {
|
||||||
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching()
|
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching(checkIfImplicitSpec)
|
||||||
matcher.addWildcardDefinition('/Archive/2019/*', 'First occurrence')
|
matcher.addWildcardDefinition('/Archive/2019/*', 'First occurrence')
|
||||||
const result = matcher.addWildcardDefinition('Archive/2019/*', 'Duplicate')
|
const result = matcher.addWildcardDefinition('Archive/2019/*', 'Duplicate')
|
||||||
|
|
||||||
expect(result).toEqual({errorMsg: "Duplicate wildcard '*' specification for Archive/2019/*"})
|
expect(result).toEqual({errorMsg: "Duplicate wildcard '*' specification for Archive/2019/*"})
|
||||||
})
|
})
|
||||||
it('regexp-match by name works (order of regexp doesn\'t matter) case A', () => {
|
it('regexp-match by name works (order of regexp doesn\'t matter) case A', () => {
|
||||||
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching()
|
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching(checkIfImplicitSpec)
|
||||||
matcher.addRegexpDefinition(/^daily$/, false, undefined, false, `r1`)
|
matcher.addRegexpDefinition(/^daily$/, false, undefined, false, `r1`)
|
||||||
matcher.addRegexpDefinition(/^daily$/, true, undefined, false, `r2`)
|
matcher.addRegexpDefinition(/^daily$/, true, undefined, false, `r2`)
|
||||||
matcher.addWildcardDefinition('/Reviews/*', `w1`)
|
matcher.addWildcardDefinition('/Reviews/*', `w1`)
|
||||||
|
@ -134,7 +136,7 @@ describe('folderMatch', () => {
|
||||||
expect(match2).toBe('r2')
|
expect(match2).toBe('r2')
|
||||||
})
|
})
|
||||||
it('regexp-match by name works (order of regexp doesn\'t matter) reversed case A', () => {
|
it('regexp-match by name works (order of regexp doesn\'t matter) reversed case A', () => {
|
||||||
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching()
|
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching(checkIfImplicitSpec)
|
||||||
matcher.addRegexpDefinition(/^daily$/, true, undefined, false, `r2`)
|
matcher.addRegexpDefinition(/^daily$/, true, undefined, false, `r2`)
|
||||||
matcher.addRegexpDefinition(/^daily$/, false, undefined, false, `r1`)
|
matcher.addRegexpDefinition(/^daily$/, false, undefined, false, `r1`)
|
||||||
matcher.addWildcardDefinition('/Reviews/*', `w1`)
|
matcher.addWildcardDefinition('/Reviews/*', `w1`)
|
||||||
|
@ -146,7 +148,7 @@ describe('folderMatch', () => {
|
||||||
expect(match2).toBe('r2')
|
expect(match2).toBe('r2')
|
||||||
})
|
})
|
||||||
it('regexp-match by path works (order of regexp doesn\'t matter) case A', () => {
|
it('regexp-match by path works (order of regexp doesn\'t matter) case A', () => {
|
||||||
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching()
|
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching(checkIfImplicitSpec)
|
||||||
matcher.addRegexpDefinition(/^Reviews\/daily$/, false, undefined, false, `r1`)
|
matcher.addRegexpDefinition(/^Reviews\/daily$/, false, undefined, false, `r1`)
|
||||||
matcher.addRegexpDefinition(/^Reviews\/daily$/, true, undefined, false, `r2`)
|
matcher.addRegexpDefinition(/^Reviews\/daily$/, true, undefined, false, `r2`)
|
||||||
matcher.addWildcardDefinition('/Reviews/*', `w1`)
|
matcher.addWildcardDefinition('/Reviews/*', `w1`)
|
||||||
|
@ -158,7 +160,7 @@ describe('folderMatch', () => {
|
||||||
expect(match2).toBe('r1')
|
expect(match2).toBe('r1')
|
||||||
})
|
})
|
||||||
it('regexp-match by path works (order of regexp doesn\'t matter) reversed case A', () => {
|
it('regexp-match by path works (order of regexp doesn\'t matter) reversed case A', () => {
|
||||||
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching()
|
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching(checkIfImplicitSpec)
|
||||||
matcher.addRegexpDefinition(/^Reviews\/daily$/, true, undefined, false, `r2`)
|
matcher.addRegexpDefinition(/^Reviews\/daily$/, true, undefined, false, `r2`)
|
||||||
matcher.addRegexpDefinition(/^Reviews\/daily$/, false, undefined, false, `r1`)
|
matcher.addRegexpDefinition(/^Reviews\/daily$/, false, undefined, false, `r1`)
|
||||||
matcher.addWildcardDefinition('/Reviews/*', `w1`)
|
matcher.addWildcardDefinition('/Reviews/*', `w1`)
|
||||||
|
@ -170,7 +172,7 @@ describe('folderMatch', () => {
|
||||||
expect(match2).toBe('r1')
|
expect(match2).toBe('r1')
|
||||||
})
|
})
|
||||||
it('regexp-match by path and name for root level - order of regexp decides - case A', () => {
|
it('regexp-match by path and name for root level - order of regexp decides - case A', () => {
|
||||||
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching()
|
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching(checkIfImplicitSpec)
|
||||||
matcher.addRegexpDefinition(/^daily$/, false, undefined, false, `r1`)
|
matcher.addRegexpDefinition(/^daily$/, false, undefined, false, `r1`)
|
||||||
matcher.addRegexpDefinition(/^daily$/, true, undefined, false, `r2`)
|
matcher.addRegexpDefinition(/^daily$/, true, undefined, false, `r2`)
|
||||||
matcher.addWildcardDefinition('/Reviews/*', `w1`)
|
matcher.addWildcardDefinition('/Reviews/*', `w1`)
|
||||||
|
@ -179,7 +181,7 @@ describe('folderMatch', () => {
|
||||||
expect(match).toBe('r2')
|
expect(match).toBe('r2')
|
||||||
})
|
})
|
||||||
it('regexp-match by path and name for root level - order of regexp decides - reversed case A', () => {
|
it('regexp-match by path and name for root level - order of regexp decides - reversed case A', () => {
|
||||||
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching()
|
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching(checkIfImplicitSpec)
|
||||||
matcher.addRegexpDefinition(/^daily$/, true, undefined, false, `r2`)
|
matcher.addRegexpDefinition(/^daily$/, true, undefined, false, `r2`)
|
||||||
matcher.addRegexpDefinition(/^daily$/, false, undefined, false, `r1`)
|
matcher.addRegexpDefinition(/^daily$/, false, undefined, false, `r1`)
|
||||||
matcher.addWildcardDefinition('/Reviews/*', `w1`)
|
matcher.addWildcardDefinition('/Reviews/*', `w1`)
|
||||||
|
@ -188,7 +190,7 @@ describe('folderMatch', () => {
|
||||||
expect(match).toBe('r1')
|
expect(match).toBe('r1')
|
||||||
})
|
})
|
||||||
it('regexp-match priorities - order of definitions irrelevant - unique priorities - case A', () => {
|
it('regexp-match priorities - order of definitions irrelevant - unique priorities - case A', () => {
|
||||||
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching()
|
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching(checkIfImplicitSpec)
|
||||||
matcher.addRegexpDefinition(/^freq\/daily$/, false, 3, false, `r1p3`)
|
matcher.addRegexpDefinition(/^freq\/daily$/, false, 3, false, `r1p3`)
|
||||||
matcher.addRegexpDefinition(/^freq\/daily$/, false, 2, false, `r2p2`)
|
matcher.addRegexpDefinition(/^freq\/daily$/, false, 2, false, `r2p2`)
|
||||||
matcher.addRegexpDefinition(/^freq\/daily$/, false, 1, false, `r3p1`)
|
matcher.addRegexpDefinition(/^freq\/daily$/, false, 1, false, `r3p1`)
|
||||||
|
@ -198,7 +200,7 @@ describe('folderMatch', () => {
|
||||||
expect(match).toBe('r1p3')
|
expect(match).toBe('r1p3')
|
||||||
})
|
})
|
||||||
it('regexp-match priorities - order of definitions irrelevant - unique priorities - reversed case A', () => {
|
it('regexp-match priorities - order of definitions irrelevant - unique priorities - reversed case A', () => {
|
||||||
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching()
|
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching(checkIfImplicitSpec)
|
||||||
matcher.addRegexpDefinition(/^freq\/daily$/, false, undefined, false, `r4pNone`)
|
matcher.addRegexpDefinition(/^freq\/daily$/, false, undefined, false, `r4pNone`)
|
||||||
matcher.addRegexpDefinition(/^freq\/daily$/, false, 1, false, `r3p1`)
|
matcher.addRegexpDefinition(/^freq\/daily$/, false, 1, false, `r3p1`)
|
||||||
matcher.addRegexpDefinition(/^freq\/daily$/, false, 2, false, `r2p2`)
|
matcher.addRegexpDefinition(/^freq\/daily$/, false, 2, false, `r2p2`)
|
||||||
|
@ -208,7 +210,7 @@ describe('folderMatch', () => {
|
||||||
expect(match).toBe('r1p3')
|
expect(match).toBe('r1p3')
|
||||||
})
|
})
|
||||||
it('regexp-match priorities - order of definitions irrelevant - duplicate priorities - case A', () => {
|
it('regexp-match priorities - order of definitions irrelevant - duplicate priorities - case A', () => {
|
||||||
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching()
|
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching(checkIfImplicitSpec)
|
||||||
matcher.addRegexpDefinition(/^daily$/, true, 3, false, `r1p3a`)
|
matcher.addRegexpDefinition(/^daily$/, true, 3, false, `r1p3a`)
|
||||||
matcher.addRegexpDefinition(/^daily$/, true, 3, false, `r1p3b`)
|
matcher.addRegexpDefinition(/^daily$/, true, 3, false, `r1p3b`)
|
||||||
matcher.addRegexpDefinition(/^daily$/, true, 2, false, `r2p2a`)
|
matcher.addRegexpDefinition(/^daily$/, true, 2, false, `r2p2a`)
|
||||||
|
@ -221,7 +223,7 @@ describe('folderMatch', () => {
|
||||||
expect(match).toBe('r1p3b')
|
expect(match).toBe('r1p3b')
|
||||||
})
|
})
|
||||||
it('regexp-match priorities - order of definitions irrelevant - unique priorities - reversed case A', () => {
|
it('regexp-match priorities - order of definitions irrelevant - unique priorities - reversed case A', () => {
|
||||||
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching()
|
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching(checkIfImplicitSpec)
|
||||||
matcher.addRegexpDefinition(/^freq\/daily$/, false, undefined, false, `r4pNone`)
|
matcher.addRegexpDefinition(/^freq\/daily$/, false, undefined, false, `r4pNone`)
|
||||||
matcher.addRegexpDefinition(/^freq\/daily$/, false, 1, false, `r3p1`)
|
matcher.addRegexpDefinition(/^freq\/daily$/, false, 1, false, `r3p1`)
|
||||||
matcher.addRegexpDefinition(/^freq\/daily$/, false, 2, false, `r2p2`)
|
matcher.addRegexpDefinition(/^freq\/daily$/, false, 2, false, `r2p2`)
|
||||||
|
@ -231,14 +233,14 @@ describe('folderMatch', () => {
|
||||||
expect(match).toBe('r1p3')
|
expect(match).toBe('r1p3')
|
||||||
})
|
})
|
||||||
it('regexp-match - edge case of matching the root folder - match by path', () => {
|
it('regexp-match - edge case of matching the root folder - match by path', () => {
|
||||||
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching()
|
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching(checkIfImplicitSpec)
|
||||||
matcher.addRegexpDefinition(/^\/$/, false, undefined, false, `r1`)
|
matcher.addRegexpDefinition(/^\/$/, false, undefined, false, `r1`)
|
||||||
// Path w/o leading / - this is how Obsidian supplies the path
|
// Path w/o leading / - this is how Obsidian supplies the path
|
||||||
const match: SortingSpec | null = matcher.folderMatch('/', '')
|
const match: SortingSpec | null = matcher.folderMatch('/', '')
|
||||||
expect(match).toBe('r1')
|
expect(match).toBe('r1')
|
||||||
})
|
})
|
||||||
it('regexp-match - edge case of matching the root folder - match by name not possible', () => {
|
it('regexp-match - edge case of matching the root folder - match by name not possible', () => {
|
||||||
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching()
|
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching(checkIfImplicitSpec)
|
||||||
// Tricky regexp which can return zero length matches
|
// Tricky regexp which can return zero length matches
|
||||||
matcher.addRegexpDefinition(/.*/, true, undefined, false, `r1`)
|
matcher.addRegexpDefinition(/.*/, true, undefined, false, `r1`)
|
||||||
matcher.addWildcardDefinition('/*', `w1`)
|
matcher.addWildcardDefinition('/*', `w1`)
|
||||||
|
@ -247,7 +249,7 @@ describe('folderMatch', () => {
|
||||||
expect(match).toBe('w1')
|
expect(match).toBe('w1')
|
||||||
})
|
})
|
||||||
it('regexp-match - edge case of no match when only regexp rules present', () => {
|
it('regexp-match - edge case of no match when only regexp rules present', () => {
|
||||||
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching()
|
const matcher: FolderWildcardMatching<SortingSpec> = new FolderWildcardMatching(checkIfImplicitSpec)
|
||||||
// Tricky regexp which can return zero length matches
|
// Tricky regexp which can return zero length matches
|
||||||
matcher.addRegexpDefinition(/abc/, true, undefined, false, `r1`)
|
matcher.addRegexpDefinition(/abc/, true, undefined, false, `r1`)
|
||||||
// Path w/o leading / - this is how Obsidian supplies the path
|
// Path w/o leading / - this is how Obsidian supplies the path
|
||||||
|
|
|
@ -35,6 +35,8 @@ export interface AddingWildcardFailure {
|
||||||
errorMsg: string
|
errorMsg: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type CheckIfImplicitSpec<SortingSpec> = (s: SortingSpec) => boolean
|
||||||
|
|
||||||
export class FolderWildcardMatching<SortingSpec> {
|
export class FolderWildcardMatching<SortingSpec> {
|
||||||
|
|
||||||
// mimics the structure of folders, so for example tree.matchAll contains the matchAll flag for the root '/'
|
// mimics the structure of folders, so for example tree.matchAll contains the matchAll flag for the root '/'
|
||||||
|
@ -44,6 +46,9 @@ export class FolderWildcardMatching<SortingSpec> {
|
||||||
|
|
||||||
regexps: Array<FolderMatchingRegexp<SortingSpec>>
|
regexps: Array<FolderMatchingRegexp<SortingSpec>>
|
||||||
|
|
||||||
|
constructor(private checkIfImplicitSpec: CheckIfImplicitSpec<SortingSpec>) {
|
||||||
|
}
|
||||||
|
|
||||||
// cache
|
// cache
|
||||||
determinedWildcardRules: { [key: string]: DeterminedSortingSpec<SortingSpec> } = {}
|
determinedWildcardRules: { [key: string]: DeterminedSortingSpec<SortingSpec> } = {}
|
||||||
|
|
||||||
|
@ -68,13 +73,13 @@ export class FolderWildcardMatching<SortingSpec> {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if (lastComponent === MATCH_CHILDREN_PATH_TOKEN) {
|
if (lastComponent === MATCH_CHILDREN_PATH_TOKEN) {
|
||||||
if (leafNode.matchChildren) {
|
if (leafNode.matchChildren && !this.checkIfImplicitSpec(leafNode.matchChildren)) {
|
||||||
return {errorMsg: `Duplicate wildcard '${lastComponent}' specification for ${wilcardDefinition}`}
|
return {errorMsg: `Duplicate wildcard '${lastComponent}' specification for ${wilcardDefinition}`}
|
||||||
} else {
|
} else {
|
||||||
leafNode.matchChildren = rule
|
leafNode.matchChildren = rule
|
||||||
}
|
}
|
||||||
} else { // Implicitly: MATCH_ALL_PATH_TOKEN
|
} else { // Implicitly: MATCH_ALL_PATH_TOKEN
|
||||||
if (leafNode.matchAll) {
|
if (leafNode.matchAll && !this.checkIfImplicitSpec(leafNode.matchAll)) {
|
||||||
return {errorMsg: `Duplicate wildcard '${lastComponent}' specification for ${wilcardDefinition}`}
|
return {errorMsg: `Duplicate wildcard '${lastComponent}' specification for ${wilcardDefinition}`}
|
||||||
} else {
|
} else {
|
||||||
leafNode.matchAll = rule
|
leafNode.matchAll = rule
|
||||||
|
|
|
@ -1677,6 +1677,11 @@ const txtInputErrorPriorityEmptyPattern: string = `
|
||||||
`
|
`
|
||||||
|
|
||||||
const txtInputEmptySpec: string = ``
|
const txtInputEmptySpec: string = ``
|
||||||
|
const txtInputOnlyCommentsSpec: string = `
|
||||||
|
// Some comment
|
||||||
|
|
||||||
|
// Another comment below empty line
|
||||||
|
`
|
||||||
|
|
||||||
describe('SortingSpecProcessor error detection and reporting', () => {
|
describe('SortingSpecProcessor error detection and reporting', () => {
|
||||||
let processor: SortingSpecProcessor;
|
let processor: SortingSpecProcessor;
|
||||||
|
@ -1915,7 +1920,7 @@ describe('SortingSpecProcessor error detection and reporting', () => {
|
||||||
`${ERR_PREFIX} 22:PriorityPrefixAfterGroupTypePrefix Priority prefix must be used before sorting group type indicator ${ERR_SUFFIX_IN_LINE(2)}`)
|
`${ERR_PREFIX} 22:PriorityPrefixAfterGroupTypePrefix Priority prefix must be used before sorting group type indicator ${ERR_SUFFIX_IN_LINE(2)}`)
|
||||||
expect(errorsLogger).toHaveBeenNthCalledWith(2, ERR_LINE_TXT('/folders /+ /! Hello'))
|
expect(errorsLogger).toHaveBeenNthCalledWith(2, ERR_LINE_TXT('/folders /+ /! Hello'))
|
||||||
})
|
})
|
||||||
it('should recognize error: combine prefix after sorting group type prefixe', () => {
|
it('should recognize error: combine prefix after sorting group type prefix', () => {
|
||||||
const inputTxtArr: Array<string> = `
|
const inputTxtArr: Array<string> = `
|
||||||
/folders /+ Hello
|
/folders /+ Hello
|
||||||
`.replace(/\t/gi, '').split('\n')
|
`.replace(/\t/gi, '').split('\n')
|
||||||
|
@ -1932,6 +1937,12 @@ describe('SortingSpecProcessor error detection and reporting', () => {
|
||||||
expect(result).toBeNull()
|
expect(result).toBeNull()
|
||||||
expect(errorsLogger).toHaveBeenCalledTimes(0)
|
expect(errorsLogger).toHaveBeenCalledTimes(0)
|
||||||
})
|
})
|
||||||
|
it('should recognize empty spec', () => {
|
||||||
|
const inputTxtArr: Array<string> = txtInputOnlyCommentsSpec.split('\n')
|
||||||
|
const result = processor.parseSortSpecFromText(inputTxtArr, 'mock-folder', 'custom-name-note.md')
|
||||||
|
expect(result).toBeNull()
|
||||||
|
expect(errorsLogger).toHaveBeenCalledTimes(0)
|
||||||
|
})
|
||||||
it.each([
|
it.each([
|
||||||
'% \\.d+...',
|
'% \\.d+...',
|
||||||
'% ...\\d+',
|
'% ...\\d+',
|
||||||
|
|
|
@ -37,6 +37,7 @@ interface ProcessingContext {
|
||||||
specs: Array<CustomSortSpec>
|
specs: Array<CustomSortSpec>
|
||||||
currentSpec?: CustomSortSpec
|
currentSpec?: CustomSortSpec
|
||||||
currentSpecGroup?: CustomSortGroup
|
currentSpecGroup?: CustomSortGroup
|
||||||
|
implicitSpec?: boolean
|
||||||
|
|
||||||
// Support for specific conditions (intentionally not generic approach)
|
// Support for specific conditions (intentionally not generic approach)
|
||||||
previousValidEntryWasTargetFolderAttr?: boolean // Entry in previous non-empty valid line
|
previousValidEntryWasTargetFolderAttr?: boolean // Entry in previous non-empty valid line
|
||||||
|
@ -577,7 +578,7 @@ const ensureCollectionHasSortSpecByName = (collection?: SortSpecsCollection | nu
|
||||||
const ensureCollectionHasSortSpecByWildcard = (collection?: SortSpecsCollection | null) => {
|
const ensureCollectionHasSortSpecByWildcard = (collection?: SortSpecsCollection | null) => {
|
||||||
collection = collection ?? {}
|
collection = collection ?? {}
|
||||||
if (!collection.sortSpecByWildcard) {
|
if (!collection.sortSpecByWildcard) {
|
||||||
collection.sortSpecByWildcard = new FolderWildcardMatching<CustomSortSpec>()
|
collection.sortSpecByWildcard = new FolderWildcardMatching<CustomSortSpec>((spec: CustomSortSpec) => !!spec.implicit)
|
||||||
}
|
}
|
||||||
return collection
|
return collection
|
||||||
}
|
}
|
||||||
|
@ -602,35 +603,38 @@ const endsWithWildcardPatternSuffix = (path: string): boolean => {
|
||||||
|
|
||||||
enum WildcardPriority {
|
enum WildcardPriority {
|
||||||
NO_WILDCARD = 1,
|
NO_WILDCARD = 1,
|
||||||
|
NO_WILDCARD_IMPLICIT,
|
||||||
MATCH_CHILDREN,
|
MATCH_CHILDREN,
|
||||||
MATCH_ALL
|
MATCH_CHILDREN_IMPLICIT,
|
||||||
|
MATCH_ALL,
|
||||||
|
MATCH_ALL_IMPLICIT
|
||||||
}
|
}
|
||||||
|
|
||||||
const stripWildcardPatternSuffix = (path: string): {path: string, detectedWildcardPriority: number} => {
|
const stripWildcardPatternSuffix = (path: string, ofImplicitSpec: boolean): {path: string, detectedWildcardPriority: number} => {
|
||||||
if (path.endsWith(MATCH_ALL_SUFFIX)) {
|
if (path.endsWith(MATCH_ALL_SUFFIX)) {
|
||||||
path = path.slice(0, -MATCH_ALL_SUFFIX.length)
|
path = path.slice(0, -MATCH_ALL_SUFFIX.length)
|
||||||
return {
|
return {
|
||||||
path: path.length > 0 ? path : '/',
|
path: path.length > 0 ? path : '/',
|
||||||
detectedWildcardPriority: WildcardPriority.MATCH_ALL
|
detectedWildcardPriority: ofImplicitSpec ? WildcardPriority.MATCH_ALL_IMPLICIT : WildcardPriority.MATCH_ALL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (path.endsWith(MATCH_CHILDREN_1_SUFFIX)) {
|
if (path.endsWith(MATCH_CHILDREN_1_SUFFIX)) {
|
||||||
path = path.slice(0, -MATCH_CHILDREN_1_SUFFIX.length)
|
path = path.slice(0, -MATCH_CHILDREN_1_SUFFIX.length)
|
||||||
return {
|
return {
|
||||||
path: path.length > 0 ? path : '/',
|
path: path.length > 0 ? path : '/',
|
||||||
detectedWildcardPriority: WildcardPriority.MATCH_CHILDREN,
|
detectedWildcardPriority: ofImplicitSpec ? WildcardPriority.MATCH_CHILDREN_IMPLICIT : WildcardPriority.MATCH_CHILDREN
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (path.endsWith(MATCH_CHILDREN_2_SUFFIX)) {
|
if (path.endsWith(MATCH_CHILDREN_2_SUFFIX)) {
|
||||||
path = path.slice(0, -MATCH_CHILDREN_2_SUFFIX.length)
|
path = path.slice(0, -MATCH_CHILDREN_2_SUFFIX.length)
|
||||||
return {
|
return {
|
||||||
path: path.length > 0 ? path : '/',
|
path: path.length > 0 ? path : '/',
|
||||||
detectedWildcardPriority: WildcardPriority.MATCH_CHILDREN
|
detectedWildcardPriority: ofImplicitSpec ? WildcardPriority.MATCH_CHILDREN_IMPLICIT : WildcardPriority.MATCH_CHILDREN
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
path: path,
|
path: path,
|
||||||
detectedWildcardPriority: WildcardPriority.NO_WILDCARD
|
detectedWildcardPriority: ofImplicitSpec ? WildcardPriority.NO_WILDCARD_IMPLICIT : WildcardPriority.NO_WILDCARD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -727,12 +731,14 @@ export class SortingSpecProcessor {
|
||||||
parseSortSpecFromText(text: Array<string>,
|
parseSortSpecFromText(text: Array<string>,
|
||||||
folderPath: string,
|
folderPath: string,
|
||||||
sortingSpecFileName: string,
|
sortingSpecFileName: string,
|
||||||
collection?: SortSpecsCollection | null
|
collection?: SortSpecsCollection | null,
|
||||||
|
implicitSpec?: boolean
|
||||||
): SortSpecsCollection | null | undefined {
|
): SortSpecsCollection | null | undefined {
|
||||||
// reset / init processing state after potential previous invocation
|
// reset / init processing state after potential previous invocation
|
||||||
this.ctx = {
|
this.ctx = {
|
||||||
folderPath: folderPath, // location of the sorting spec file
|
folderPath: folderPath, // location of the sorting spec file
|
||||||
specs: []
|
specs: [],
|
||||||
|
implicitSpec: implicitSpec
|
||||||
};
|
};
|
||||||
this.currentEntryLine = null
|
this.currentEntryLine = null
|
||||||
this.currentEntryLineIdx = null
|
this.currentEntryLineIdx = null
|
||||||
|
@ -839,7 +845,7 @@ export class SortingSpecProcessor {
|
||||||
for (let idx = 0; idx < spec.targetFoldersPaths.length; idx++) {
|
for (let idx = 0; idx < spec.targetFoldersPaths.length; idx++) {
|
||||||
const originalPath = spec.targetFoldersPaths[idx]
|
const originalPath = spec.targetFoldersPaths[idx]
|
||||||
if (!originalPath.startsWith(MatchFolderNameLexeme) && !originalPath.startsWith(MatchFolderByRegexpLexeme)) {
|
if (!originalPath.startsWith(MatchFolderNameLexeme) && !originalPath.startsWith(MatchFolderByRegexpLexeme)) {
|
||||||
const {path, detectedWildcardPriority} = stripWildcardPatternSuffix(originalPath)
|
const {path, detectedWildcardPriority} = stripWildcardPatternSuffix(originalPath, !!spec.implicit)
|
||||||
let storeTheSpec: boolean = true
|
let storeTheSpec: boolean = true
|
||||||
const preexistingSortSpecPriority: WildcardPriority = this.pathMatchPriorityForPath[path]
|
const preexistingSortSpecPriority: WildcardPriority = this.pathMatchPriorityForPath[path]
|
||||||
if (preexistingSortSpecPriority) {
|
if (preexistingSortSpecPriority) {
|
||||||
|
@ -1446,7 +1452,8 @@ export class SortingSpecProcessor {
|
||||||
private putNewSpecForNewTargetFolder(folderPath?: string): CustomSortSpec {
|
private putNewSpecForNewTargetFolder(folderPath?: string): CustomSortSpec {
|
||||||
const newSpec: CustomSortSpec = {
|
const newSpec: CustomSortSpec = {
|
||||||
targetFoldersPaths: [folderPath ?? this.ctx.folderPath],
|
targetFoldersPaths: [folderPath ?? this.ctx.folderPath],
|
||||||
groups: []
|
groups: [],
|
||||||
|
implicit: this.ctx.implicitSpec
|
||||||
}
|
}
|
||||||
|
|
||||||
this.ctx.specs.push(newSpec);
|
this.ctx.specs.push(newSpec);
|
||||||
|
|
Loading…
Reference in New Issue