Change:
Currently, the editor does not support customizing file labels in a way that would allow filenames to be prefixed with the name of the application or folder from the start of the path. This limitation affects projects structured in a monorepo setup, particularly when files are deeply nested within application-specific directories. Supporting negative indices for could solve this problem. This would enable accessing folder names starting from the beginning of the path. Implementing negative indices would cater to the needs of projects with files at various nesting levels within their structure.
Is the reasoning not the other way round or am I misunderstanding how it currently works? E.g. I'd like to access last 2 parts of the path, but the description of the settings suggests that only the single final and the starting folders can be accessed.
For the following path you will get the following values: Path: : : : : With negative indices: : : :
Here is an example of the mono repo: It has a root and multiple projects in the folder. It is common to make changes in multiple "packages" at once, and it would be convenient if we could identify files by the . Example: -
Verification steps: a custom editor label. The template should include , for which is a negative number. For example, add in , item: value: a file which matches the pattern specified in step 1. For the example specified in step 1: every file matches the pattern editor tab should have set the correct folder name for . Here an explanation on how negative indices work: For the example specified in step 1: the name of the editor in the tab should start with the top level folder the file is located in. In the vscode repo the file would have the custom name
I have followed the steps for the verification and the settings file is renamed to . The TS files are renamed correctly to . Is this expected?

Discussion:
} if (pattern.parsedPattern(relevantPath)) { <del> return this.applyTempate(pattern.template, resource); </del> <ins> return this.applyTempate(pattern.template, resource, relevantPath); </ins> } } return undefined; } <del> private readonly _parsedTemplateExpression = /${(dirname|filename|extname|dirname((d+)))}/g; private applyTempate(template: string, resource: URI): string { </del> <ins> private readonly _parsedTemplateExpression = /${(dirname|filename|extname|dirname(([-+]?d+)))}/g; private applyTempate(template: string, resource: URI, relevantPath: string): string { </ins> let parsedPath: undefined | ParsedPath; return template.replace(this._parsedTemplateExpression, (match: string, variable: string, arg: string) => { parsedPath = parsedPath ?? parsePath(resource.path);

return parsedPath.ext.slice(1); default: { // dirname and dirname(arg) const n = variable === 'dirname' ? 0 : parseInt(arg); <del> const nthDir = this.getNthDirname(parsedPath, n); </del> <ins> const nthDir = this.getNthDirname(relevantPath, n); </ins> if (nthDir) { return nthDir; }

}); } <del> private getNthDirname(path: ParsedPath, n: number): string | undefined { </del> <ins> private getNthDirname(path: string, n: number): string | undefined { </ins> // grand-parent/parent/filename.ext1.ext2 -> [grand-parent, parent] <del> const pathFragments = path.dir.split('/'); </del> <ins> const pathFragments = path.split('/'); </ins> const length = pathFragments.length; <del> const nth = length - 1 - n; if (nth < 0) { return undefined; </del> <ins> let nthDir; if (n < 0) { const nth = Math.abs(n) - 1; nthDir = pathFragments[nth]; } else { const nth = length - 1 - n - 1; // -1 for the filename, -1 for 0-based index nthDir = pathFragments[nth]; </ins> } <del> const nthDir = pathFragments[nth]; </del> if (nthDir === undefined || nthDir === '') { return undefined; }