#60 - Simplified integration with obsidian-icon-folder plugin

- extended the parser with support of new lexeme with-icon:, with or w/o parameter
- unit tests
This commit is contained in:
SebastianMC 2023-03-01 10:42:35 +01:00
parent 01af14b174
commit bd875fa804
5 changed files with 50 additions and 25 deletions

View File

@ -9,7 +9,7 @@ export enum CustomSortGroupType {
ExactHeadAndTail, // Like W...n or Un...ed, which is shorter variant of typing the entire title ExactHeadAndTail, // Like W...n or Un...ed, which is shorter variant of typing the entire title
HasMetadataField, // Notes (or folder's notes) containing a specific metadata field HasMetadataField, // Notes (or folder's notes) containing a specific metadata field
StarredOnly, StarredOnly,
IconFolderPlugin HasIcon
} }
export enum CustomSortOrder { export enum CustomSortOrder {
@ -60,7 +60,7 @@ export interface CustomSortGroup {
matchFilenameWithExt?: boolean matchFilenameWithExt?: boolean
foldersOnly?: boolean foldersOnly?: boolean
withMetadataFieldName?: string // for 'with-metadata:' grouping withMetadataFieldName?: string // for 'with-metadata:' grouping
folderIconName?: string // for integration with obsidian-folder-icon community plugin iconName?: string // for integration with obsidian-folder-icon community plugin
priority?: number priority?: number
combineWithIdx?: number combineWithIdx?: number
} }

View File

@ -1071,14 +1071,14 @@ describe('determineSortingGroup', () => {
expect(starredPluginInstance.findStarredFile).toHaveBeenCalledTimes(2) expect(starredPluginInstance.findStarredFile).toHaveBeenCalledTimes(2)
}) })
}) })
describe('CustomSortGroupType.IconFolderPlugin', () => { describe('CustomSortGroupType.HasIcon', () => {
it('should not match file w/o icon', () => { it('should not match file w/o icon', () => {
// given // given
const file: TFile = mockTFile('References', 'md', 111, MOCK_TIMESTAMP + 222, MOCK_TIMESTAMP + 333); const file: TFile = mockTFile('References', 'md', 111, MOCK_TIMESTAMP + 222, MOCK_TIMESTAMP + 333);
const sortSpec: CustomSortSpec = { const sortSpec: CustomSortSpec = {
targetFoldersPaths: ['/'], targetFoldersPaths: ['/'],
groups: [{ groups: [{
type: CustomSortGroupType.IconFolderPlugin type: CustomSortGroupType.HasIcon
}] }]
} }
const obsidianIconFolderPluginInstance: Partial<ObsidianIconFolder_PluginInstance> = { const obsidianIconFolderPluginInstance: Partial<ObsidianIconFolder_PluginInstance> = {
@ -1110,8 +1110,8 @@ describe('determineSortingGroup', () => {
const sortSpec: CustomSortSpec = { const sortSpec: CustomSortSpec = {
targetFoldersPaths: ['/'], targetFoldersPaths: ['/'],
groups: [{ groups: [{
type: CustomSortGroupType.IconFolderPlugin, type: CustomSortGroupType.HasIcon,
folderIconName: 'IncorrectIconName' iconName: 'IncorrectIconName'
}] }]
} }
const obsidianIconFolderPluginInstance: Partial<ObsidianIconFolder_PluginInstance> = { const obsidianIconFolderPluginInstance: Partial<ObsidianIconFolder_PluginInstance> = {
@ -1146,7 +1146,7 @@ describe('determineSortingGroup', () => {
const sortSpec: CustomSortSpec = { const sortSpec: CustomSortSpec = {
targetFoldersPaths: ['/'], targetFoldersPaths: ['/'],
groups: [{ groups: [{
type: CustomSortGroupType.IconFolderPlugin type: CustomSortGroupType.HasIcon
}] }]
} }
const obsidianIconFolderPluginInstance: Partial<ObsidianIconFolder_PluginInstance> = { const obsidianIconFolderPluginInstance: Partial<ObsidianIconFolder_PluginInstance> = {
@ -1181,8 +1181,8 @@ describe('determineSortingGroup', () => {
const sortSpec: CustomSortSpec = { const sortSpec: CustomSortSpec = {
targetFoldersPaths: ['/'], targetFoldersPaths: ['/'],
groups: [{ groups: [{
type: CustomSortGroupType.IconFolderPlugin, type: CustomSortGroupType.HasIcon,
folderIconName: 'CorrectIconName' iconName: 'CorrectIconName'
}] }]
} }
const obsidianIconFolderPluginInstance: Partial<ObsidianIconFolder_PluginInstance> = { const obsidianIconFolderPluginInstance: Partial<ObsidianIconFolder_PluginInstance> = {
@ -1217,7 +1217,7 @@ describe('determineSortingGroup', () => {
const sortSpec: CustomSortSpec = { const sortSpec: CustomSortSpec = {
targetFoldersPaths: ['/'], targetFoldersPaths: ['/'],
groups: [{ groups: [{
type: CustomSortGroupType.IconFolderPlugin type: CustomSortGroupType.HasIcon
}] }]
} }
const obsidianIconFolderPluginInstance: Partial<ObsidianIconFolder_PluginInstance> = { const obsidianIconFolderPluginInstance: Partial<ObsidianIconFolder_PluginInstance> = {
@ -1257,7 +1257,7 @@ describe('determineSortingGroup', () => {
const sortSpec: CustomSortSpec = { const sortSpec: CustomSortSpec = {
targetFoldersPaths: ['/'], targetFoldersPaths: ['/'],
groups: [{ groups: [{
type: CustomSortGroupType.IconFolderPlugin type: CustomSortGroupType.HasIcon
}] }]
} }
const obsidianIconFolderPluginInstance: Partial<ObsidianIconFolder_PluginInstance> = { const obsidianIconFolderPluginInstance: Partial<ObsidianIconFolder_PluginInstance> = {
@ -1300,7 +1300,7 @@ describe('determineSortingGroup', () => {
const sortSpec: CustomSortSpec = { const sortSpec: CustomSortSpec = {
targetFoldersPaths: ['/'], targetFoldersPaths: ['/'],
groups: [{ groups: [{
type: CustomSortGroupType.IconFolderPlugin type: CustomSortGroupType.HasIcon
}] }]
} }
const obsidianIconFolderPluginInstance: Partial<ObsidianIconFolder_PluginInstance> = { const obsidianIconFolderPluginInstance: Partial<ObsidianIconFolder_PluginInstance> = {
@ -1346,8 +1346,8 @@ describe('determineSortingGroup', () => {
const sortSpec: CustomSortSpec = { const sortSpec: CustomSortSpec = {
targetFoldersPaths: ['/'], targetFoldersPaths: ['/'],
groups: [{ groups: [{
type: CustomSortGroupType.IconFolderPlugin, type: CustomSortGroupType.HasIcon,
folderIconName: 'ConfiguredIcon-by-string' iconName: 'ConfiguredIcon-by-string'
}] }]
} }
const obsidianIconFolderPluginInstance: Partial<ObsidianIconFolder_PluginInstance> = { const obsidianIconFolderPluginInstance: Partial<ObsidianIconFolder_PluginInstance> = {
@ -1390,8 +1390,8 @@ describe('determineSortingGroup', () => {
const sortSpec: CustomSortSpec = { const sortSpec: CustomSortSpec = {
targetFoldersPaths: ['/'], targetFoldersPaths: ['/'],
groups: [{ groups: [{
type: CustomSortGroupType.IconFolderPlugin, type: CustomSortGroupType.HasIcon,
folderIconName: 'ConfiguredIcon' iconName: 'ConfiguredIcon'
}] }]
} }
const obsidianIconFolderPluginInstance: Partial<ObsidianIconFolder_PluginInstance> = { const obsidianIconFolderPluginInstance: Partial<ObsidianIconFolder_PluginInstance> = {
@ -1437,8 +1437,8 @@ describe('determineSortingGroup', () => {
const sortSpec: CustomSortSpec = { const sortSpec: CustomSortSpec = {
targetFoldersPaths: ['/'], targetFoldersPaths: ['/'],
groups: [{ groups: [{
type: CustomSortGroupType.IconFolderPlugin, type: CustomSortGroupType.HasIcon,
folderIconName: 'ConfiguredIcon-by-string' iconName: 'ConfiguredIcon-by-string'
}] }]
} }
const obsidianIconFolderPluginInstance: Partial<ObsidianIconFolder_PluginInstance> = { const obsidianIconFolderPluginInstance: Partial<ObsidianIconFolder_PluginInstance> = {
@ -1481,8 +1481,8 @@ describe('determineSortingGroup', () => {
const sortSpec: CustomSortSpec = { const sortSpec: CustomSortSpec = {
targetFoldersPaths: ['/'], targetFoldersPaths: ['/'],
groups: [{ groups: [{
type: CustomSortGroupType.IconFolderPlugin, type: CustomSortGroupType.HasIcon,
folderIconName: 'ConfiguredIcon' iconName: 'ConfiguredIcon'
}] }]
} }
const obsidianIconFolderPluginInstance: Partial<ObsidianIconFolder_PluginInstance> = { const obsidianIconFolderPluginInstance: Partial<ObsidianIconFolder_PluginInstance> = {

View File

@ -271,12 +271,12 @@ export const determineSortingGroup = function (entry: TFile | TFolder, spec: Cus
} }
} }
break break
case CustomSortGroupType.IconFolderPlugin: case CustomSortGroupType.HasIcon:
if(ctx?.iconFolderPluginInstance) { if(ctx?.iconFolderPluginInstance) {
let iconName: string | undefined = determineIconOf(entry, ctx.iconFolderPluginInstance) let iconName: string | undefined = determineIconOf(entry, ctx.iconFolderPluginInstance)
if (iconName) { if (iconName) {
if (group.folderIconName) { if (group.iconName) {
determined = iconName === group.folderIconName determined = iconName === group.iconName
} else { } else {
determined = true determined = true
} }

View File

@ -1,7 +1,9 @@
import { import {
CompoundDashNumberNormalizerFn, CompoundDashNumberNormalizerFn,
CompoundDashRomanNumberNormalizerFn, CompoundDashRomanNumberNormalizerFn,
CompoundDotNumberNormalizerFn, ConsumedFolderMatchingRegexp, consumeFolderByRegexpExpression, CompoundDotNumberNormalizerFn,
ConsumedFolderMatchingRegexp,
consumeFolderByRegexpExpression,
convertPlainStringToRegex, convertPlainStringToRegex,
detectNumericSortingSymbols, detectNumericSortingSymbols,
escapeRegexUnsafeCharacters, escapeRegexUnsafeCharacters,
@ -29,6 +31,8 @@ target-folder: tricky folder
< a-z by-metadata: Some-dedicated-field < a-z by-metadata: Some-dedicated-field
with-metadata: Pages with-metadata: Pages
> a-z by-metadata: > a-z by-metadata:
/: with-icon:
with-icon: RiClock24
starred: starred:
/:files starred: /:files starred:
/folders starred: /folders starred:
@ -85,6 +89,8 @@ target-folder: tricky folder 2
< a-z by-metadata: Some-dedicated-field < a-z by-metadata: Some-dedicated-field
% with-metadata: Pages % with-metadata: Pages
> a-z by-metadata: > a-z by-metadata:
/:files with-icon:
/folders:files with-icon: RiClock24
/folders:files starred: /folders:files starred:
/:files starred: /:files starred:
/folders starred: /folders starred:
@ -171,6 +177,14 @@ const expectedSortSpecsExampleA: { [key: string]: CustomSortSpec } = {
type: CustomSortGroupType.HasMetadataField, type: CustomSortGroupType.HasMetadataField,
withMetadataFieldName: 'Pages', withMetadataFieldName: 'Pages',
order: CustomSortOrder.byMetadataFieldAlphabeticalReverse order: CustomSortOrder.byMetadataFieldAlphabeticalReverse
}, {
type: CustomSortGroupType.HasIcon,
order: CustomSortOrder.alphabetical,
filesOnly: true
}, {
type: CustomSortGroupType.HasIcon,
order: CustomSortOrder.alphabetical,
iconName: 'RiClock24'
}, { }, {
type: CustomSortGroupType.StarredOnly, type: CustomSortGroupType.StarredOnly,
order: CustomSortOrder.alphabetical order: CustomSortOrder.alphabetical
@ -186,7 +200,7 @@ const expectedSortSpecsExampleA: { [key: string]: CustomSortSpec } = {
order: CustomSortOrder.alphabetical, order: CustomSortOrder.alphabetical,
type: CustomSortGroupType.Outsiders type: CustomSortGroupType.Outsiders
}], }],
outsidersGroupIdx: 5, outsidersGroupIdx: 7,
targetFoldersPaths: [ targetFoldersPaths: [
'tricky folder 2' 'tricky folder 2'
] ]

View File

@ -207,6 +207,8 @@ const MetadataFieldIndicatorLexeme: string = 'with-metadata:'
const StarredItemsIndicatorLexeme: string = 'starred:' const StarredItemsIndicatorLexeme: string = 'starred:'
const IconIndicatorLexeme: string = 'with-icon:'
const CommentPrefix: string = '//' const CommentPrefix: string = '//'
const PriorityModifierPrio1Lexeme: string = '/!' const PriorityModifierPrio1Lexeme: string = '/!'
@ -1489,6 +1491,15 @@ export class SortingSpecProcessor {
foldersOnly: spec.foldersOnly, foldersOnly: spec.foldersOnly,
matchFilenameWithExt: spec.matchFilenameWithExt matchFilenameWithExt: spec.matchFilenameWithExt
} }
} else if (theOnly.startsWith(IconIndicatorLexeme)) {
const iconName: string | undefined = extractIdentifier(theOnly.substring(IconIndicatorLexeme.length))
return {
type: CustomSortGroupType.HasIcon,
iconName: iconName,
filesOnly: spec.filesOnly,
foldersOnly: spec.foldersOnly,
matchFilenameWithExt: spec.matchFilenameWithExt
}
} else if (theOnly.startsWith(StarredItemsIndicatorLexeme)) { } else if (theOnly.startsWith(StarredItemsIndicatorLexeme)) {
return { return {
type: CustomSortGroupType.StarredOnly, type: CustomSortGroupType.StarredOnly,