From 9b7a8813e04466f788fab91d73e67f4dc90804e0 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 27 Apr 2017 15:24:58 +0200 Subject: [PATCH] :bug: SourceControlResourceDecorations.faded fixes #24097 --- extensions/git/src/model.ts | 52 ++++++++++++------- src/vs/vscode.d.ts | 6 +++ src/vs/workbench/api/node/extHost.protocol.ts | 3 +- src/vs/workbench/api/node/extHostSCM.ts | 3 +- src/vs/workbench/api/node/mainThreadSCM.ts | 10 ++-- .../scm/electron-browser/media/scmViewlet.css | 4 ++ .../parts/scm/electron-browser/scmViewlet.ts | 4 +- src/vs/workbench/services/scm/common/scm.ts | 1 + 8 files changed, 56 insertions(+), 27 deletions(-) diff --git a/extensions/git/src/model.ts b/extensions/git/src/model.ts index 898d08f650d..1d74a87d3a3 100644 --- a/extensions/git/src/model.ts +++ b/extensions/git/src/model.ts @@ -132,14 +132,23 @@ export class Resource implements SourceControlResourceState { } } + @memoize + private get faded(): boolean { + const workspaceRootPath = this.workspaceRoot.fsPath; + return this.resourceUri.fsPath.substr(0, workspaceRootPath.length) !== workspaceRootPath; + } + get decorations(): SourceControlResourceDecorations { const light = { iconPath: this.getIconPath('light') }; const dark = { iconPath: this.getIconPath('dark') }; + const strikeThrough = this.strikeThrough; + const faded = this.faded; - return { strikeThrough: this.strikeThrough, light, dark }; + return { strikeThrough, faded, light, dark }; } constructor( + private workspaceRoot: Uri, private _resourceGroup: ResourceGroup, private _resourceUri: Uri, private _type: Status, @@ -351,6 +360,7 @@ export class Model implements Disposable { this._onDidChangeResources.fire(); } + private workspaceRoot: Uri; private onWorkspaceChange: Event; private isRepositoryHuge = false; private didWarnAboutLimit = false; @@ -359,8 +369,10 @@ export class Model implements Disposable { constructor( private _git: Git, - private workspaceRootPath: string + workspaceRootPath: string ) { + this.workspaceRoot = Uri.file(workspaceRootPath); + const fsWatcher = workspace.createFileSystemWatcher('**'); this.onWorkspaceChange = anyEvent(fsWatcher.onDidChange, fsWatcher.onDidCreate, fsWatcher.onDidDelete); this.disposables.push(fsWatcher); @@ -374,7 +386,7 @@ export class Model implements Disposable { return; } - await this._git.init(this.workspaceRootPath); + await this._git.init(this.workspaceRoot.fsPath); await this.status(); } @@ -567,7 +579,7 @@ export class Model implements Disposable { this.repositoryDisposable.dispose(); const disposables: Disposable[] = []; - const repositoryRoot = await this._git.getRepositoryRoot(this.workspaceRootPath); + const repositoryRoot = await this._git.getRepositoryRoot(this.workspaceRoot.fsPath); this.repository = this._git.open(repositoryRoot); const dotGitPath = path.join(repositoryRoot, '.git'); @@ -640,30 +652,30 @@ export class Model implements Disposable { const renameUri = raw.rename ? Uri.file(path.join(this.repository.root, raw.rename)) : undefined; switch (raw.x + raw.y) { - case '??': return workingTree.push(new Resource(this.workingTreeGroup, uri, Status.UNTRACKED)); - case '!!': return workingTree.push(new Resource(this.workingTreeGroup, uri, Status.IGNORED)); - case 'DD': return merge.push(new Resource(this.mergeGroup, uri, Status.BOTH_DELETED)); - case 'AU': return merge.push(new Resource(this.mergeGroup, uri, Status.ADDED_BY_US)); - case 'UD': return merge.push(new Resource(this.mergeGroup, uri, Status.DELETED_BY_THEM)); - case 'UA': return merge.push(new Resource(this.mergeGroup, uri, Status.ADDED_BY_THEM)); - case 'DU': return merge.push(new Resource(this.mergeGroup, uri, Status.DELETED_BY_US)); - case 'AA': return merge.push(new Resource(this.mergeGroup, uri, Status.BOTH_ADDED)); - case 'UU': return merge.push(new Resource(this.mergeGroup, uri, Status.BOTH_MODIFIED)); + case '??': return workingTree.push(new Resource(this.workspaceRoot, this.workingTreeGroup, uri, Status.UNTRACKED)); + case '!!': return workingTree.push(new Resource(this.workspaceRoot, this.workingTreeGroup, uri, Status.IGNORED)); + case 'DD': return merge.push(new Resource(this.workspaceRoot, this.mergeGroup, uri, Status.BOTH_DELETED)); + case 'AU': return merge.push(new Resource(this.workspaceRoot, this.mergeGroup, uri, Status.ADDED_BY_US)); + case 'UD': return merge.push(new Resource(this.workspaceRoot, this.mergeGroup, uri, Status.DELETED_BY_THEM)); + case 'UA': return merge.push(new Resource(this.workspaceRoot, this.mergeGroup, uri, Status.ADDED_BY_THEM)); + case 'DU': return merge.push(new Resource(this.workspaceRoot, this.mergeGroup, uri, Status.DELETED_BY_US)); + case 'AA': return merge.push(new Resource(this.workspaceRoot, this.mergeGroup, uri, Status.BOTH_ADDED)); + case 'UU': return merge.push(new Resource(this.workspaceRoot, this.mergeGroup, uri, Status.BOTH_MODIFIED)); } let isModifiedInIndex = false; switch (raw.x) { - case 'M': index.push(new Resource(this.indexGroup, uri, Status.INDEX_MODIFIED)); isModifiedInIndex = true; break; - case 'A': index.push(new Resource(this.indexGroup, uri, Status.INDEX_ADDED)); break; - case 'D': index.push(new Resource(this.indexGroup, uri, Status.INDEX_DELETED)); break; - case 'R': index.push(new Resource(this.indexGroup, uri, Status.INDEX_RENAMED, renameUri)); break; - case 'C': index.push(new Resource(this.indexGroup, uri, Status.INDEX_COPIED)); break; + case 'M': index.push(new Resource(this.workspaceRoot, this.indexGroup, uri, Status.INDEX_MODIFIED)); isModifiedInIndex = true; break; + case 'A': index.push(new Resource(this.workspaceRoot, this.indexGroup, uri, Status.INDEX_ADDED)); break; + case 'D': index.push(new Resource(this.workspaceRoot, this.indexGroup, uri, Status.INDEX_DELETED)); break; + case 'R': index.push(new Resource(this.workspaceRoot, this.indexGroup, uri, Status.INDEX_RENAMED, renameUri)); break; + case 'C': index.push(new Resource(this.workspaceRoot, this.indexGroup, uri, Status.INDEX_COPIED)); break; } switch (raw.y) { - case 'M': workingTree.push(new Resource(this.workingTreeGroup, uri, Status.MODIFIED, renameUri)); break; - case 'D': workingTree.push(new Resource(this.workingTreeGroup, uri, Status.DELETED, renameUri)); break; + case 'M': workingTree.push(new Resource(this.workspaceRoot, this.workingTreeGroup, uri, Status.MODIFIED, renameUri)); break; + case 'D': workingTree.push(new Resource(this.workspaceRoot, this.workingTreeGroup, uri, Status.DELETED, renameUri)); break; } }); diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 53f4f622027..447839ea5ea 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -4680,6 +4680,12 @@ declare module 'vscode' { */ readonly strikeThrough?: boolean; + /** + * Whether the [source control resource state](#SourceControlResourceState) should + * be striked-through in the UI. + */ + readonly faded?: boolean; + /** * The light theme decorations. */ diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index cb456bab6d7..d4cd004550a 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -284,7 +284,8 @@ export type SCMRawResource = [ string /*resourceUri*/, modes.Command /*command*/, string[] /*icons: light, dark*/, - boolean /*strike through*/ + boolean /*strike through*/, + boolean /*faded*/ ]; export abstract class MainThreadSCMShape { diff --git a/src/vs/workbench/api/node/extHostSCM.ts b/src/vs/workbench/api/node/extHostSCM.ts index 5c9a0c3304c..079d623d5dd 100644 --- a/src/vs/workbench/api/node/extHostSCM.ts +++ b/src/vs/workbench/api/node/extHostSCM.ts @@ -115,8 +115,9 @@ class ExtHostSourceControlResourceGroup implements vscode.SourceControlResourceG } const strikeThrough = r.decorations && !!r.decorations.strikeThrough; + const faded = r.decorations && !!r.decorations.faded; - return [handle, sourceUri, command, icons, strikeThrough] as SCMRawResource; + return [handle, sourceUri, command, icons, strikeThrough, faded] as SCMRawResource; }); this._proxy.$updateGroupResourceStates(this._sourceControlHandle, this._handle, rawResources); diff --git a/src/vs/workbench/api/node/mainThreadSCM.ts b/src/vs/workbench/api/node/mainThreadSCM.ts index 130ff149de3..42129cde3ec 100644 --- a/src/vs/workbench/api/node/mainThreadSCM.ts +++ b/src/vs/workbench/api/node/mainThreadSCM.ts @@ -2,6 +2,7 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ + 'use strict'; import { TPromise } from 'vs/base/common/winjs.base'; @@ -10,7 +11,7 @@ import Event, { Emitter } from 'vs/base/common/event'; import { assign } from 'vs/base/common/objects'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { IThreadService } from 'vs/workbench/services/thread/common/threadService'; -import { ISCMService, ISCMProvider, ISCMResource, ISCMResourceGroup } from 'vs/workbench/services/scm/common/scm'; +import { ISCMService, ISCMProvider, ISCMResource, ISCMResourceGroup, ISCMResourceDecorations } from 'vs/workbench/services/scm/common/scm'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { ExtHostContext, MainThreadSCMShape, ExtHostSCMShape, SCMProviderFeatures, SCMRawResource, SCMGroupFeatures } from './extHost.protocol'; @@ -46,7 +47,7 @@ class MainThreadSCMResource implements ISCMResource { public sourceUri: URI, public command: Command | undefined, public resourceGroup: ISCMResourceGroup, - public decorations + public decorations: ISCMResourceDecorations ) { } toJSON(): any { @@ -144,13 +145,14 @@ class MainThreadSCMProvider implements ISCMProvider { } group.resources = resources.map(rawResource => { - const [handle, sourceUri, command, icons, strikeThrough] = rawResource; + const [handle, sourceUri, command, icons, strikeThrough, faded] = rawResource; const icon = icons[0]; const iconDark = icons[1] || icon; const decorations = { icon: icon && URI.parse(icon), iconDark: iconDark && URI.parse(iconDark), - strikeThrough + strikeThrough, + faded }; return new MainThreadSCMResource( diff --git a/src/vs/workbench/parts/scm/electron-browser/media/scmViewlet.css b/src/vs/workbench/parts/scm/electron-browser/media/scmViewlet.css index b0f8cdbc2c9..626f8cb689e 100644 --- a/src/vs/workbench/parts/scm/electron-browser/media/scmViewlet.css +++ b/src/vs/workbench/parts/scm/electron-browser/media/scmViewlet.css @@ -36,6 +36,10 @@ height: 100%; } +.scm-viewlet .monaco-list-row > .resource.faded { + opacity: 0.7; +} + .scm-viewlet .monaco-list-row > .resource > .name { flex: 1; overflow: hidden; diff --git a/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts b/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts index ad34b252a7c..4bf09bf4e11 100644 --- a/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts +++ b/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts @@ -117,6 +117,7 @@ class ResourceGroupRenderer implements IRenderer { const decorationIcon = append(element, $('.decoration-icon')); - return { name, fileLabel, decorationIcon, actionBar }; + return { element, name, fileLabel, decorationIcon, actionBar }; } renderElement(resource: ISCMResource, index: number, template: ResourceTemplate): void { @@ -179,6 +180,7 @@ class ResourceRenderer implements IRenderer { template.actionBar.context = resource; template.actionBar.push(this.scmMenus.getResourceActions(resource)); toggleClass(template.name, 'strike-through', resource.decorations.strikeThrough); + toggleClass(template.element, 'faded', resource.decorations.faded); const theme = this.themeService.getTheme(); const icon = theme.type === LIGHT ? resource.decorations.icon : resource.decorations.iconDark; diff --git a/src/vs/workbench/services/scm/common/scm.ts b/src/vs/workbench/services/scm/common/scm.ts index e6eaaf95c34..2af470e8801 100644 --- a/src/vs/workbench/services/scm/common/scm.ts +++ b/src/vs/workbench/services/scm/common/scm.ts @@ -23,6 +23,7 @@ export interface ISCMResourceDecorations { icon?: URI; iconDark?: URI; strikeThrough?: boolean; + faded?: boolean; } export interface ISCMResource { -- GitLab