From b80da8bb5ad139f8c06022ceeca654ffc6f1d0ca Mon Sep 17 00:00:00 2001 From: Dipen Ved Date: Thu, 24 Jan 2019 23:07:57 +0530 Subject: [PATCH] Show the folder path a file is in, in title of the window (#66746) * Add active folder feature * use urilabel instead * use resource instead of path * show empty instead for activeFolderShort --- .../src/settingsDocumentHelper.ts | 7 +++++-- src/vs/base/common/paths.ts | 2 +- .../browser/parts/titlebar/titlebarPart.ts | 20 +++++++++++++++---- .../electron-browser/main.contribution.ts | 2 +- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/extensions/configuration-editing/src/settingsDocumentHelper.ts b/extensions/configuration-editing/src/settingsDocumentHelper.ts index e6b137809ff58..d4ac414897da1 100644 --- a/extensions/configuration-editing/src/settingsDocumentHelper.ts +++ b/extensions/configuration-editing/src/settingsDocumentHelper.ts @@ -44,8 +44,11 @@ export class SettingsDocument { const completions: vscode.CompletionItem[] = []; completions.push(this.newSimpleCompletionItem('${activeEditorShort}', range, localize('activeEditorShort', "the file name (e.g. myFile.txt)"))); - completions.push(this.newSimpleCompletionItem('${activeEditorMedium}', range, localize('activeEditorMedium', "the path of the file relative to the workspace folder (e.g. myFolder/myFile.txt)"))); - completions.push(this.newSimpleCompletionItem('${activeEditorLong}', range, localize('activeEditorLong', "the full path of the file (e.g. /Users/Development/myProject/myFolder/myFile.txt)"))); + completions.push(this.newSimpleCompletionItem('${activeEditorMedium}', range, localize('activeEditorMedium', "the path of the file relative to the workspace folder (e.g. myFolder/myFileFolder/myFile.txt)"))); + completions.push(this.newSimpleCompletionItem('${activeEditorLong}', range, localize('activeEditorLong', "the full path of the file (e.g. /Users/Development/myFolder/myFileFolder/myFile.txt)"))); + completions.push(this.newSimpleCompletionItem('${activeFolderShort}', range, localize('activeFolderShort', "the name of the folder the file is contained in (e.g. myFileFolder)"))); + completions.push(this.newSimpleCompletionItem('${activeFolderMedium}', range, localize('activeFolderMedium', "the path of the folder the file is contained in, relative to the workspace folder (e.g. myFolder/myFileFolder)"))); + completions.push(this.newSimpleCompletionItem('${activeFolderLong}', range, localize('activeFolderLong', "the full path of the folder the file is contained in (e.g. /Users/Development/myFolder/myFileFolder)"))); completions.push(this.newSimpleCompletionItem('${rootName}', range, localize('rootName', "name of the workspace (e.g. myFolder or myWorkspace)"))); completions.push(this.newSimpleCompletionItem('${rootPath}', range, localize('rootPath', "file path of the workspace (e.g. /Users/Development/myWorkspace)"))); completions.push(this.newSimpleCompletionItem('${folderName}', range, localize('folderName', "name of the workspace folder the file is contained in (e.g. myFolder)"))); diff --git a/src/vs/base/common/paths.ts b/src/vs/base/common/paths.ts index 26f885e6b7bc4..33496d1d7d98a 100644 --- a/src/vs/base/common/paths.ts +++ b/src/vs/base/common/paths.ts @@ -27,7 +27,7 @@ function isPathSeparator(code: number) { * @param separator the separator to use * @returns the directory name of a path. * '.' is returned for empty paths or single segment relative paths (as done by NodeJS) - * For paths consisting only of a root, the inout path is returned + * For paths consisting only of a root, the input path is returned */ export function dirname(path: string, separator = nativeSep): string { const len = path.length; diff --git a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts index 8f7d118547c21..93263deebea68 100644 --- a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts +++ b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts @@ -5,6 +5,7 @@ import 'vs/css!./media/titlebarpart'; import * as paths from 'vs/base/common/paths'; +import * as resources from 'vs/base/common/resources'; import { Part } from 'vs/workbench/browser/part'; import { ITitleService, ITitleProperties } from 'vs/workbench/services/title/common/titleService'; import { getZoomFactor } from 'vs/base/browser/browser'; @@ -238,21 +239,26 @@ export class TitlebarPart extends Part implements ITitleService, ISerializableVi /** * Possible template values: * - * {activeEditorLong}: e.g. /Users/Development/myProject/myFolder/myFile.txt - * {activeEditorMedium}: e.g. myFolder/myFile.txt + * {activeEditorLong}: e.g. /Users/Development/myFolder/myFileFolder/myFile.txt + * {activeEditorMedium}: e.g. myFolder/myFileFolder/myFile.txt * {activeEditorShort}: e.g. myFile.txt + * {activeFolderLong}: e.g. /Users/Development/myFolder/myFileFolder + * {activeFolderMedium}: e.g. myFolder/myFileFolder + * {activeFolderShort}: e.g. myFileFolder * {rootName}: e.g. myFolder1, myFolder2, myFolder3 - * {rootPath}: e.g. /Users/Development/myProject + * {rootPath}: e.g. /Users/Development * {folderName}: e.g. myFolder * {folderPath}: e.g. /Users/Development/myFolder * {appName}: e.g. VS Code - * {dirty}: indiactor + * {dirty}: indicator * {separator}: conditional separator */ private doGetWindowTitle(): string { const editor = this.editorService.activeEditor; const workspace = this.contextService.getWorkspace(); + let editorResource = editor ? toResource(editor, { supportSideBySide: true }) : undefined; + let root: URI; if (workspace.configuration) { root = workspace.configuration; @@ -269,6 +275,9 @@ export class TitlebarPart extends Part implements ITitleService, ISerializableVi const activeEditorShort = editor ? editor.getTitle(Verbosity.SHORT) : ''; const activeEditorMedium = editor ? editor.getTitle(Verbosity.MEDIUM) : activeEditorShort; const activeEditorLong = editor ? editor.getTitle(Verbosity.LONG) : activeEditorMedium; + const activeFolderShort = editorResource ? resources.dirname(editorResource).path !== '.' ? resources.basename(resources.dirname(editorResource)) : '' : ''; + const activeFolderMedium = editorResource ? resources.dirname(editorResource).path !== '.' ? this.labelService.getUriLabel(resources.dirname(editorResource), { relative: true }) : '' : ''; + const activeFolderLong = editorResource ? resources.dirname(editorResource).path !== '.' ? this.labelService.getUriLabel(resources.dirname(editorResource)) : '' : ''; const rootName = this.labelService.getWorkspaceLabel(workspace); const rootPath = root ? this.labelService.getUriLabel(root) : ''; const folderName = folder ? folder.name : ''; @@ -282,6 +291,9 @@ export class TitlebarPart extends Part implements ITitleService, ISerializableVi activeEditorShort, activeEditorLong, activeEditorMedium, + activeFolderShort, + activeFolderMedium, + activeFolderLong, rootName, rootPath, folderName, diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 8ce0542d0fa34..d88705f06e40b 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -780,7 +780,7 @@ configurationRegistry.registerConfiguration({ 'type': 'string', 'default': isMacintosh ? '${activeEditorShort}${separator}${rootName}' : '${dirty}${activeEditorShort}${separator}${rootName}${separator}${appName}', 'markdownDescription': nls.localize({ comment: ['This is the description for a setting. Values surrounded by parenthesis are not to be translated.'], key: 'title' }, - "Controls the window title based on the active editor. Variables are substituted based on the context:\n- `\${activeEditorShort}`: the file name (e.g. myFile.txt).\n- `\${activeEditorMedium}`: the path of the file relative to the workspace folder (e.g. myFolder/myFile.txt).\n- `\${activeEditorLong}`: the full path of the file (e.g. /Users/Development/myProject/myFolder/myFile.txt).\n- `\${folderName}`: name of the workspace folder the file is contained in (e.g. myFolder).\n- `\${folderPath}`: file path of the workspace folder the file is contained in (e.g. /Users/Development/myFolder).\n- `\${rootName}`: name of the workspace (e.g. myFolder or myWorkspace).\n- `\${rootPath}`: file path of the workspace (e.g. /Users/Development/myWorkspace).\n- `\${appName}`: e.g. VS Code.\n- `\${dirty}`: a dirty indicator if the active editor is dirty.\n- `\${separator}`: a conditional separator (\" - \") that only shows when surrounded by variables with values or static text.") + "Controls the window title based on the active editor. Variables are substituted based on the context:\n- `\${activeEditorShort}`: the file name (e.g. myFile.txt).\n- `\${activeEditorMedium}`: the path of the file relative to the workspace folder (e.g. myFolder/myFileFolder/myFile.txt).\n- `\${activeEditorLong}`: the full path of the file (e.g. /Users/Development/myFolder/myFileFolder/myFile.txt).\n- `\${activeFolderShort}`: the name of the folder the file is contained in (e.g. myFileFolder).\n- `\${activeFolderMedium}`: the path of the folder the file is contained in, relative to the workspace folder (e.g. myFolder/myFileFolder).\n- `\${activeFolderLong}`: the full path of the folder the file is contained in (e.g. /Users/Development/myFolder/myFileFolder).\n- `\${folderName}`: name of the workspace folder the file is contained in (e.g. myFolder).\n- `\${folderPath}`: file path of the workspace folder the file is contained in (e.g. /Users/Development/myFolder).\n- `\${rootName}`: name of the workspace (e.g. myFolder or myWorkspace).\n- `\${rootPath}`: file path of the workspace (e.g. /Users/Development/myWorkspace).\n- `\${appName}`: e.g. VS Code.\n- `\${dirty}`: a dirty indicator if the active editor is dirty.\n- `\${separator}`: a conditional separator (\" - \") that only shows when surrounded by variables with values or static text.") }, 'window.newWindowDimensions': { 'type': 'string',