diff --git a/src/vs/editor/browser/editorBrowser.ts b/src/vs/editor/browser/editorBrowser.ts index 3a05cd5c8f4eddd7503444a386ea4d87b4fedd6b..0253876b502ef811f520296dd33aa66f4eca53e2 100644 --- a/src/vs/editor/browser/editorBrowser.ts +++ b/src/vs/editor/browser/editorBrowser.ts @@ -18,6 +18,7 @@ import { IModelContentChangedEvent, IModelDecorationsChangedEvent, IModelLanguag import { OverviewRulerZone } from 'vs/editor/common/view/overviewZoneManager'; import { IEditorWhitespace } from 'vs/editor/common/viewLayout/whitespaceComputer'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; +import { IDiffComputationResult } from 'vs/editor/common/services/editorWorkerService'; /** * A view zone is a full horizontal rectangle that 'pushes' text down. @@ -906,6 +907,12 @@ export interface IDiffEditor extends editorCommon.IEditor { */ getLineChanges(): editorCommon.ILineChange[] | null; + /** + * Get the computed diff information. + * @internal + */ + getDiffComputationResult(): IDiffComputationResult | null; + /** * Get information based on computed diff about a line number from the original model. * If the diff computation is not finished or the model is missing, will return null. diff --git a/src/vs/editor/browser/widget/diffEditorWidget.ts b/src/vs/editor/browser/widget/diffEditorWidget.ts index fd79438a75d9a9a3b87f01eebb1019ddb41e35ff..1ac2ad306998b8f8b814f00aeb65f1ac9e2e6910 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget.ts @@ -578,6 +578,10 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE return this._diffComputationResult.changes; } + public getDiffComputationResult(): IDiffComputationResult | null { + return this._diffComputationResult; + } + public getOriginalEditor(): editorBrowser.ICodeEditor { return this.originalEditor; } diff --git a/src/vs/workbench/contrib/codeEditor/browser/codeEditor.contribution.ts b/src/vs/workbench/contrib/codeEditor/browser/codeEditor.contribution.ts index 39a4d1afe662b52941f3759bd092919aec8a962d..dcc524d15e761789f723c7fc3e0d939da6c5427b 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/codeEditor.contribution.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/codeEditor.contribution.ts @@ -5,6 +5,7 @@ import './menuPreventer'; import './accessibility/accessibility'; +import './diffEditorHelper'; import './inspectKeybindings'; import './largeFileOptimizations'; import './selectionClipboard'; diff --git a/src/vs/workbench/contrib/codeEditor/browser/diffEditorHelper.ts b/src/vs/workbench/contrib/codeEditor/browser/diffEditorHelper.ts new file mode 100644 index 0000000000000000000000000000000000000000..eed47f4fad8299877a3d0ac2e3bcf69e5f9cef76 --- /dev/null +++ b/src/vs/workbench/contrib/codeEditor/browser/diffEditorHelper.ts @@ -0,0 +1,91 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as nls from 'vs/nls'; +import { IDiffEditor } from 'vs/editor/browser/editorBrowser'; +import { registerDiffEditorContribution } from 'vs/editor/browser/editorExtensions'; +import { IEditorContribution } from 'vs/editor/common/editorCommon'; +import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; +import { FloatingClickWidget } from 'vs/workbench/browser/parts/editor/editorWidgets'; +import { IDiffComputationResult } from 'vs/editor/common/services/editorWorkerService'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; + +const enum WidgetState { + Hidden, + HintWhitespace +} + +class DiffEditorHelperContribution extends Disposable implements IEditorContribution { + + private _helperWidget: FloatingClickWidget | null; + private _helperWidgetListener: IDisposable | null; + private _state: WidgetState; + + constructor( + private readonly _diffEditor: IDiffEditor, + @IInstantiationService private readonly _instantiationService: IInstantiationService, + @IConfigurationService private readonly _configurationService: IConfigurationService, + ) { + super(); + this._helperWidget = null; + this._helperWidgetListener = null; + this._state = WidgetState.Hidden; + + + this._register(this._diffEditor.onDidUpdateDiff(() => { + this._setState(this._deduceState(this._diffEditor.getDiffComputationResult())); + })); + } + + private _deduceState(diffComputationResult: IDiffComputationResult | null): WidgetState { + if (!diffComputationResult) { + return WidgetState.Hidden; + } + if (this._diffEditor.ignoreTrimWhitespace && diffComputationResult.changes.length === 0 && !diffComputationResult.identical) { + return WidgetState.HintWhitespace; + } + return WidgetState.Hidden; + } + + private _setState(newState: WidgetState) { + if (this._state === newState) { + return; + } + + this._state = newState; + + if (this._helperWidgetListener) { + this._helperWidgetListener.dispose(); + this._helperWidgetListener = null; + } + if (this._helperWidget) { + this._helperWidget.dispose(); + this._helperWidget = null; + } + + if (this._state === WidgetState.HintWhitespace) { + this._helperWidget = this._instantiationService.createInstance(FloatingClickWidget, this._diffEditor.getModifiedEditor(), nls.localize('hintWhitespace', "Show Whitespace Differences"), null); + this._helperWidgetListener = this._helperWidget.onClick(() => this._onDidClickHelperWidget()); + this._helperWidget.render(); + } + } + + private _onDidClickHelperWidget(): void { + if (this._state === WidgetState.HintWhitespace) { + this._configurationService.updateValue('diffEditor.ignoreTrimWhitespace', false, ConfigurationTarget.USER); + } + } + + dispose(): void { + super.dispose(); + } + + getId(): string { + return 'editor.contrib.diffEditorHelper'; + } +} + +registerDiffEditorContribution(DiffEditorHelperContribution);