Merge from vscode e3b9b8eefc062d68ba8a4b6a817162d132f3b533 (#6932)

* Merge from vscode e3b9b8eefc062d68ba8a4b6a817162d132f3b533

* skip failing test

* add comment
This commit is contained in:
Anthony Dresser
2019-08-24 00:19:48 -07:00
committed by GitHub
parent 023d06d114
commit 92a3acbfe8
77 changed files with 992 additions and 559 deletions

View File

@@ -40,8 +40,10 @@ import { ServiceCollection } from 'vs/platform/instantiation/common/serviceColle
import { INotificationService } from 'vs/platform/notification/common/notification';
import { defaultInsertColor, defaultRemoveColor, diffBorder, diffInserted, diffInsertedOutline, diffRemoved, diffRemovedOutline, scrollbarShadow } from 'vs/platform/theme/common/colorRegistry';
import { ITheme, IThemeService, getThemeTypeSelector, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
// {{SQL CARBON EDIT}}
import { reverseLineChanges } from 'sql/editor/browser/diffEditorHelper';
import { reverseLineChanges } from 'sql/editor/browser/diffEditorHelper'; // {{SQL CARBON EDIT}}
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IDiffLinesChange, InlineDiffMargin } from 'vs/editor/browser/widget/inlineDiffMargin';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
interface IEditorDiffDecorations {
decorations: IModelDeltaDecoration[];
@@ -49,7 +51,7 @@ interface IEditorDiffDecorations {
}
interface IEditorDiffDecorationsWithZones extends IEditorDiffDecorations {
zones: editorBrowser.IViewZone[];
zones: IMyViewZone[];
}
interface IEditorsDiffDecorationsWithZones {
@@ -58,8 +60,8 @@ interface IEditorsDiffDecorationsWithZones {
}
interface IEditorsZones {
original: editorBrowser.IViewZone[];
modified: editorBrowser.IViewZone[];
original: IMyViewZone[];
modified: IMyViewZone[];
}
interface IDiffEditorWidgetStyle {
@@ -73,11 +75,16 @@ interface IDiffEditorWidgetStyle {
class VisualEditorState {
private _zones: string[];
private inlineDiffMargins: InlineDiffMargin[];
private _zonesMap: { [zoneId: string]: boolean; };
private _decorations: string[];
constructor() {
constructor(
private _contextMenuService: IContextMenuService,
private _clipboardService: IClipboardService
) {
this._zones = [];
this.inlineDiffMargins = [];
this._zonesMap = {};
this._decorations = [];
}
@@ -111,13 +118,22 @@ class VisualEditorState {
for (let i = 0, length = this._zones.length; i < length; i++) {
viewChangeAccessor.removeZone(this._zones[i]);
}
for (let i = 0, length = this.inlineDiffMargins.length; i < length; i++) {
this.inlineDiffMargins[i].dispose();
}
this._zones = [];
this._zonesMap = {};
this.inlineDiffMargins = [];
for (let i = 0, length = newDecorations.zones.length; i < length; i++) {
newDecorations.zones[i].suppressMouseDown = true;
let zoneId = viewChangeAccessor.addZone(newDecorations.zones[i]);
const viewZone = <editorBrowser.IViewZone>newDecorations.zones[i];
viewZone.suppressMouseDown = false;
let zoneId = viewChangeAccessor.addZone(viewZone);
this._zones.push(zoneId);
this._zonesMap[String(zoneId)] = true;
if (newDecorations.zones[i].diff && viewZone.marginDomNode) {
this.inlineDiffMargins.push(new InlineDiffMargin(viewZone.marginDomNode, editor, newDecorations.zones[i].diff!, this._contextMenuService, this._clipboardService));
}
}
});
@@ -207,7 +223,9 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
@IInstantiationService instantiationService: IInstantiationService,
@ICodeEditorService codeEditorService: ICodeEditorService,
@IThemeService themeService: IThemeService,
@INotificationService notificationService: INotificationService
@INotificationService notificationService: INotificationService,
@IContextMenuService contextMenuService: IContextMenuService,
@IClipboardService clipboardService: IClipboardService
) {
super();
@@ -289,8 +307,8 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
this._currentlyChangingViewZones = false;
this._diffComputationToken = 0;
this._originalEditorState = new VisualEditorState();
this._modifiedEditorState = new VisualEditorState();
this._originalEditorState = new VisualEditorState(contextMenuService, clipboardService);
this._modifiedEditorState = new VisualEditorState(contextMenuService, clipboardService);
this._isVisible = true;
this._isHandlingScrollEvent = false;
@@ -1278,6 +1296,7 @@ interface IMyViewZone {
minWidthInPx?: number;
domNode: HTMLElement | null;
marginDomNode?: HTMLElement | null;
diff?: IDiffLinesChange;
}
class ForeignViewZonesIterator {
@@ -1489,12 +1508,12 @@ abstract class ViewZonesComputer {
};
}
private static _ensureDomNodes(zones: IMyViewZone[]): editorBrowser.IViewZone[] {
private static _ensureDomNodes(zones: IMyViewZone[]): IMyViewZone[] {
return zones.map((z) => {
if (!z.domNode) {
z.domNode = createFakeLinesDiv();
}
return <editorBrowser.IViewZone>z;
return z;
});
}
@@ -1997,8 +2016,10 @@ class InlineViewZonesComputer extends ViewZonesComputer {
let lineHeight = this.modifiedEditorConfiguration.lineHeight;
const typicalHalfwidthCharacterWidth = this.modifiedEditorConfiguration.fontInfo.typicalHalfwidthCharacterWidth;
let maxCharsPerLine = 0;
const originalContent: string[] = [];
for (let lineNumber = lineChange.originalStartLineNumber; lineNumber <= lineChange.originalEndLineNumber; lineNumber++) {
maxCharsPerLine = Math.max(maxCharsPerLine, this._renderOriginalLine(lineNumber - lineChange.originalStartLineNumber, this.originalModel, this.modifiedEditorConfiguration, this.modifiedEditorTabSize, lineNumber, decorations, sb));
originalContent.push(this.originalModel.getLineContent(lineNumber));
if (this.renderIndicators) {
let index = lineNumber - lineChange.originalStartLineNumber;
@@ -2025,7 +2046,14 @@ class InlineViewZonesComputer extends ViewZonesComputer {
heightInLines: lineChangeOriginalLength,
minWidthInPx: (maxCharsPerLine * typicalHalfwidthCharacterWidth),
domNode: domNode,
marginDomNode: marginDomNode
marginDomNode: marginDomNode,
diff: {
originalStartLineNumber: lineChange.originalStartLineNumber,
originalEndLineNumber: lineChange.originalEndLineNumber,
modifiedStartLineNumber: lineChange.modifiedStartLineNumber,
modifiedEndLineNumber: lineChange.modifiedEndLineNumber,
originalContent: originalContent
}
};
}

View File

@@ -16,6 +16,8 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { INotificationService } from 'vs/platform/notification/common/notification';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
export class EmbeddedCodeEditorWidget extends CodeEditorWidget {
@@ -74,9 +76,11 @@ export class EmbeddedDiffEditorWidget extends DiffEditorWidget {
@IInstantiationService instantiationService: IInstantiationService,
@ICodeEditorService codeEditorService: ICodeEditorService,
@IThemeService themeService: IThemeService,
@INotificationService notificationService: INotificationService
@INotificationService notificationService: INotificationService,
@IContextMenuService contextMenuService: IContextMenuService,
@IClipboardService clipboardService: IClipboardService
) {
super(domElement, parentEditor.getRawConfiguration(), editorWorkerService, contextKeyService, instantiationService, codeEditorService, themeService, notificationService);
super(domElement, parentEditor.getRawConfiguration(), editorWorkerService, contextKeyService, instantiationService, codeEditorService, themeService, notificationService, contextMenuService, clipboardService);
this._parentEditor = parentEditor;
this._overwriteOptions = options;

View File

@@ -0,0 +1,139 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as nls from 'vs/nls';
import * as dom from 'vs/base/browser/dom';
import { Action } from 'vs/base/common/actions';
import { Disposable } from 'vs/base/common/lifecycle';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { Range } from 'vs/editor/common/core/range';
import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget';
export interface IDiffLinesChange {
readonly originalStartLineNumber: number;
readonly originalEndLineNumber: number;
readonly modifiedStartLineNumber: number;
readonly modifiedEndLineNumber: number;
readonly originalContent: string[];
}
export class InlineDiffMargin extends Disposable {
private readonly _lightBulb: HTMLElement;
constructor(
marginDomNode: HTMLElement,
public editor: CodeEditorWidget,
public diff: IDiffLinesChange,
private _contextMenuService: IContextMenuService,
private _clipboardService: IClipboardService
) {
super();
// make sure the diff margin shows above overlay.
marginDomNode.style.zIndex = '10';
this._lightBulb = document.createElement('div');
this._lightBulb.className = 'lightbulb-glyph';
this._lightBulb.style.position = 'absolute';
const lineHeight = editor.getConfiguration().lineHeight;
const lineFeed = editor.getModel()!.getEOL();
this._lightBulb.style.right = '0px';
this._lightBulb.style.visibility = 'hidden';
this._lightBulb.style.height = `${lineHeight}px`;
marginDomNode.appendChild(this._lightBulb);
const actions = [
new Action(
'diff.clipboard.copyDeletedContent',
nls.localize('diff.clipboard.copyDeletedContent.label', "Copy deleted lines content to clipboard"),
undefined,
true,
async () => {
await this._clipboardService.writeText(diff.originalContent.join(lineFeed) + lineFeed);
}
)
];
let currentLineNumberOffset = 0;
const copyLineAction = new Action(
'diff.clipboard.copyDeletedLineContent',
nls.localize('diff.clipboard.copyDeletedLineContent.label', "Copy deleted line {0} content to clipboard", diff.originalStartLineNumber),
undefined,
true,
async () => {
await this._clipboardService.writeText(diff.originalContent[currentLineNumberOffset]);
}
);
actions.push(copyLineAction);
const readOnly = editor.getConfiguration().readOnly;
if (!readOnly) {
actions.push(new Action('diff.inline.revertChange', nls.localize('diff.inline.revertChange.label', "Revert this change"), undefined, true, async () => {
if (diff.modifiedEndLineNumber === 0) {
// deletion only
const column = editor.getModel()!.getLineMaxColumn(diff.modifiedStartLineNumber);
editor.executeEdits('diffEditor', [
{
range: new Range(diff.modifiedStartLineNumber, column, diff.modifiedStartLineNumber, column),
text: lineFeed + diff.originalContent.join(lineFeed)
}
]);
} else {
const column = editor.getModel()!.getLineMaxColumn(diff.modifiedEndLineNumber);
editor.executeEdits('diffEditor', [
{
range: new Range(diff.modifiedStartLineNumber, 1, diff.modifiedEndLineNumber, column),
text: diff.originalContent.join(lineFeed)
}
]);
}
}));
}
this._register(dom.addStandardDisposableListener(marginDomNode, 'mouseenter', e => {
this._lightBulb.style.visibility = 'visible';
currentLineNumberOffset = this._updateLightBulbPosition(marginDomNode, e.y, lineHeight);
}));
this._register(dom.addStandardDisposableListener(marginDomNode, 'mouseleave', e => {
this._lightBulb.style.visibility = 'hidden';
}));
this._register(dom.addStandardDisposableListener(marginDomNode, 'mousemove', e => {
currentLineNumberOffset = this._updateLightBulbPosition(marginDomNode, e.y, lineHeight);
}));
this._register(dom.addStandardDisposableListener(this._lightBulb, 'mousedown', e => {
const { top, height } = dom.getDomNodePagePosition(this._lightBulb);
let pad = Math.floor(lineHeight / 3) + lineHeight;
this._contextMenuService.showContextMenu({
getAnchor: () => {
return {
x: e.posx,
y: top + height + pad
};
},
getActions: () => {
copyLineAction.label = nls.localize('diff.clipboard.copyDeletedLineContent.label', "Copy deleted line {0} content to clipboard", diff.originalStartLineNumber + currentLineNumberOffset);
return actions;
},
autoSelectFirstItem: true
});
}));
}
private _updateLightBulbPosition(marginDomNode: HTMLElement, y: number, lineHeight: number): number {
const { top } = dom.getDomNodePagePosition(marginDomNode);
const offset = y - top;
const lineNumberOffset = Math.floor(offset / lineHeight);
const newTop = lineNumberOffset * lineHeight;
this._lightBulb.style.top = `${newTop}px`;
return lineNumberOffset;
}
}