diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a2cf599..743a626e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ ### ✨ New features +- [#844](https://github.com/estruyf/vscode-front-matter/issues/844): New `{{filePrefix.index}}` placeholder to add the index number of the file in the folder + ### 🎨 Enhancements - [#833](https://github.com/estruyf/vscode-front-matter/issues/833): Added support for Asciidoc files diff --git a/src/helpers/ArticleHelper.ts b/src/helpers/ArticleHelper.ts index b7824e23..c669903f 100644 --- a/src/helpers/ArticleHelper.ts +++ b/src/helpers/ArticleHelper.ts @@ -32,6 +32,7 @@ import { parseWinPath, processArticlePlaceholdersFromPath, processDateTimePlaceholders, + processFilePrefixPlaceholders, processI18nPlaceholders, processTimePlaceholders } from '.'; @@ -631,6 +632,7 @@ export class ArticleHelper { if (prefix && typeof prefix === 'string') { prefix = await ArticleHelper.processCustomPlaceholders(prefix, title, filePath, true); + prefix = await processFilePrefixPlaceholders(prefix, filePath); let selectedFolder: ContentFolder | undefined | null = null; if (filePath) { diff --git a/src/helpers/index.ts b/src/helpers/index.ts index f576d448..381cb1b0 100644 --- a/src/helpers/index.ts +++ b/src/helpers/index.ts @@ -33,6 +33,7 @@ export * from './openFileInEditor'; export * from './parseWinPath'; export * from './processArticlePlaceholders'; export * from './processDateTimePlaceholders'; +export * from './processFilePrefixPlaceholders'; export * from './processFmPlaceholders'; export * from './processI18nPlaceholders'; export * from './processPathPlaceholders'; diff --git a/src/helpers/processFilePrefixPlaceholders.ts b/src/helpers/processFilePrefixPlaceholders.ts new file mode 100644 index 00000000..c9a1a788 --- /dev/null +++ b/src/helpers/processFilePrefixPlaceholders.ts @@ -0,0 +1,55 @@ +import { FileType, Uri, workspace } from 'vscode'; +import { parse } from 'path'; + +/** + * Processes file prefix placeholders in a given string value. + * + * This function replaces placeholders in the format `{{filePrefix.index}}` or `{{filePrefix.index|zeros:4}}` + * with the appropriate index number based on the number of files in the directory of the given file path. + * + * @param value - The string containing the placeholders to be replaced. + * @param folderPath - The path of the file whose directory will be used to determine the index number. + * @returns A promise that resolves to the string with the placeholders replaced by the index number. + */ +export const processFilePrefixPlaceholders = async (value: string, folderPath?: string) => { + // Example: {{filePrefix.index}} or {{filePrefix.index|chars:4,zeros:true}} + if (value && value.includes('{{filePrefix.index') && folderPath) { + const dirContent = await workspace.fs.readDirectory(Uri.file(folderPath)); + const files = dirContent.filter(([_, type]) => type === FileType.File); + + let chars = 3; + let idxValue = files.length + 1; + + if (value.includes('{{filePrefix.index}}')) { + const regex = new RegExp('{{filePrefix.index}}', 'g'); + const placeholderValue = idxValue.toString().padStart(chars, '0'); + value = value.replace(regex, placeholderValue); + } + // Example: {{filePrefix.index|zeros:4}} + else if (value.includes('{{filePrefix.index')) { + const regex = /{{filePrefix.index[^}]*}}/g; + const matches = value.match(regex); + if (matches) { + for (const match of matches) { + const placeholderParts = match.split('|'); + if (placeholderParts.length > 1) { + let options = placeholderParts[1].trim().replace('}}', '').split(','); + + for (const option of options) { + if (option.startsWith('zeros:')) { + chars = parseInt(option.replace('zeros:', '')); + } + } + + const placeholderValue = chars + ? idxValue.toString().padStart(chars, '0') + : idxValue.toString(); + value = value.replace(match, placeholderValue); + } + } + } + } + } + + return value; +};