Merge from vscode a5cf1da01d5db3d2557132be8d30f89c38019f6c (#8525)

* Merge from vscode a5cf1da01d5db3d2557132be8d30f89c38019f6c

* remove files we don't want

* fix hygiene

* update distro

* update distro

* fix hygiene

* fix strict nulls

* distro

* distro

* fix tests

* fix tests

* add another edit

* fix viewlet icon

* fix azure dialog

* fix some padding

* fix more padding issues
This commit is contained in:
Anthony Dresser
2019-12-04 19:28:22 -08:00
committed by GitHub
parent a8818ab0df
commit f5ce7fb2a5
1507 changed files with 42813 additions and 27370 deletions

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { localize } from 'vs/nls';
import { basename } from 'vs/base/common/resources';
import { basename, relativePath } from 'vs/base/common/resources';
import { IDisposable, dispose, Disposable, DisposableStore, combinedDisposable, MutableDisposable } from 'vs/base/common/lifecycle';
import { Event } from 'vs/base/common/event';
import { VIEWLET_ID, ISCMService, ISCMRepository } from 'vs/workbench/contrib/scm/common/scm';
@@ -13,7 +13,6 @@ import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
import { IStatusbarService, StatusbarAlignment as MainThreadStatusBarAlignment } from 'vs/workbench/services/statusbar/common/statusbar';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { commonPrefixLength } from 'vs/base/common/strings';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
function getCount(repository: ISCMRepository): number {
@@ -51,23 +50,23 @@ export class SCMStatusController implements IWorkbenchContribution {
this.onDidAddRepository(repository);
}
editorService.onDidActiveEditorChange(this.onDidActiveEditorChange, this, this.disposables);
editorService.onDidActiveEditorChange(this.tryFocusRepositoryBasedOnActiveEditor, this, this.disposables);
this.renderActivityCount();
}
private onDidActiveEditorChange(): void {
private tryFocusRepositoryBasedOnActiveEditor(): boolean {
if (!this.editorService.activeEditor) {
return;
return false;
}
const resource = this.editorService.activeEditor.getResource();
if (!resource || resource.scheme !== 'file') {
return;
if (!resource) {
return false;
}
let bestRepository: ISCMRepository | null = null;
let bestMatchLength = Number.NEGATIVE_INFINITY;
let bestMatchLength = Number.POSITIVE_INFINITY;
for (const repository of this.scmService.repositories) {
const root = repository.provider.rootUri;
@@ -76,22 +75,24 @@ export class SCMStatusController implements IWorkbenchContribution {
continue;
}
const rootFSPath = root.fsPath;
const prefixLength = commonPrefixLength(rootFSPath, resource.fsPath);
const path = relativePath(root, resource);
if (prefixLength === rootFSPath.length && prefixLength > bestMatchLength) {
if (path && !/^\.\./.test(path) && path.length < bestMatchLength) {
bestRepository = repository;
bestMatchLength = prefixLength;
bestMatchLength = path.length;
}
}
if (bestRepository) {
this.onDidFocusRepository(bestRepository);
if (!bestRepository) {
return false;
}
this.focusRepository(bestRepository);
return true;
}
private onDidAddRepository(repository: ISCMRepository): void {
const focusDisposable = repository.onDidFocus(() => this.onDidFocusRepository(repository));
const focusDisposable = repository.onDidFocus(() => this.focusRepository(repository));
const onDidChange = Event.any(repository.provider.onDidChange, repository.provider.onDidChangeResources);
const changeDisposable = onDidChange(() => this.renderActivityCount());
@@ -102,7 +103,7 @@ export class SCMStatusController implements IWorkbenchContribution {
this.disposables = this.disposables.filter(d => d !== removeDisposable);
if (this.scmService.repositories.length === 0) {
this.onDidFocusRepository(undefined);
this.focusRepository(undefined);
} else if (this.focusedRepository === repository) {
this.scmService.repositories[0].focus();
}
@@ -113,12 +114,18 @@ export class SCMStatusController implements IWorkbenchContribution {
const disposable = combinedDisposable(focusDisposable, changeDisposable, removeDisposable);
this.disposables.push(disposable);
if (!this.focusedRepository) {
this.onDidFocusRepository(repository);
if (this.focusedRepository) {
return;
}
if (this.tryFocusRepositoryBasedOnActiveEditor()) {
return;
}
this.focusRepository(repository);
}
private onDidFocusRepository(repository: ISCMRepository | undefined): void {
private focusRepository(repository: ISCMRepository | undefined): void {
if (this.focusedRepository === repository) {
return;
}

View File

@@ -24,14 +24,13 @@ import { registerColor } from 'vs/platform/theme/common/colorRegistry';
import { Color, RGBA } from 'vs/base/common/color';
import { ICodeEditor, IEditorMouseEvent, MouseTargetType } from 'vs/editor/browser/editorBrowser';
import { registerEditorAction, registerEditorContribution, ServicesAccessor, EditorAction } from 'vs/editor/browser/editorExtensions';
import { PeekViewWidget, getOuterEditor } from 'vs/editor/contrib/referenceSearch/peekViewWidget';
import { PeekViewWidget, getOuterEditor, peekViewBorder, peekViewTitleBackground, peekViewTitleForeground, peekViewTitleInfoForeground } from 'vs/editor/contrib/peekView/peekView';
import { IContextKeyService, IContextKey, ContextKeyExpr, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { Position } from 'vs/editor/common/core/position';
import { rot } from 'vs/base/common/numbers';
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { peekViewBorder, peekViewTitleBackground, peekViewTitleForeground, peekViewTitleInfoForeground } from 'vs/editor/contrib/referenceSearch/referencesWidget';
import { EmbeddedDiffEditorWidget } from 'vs/editor/browser/widget/embeddedCodeEditorWidget';
import { IDiffEditorOptions, EditorOption } from 'vs/editor/common/config/editorOptions';
import { Action, IAction, ActionRunner } from 'vs/base/common/actions';
@@ -41,7 +40,7 @@ import { basename, isEqualOrParent } from 'vs/base/common/resources';
import { MenuId, IMenuService, IMenu, MenuItemAction, MenuRegistry } from 'vs/platform/actions/common/actions';
import { createAndFillInActionBarActions, ContextAwareMenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IChange, IEditorModel, ScrollType, IEditorContribution, IDiffEditorModel } from 'vs/editor/common/editorCommon';
import { OverviewRulerLane, ITextModel, IModelDecorationOptions } from 'vs/editor/common/model';
import { OverviewRulerLane, ITextModel, IModelDecorationOptions, MinimapPosition } from 'vs/editor/common/model';
import { sortedDiff, firstIndex } from 'vs/base/common/arrays';
import { IMarginData } from 'vs/editor/browser/controller/mouseTarget';
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
@@ -825,6 +824,24 @@ export const editorGutterDeletedBackground = registerColor('editorGutter.deleted
hc: new Color(new RGBA(141, 14, 20))
}, nls.localize('editorGutterDeletedBackground', "Editor gutter background color for lines that are deleted."));
export const minimapGutterModifiedBackground = registerColor('minimapGutter.modifiedBackground', {
dark: new Color(new RGBA(12, 125, 157)),
light: new Color(new RGBA(102, 175, 224)),
hc: new Color(new RGBA(0, 73, 122))
}, nls.localize('minimapGutterModifiedBackground', "Minimap gutter background color for lines that are modified."));
export const minimapGutterAddedBackground = registerColor('minimapGutter.addedBackground', {
dark: new Color(new RGBA(88, 124, 12)),
light: new Color(new RGBA(129, 184, 139)),
hc: new Color(new RGBA(27, 82, 37))
}, nls.localize('minimapGutterAddedBackground', "Minimap gutter background color for lines that are added."));
export const minimapGutterDeletedBackground = registerColor('minimapGutter.deletedBackground', {
dark: new Color(new RGBA(148, 21, 27)),
light: new Color(new RGBA(202, 75, 81)),
hc: new Color(new RGBA(141, 14, 20))
}, nls.localize('minimapGutterDeletedBackground', "Minimap gutter background color for lines that are deleted."));
const overviewRulerDefault = new Color(new RGBA(0, 122, 204, 0.6));
export const overviewRulerModifiedForeground = registerColor('editorOverviewRuler.modifiedForeground', { dark: overviewRulerDefault, light: overviewRulerDefault, hc: overviewRulerDefault }, nls.localize('overviewRulerModifiedForeground', 'Overview ruler marker color for modified content.'));
export const overviewRulerAddedForeground = registerColor('editorOverviewRuler.addedForeground', { dark: overviewRulerDefault, light: overviewRulerDefault, hc: overviewRulerDefault }, nls.localize('overviewRulerAddedForeground', 'Overview ruler marker color for added content.'));
@@ -832,7 +849,7 @@ export const overviewRulerDeletedForeground = registerColor('editorOverviewRuler
class DirtyDiffDecorator extends Disposable {
static createDecoration(className: string, foregroundColor: string, options: { gutter: boolean, overview: boolean, isWholeLine: boolean }): ModelDecorationOptions {
static createDecoration(className: string, options: { gutter: boolean, overview: { active: boolean, color: string }, minimap: { active: boolean, color: string }, isWholeLine: boolean }): ModelDecorationOptions {
const decorationOptions: IModelDecorationOptions = {
isWholeLine: options.isWholeLine,
};
@@ -841,13 +858,20 @@ class DirtyDiffDecorator extends Disposable {
decorationOptions.linesDecorationsClassName = `dirty-diff-glyph ${className}`;
}
if (options.overview) {
if (options.overview.active) {
decorationOptions.overviewRuler = {
color: themeColorFromId(foregroundColor),
color: themeColorFromId(options.overview.color),
position: OverviewRulerLane.Left
};
}
if (options.minimap.active) {
decorationOptions.minimap = {
color: themeColorFromId(options.minimap.color),
position: MinimapPosition.Gutter
};
}
return ModelDecorationOptions.createDynamic(decorationOptions);
}
@@ -867,11 +891,26 @@ class DirtyDiffDecorator extends Disposable {
const decorations = configurationService.getValue<string>('scm.diffDecorations');
const gutter = decorations === 'all' || decorations === 'gutter';
const overview = decorations === 'all' || decorations === 'overview';
const options = { gutter, overview, isWholeLine: true };
const minimap = decorations === 'all' || decorations === 'minimap';
this.modifiedOptions = DirtyDiffDecorator.createDecoration('dirty-diff-modified', overviewRulerModifiedForeground, options);
this.addedOptions = DirtyDiffDecorator.createDecoration('dirty-diff-added', overviewRulerAddedForeground, options);
this.deletedOptions = DirtyDiffDecorator.createDecoration('dirty-diff-deleted', overviewRulerDeletedForeground, { ...options, isWholeLine: false });
this.modifiedOptions = DirtyDiffDecorator.createDecoration('dirty-diff-modified', {
gutter,
overview: { active: overview, color: overviewRulerModifiedForeground },
minimap: { active: minimap, color: minimapGutterModifiedBackground },
isWholeLine: true
});
this.addedOptions = DirtyDiffDecorator.createDecoration('dirty-diff-added', {
gutter,
overview: { active: overview, color: overviewRulerAddedForeground },
minimap: { active: minimap, color: minimapGutterAddedBackground },
isWholeLine: true
});
this.deletedOptions = DirtyDiffDecorator.createDecoration('dirty-diff-deleted', {
gutter,
overview: { active: overview, color: overviewRulerDeletedForeground },
minimap: { active: minimap, color: minimapGutterDeletedBackground },
isWholeLine: false
});
this._register(model.onDidChange(this.onDidChange, this));
}
@@ -1176,9 +1215,15 @@ class DirtyDiffItem {
}
}
interface IViewState {
readonly width: number;
readonly visibility: 'always' | 'hover';
}
export class DirtyDiffWorkbenchController extends Disposable implements ext.IWorkbenchContribution, IModelRegistry {
private enabled = false;
private viewState: IViewState = { width: 3, visibility: 'always' };
private models: ITextModel[] = [];
private items: { [modelId: string]: DirtyDiffItem; } = Object.create(null);
private readonly transientDisposables = this._register(new DisposableStore());
@@ -1223,15 +1268,20 @@ export class DirtyDiffWorkbenchController extends Disposable implements ext.IWor
width = 3;
}
this.stylesheet.innerHTML = `.monaco-editor .dirty-diff-modified,.monaco-editor .dirty-diff-added{border-left-width:${width}px;}`;
this.setViewState({ ...this.viewState, width });
}
private onDidChangeDiffVisibiltiyConfiguration(): void {
const visibility = this.configurationService.getValue<string>('scm.diffDecorationsGutterVisibility');
const visibility = this.configurationService.getValue<'always' | 'hover'>('scm.diffDecorationsGutterVisibility');
this.setViewState({ ...this.viewState, visibility });
}
private setViewState(state: IViewState): void {
this.viewState = state;
this.stylesheet.innerHTML = `
.monaco-editor .dirty-diff-modified,.monaco-editor .dirty-diff-added{border-left-width:${state.width}px;}
.monaco-editor .dirty-diff-modified, .monaco-editor .dirty-diff-added, .monaco-editor .dirty-diff-deleted {
opacity: ${visibility === 'always' ? 1 : 0};
opacity: ${state.visibility === 'always' ? 1 : 0};
}
`;
}

View File

@@ -8,7 +8,7 @@ import { localize } from 'vs/nls';
import { Event, Emitter } from 'vs/base/common/event';
import { basename } from 'vs/base/common/resources';
import { IDisposable, dispose, Disposable, DisposableStore, combinedDisposable } from 'vs/base/common/lifecycle';
import { ViewletPanel, IViewletPanelOptions } from 'vs/workbench/browser/parts/views/panelViewlet';
import { ViewletPane, IViewletPaneOptions } from 'vs/workbench/browser/parts/views/paneViewlet';
import { append, $, toggleClass } from 'vs/base/browser/dom';
import { IListVirtualDelegate, IListRenderer, IListContextMenuEvent, IListEvent } from 'vs/base/browser/ui/list/list';
import { ISCMService, ISCMRepository } from 'vs/workbench/contrib/scm/common/scm';
@@ -29,6 +29,7 @@ import { renderCodicons } from 'vs/base/browser/ui/codiconLabel/codiconLabel';
import { WorkbenchList } from 'vs/platform/list/browser/listService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IViewDescriptor } from 'vs/workbench/common/views';
import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
export interface ISpliceEvent<T> {
index: number;
@@ -167,16 +168,16 @@ class ProviderRenderer implements IListRenderer<ISCMRepository, RepositoryTempla
}
}
export class MainPanel extends ViewletPanel {
export class MainPane extends ViewletPane {
static readonly ID = 'scm.mainPanel';
static readonly ID = 'scm.mainPane';
static readonly TITLE = localize('scm providers', "Source Control Providers");
private list!: WorkbenchList<ISCMRepository>;
constructor(
protected viewModel: IViewModel,
options: IViewletPanelOptions,
options: IViewletPaneOptions,
@IKeybindingService protected keybindingService: IKeybindingService,
@IContextMenuService protected contextMenuService: IContextMenuService,
@ISCMService protected scmService: ISCMService,
@@ -193,9 +194,12 @@ export class MainPanel extends ViewletPanel {
const renderer = this.instantiationService.createInstance(ProviderRenderer);
const identityProvider = { getId: (r: ISCMRepository) => r.provider.id };
this.list = this.instantiationService.createInstance(WorkbenchList, `SCM Main`, container, delegate, [renderer], {
this.list = this.instantiationService.createInstance<typeof WorkbenchList, WorkbenchList<ISCMRepository>>(WorkbenchList, `SCM Main`, container, delegate, [renderer], {
identityProvider,
horizontalScrolling: false
horizontalScrolling: false,
overrideStyles: {
listBackground: SIDE_BAR_BACKGROUND
}
});
this._register(renderer.onDidRenderElement(e => this.list.updateWidth(this.viewModel.repositories.indexOf(e)), null));
@@ -311,10 +315,10 @@ export class MainPanel extends ViewletPanel {
}
}
export class MainPanelDescriptor implements IViewDescriptor {
export class MainPaneDescriptor implements IViewDescriptor {
readonly id = MainPanel.ID;
readonly name = MainPanel.TITLE;
readonly id = MainPane.ID;
readonly name = MainPane.TITLE;
readonly ctorDescriptor: { ctor: any, arguments?: any[] };
readonly canToggleVisibility = true;
readonly hideByDefault = false;
@@ -323,6 +327,6 @@ export class MainPanelDescriptor implements IViewDescriptor {
readonly when = ContextKeyExpr.or(ContextKeyExpr.equals('config.scm.alwaysShowProviders', true), ContextKeyExpr.and(ContextKeyExpr.notEquals('scm.providerCount', 0), ContextKeyExpr.notEquals('scm.providerCount', 1)));
constructor(viewModel: IViewModel) {
this.ctorDescriptor = { ctor: MainPanel, arguments: [viewModel] };
this.ctorDescriptor = { ctor: MainPane, arguments: [viewModel] };
}
}

View File

@@ -39,7 +39,7 @@
transition: height 80ms linear;
}
.monaco-editor .margin-view-overlays > div:hover > .dirty-diff-glyph:before {
.monaco-editor .margin-view-overlays .dirty-diff-glyph:hover::before {
position: absolute;
content: '';
height: 100%;
@@ -47,7 +47,7 @@
left: -6px;
}
.monaco-editor .margin-view-overlays > div:hover > .dirty-diff-deleted:after {
.monaco-editor .margin-view-overlays .dirty-diff-deleted:hover::after {
bottom: 0;
border-top-width: 0;
border-bottom-width: 0;
@@ -56,4 +56,4 @@
/* Hide glyph decorations when inside the inline diff editor */
.monaco-editor.modified-in-monaco-diff-editor .margin-view-overlays > div > .dirty-diff-glyph {
display: none;
}
}

View File

@@ -1,10 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0)">
<path d="M21 8.25C21.0035 7.55379 20.8131 6.87035 20.4502 6.27622C20.0872 5.68209 19.566 5.20073 18.945 4.88605C18.3239 4.57137 17.6275 4.4358 16.9338 4.49451C16.24 4.55323 15.5764 4.80392 15.017 5.2185C14.4577 5.63308 14.0248 6.19518 13.7669 6.84186C13.509 7.48854 13.4361 8.19426 13.5566 8.87998C13.6771 9.5657 13.986 10.2044 14.4489 10.7244C14.9118 11.2445 15.5104 11.6254 16.1775 11.8245C15.9312 12.3251 15.5501 12.7472 15.0771 13.0431C14.6041 13.3391 14.058 13.4973 13.5 13.5H10.5C9.3894 13.5039 8.32 13.921 7.5 14.67V7.4235C8.41053 7.23764 9.21962 6.72031 9.7704 5.97181C10.3212 5.22331 10.5744 4.29696 10.481 3.37236C10.3876 2.44776 9.95422 1.59077 9.26486 0.96755C8.57551 0.344328 7.67931 -0.000732422 6.75 -0.000732422C5.82069 -0.000732422 4.92449 0.344328 4.23513 0.96755C3.54578 1.59077 3.11239 2.44776 3.01899 3.37236C2.92558 4.29696 3.17882 5.22331 3.7296 5.97181C4.28038 6.72031 5.08947 7.23764 6 7.4235V16.5735C5.09118 16.7473 4.27737 17.2477 3.71208 17.9802C3.14679 18.7128 2.8691 19.6269 2.93137 20.5501C2.99365 21.4733 3.39159 22.3418 4.05014 22.9917C4.70869 23.6417 5.58233 24.0283 6.50626 24.0785C7.4302 24.1287 8.34056 23.839 9.06564 23.2642C9.79073 22.6894 10.2804 21.8691 10.4423 20.9581C10.6042 20.047 10.4272 19.1083 9.94457 18.3188C9.46196 17.5293 8.70715 16.9437 7.8225 16.6725C8.06925 16.1724 8.4505 15.751 8.92346 15.4556C9.39642 15.1601 9.94236 15.0024 10.5 15H13.5C14.436 14.9957 15.3473 14.6996 16.1071 14.153C16.8669 13.6064 17.4373 12.8365 17.739 11.9505C18.6381 11.8323 19.4639 11.3922 20.0635 10.7118C20.6631 10.0314 20.9958 9.15685 21 8.25ZM4.5 3.75C4.5 3.30499 4.63196 2.86998 4.87919 2.49997C5.12643 2.12996 5.47783 1.84157 5.88896 1.67127C6.3001 1.50098 6.7525 1.45642 7.18895 1.54324C7.62541 1.63005 8.02632 1.84434 8.34099 2.15901C8.65566 2.47368 8.86995 2.87459 8.95677 3.31105C9.04358 3.74751 8.99903 4.19991 8.82873 4.61104C8.65843 5.02217 8.37004 5.37358 8.00003 5.62081C7.63002 5.86804 7.19501 6 6.75 6C6.15326 6 5.58097 5.76295 5.15901 5.34099C4.73705 4.91904 4.5 4.34674 4.5 3.75ZM9 20.25C9 20.695 8.86804 21.13 8.62081 21.5C8.37357 21.87 8.02217 22.1584 7.61104 22.3287C7.1999 22.499 6.7475 22.5436 6.31105 22.4568C5.87459 22.37 5.47368 22.1557 5.15901 21.841C4.84434 21.5263 4.63005 21.1254 4.54323 20.689C4.45642 20.2525 4.50097 19.8001 4.67127 19.389C4.84157 18.9778 5.12996 18.6264 5.49997 18.3792C5.86998 18.132 6.30499 18 6.75 18C7.34674 18 7.91903 18.2371 8.34099 18.659C8.76295 19.081 9 19.6533 9 20.25ZM17.25 10.5C16.805 10.5 16.37 10.368 16 10.1208C15.63 9.87358 15.3416 9.52217 15.1713 9.11104C15.001 8.69991 14.9564 8.24751 15.0432 7.81105C15.13 7.37459 15.3443 6.97368 15.659 6.65901C15.9737 6.34434 16.3746 6.13005 16.811 6.04323C17.2475 5.95642 17.6999 6.00098 18.111 6.17127C18.5222 6.34157 18.8736 6.62996 19.1208 6.99997C19.368 7.36998 19.5 7.80499 19.5 8.25C19.5 8.84674 19.2629 9.41904 18.841 9.84099C18.419 10.2629 17.8467 10.5 17.25 10.5Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -3,10 +3,6 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
.monaco-workbench .activitybar > .content .monaco-action-bar .action-label.scm {
-webkit-mask: url('scm-activity-bar.svg') no-repeat 50% 50%;
}
.monaco-workbench .viewlet.scm-viewlet .collapsible.header .actions {
width: initial;
flex: 1;
@@ -19,7 +15,7 @@
}
.scm-viewlet:not(.empty) .empty-message,
.scm-viewlet.empty .monaco-panel-view {
.scm-viewlet.empty .monaco-pane-view {
display: none;
}
@@ -48,8 +44,15 @@
align-items: center;
}
.scm-viewlet .monaco-list-row > .scm-provider > .monaco-action-bar .action-label {
text-overflow: ellipsis;
overflow: hidden;
min-width: 14px; /* minimum size of icons */
}
.scm-viewlet .monaco-list-row > .scm-provider > .monaco-action-bar .action-label .codicon {
font-size: 14px;
vertical-align: sub;
}
.scm-viewlet .monaco-list-row > .scm-provider > .monaco-action-bar .action-item:last-of-type {
@@ -133,6 +136,7 @@
.scm-viewlet .monaco-list .monaco-list-row .resource-group > .actions,
.scm-viewlet .monaco-list .monaco-list-row .resource > .name > .monaco-icon-label > .actions {
display: none;
max-width: fit-content;
}
.scm-viewlet .monaco-list .monaco-list-row:hover .resource-group > .actions,

View File

@@ -6,9 +6,9 @@
import 'vs/css!./media/scmViewlet';
import { Event, Emitter } from 'vs/base/common/event';
import { domEvent } from 'vs/base/browser/event';
import { basename } from 'vs/base/common/resources';
import { basename, isEqual } from 'vs/base/common/resources';
import { IDisposable, Disposable, DisposableStore, combinedDisposable } from 'vs/base/common/lifecycle';
import { ViewletPanel, IViewletPanelOptions } from 'vs/workbench/browser/parts/views/panelViewlet';
import { ViewletPane, IViewletPaneOptions } from 'vs/workbench/browser/parts/views/paneViewlet';
import { append, $, addClass, toggleClass, trackFocus, removeClass } from 'vs/base/browser/dom';
import { IListVirtualDelegate, IIdentityProvider } from 'vs/base/browser/ui/list/list';
import { ISCMRepository, ISCMResourceGroup, ISCMResource, InputValidationType } from 'vs/workbench/contrib/scm/common/scm';
@@ -38,7 +38,7 @@ import * as platform from 'vs/base/common/platform';
import { ITreeNode, ITreeFilter, ITreeSorter, ITreeContextMenuEvent } from 'vs/base/browser/ui/tree/tree';
import { ResourceTree, IResourceNode } from 'vs/base/common/resourceTree';
import { ISequence, ISplice } from 'vs/base/common/sequence';
import { ObjectTree, ICompressibleTreeRenderer, ICompressibleKeyboardNavigationLabelProvider } from 'vs/base/browser/ui/tree/objectTree';
import { ICompressibleTreeRenderer, ICompressibleKeyboardNavigationLabelProvider } from 'vs/base/browser/ui/tree/objectTree';
import { Iterator } from 'vs/base/common/iterator';
import { ICompressedTreeNode, ICompressedTreeElement } from 'vs/base/browser/ui/tree/compressedObjectTreeModel';
import { URI } from 'vs/base/common/uri';
@@ -47,11 +47,13 @@ import { compareFileNames } from 'vs/base/common/comparers';
import { FuzzyScore, createMatches } from 'vs/base/common/filters';
import { IViewDescriptor } from 'vs/workbench/common/views';
import { localize } from 'vs/nls';
import { flatten } from 'vs/base/common/arrays';
import { flatten, find } from 'vs/base/common/arrays';
import { memoize } from 'vs/base/common/decorators';
import { IWorkbenchThemeService, IFileIconTheme } from 'vs/workbench/services/themes/common/workbenchThemeService';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { toResource, SideBySideEditor } from 'vs/workbench/common/editor';
import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
import { Hasher } from 'vs/base/common/hash';
type TreeElement = ISCMResourceGroup | IResourceNode<ISCMResource, ISCMResourceGroup> | ISCMResource;
@@ -428,7 +430,7 @@ class ViewModel {
constructor(
private groups: ISequence<ISCMResourceGroup>,
private tree: ObjectTree<TreeElement, FuzzyScore>,
private tree: WorkbenchCompressibleObjectTree<TreeElement, FuzzyScore>,
private _mode: ViewModelMode,
@IEditorService protected editorService: IEditorService,
@IConfigurationService protected configurationService: IConfigurationService,
@@ -466,18 +468,16 @@ class ViewModel {
}
private onDidSpliceGroup(item: IGroupItem, { start, deleteCount, toInsert }: ISplice<ISCMResource>): void {
if (this._mode === ViewModelMode.Tree) {
for (const resource of toInsert) {
item.tree.add(resource.sourceUri, resource);
}
}
const deleted = item.resources.splice(start, deleteCount, ...toInsert);
if (this._mode === ViewModelMode.Tree) {
for (const resource of deleted) {
item.tree.delete(resource.sourceUri);
}
for (const resource of toInsert) {
item.tree.add(resource.sourceUri, resource);
}
}
this.refresh(item);
@@ -536,12 +536,15 @@ class ViewModel {
// go backwards from last group
for (let i = this.items.length - 1; i >= 0; i--) {
const node = this.items[i].tree.getNode(uri);
const item = this.items[i];
const resource = this.mode === ViewModelMode.Tree
? item.tree.getNode(uri)?.element
: find(item.resources, r => isEqual(r.sourceUri, uri));
if (node && node.element) {
this.tree.reveal(node.element);
this.tree.setSelection([node.element]);
this.tree.setFocus([node.element]);
if (resource) {
this.tree.reveal(resource);
this.tree.setSelection([resource]);
this.tree.setFocus([resource]);
return;
}
}
@@ -570,7 +573,7 @@ export class ToggleViewModeAction extends Action {
}
private onDidChangeMode(mode: ViewModelMode): void {
const iconClass = mode === ViewModelMode.List ? 'codicon-filter' : 'codicon-selection';
const iconClass = mode === ViewModelMode.List ? 'codicon-list-tree' : 'codicon-list-flat';
this.class = `scm-action toggle-view-mode ${iconClass}`;
}
}
@@ -583,14 +586,14 @@ function convertValidationType(type: InputValidationType): MessageType {
}
}
export class RepositoryPanel extends ViewletPanel {
export class RepositoryPane extends ViewletPane {
private cachedHeight: number | undefined = undefined;
private cachedWidth: number | undefined = undefined;
private inputBoxContainer!: HTMLElement;
private inputBox!: InputBox;
private listContainer!: HTMLElement;
private tree!: ObjectTree<TreeElement, FuzzyScore>;
private tree!: WorkbenchCompressibleObjectTree<TreeElement, FuzzyScore>;
private viewModel!: ViewModel;
private listLabels!: ResourceLabels;
private menus: SCMMenus;
@@ -600,7 +603,7 @@ export class RepositoryPanel extends ViewletPanel {
constructor(
readonly repository: ISCMRepository,
options: IViewletPanelOptions,
options: IViewletPaneOptions,
@IKeybindingService protected keybindingService: IKeybindingService,
@IWorkbenchThemeService protected themeService: IWorkbenchThemeService,
@IContextMenuService protected contextMenuService: IContextMenuService,
@@ -732,7 +735,7 @@ export class RepositoryPanel extends ViewletPanel {
const keyboardNavigationLabelProvider = new SCMTreeKeyboardNavigationLabelProvider();
const identityProvider = new SCMResourceIdentityProvider();
this.tree = this.instantiationService.createInstance(
this.tree = this.instantiationService.createInstance<typeof WorkbenchCompressibleObjectTree, WorkbenchCompressibleObjectTree<TreeElement, FuzzyScore>>(
WorkbenchCompressibleObjectTree,
'SCM Tree Repo',
this.listContainer,
@@ -743,7 +746,10 @@ export class RepositoryPanel extends ViewletPanel {
horizontalScrolling: false,
filter,
sorter,
keyboardNavigationLabelProvider
keyboardNavigationLabelProvider,
overrideStyles: {
listBackground: SIDE_BAR_BACKGROUND
}
});
this._register(Event.chain(this.tree.onDidOpen)
@@ -958,9 +964,12 @@ export class RepositoryViewDescriptor implements IViewDescriptor {
constructor(readonly repository: ISCMRepository, readonly hideByDefault: boolean) {
const repoId = repository.provider.rootUri ? repository.provider.rootUri.toString() : `#${RepositoryViewDescriptor.counter++}`;
this.id = `scm:repository:${repository.provider.label}:${repoId}`;
const hasher = new Hasher();
hasher.hash(repository.provider.label);
hasher.hash(repoId);
this.id = `scm:repository:${hasher.value}`;
this.name = repository.provider.rootUri ? basename(repository.provider.rootUri) : repository.provider.label;
this.ctorDescriptor = { ctor: RepositoryPanel, arguments: [repository] };
this.ctorDescriptor = { ctor: RepositoryPane, arguments: [repository] };
}
}

View File

@@ -38,13 +38,12 @@ class OpenSCMViewletAction extends ShowViewletAction {
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench)
.registerWorkbenchContribution(DirtyDiffWorkbenchController, LifecyclePhase.Restored);
Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets).registerViewlet(new ViewletDescriptor(
Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets).registerViewlet(ViewletDescriptor.create(
SCMViewlet,
VIEWLET_ID,
localize('source control', "Source Control"),
'scm',
// {{SQL CARBON EDIT}}
12
'codicon-source-control',
12 // {{SQL CARBON EDIT}}
));
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench)
@@ -52,7 +51,7 @@ Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench)
// Register Action to Open Viewlet
Registry.as<IWorkbenchActionRegistry>(WorkbenchActionExtensions.WorkbenchActions).registerWorkbenchAction(
new SyncActionDescriptor(OpenSCMViewletAction, VIEWLET_ID, localize('toggleSCMViewlet', "Show SCM"), {
SyncActionDescriptor.create(OpenSCMViewletAction, VIEWLET_ID, localize('toggleSCMViewlet', "Show SCM"), {
primary: 0,
win: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_G },
linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_G },
@@ -81,7 +80,7 @@ Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration).regis
},
'scm.diffDecorations': {
type: 'string',
enum: ['all', 'gutter', 'overview', 'none'],
enum: ['all', 'gutter', 'overview', 'minimap', 'none'],
default: 'all',
description: localize('diffDecorations', "Controls diff decorations in the editor.")
},
@@ -98,7 +97,7 @@ Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration).regis
localize('scm.diffDecorationsGutterVisibility.always', "Show the diff decorator in the gutter at all times."),
localize('scm.diffDecorationsGutterVisibility.hover', "Show the diff decorator in the gutter only on hover.")
],
description: localize('scm.diffDecorationsGutterVisibility', "Controls the visibilty of the Source Control diff decorator in the gutter."),
description: localize('scm.diffDecorationsGutterVisibility', "Controls the visibility of the Source Control diff decorator in the gutter."),
default: 'always'
},
'scm.alwaysShowActions': {

View File

@@ -29,8 +29,8 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace
import { IViewsRegistry, Extensions } from 'vs/workbench/common/views';
import { Registry } from 'vs/platform/registry/common/platform';
import { nextTick } from 'vs/base/common/process';
import { RepositoryPanel, RepositoryViewDescriptor } from 'vs/workbench/contrib/scm/browser/repositoryPanel';
import { MainPanelDescriptor, MainPanel } from 'vs/workbench/contrib/scm/browser/mainPanel';
import { RepositoryPane, RepositoryViewDescriptor } from 'vs/workbench/contrib/scm/browser/repositoryPane';
import { MainPaneDescriptor, MainPane } from 'vs/workbench/contrib/scm/browser/mainPane';
export interface ISpliceEvent<T> {
index: number;
@@ -73,8 +73,8 @@ export class SCMViewlet extends ViewContainerViewlet implements IViewModel {
}
get visibleRepositories(): ISCMRepository[] {
return this.panels.filter(panel => panel instanceof RepositoryPanel)
.map(panel => (panel as RepositoryPanel).repository);
return this.panes.filter(pane => pane instanceof RepositoryPane)
.map(pane => (pane as RepositoryPane).repository);
}
get onDidChangeVisibleRepositories(): Event<ISCMRepository[]> {
@@ -107,11 +107,11 @@ export class SCMViewlet extends ViewContainerViewlet implements IViewModel {
this.message = $('.empty-message', { tabIndex: 0 }, localize('no open repo', "No source control providers registered."));
const viewsRegistry = Registry.as<IViewsRegistry>(Extensions.ViewsRegistry);
viewsRegistry.registerViews([new MainPanelDescriptor(this)], VIEW_CONTAINER);
viewsRegistry.registerViews([new MainPaneDescriptor(this)], VIEW_CONTAINER);
this._register(configurationService.onDidChangeConfiguration(e => {
if (e.affectsConfiguration('scm.alwaysShowProviders') && configurationService.getValue<boolean>('scm.alwaysShowProviders')) {
this.viewsModel.setVisible(MainPanel.ID, true);
this.viewsModel.setVisible(MainPane.ID, true);
}
}));
@@ -184,11 +184,11 @@ export class SCMViewlet extends ViewContainerViewlet implements IViewModel {
const repository = this.visibleRepositories[0];
if (repository) {
const panel = this.panels
.filter(panel => panel instanceof RepositoryPanel && panel.repository === repository)[0] as RepositoryPanel | undefined;
const pane = this.panes
.filter(pane => pane instanceof RepositoryPane && pane.repository === repository)[0] as RepositoryPane | undefined;
if (panel) {
panel.focus();
if (pane) {
pane.focus();
} else {
super.focus();
}
@@ -257,10 +257,10 @@ export class SCMViewlet extends ViewContainerViewlet implements IViewModel {
for (const viewDescriptor of toSetInvisible) {
if (oneToOne) {
const panel = this.panels.filter(panel => panel.id === viewDescriptor.id)[0];
const pane = this.panes.filter(pane => pane.id === viewDescriptor.id)[0];
if (panel) {
size = this.getPanelSize(panel);
if (pane) {
size = this.getPaneSize(pane);
}
}