mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Merge VS Code 1.21 source code (#1067)
* Initial VS Code 1.21 file copy with patches * A few more merges * Post npm install * Fix batch of build breaks * Fix more build breaks * Fix more build errors * Fix more build breaks * Runtime fixes 1 * Get connection dialog working with some todos * Fix a few packaging issues * Copy several node_modules to package build to fix loader issues * Fix breaks from master * A few more fixes * Make tests pass * First pass of license header updates * Second pass of license header updates * Fix restore dialog issues * Remove add additional themes menu items * fix select box issues where the list doesn't show up * formatting * Fix editor dispose issue * Copy over node modules to correct location on all platforms
This commit is contained in:
@@ -335,6 +335,8 @@ export class Configuration extends CommonEditorConfiguration {
|
||||
extra += 'ff ';
|
||||
} else if (browser.isEdge) {
|
||||
extra += 'edge ';
|
||||
} else if (browser.isSafari) {
|
||||
extra += 'safari ';
|
||||
}
|
||||
if (platform.isMacintosh) {
|
||||
extra += 'mac ';
|
||||
|
||||
@@ -455,10 +455,7 @@ export namespace CoreNavigationCommands {
|
||||
cursors.setStates(
|
||||
source,
|
||||
CursorChangeReason.Explicit,
|
||||
CursorState.ensureInEditableRange(
|
||||
cursors.context,
|
||||
CursorMoveCommands.move(cursors.context, cursors.getAll(), args)
|
||||
)
|
||||
CursorMoveCommands.move(cursors.context, cursors.getAll(), args)
|
||||
);
|
||||
cursors.reveal(true, RevealTarget.Primary, editorCommon.ScrollType.Smooth);
|
||||
}
|
||||
@@ -707,7 +704,7 @@ export namespace CoreNavigationCommands {
|
||||
public runCoreEditorCommand(cursors: ICursors, args: any): void {
|
||||
const context = cursors.context;
|
||||
|
||||
if (context.config.readOnly || context.model.hasEditableRange()) {
|
||||
if (context.config.readOnly) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -772,7 +769,7 @@ export namespace CoreNavigationCommands {
|
||||
public runCoreEditorCommand(cursors: ICursors, args: any): void {
|
||||
const context = cursors.context;
|
||||
|
||||
if (context.config.readOnly || context.model.hasEditableRange()) {
|
||||
if (context.config.readOnly) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -804,10 +801,7 @@ export namespace CoreNavigationCommands {
|
||||
cursors.setStates(
|
||||
args.source,
|
||||
CursorChangeReason.Explicit,
|
||||
CursorState.ensureInEditableRange(
|
||||
cursors.context,
|
||||
CursorMoveCommands.moveToBeginningOfLine(cursors.context, cursors.getAll(), this._inSelectionMode)
|
||||
)
|
||||
CursorMoveCommands.moveToBeginningOfLine(cursors.context, cursors.getAll(), this._inSelectionMode)
|
||||
);
|
||||
cursors.reveal(true, RevealTarget.Primary, editorCommon.ScrollType.Smooth);
|
||||
}
|
||||
@@ -856,10 +850,7 @@ export namespace CoreNavigationCommands {
|
||||
cursors.setStates(
|
||||
args.source,
|
||||
CursorChangeReason.Explicit,
|
||||
CursorState.ensureInEditableRange(
|
||||
cursors.context,
|
||||
this._exec(cursors.context, cursors.getAll())
|
||||
)
|
||||
this._exec(cursors.context, cursors.getAll())
|
||||
);
|
||||
cursors.reveal(true, RevealTarget.Primary, editorCommon.ScrollType.Smooth);
|
||||
}
|
||||
@@ -889,10 +880,7 @@ export namespace CoreNavigationCommands {
|
||||
cursors.setStates(
|
||||
args.source,
|
||||
CursorChangeReason.Explicit,
|
||||
CursorState.ensureInEditableRange(
|
||||
cursors.context,
|
||||
CursorMoveCommands.moveToEndOfLine(cursors.context, cursors.getAll(), this._inSelectionMode)
|
||||
)
|
||||
CursorMoveCommands.moveToEndOfLine(cursors.context, cursors.getAll(), this._inSelectionMode)
|
||||
);
|
||||
cursors.reveal(true, RevealTarget.Primary, editorCommon.ScrollType.Smooth);
|
||||
}
|
||||
@@ -941,10 +929,7 @@ export namespace CoreNavigationCommands {
|
||||
cursors.setStates(
|
||||
args.source,
|
||||
CursorChangeReason.Explicit,
|
||||
CursorState.ensureInEditableRange(
|
||||
cursors.context,
|
||||
this._exec(cursors.context, cursors.getAll())
|
||||
)
|
||||
this._exec(cursors.context, cursors.getAll())
|
||||
);
|
||||
cursors.reveal(true, RevealTarget.Primary, editorCommon.ScrollType.Smooth);
|
||||
}
|
||||
@@ -975,10 +960,7 @@ export namespace CoreNavigationCommands {
|
||||
cursors.setStates(
|
||||
args.source,
|
||||
CursorChangeReason.Explicit,
|
||||
CursorState.ensureInEditableRange(
|
||||
cursors.context,
|
||||
CursorMoveCommands.moveToBeginningOfBuffer(cursors.context, cursors.getAll(), this._inSelectionMode)
|
||||
)
|
||||
CursorMoveCommands.moveToBeginningOfBuffer(cursors.context, cursors.getAll(), this._inSelectionMode)
|
||||
);
|
||||
cursors.reveal(true, RevealTarget.Primary, editorCommon.ScrollType.Smooth);
|
||||
}
|
||||
@@ -1022,10 +1004,7 @@ export namespace CoreNavigationCommands {
|
||||
cursors.setStates(
|
||||
args.source,
|
||||
CursorChangeReason.Explicit,
|
||||
CursorState.ensureInEditableRange(
|
||||
cursors.context,
|
||||
CursorMoveCommands.moveToEndOfBuffer(cursors.context, cursors.getAll(), this._inSelectionMode)
|
||||
)
|
||||
CursorMoveCommands.moveToEndOfBuffer(cursors.context, cursors.getAll(), this._inSelectionMode)
|
||||
);
|
||||
cursors.reveal(true, RevealTarget.Primary, editorCommon.ScrollType.Smooth);
|
||||
}
|
||||
@@ -1272,7 +1251,7 @@ export namespace CoreNavigationCommands {
|
||||
|
||||
public runCoreEditorCommand(cursors: ICursors, args: any): void {
|
||||
const context = cursors.context;
|
||||
if (context.config.readOnly || context.model.hasEditableRange()) {
|
||||
if (context.config.readOnly) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1335,7 +1314,7 @@ export namespace CoreNavigationCommands {
|
||||
public runCoreEditorCommand(cursors: ICursors, args: any): void {
|
||||
const context = cursors.context;
|
||||
|
||||
if (context.config.readOnly || context.model.hasEditableRange()) {
|
||||
if (context.config.readOnly) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1383,10 +1362,7 @@ export namespace CoreNavigationCommands {
|
||||
cursors.setStates(
|
||||
args.source,
|
||||
CursorChangeReason.Explicit,
|
||||
CursorState.ensureInEditableRange(
|
||||
cursors.context,
|
||||
CursorMoveCommands.expandLineSelection(cursors.context, cursors.getAll())
|
||||
)
|
||||
CursorMoveCommands.expandLineSelection(cursors.context, cursors.getAll())
|
||||
);
|
||||
cursors.reveal(true, RevealTarget.Primary, editorCommon.ScrollType.Smooth);
|
||||
}
|
||||
@@ -1723,44 +1699,6 @@ class EditorOrNativeTextInputCommand extends Command {
|
||||
}
|
||||
}
|
||||
|
||||
registerCommand(new EditorOrNativeTextInputCommand({
|
||||
editorHandler: CoreNavigationCommands.SelectAll,
|
||||
inputHandler: 'selectAll',
|
||||
id: 'editor.action.selectAll',
|
||||
precondition: null,
|
||||
kbOpts: {
|
||||
weight: CORE_WEIGHT,
|
||||
kbExpr: null,
|
||||
primary: KeyMod.CtrlCmd | KeyCode.KEY_A
|
||||
}
|
||||
}));
|
||||
|
||||
registerCommand(new EditorOrNativeTextInputCommand({
|
||||
editorHandler: H.Undo,
|
||||
inputHandler: 'undo',
|
||||
id: H.Undo,
|
||||
precondition: EditorContextKeys.writable,
|
||||
kbOpts: {
|
||||
weight: CORE_WEIGHT,
|
||||
kbExpr: EditorContextKeys.textFocus,
|
||||
primary: KeyMod.CtrlCmd | KeyCode.KEY_Z
|
||||
}
|
||||
}));
|
||||
|
||||
registerCommand(new EditorOrNativeTextInputCommand({
|
||||
editorHandler: H.Redo,
|
||||
inputHandler: 'redo',
|
||||
id: H.Redo,
|
||||
precondition: EditorContextKeys.writable,
|
||||
kbOpts: {
|
||||
weight: CORE_WEIGHT,
|
||||
kbExpr: EditorContextKeys.textFocus,
|
||||
primary: KeyMod.CtrlCmd | KeyCode.KEY_Y,
|
||||
secondary: [KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_Z],
|
||||
mac: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_Z }
|
||||
}
|
||||
}));
|
||||
|
||||
/**
|
||||
* A command that will invoke a command on the focused editor.
|
||||
*/
|
||||
@@ -1786,6 +1724,46 @@ class EditorHandlerCommand extends Command {
|
||||
}
|
||||
}
|
||||
|
||||
registerCommand(new EditorOrNativeTextInputCommand({
|
||||
editorHandler: CoreNavigationCommands.SelectAll,
|
||||
inputHandler: 'selectAll',
|
||||
id: 'editor.action.selectAll',
|
||||
precondition: null,
|
||||
kbOpts: {
|
||||
weight: CORE_WEIGHT,
|
||||
kbExpr: null,
|
||||
primary: KeyMod.CtrlCmd | KeyCode.KEY_A
|
||||
}
|
||||
}));
|
||||
|
||||
registerCommand(new EditorOrNativeTextInputCommand({
|
||||
editorHandler: H.Undo,
|
||||
inputHandler: 'undo',
|
||||
id: H.Undo,
|
||||
precondition: EditorContextKeys.writable,
|
||||
kbOpts: {
|
||||
weight: CORE_WEIGHT,
|
||||
kbExpr: EditorContextKeys.textFocus,
|
||||
primary: KeyMod.CtrlCmd | KeyCode.KEY_Z
|
||||
}
|
||||
}));
|
||||
registerCommand(new EditorHandlerCommand('default:' + H.Undo, H.Undo));
|
||||
|
||||
registerCommand(new EditorOrNativeTextInputCommand({
|
||||
editorHandler: H.Redo,
|
||||
inputHandler: 'redo',
|
||||
id: H.Redo,
|
||||
precondition: EditorContextKeys.writable,
|
||||
kbOpts: {
|
||||
weight: CORE_WEIGHT,
|
||||
kbExpr: EditorContextKeys.textFocus,
|
||||
primary: KeyMod.CtrlCmd | KeyCode.KEY_Y,
|
||||
secondary: [KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_Z],
|
||||
mac: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_Z }
|
||||
}
|
||||
}));
|
||||
registerCommand(new EditorHandlerCommand('default:' + H.Redo, H.Redo));
|
||||
|
||||
function registerOverwritableCommand(handlerId: string): void {
|
||||
registerCommand(new EditorHandlerCommand('default:' + handlerId, handlerId));
|
||||
registerCommand(new EditorHandlerCommand(handlerId, handlerId));
|
||||
|
||||
@@ -364,7 +364,7 @@ abstract class BareHitTestRequest {
|
||||
|
||||
this.mouseVerticalOffset = Math.max(0, ctx.getCurrentScrollTop() + pos.y - editorPos.y);
|
||||
this.mouseContentHorizontalOffset = ctx.getCurrentScrollLeft() + pos.x - editorPos.x - ctx.layoutInfo.contentLeft;
|
||||
this.isInMarginArea = (pos.x - editorPos.x < ctx.layoutInfo.contentLeft);
|
||||
this.isInMarginArea = (pos.x - editorPos.x < ctx.layoutInfo.contentLeft && pos.x - editorPos.x >= ctx.layoutInfo.glyphMarginLeft);
|
||||
this.isInContentArea = !this.isInMarginArea;
|
||||
this.mouseColumn = Math.max(0, MouseTargetFactory._getMouseColumn(this.mouseContentHorizontalOffset, ctx.typicalHalfwidthCharacterWidth));
|
||||
}
|
||||
@@ -587,6 +587,8 @@ export class MouseTargetFactory {
|
||||
offsetX: offset
|
||||
};
|
||||
|
||||
offset -= ctx.layoutInfo.glyphMarginLeft;
|
||||
|
||||
if (offset <= ctx.layoutInfo.glyphMarginWidth) {
|
||||
// On the glyph margin
|
||||
return request.fulfill(MouseTargetType.GUTTER_GLYPH_MARGIN, pos, res.range, detail);
|
||||
@@ -694,7 +696,7 @@ export class MouseTargetFactory {
|
||||
return request.fulfill(MouseTargetType.CONTENT_EMPTY, pos, void 0, EMPTY_CONTENT_IN_LINES);
|
||||
}
|
||||
|
||||
let visibleRange = ctx.visibleRangeForPosition2(lineNumber, column);
|
||||
const visibleRange = ctx.visibleRangeForPosition2(lineNumber, column);
|
||||
|
||||
if (!visibleRange) {
|
||||
return request.fulfill(MouseTargetType.UNKNOWN, pos);
|
||||
@@ -706,33 +708,35 @@ export class MouseTargetFactory {
|
||||
return request.fulfill(MouseTargetType.CONTENT_TEXT, pos);
|
||||
}
|
||||
|
||||
let mouseIsBetween: boolean;
|
||||
// Let's define a, b, c and check if the offset is in between them...
|
||||
interface OffsetColumn { offset: number; column: number; }
|
||||
|
||||
let points: OffsetColumn[] = [];
|
||||
points.push({ offset: visibleRange.left, column: column });
|
||||
if (column > 1) {
|
||||
let prevColumnHorizontalOffset = visibleRange.left;
|
||||
mouseIsBetween = false;
|
||||
mouseIsBetween = mouseIsBetween || (prevColumnHorizontalOffset < request.mouseContentHorizontalOffset && request.mouseContentHorizontalOffset < columnHorizontalOffset); // LTR case
|
||||
mouseIsBetween = mouseIsBetween || (columnHorizontalOffset < request.mouseContentHorizontalOffset && request.mouseContentHorizontalOffset < prevColumnHorizontalOffset); // RTL case
|
||||
if (mouseIsBetween) {
|
||||
let rng = new EditorRange(lineNumber, column, lineNumber, column - 1);
|
||||
const visibleRange = ctx.visibleRangeForPosition2(lineNumber, column - 1);
|
||||
if (visibleRange) {
|
||||
points.push({ offset: visibleRange.left, column: column - 1 });
|
||||
}
|
||||
}
|
||||
const lineMaxColumn = ctx.model.getLineMaxColumn(lineNumber);
|
||||
if (column < lineMaxColumn) {
|
||||
const visibleRange = ctx.visibleRangeForPosition2(lineNumber, column + 1);
|
||||
if (visibleRange) {
|
||||
points.push({ offset: visibleRange.left, column: column + 1 });
|
||||
}
|
||||
}
|
||||
|
||||
points.sort((a, b) => a.offset - b.offset);
|
||||
|
||||
for (let i = 1; i < points.length; i++) {
|
||||
const prev = points[i - 1];
|
||||
const curr = points[i];
|
||||
if (prev.offset <= request.mouseContentHorizontalOffset && request.mouseContentHorizontalOffset <= curr.offset) {
|
||||
const rng = new EditorRange(lineNumber, prev.column, lineNumber, curr.column);
|
||||
return request.fulfill(MouseTargetType.CONTENT_TEXT, pos, rng);
|
||||
}
|
||||
}
|
||||
|
||||
let lineMaxColumn = ctx.model.getLineMaxColumn(lineNumber);
|
||||
if (column < lineMaxColumn) {
|
||||
let nextColumnVisibleRange = ctx.visibleRangeForPosition2(lineNumber, column + 1);
|
||||
if (nextColumnVisibleRange) {
|
||||
let nextColumnHorizontalOffset = nextColumnVisibleRange.left;
|
||||
mouseIsBetween = false;
|
||||
mouseIsBetween = mouseIsBetween || (columnHorizontalOffset < request.mouseContentHorizontalOffset && request.mouseContentHorizontalOffset < nextColumnHorizontalOffset); // LTR case
|
||||
mouseIsBetween = mouseIsBetween || (nextColumnHorizontalOffset < request.mouseContentHorizontalOffset && request.mouseContentHorizontalOffset < columnHorizontalOffset); // RTL case
|
||||
if (mouseIsBetween) {
|
||||
let rng = new EditorRange(lineNumber, column, lineNumber, column + 1);
|
||||
return request.fulfill(MouseTargetType.CONTENT_TEXT, pos, rng);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return request.fulfill(MouseTargetType.CONTENT_TEXT, pos);
|
||||
}
|
||||
|
||||
@@ -940,4 +944,4 @@ export class MouseTargetFactory {
|
||||
hitTarget: null
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,13 +19,14 @@ import { HorizontalRange, RenderingContext, RestrictedRenderingContext } from 'v
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { ViewController } from 'vs/editor/browser/view/viewController';
|
||||
import { EndOfLinePreference, ScrollType } from 'vs/editor/common/editorCommon';
|
||||
import { ScrollType } from 'vs/editor/common/editorCommon';
|
||||
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { PartFingerprints, PartFingerprint, ViewPart } from 'vs/editor/browser/view/viewPart';
|
||||
import { Margin } from 'vs/editor/browser/viewParts/margin/margin';
|
||||
import { LineNumbersOverlay } from 'vs/editor/browser/viewParts/lineNumbers/lineNumbers';
|
||||
import { BareFontInfo } from 'vs/editor/common/config/fontInfo';
|
||||
import { RenderLineNumbersType } from 'vs/editor/common/config/editorOptions';
|
||||
import { EndOfLinePreference } from 'vs/editor/common/model';
|
||||
|
||||
export interface ITextAreaHandlerHelper {
|
||||
visibleRangeForPositionRelativeToEditor(lineNumber: number, column: number): HorizontalRange;
|
||||
@@ -51,6 +52,40 @@ class VisibleTextAreaData {
|
||||
|
||||
const canUseZeroSizeTextarea = (browser.isEdgeOrIE || browser.isFirefox);
|
||||
|
||||
interface LocalClipboardMetadata {
|
||||
lastCopiedValue: string;
|
||||
isFromEmptySelection: boolean;
|
||||
multicursorText: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Every time we write to the clipboard, we record a bit of extra metadata here.
|
||||
* Every time we read from the cipboard, if the text matches our last written text,
|
||||
* we can fetch the previous metadata.
|
||||
*/
|
||||
class LocalClipboardMetadataManager {
|
||||
public static INSTANCE = new LocalClipboardMetadataManager();
|
||||
|
||||
private _lastState: LocalClipboardMetadata;
|
||||
|
||||
constructor() {
|
||||
this._lastState = null;
|
||||
}
|
||||
|
||||
public set(state: LocalClipboardMetadata): void {
|
||||
this._lastState = state;
|
||||
}
|
||||
|
||||
public get(pastedText: string): LocalClipboardMetadata {
|
||||
if (this._lastState && this._lastState.lastCopiedValue === pastedText) {
|
||||
// match!
|
||||
return this._lastState;
|
||||
}
|
||||
this._lastState = null;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export class TextAreaHandler extends ViewPart {
|
||||
|
||||
private readonly _viewController: ViewController;
|
||||
@@ -70,8 +105,6 @@ export class TextAreaHandler extends ViewPart {
|
||||
*/
|
||||
private _visibleTextArea: VisibleTextAreaData;
|
||||
private _selections: Selection[];
|
||||
private _lastCopiedValue: string;
|
||||
private _lastCopiedValueIsFromEmptySelection: boolean;
|
||||
|
||||
public readonly textArea: FastDomNode<HTMLTextAreaElement>;
|
||||
public readonly textAreaCover: FastDomNode<HTMLElement>;
|
||||
@@ -97,8 +130,6 @@ export class TextAreaHandler extends ViewPart {
|
||||
|
||||
this._visibleTextArea = null;
|
||||
this._selections = [new Selection(1, 1, 1, 1)];
|
||||
this._lastCopiedValue = null;
|
||||
this._lastCopiedValueIsFromEmptySelection = false;
|
||||
|
||||
// Text Area (The focus will always be in the textarea when the cursor is blinking)
|
||||
this.textArea = createFastDomNode(document.createElement('textarea'));
|
||||
@@ -132,21 +163,29 @@ export class TextAreaHandler extends ViewPart {
|
||||
|
||||
const textAreaInputHost: ITextAreaInputHost = {
|
||||
getPlainTextToCopy: (): string => {
|
||||
const whatToCopy = this._context.model.getPlainTextToCopy(this._selections, this._emptySelectionClipboard);
|
||||
const rawWhatToCopy = this._context.model.getPlainTextToCopy(this._selections, this._emptySelectionClipboard);
|
||||
const newLineCharacter = this._context.model.getEOL();
|
||||
|
||||
if (this._emptySelectionClipboard) {
|
||||
if (browser.isFirefox) {
|
||||
// When writing "LINE\r\n" to the clipboard and then pasting,
|
||||
// Firefox pastes "LINE\n", so let's work around this quirk
|
||||
this._lastCopiedValue = whatToCopy.replace(/\r\n/g, '\n');
|
||||
} else {
|
||||
this._lastCopiedValue = whatToCopy;
|
||||
}
|
||||
const isFromEmptySelection = (this._emptySelectionClipboard && this._selections.length === 1 && this._selections[0].isEmpty());
|
||||
const multicursorText = (Array.isArray(rawWhatToCopy) ? rawWhatToCopy : null);
|
||||
const whatToCopy = (Array.isArray(rawWhatToCopy) ? rawWhatToCopy.join(newLineCharacter) : rawWhatToCopy);
|
||||
|
||||
let selections = this._selections;
|
||||
this._lastCopiedValueIsFromEmptySelection = (selections.length === 1 && selections[0].isEmpty());
|
||||
let metadata: LocalClipboardMetadata = null;
|
||||
if (isFromEmptySelection || multicursorText) {
|
||||
// Only store the non-default metadata
|
||||
|
||||
// When writing "LINE\r\n" to the clipboard and then pasting,
|
||||
// Firefox pastes "LINE\n", so let's work around this quirk
|
||||
const lastCopiedValue = (browser.isFirefox ? whatToCopy.replace(/\r\n/g, '\n') : whatToCopy);
|
||||
metadata = {
|
||||
lastCopiedValue: lastCopiedValue,
|
||||
isFromEmptySelection: (this._emptySelectionClipboard && this._selections.length === 1 && this._selections[0].isEmpty()),
|
||||
multicursorText: multicursorText
|
||||
};
|
||||
}
|
||||
|
||||
LocalClipboardMetadataManager.INSTANCE.set(metadata);
|
||||
|
||||
return whatToCopy;
|
||||
},
|
||||
|
||||
@@ -199,11 +238,15 @@ export class TextAreaHandler extends ViewPart {
|
||||
}));
|
||||
|
||||
this._register(this._textAreaInput.onPaste((e: IPasteData) => {
|
||||
const metadata = LocalClipboardMetadataManager.INSTANCE.get(e.text);
|
||||
|
||||
let pasteOnNewLine = false;
|
||||
if (this._emptySelectionClipboard) {
|
||||
pasteOnNewLine = (e.text === this._lastCopiedValue && this._lastCopiedValueIsFromEmptySelection);
|
||||
let multicursorText: string[] = null;
|
||||
if (metadata) {
|
||||
pasteOnNewLine = (this._emptySelectionClipboard && metadata.isFromEmptySelection);
|
||||
multicursorText = metadata.multicursorText;
|
||||
}
|
||||
this._viewController.paste('keyboard', e.text, pasteOnNewLine);
|
||||
this._viewController.paste('keyboard', e.text, pasteOnNewLine, multicursorText);
|
||||
}));
|
||||
|
||||
this._register(this._textAreaInput.onCut(() => {
|
||||
|
||||
@@ -558,6 +558,10 @@ class TextAreaWrapper extends Disposable implements ITextAreaWrapper {
|
||||
|
||||
if (currentIsFocused && currentSelectionStart === selectionStart && currentSelectionEnd === selectionEnd) {
|
||||
// No change
|
||||
// Firefox iframe bug https://github.com/Microsoft/monaco-editor/issues/643#issuecomment-367871377
|
||||
if (browser.isFirefox && window.parent !== window) {
|
||||
textArea.focus();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -567,6 +571,9 @@ class TextAreaWrapper extends Disposable implements ITextAreaWrapper {
|
||||
// No need to focus, only need to change the selection range
|
||||
this.setIgnoreSelectionChangeTime('setSelectionRange');
|
||||
textArea.setSelectionRange(selectionStart, selectionEnd);
|
||||
if (browser.isFirefox && window.parent !== window) {
|
||||
textArea.focus();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { EndOfLinePreference } from 'vs/editor/common/editorCommon';
|
||||
import { EndOfLinePreference } from 'vs/editor/common/model';
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
|
||||
export interface ITextAreaWrapper {
|
||||
|
||||
@@ -30,7 +30,7 @@ export class EditorState {
|
||||
this.flags = flags;
|
||||
|
||||
if ((this.flags & CodeEditorStateFlag.Value) !== 0) {
|
||||
var model = editor.getModel();
|
||||
let model = editor.getModel();
|
||||
this.modelVersionId = model ? strings.format('{0}#{1}', model.uri.toString(), model.getVersionId()) : null;
|
||||
}
|
||||
if ((this.flags & CodeEditorStateFlag.Position) !== 0) {
|
||||
@@ -50,7 +50,7 @@ export class EditorState {
|
||||
if (!(other instanceof EditorState)) {
|
||||
return false;
|
||||
}
|
||||
var state = <EditorState>other;
|
||||
let state = <EditorState>other;
|
||||
|
||||
if (this.modelVersionId !== state.modelVersionId) {
|
||||
return false;
|
||||
|
||||
@@ -18,6 +18,7 @@ import { ICursorPositionChangedEvent, ICursorSelectionChangedEvent } from 'vs/ed
|
||||
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ICursors, CursorConfiguration } from 'vs/editor/common/controller/cursorCommon';
|
||||
import { IEditorWhitespace } from 'vs/editor/common/viewLayout/whitespaceComputer';
|
||||
import { ITextModel, IIdentifiedSingleEditOperation, IModelDecoration, IModelDeltaDecoration } from 'vs/editor/common/model';
|
||||
|
||||
/**
|
||||
* A view zone is a full horizontal rectangle that 'pushes' text down.
|
||||
@@ -480,7 +481,7 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
||||
/**
|
||||
* Type the getModel() of IEditor.
|
||||
*/
|
||||
getModel(): editorCommon.IModel;
|
||||
getModel(): ITextModel;
|
||||
|
||||
/**
|
||||
* Returns the current editor's configuration
|
||||
@@ -495,13 +496,13 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
||||
|
||||
/**
|
||||
* Get value of the current model attached to this editor.
|
||||
* @see IModel.getValue
|
||||
* @see `ITextModel.getValue`
|
||||
*/
|
||||
getValue(options?: { preserveBOM: boolean; lineEnding: string; }): string;
|
||||
|
||||
/**
|
||||
* Set the value of the current model attached to this editor.
|
||||
* @see IModel.setValue
|
||||
* @see `ITextModel.setValue`
|
||||
*/
|
||||
setValue(newValue: string): void;
|
||||
|
||||
@@ -563,7 +564,7 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
||||
* @param edits The edits to execute.
|
||||
* @param endCursoState Cursor state after the edits were applied.
|
||||
*/
|
||||
executeEdits(source: string, edits: editorCommon.IIdentifiedSingleEditOperation[], endCursoState?: Selection[]): boolean;
|
||||
executeEdits(source: string, edits: IIdentifiedSingleEditOperation[], endCursoState?: Selection[]): boolean;
|
||||
|
||||
/**
|
||||
* Execute multiple (concommitent) commands on the editor.
|
||||
@@ -585,13 +586,13 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
||||
/**
|
||||
* Get all the decorations on a line (filtering out decorations from other editors).
|
||||
*/
|
||||
getLineDecorations(lineNumber: number): editorCommon.IModelDecoration[];
|
||||
getLineDecorations(lineNumber: number): IModelDecoration[];
|
||||
|
||||
/**
|
||||
* All decorations added through this call will get the ownerId of this editor.
|
||||
* @see IModel.deltaDecorations
|
||||
* @see `ITextModel.deltaDecorations`
|
||||
*/
|
||||
deltaDecorations(oldDecorations: string[], newDecorations: editorCommon.IModelDeltaDecoration[]): string[];
|
||||
deltaDecorations(oldDecorations: string[], newDecorations: IModelDeltaDecoration[]): string[];
|
||||
|
||||
/**
|
||||
* @internal
|
||||
@@ -618,6 +619,12 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
||||
*/
|
||||
getCenteredRangeInViewport(): Range;
|
||||
|
||||
/**
|
||||
* Returns the ranges that are currently visible.
|
||||
* Does not account for horizontal scrolling.
|
||||
*/
|
||||
getVisibleRanges(): Range[];
|
||||
|
||||
/**
|
||||
* Get the view zones.
|
||||
* @internal
|
||||
|
||||
@@ -20,6 +20,7 @@ import { IEditorService } from 'vs/platform/editor/common/editor';
|
||||
import { IContextKeyService, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { ICodeEditorService, getCodeEditor } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
|
||||
export type ServicesAccessor = ServicesAccessor;
|
||||
export type IEditorContributionCtor = IConstructorSignature1<ICodeEditor, editorCommon.IEditorContribution>;
|
||||
@@ -30,14 +31,12 @@ export interface ICommandKeybindingsOptions extends IKeybindings {
|
||||
kbExpr?: ContextKeyExpr;
|
||||
weight?: number;
|
||||
}
|
||||
|
||||
export interface ICommandOptions {
|
||||
id: string;
|
||||
precondition: ContextKeyExpr;
|
||||
kbOpts?: ICommandKeybindingsOptions;
|
||||
description?: ICommandHandlerDescription;
|
||||
}
|
||||
|
||||
export abstract class Command {
|
||||
public readonly id: string;
|
||||
public readonly precondition: ContextKeyExpr;
|
||||
@@ -224,7 +223,7 @@ export function registerLanguageCommand(id: string, handler: (accessor: Services
|
||||
CommandsRegistry.registerCommand(id, (accessor, args) => handler(accessor, args || {}));
|
||||
}
|
||||
|
||||
export function registerDefaultLanguageCommand(id: string, handler: (model: editorCommon.IModel, position: Position, args: { [n: string]: any }) => any) {
|
||||
export function registerDefaultLanguageCommand(id: string, handler: (model: ITextModel, position: Position, args: { [n: string]: any }) => any) {
|
||||
registerLanguageCommand(id, function (accessor, args) {
|
||||
|
||||
const { resource, position } = args;
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
'use strict';
|
||||
|
||||
import Event, { Emitter } from 'vs/base/common/event';
|
||||
import { IDecorationRenderOptions, IModelDecorationOptions, IModel } from 'vs/editor/common/editorCommon';
|
||||
import { IDecorationRenderOptions } from 'vs/editor/common/editorCommon';
|
||||
import { IModelDecorationOptions, ITextModel } from 'vs/editor/common/model';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { ICodeEditor, IDiffEditor } from 'vs/editor/browser/editorBrowser';
|
||||
|
||||
@@ -102,7 +103,7 @@ export abstract class AbstractCodeEditorService implements ICodeEditorService {
|
||||
|
||||
private _transientWatchers: { [uri: string]: ModelTransientSettingWatcher; } = {};
|
||||
|
||||
public setTransientModelProperty(model: IModel, key: string, value: any): void {
|
||||
public setTransientModelProperty(model: ITextModel, key: string, value: any): void {
|
||||
const uri = model.uri.toString();
|
||||
|
||||
let w: ModelTransientSettingWatcher;
|
||||
@@ -116,7 +117,7 @@ export abstract class AbstractCodeEditorService implements ICodeEditorService {
|
||||
w.set(key, value);
|
||||
}
|
||||
|
||||
public getTransientModelProperty(model: IModel, key: string): any {
|
||||
public getTransientModelProperty(model: ITextModel, key: string): any {
|
||||
const uri = model.uri.toString();
|
||||
|
||||
if (!this._transientWatchers.hasOwnProperty(uri)) {
|
||||
@@ -135,7 +136,7 @@ export class ModelTransientSettingWatcher {
|
||||
public readonly uri: string;
|
||||
private readonly _values: { [key: string]: any; };
|
||||
|
||||
constructor(uri: string, model: IModel, owner: AbstractCodeEditorService) {
|
||||
constructor(uri: string, model: ITextModel, owner: AbstractCodeEditorService) {
|
||||
this.uri = uri;
|
||||
this._values = {};
|
||||
model.onWillDispose(() => owner._removeWatcher(this));
|
||||
|
||||
@@ -5,75 +5,55 @@
|
||||
'use strict';
|
||||
|
||||
import * as nls from 'vs/nls';
|
||||
import { flatten } from 'vs/base/common/arrays';
|
||||
import { IStringDictionary, forEach, values, groupBy, size } from 'vs/base/common/collections';
|
||||
import { IDisposable, dispose, IReference } from 'vs/base/common/lifecycle';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { ITextModelService, ITextEditorModel } from 'vs/editor/common/services/resolverService';
|
||||
import { IFileService, IFileChange } from 'vs/platform/files/common/files';
|
||||
import { IFileService, FileChangeType } from 'vs/platform/files/common/files';
|
||||
import { EditOperation } from 'vs/editor/common/core/editOperation';
|
||||
import { Range, IRange } from 'vs/editor/common/core/range';
|
||||
import { Selection, ISelection } from 'vs/editor/common/core/selection';
|
||||
import { IIdentifiedSingleEditOperation, IModel, EndOfLineSequence } from 'vs/editor/common/editorCommon';
|
||||
import { IProgressRunner } from 'vs/platform/progress/common/progress';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import { IIdentifiedSingleEditOperation, ITextModel, EndOfLineSequence } from 'vs/editor/common/model';
|
||||
import { IProgressRunner, emptyProgressRunner, IProgress } from 'vs/platform/progress/common/progress';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { optional } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ResourceTextEdit, ResourceFileEdit, isResourceFileEdit, isResourceTextEdit } from 'vs/editor/common/modes';
|
||||
import { getPathLabel } from 'vs/base/common/labels';
|
||||
|
||||
export interface IResourceEdit {
|
||||
resource: URI;
|
||||
range?: IRange;
|
||||
newText: string;
|
||||
newEol?: EndOfLineSequence;
|
||||
}
|
||||
|
||||
interface IRecording {
|
||||
stop(): void;
|
||||
hasChanged(resource: URI): boolean;
|
||||
allChanges(): IFileChange[];
|
||||
}
|
||||
abstract class IRecording {
|
||||
|
||||
class ChangeRecorder {
|
||||
|
||||
private _fileService: IFileService;
|
||||
|
||||
constructor(fileService?: IFileService) {
|
||||
this._fileService = fileService;
|
||||
}
|
||||
|
||||
public start(): IRecording {
|
||||
|
||||
const changes: IStringDictionary<IFileChange[]> = Object.create(null);
|
||||
static start(fileService: IFileService): IRecording {
|
||||
|
||||
const _changes = new Set<string>();
|
||||
let stop: IDisposable;
|
||||
if (this._fileService) {
|
||||
stop = this._fileService.onFileChanges((event) => {
|
||||
event.changes.forEach(change => {
|
||||
|
||||
const key = String(change.resource);
|
||||
let array = changes[key];
|
||||
|
||||
if (!array) {
|
||||
changes[key] = array = [];
|
||||
if (fileService) {
|
||||
// watch only when there is a fileservice available
|
||||
stop = fileService.onFileChanges(event => {
|
||||
for (const change of event.changes) {
|
||||
if (change.type === FileChangeType.UPDATED) {
|
||||
_changes.add(change.resource.toString());
|
||||
}
|
||||
|
||||
array.push(change);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
stop: () => { return stop && stop.dispose(); },
|
||||
hasChanged: (resource: URI) => !!changes[resource.toString()],
|
||||
allChanges: () => flatten(values(changes))
|
||||
stop() { return dispose(stop); },
|
||||
hasChanged(resource) { return _changes.has(resource.toString()); }
|
||||
};
|
||||
}
|
||||
|
||||
abstract stop(): void;
|
||||
abstract hasChanged(resource: URI): boolean;
|
||||
}
|
||||
|
||||
class EditTask implements IDisposable {
|
||||
|
||||
private _initialSelections: Selection[];
|
||||
private _endCursorSelection: Selection;
|
||||
private get _model(): IModel { return this._modelReference.object.textEditorModel; }
|
||||
private get _model(): ITextModel { return this._modelReference.object.textEditorModel; }
|
||||
private _modelReference: IReference<ITextEditorModel>;
|
||||
private _edits: IIdentifiedSingleEditOperation[];
|
||||
private _newEol: EndOfLineSequence;
|
||||
@@ -84,26 +64,34 @@ class EditTask implements IDisposable {
|
||||
this._edits = [];
|
||||
}
|
||||
|
||||
public addEdit(edit: IResourceEdit): void {
|
||||
|
||||
if (typeof edit.newEol === 'number') {
|
||||
// honor eol-change
|
||||
this._newEol = edit.newEol;
|
||||
}
|
||||
|
||||
if (edit.range || edit.newText) {
|
||||
// create edit operation
|
||||
let range: Range;
|
||||
if (!edit.range) {
|
||||
range = this._model.getFullModelRange();
|
||||
} else {
|
||||
range = Range.lift(edit.range);
|
||||
}
|
||||
this._edits.push(EditOperation.replaceMove(range, edit.newText));
|
||||
dispose() {
|
||||
if (this._model) {
|
||||
this._modelReference.dispose();
|
||||
this._modelReference = null;
|
||||
}
|
||||
}
|
||||
|
||||
public apply(): void {
|
||||
addEdit(resourceEdit: ResourceTextEdit): void {
|
||||
|
||||
for (const edit of resourceEdit.edits) {
|
||||
if (typeof edit.eol === 'number') {
|
||||
// honor eol-change
|
||||
this._newEol = edit.eol;
|
||||
}
|
||||
if (edit.range || edit.text) {
|
||||
// create edit operation
|
||||
let range: Range;
|
||||
if (!edit.range) {
|
||||
range = this._model.getFullModelRange();
|
||||
} else {
|
||||
range = Range.lift(edit.range);
|
||||
}
|
||||
this._edits.push(EditOperation.replaceMove(range, edit.text));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
apply(): void {
|
||||
if (this._edits.length > 0) {
|
||||
|
||||
this._edits = this._edits.map((value, index) => ({ value, index })).sort((a, b) => {
|
||||
@@ -160,16 +148,10 @@ class EditTask implements IDisposable {
|
||||
return [this._endCursorSelection];
|
||||
}
|
||||
|
||||
public getEndCursorSelection(): Selection {
|
||||
getEndCursorSelection(): Selection {
|
||||
return this._endCursorSelection;
|
||||
}
|
||||
|
||||
dispose() {
|
||||
if (this._model) {
|
||||
this._modelReference.dispose();
|
||||
this._modelReference = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SourceModelEditTask extends EditTask {
|
||||
@@ -189,34 +171,42 @@ class SourceModelEditTask extends EditTask {
|
||||
class BulkEditModel implements IDisposable {
|
||||
|
||||
private _textModelResolverService: ITextModelService;
|
||||
private _numberOfResourcesToModify: number = 0;
|
||||
private _edits: IStringDictionary<IResourceEdit[]> = Object.create(null);
|
||||
private _edits = new Map<string, ResourceTextEdit[]>();
|
||||
private _tasks: EditTask[];
|
||||
private _sourceModel: URI;
|
||||
private _sourceSelections: Selection[];
|
||||
private _sourceModelTask: SourceModelEditTask;
|
||||
private _progress: IProgress<void>;
|
||||
|
||||
constructor(textModelResolverService: ITextModelService, sourceModel: URI, sourceSelections: Selection[], edits: IResourceEdit[], private progress: IProgressRunner = null) {
|
||||
constructor(
|
||||
textModelResolverService: ITextModelService,
|
||||
editor: ICodeEditor,
|
||||
edits: ResourceTextEdit[],
|
||||
progress: IProgress<void>
|
||||
) {
|
||||
this._textModelResolverService = textModelResolverService;
|
||||
this._sourceModel = sourceModel;
|
||||
this._sourceSelections = sourceSelections;
|
||||
this._sourceModelTask = null;
|
||||
this._sourceModel = editor ? editor.getModel().uri : undefined;
|
||||
this._sourceSelections = editor ? editor.getSelections() : undefined;
|
||||
this._sourceModelTask = undefined;
|
||||
this._progress = progress;
|
||||
|
||||
for (let edit of edits) {
|
||||
this._addEdit(edit);
|
||||
}
|
||||
edits.forEach(this.addEdit, this);
|
||||
}
|
||||
|
||||
private _addEdit(edit: IResourceEdit): void {
|
||||
let array = this._edits[edit.resource.toString()];
|
||||
dispose(): void {
|
||||
this._tasks = dispose(this._tasks);
|
||||
}
|
||||
|
||||
addEdit(edit: ResourceTextEdit): void {
|
||||
let array = this._edits.get(edit.resource.toString());
|
||||
if (!array) {
|
||||
this._edits[edit.resource.toString()] = array = [];
|
||||
this._numberOfResourcesToModify += 1;
|
||||
array = [];
|
||||
this._edits.set(edit.resource.toString(), array);
|
||||
}
|
||||
array.push(edit);
|
||||
}
|
||||
|
||||
public prepare(): TPromise<BulkEditModel> {
|
||||
async prepare(): TPromise<BulkEditModel> {
|
||||
|
||||
if (this._tasks) {
|
||||
throw new Error('illegal state - already prepared');
|
||||
@@ -225,145 +215,80 @@ class BulkEditModel implements IDisposable {
|
||||
this._tasks = [];
|
||||
const promises: TPromise<any>[] = [];
|
||||
|
||||
if (this.progress) {
|
||||
this.progress.total(this._numberOfResourcesToModify * 2);
|
||||
}
|
||||
|
||||
forEach(this._edits, entry => {
|
||||
const promise = this._textModelResolverService.createModelReference(URI.parse(entry.key)).then(ref => {
|
||||
this._edits.forEach((value, key) => {
|
||||
const promise = this._textModelResolverService.createModelReference(URI.parse(key)).then(ref => {
|
||||
const model = ref.object;
|
||||
|
||||
if (!model || !model.textEditorModel) {
|
||||
throw new Error(`Cannot load file ${entry.key}`);
|
||||
throw new Error(`Cannot load file ${key}`);
|
||||
}
|
||||
|
||||
const textEditorModel = model.textEditorModel;
|
||||
let task: EditTask;
|
||||
|
||||
if (this._sourceModel && textEditorModel.uri.toString() === this._sourceModel.toString()) {
|
||||
if (this._sourceModel && model.textEditorModel.uri.toString() === this._sourceModel.toString()) {
|
||||
this._sourceModelTask = new SourceModelEditTask(ref, this._sourceSelections);
|
||||
task = this._sourceModelTask;
|
||||
} else {
|
||||
task = new EditTask(ref);
|
||||
}
|
||||
|
||||
entry.value.forEach(edit => task.addEdit(edit));
|
||||
value.forEach(edit => task.addEdit(edit));
|
||||
this._tasks.push(task);
|
||||
if (this.progress) {
|
||||
this.progress.worked(1);
|
||||
}
|
||||
this._progress.report(undefined);
|
||||
});
|
||||
promises.push(promise);
|
||||
});
|
||||
|
||||
await TPromise.join(promises);
|
||||
|
||||
return TPromise.join(promises).then(_ => this);
|
||||
return this;
|
||||
}
|
||||
|
||||
public apply(): Selection {
|
||||
this._tasks.forEach(task => this.applyTask(task));
|
||||
let r: Selection = null;
|
||||
if (this._sourceModelTask) {
|
||||
r = this._sourceModelTask.getEndCursorSelection();
|
||||
apply(): Selection {
|
||||
for (const task of this._tasks) {
|
||||
task.apply();
|
||||
this._progress.report(undefined);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
private applyTask(task: EditTask): void {
|
||||
task.apply();
|
||||
if (this.progress) {
|
||||
this.progress.worked(1);
|
||||
}
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this._tasks = dispose(this._tasks);
|
||||
return this._sourceModelTask
|
||||
? this._sourceModelTask.getEndCursorSelection()
|
||||
: undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export interface BulkEdit {
|
||||
progress(progress: IProgressRunner): void;
|
||||
add(edit: IResourceEdit[]): void;
|
||||
finish(): TPromise<ISelection>;
|
||||
ariaMessage(): string;
|
||||
}
|
||||
export type Edit = ResourceFileEdit | ResourceTextEdit;
|
||||
|
||||
export function bulkEdit(textModelResolverService: ITextModelService, editor: ICodeEditor, edits: IResourceEdit[], fileService?: IFileService, progress: IProgressRunner = null): TPromise<any> {
|
||||
let bulk = createBulkEdit(textModelResolverService, editor, fileService);
|
||||
bulk.add(edits);
|
||||
bulk.progress(progress);
|
||||
return bulk.finish();
|
||||
}
|
||||
export class BulkEdit {
|
||||
|
||||
export function createBulkEdit(textModelResolverService: ITextModelService, editor?: ICodeEditor, fileService?: IFileService): BulkEdit {
|
||||
|
||||
let all: IResourceEdit[] = [];
|
||||
let recording = new ChangeRecorder(fileService).start();
|
||||
let progressRunner: IProgressRunner;
|
||||
|
||||
function progress(progress: IProgressRunner) {
|
||||
progressRunner = progress;
|
||||
static perform(edits: Edit[], textModelService: ITextModelService, fileService: IFileService, editor: ICodeEditor): TPromise<any> {
|
||||
const edit = new BulkEdit(editor, null, textModelService, fileService);
|
||||
edit.add(edits);
|
||||
return edit.perform();
|
||||
}
|
||||
|
||||
function add(edits: IResourceEdit[]): void {
|
||||
all.push(...edits);
|
||||
private _edits: Edit[] = [];
|
||||
private _editor: ICodeEditor;
|
||||
private _progress: IProgressRunner;
|
||||
|
||||
constructor(
|
||||
editor: ICodeEditor,
|
||||
progress: IProgressRunner,
|
||||
@ITextModelService private readonly _textModelService: ITextModelService,
|
||||
@optional(IFileService) private _fileService: IFileService
|
||||
) {
|
||||
this._editor = editor;
|
||||
this._progress = progress || emptyProgressRunner;
|
||||
}
|
||||
|
||||
function getConcurrentEdits() {
|
||||
let names: string[];
|
||||
for (let edit of all) {
|
||||
if (recording.hasChanged(edit.resource)) {
|
||||
if (!names) {
|
||||
names = [];
|
||||
}
|
||||
names.push(edit.resource.fsPath);
|
||||
}
|
||||
add(edits: Edit[] | Edit): void {
|
||||
if (Array.isArray(edits)) {
|
||||
this._edits.push(...edits);
|
||||
} else {
|
||||
this._edits.push(edits);
|
||||
}
|
||||
if (names) {
|
||||
return nls.localize('conflict', "These files have changed in the meantime: {0}", names.join(', '));
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function finish(): TPromise<ISelection> {
|
||||
|
||||
if (all.length === 0) {
|
||||
return TPromise.as(undefined);
|
||||
}
|
||||
|
||||
let concurrentEdits = getConcurrentEdits();
|
||||
if (concurrentEdits) {
|
||||
return TPromise.wrapError<ISelection>(new Error(concurrentEdits));
|
||||
}
|
||||
|
||||
let uri: URI;
|
||||
let selections: Selection[];
|
||||
|
||||
if (editor && editor.getModel()) {
|
||||
uri = editor.getModel().uri;
|
||||
selections = editor.getSelections();
|
||||
}
|
||||
|
||||
const model = new BulkEditModel(textModelResolverService, uri, selections, all, progressRunner);
|
||||
|
||||
return model.prepare().then(_ => {
|
||||
|
||||
let concurrentEdits = getConcurrentEdits();
|
||||
if (concurrentEdits) {
|
||||
throw new Error(concurrentEdits);
|
||||
}
|
||||
|
||||
recording.stop();
|
||||
|
||||
const result = model.apply();
|
||||
model.dispose();
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
function ariaMessage(): string {
|
||||
let editCount = all.length;
|
||||
let resourceCount = size(groupBy(all, edit => edit.resource.toString()));
|
||||
ariaMessage(): string {
|
||||
const editCount = this._edits.reduce((prev, cur) => isResourceFileEdit(cur) ? prev : prev + cur.edits.length, 0);
|
||||
const resourceCount = this._edits.length;
|
||||
if (editCount === 0) {
|
||||
return nls.localize('summary.0', "Made no edits");
|
||||
} else if (editCount > 1 && resourceCount > 1) {
|
||||
@@ -373,10 +298,84 @@ export function createBulkEdit(textModelResolverService: ITextModelService, edit
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
progress,
|
||||
add,
|
||||
finish,
|
||||
ariaMessage
|
||||
};
|
||||
async perform(): TPromise<Selection> {
|
||||
|
||||
let seen = new Set<string>();
|
||||
let total = 0;
|
||||
|
||||
const groups: Edit[][] = [];
|
||||
let group: Edit[];
|
||||
for (const edit of this._edits) {
|
||||
if (!group
|
||||
|| (isResourceFileEdit(group[0]) && !isResourceFileEdit(edit))
|
||||
|| (isResourceTextEdit(group[0]) && !isResourceTextEdit(edit))
|
||||
) {
|
||||
group = [];
|
||||
groups.push(group);
|
||||
}
|
||||
group.push(edit);
|
||||
|
||||
if (isResourceFileEdit(edit)) {
|
||||
total += 1;
|
||||
} else if (!seen.has(edit.resource.toString())) {
|
||||
seen.add(edit.resource.toString());
|
||||
total += 2;
|
||||
}
|
||||
}
|
||||
|
||||
// define total work and progress callback
|
||||
// for child operations
|
||||
this._progress.total(total);
|
||||
let progress: IProgress<void> = { report: _ => this._progress.worked(1) };
|
||||
|
||||
// do it. return the last selection computed
|
||||
// by a text change (can be undefined then)
|
||||
let res: Selection = undefined;
|
||||
for (const group of groups) {
|
||||
if (isResourceFileEdit(group[0])) {
|
||||
await this._performFileEdits(<ResourceFileEdit[]>group, progress);
|
||||
} else {
|
||||
res = await this._performTextEdits(<ResourceTextEdit[]>group, progress) || res;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private async _performFileEdits(edits: ResourceFileEdit[], progress: IProgress<void>) {
|
||||
for (const edit of edits) {
|
||||
|
||||
progress.report(undefined);
|
||||
|
||||
if (edit.newUri && edit.oldUri) {
|
||||
await this._fileService.moveFile(edit.oldUri, edit.newUri, false);
|
||||
} else if (!edit.newUri && edit.oldUri) {
|
||||
await this._fileService.del(edit.oldUri, true);
|
||||
} else if (edit.newUri && !edit.oldUri) {
|
||||
await this._fileService.createFile(edit.newUri, undefined, { overwrite: false });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async _performTextEdits(edits: ResourceTextEdit[], progress: IProgress<void>): TPromise<Selection> {
|
||||
|
||||
const recording = IRecording.start(this._fileService);
|
||||
const model = new BulkEditModel(this._textModelService, this._editor, edits, progress);
|
||||
|
||||
await model.prepare();
|
||||
|
||||
const conflicts = edits
|
||||
.filter(edit => recording.hasChanged(edit.resource))
|
||||
.map(edit => getPathLabel(edit.resource));
|
||||
|
||||
recording.stop();
|
||||
|
||||
if (conflicts.length > 0) {
|
||||
model.dispose();
|
||||
throw new Error(nls.localize('conflict', "These files have changed in the meantime: {0}", conflicts.join(', ')));
|
||||
}
|
||||
|
||||
const selection = await model.apply();
|
||||
model.dispose();
|
||||
return selection;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
|
||||
import Event from 'vs/base/common/event';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IDecorationRenderOptions, IModelDecorationOptions, IModel } from 'vs/editor/common/editorCommon';
|
||||
import { IDecorationRenderOptions } from 'vs/editor/common/editorCommon';
|
||||
import { IModelDecorationOptions, ITextModel } from 'vs/editor/common/model';
|
||||
import { IEditor } from 'vs/platform/editor/common/editor';
|
||||
import { ICodeEditor, IDiffEditor, isCodeEditor, isDiffEditor } from 'vs/editor/browser/editorBrowser';
|
||||
|
||||
@@ -38,8 +39,8 @@ export interface ICodeEditorService {
|
||||
removeDecorationType(key: string): void;
|
||||
resolveDecorationOptions(typeKey: string, writable: boolean): IModelDecorationOptions;
|
||||
|
||||
setTransientModelProperty(model: IModel, key: string, value: any): void;
|
||||
getTransientModelProperty(model: IModel, key: string): any;
|
||||
setTransientModelProperty(model: ITextModel, key: string, value: any): void;
|
||||
getTransientModelProperty(model: ITextModel, key: string): any;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,10 +7,8 @@
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import {
|
||||
IDecorationRenderOptions, IModelDecorationOptions, IModelDecorationOverviewRulerOptions, IThemeDecorationRenderOptions,
|
||||
IContentDecorationRenderOptions, OverviewRulerLane, TrackedRangeStickiness, isThemeColor
|
||||
} from 'vs/editor/common/editorCommon';
|
||||
import { IDecorationRenderOptions, IThemeDecorationRenderOptions, IContentDecorationRenderOptions, isThemeColor } from 'vs/editor/common/editorCommon';
|
||||
import { IModelDecorationOptions, IModelDecorationOverviewRulerOptions, OverviewRulerLane, TrackedRangeStickiness } from 'vs/editor/common/model';
|
||||
import { AbstractCodeEditorService } from 'vs/editor/browser/services/abstractCodeEditorService';
|
||||
import { IDisposable, dispose as disposeAll } from 'vs/base/common/lifecycle';
|
||||
import { IThemeService, ITheme, ThemeColor } from 'vs/platform/theme/common/themeService';
|
||||
@@ -210,6 +208,8 @@ const _CSS_MAP = {
|
||||
borderStyle: 'border-style:{0};',
|
||||
borderWidth: 'border-width:{0};',
|
||||
|
||||
fontStyle: 'font-style:{0};',
|
||||
fontWeight: 'font-weight:{0};',
|
||||
textDecoration: 'text-decoration:{0};',
|
||||
cursor: 'cursor:{0};',
|
||||
letterSpacing: 'letter-spacing:{0};',
|
||||
@@ -357,7 +357,7 @@ class DecorationCSSRules {
|
||||
return '';
|
||||
}
|
||||
let cssTextArr: string[] = [];
|
||||
this.collectCSSText(opts, ['textDecoration', 'cursor', 'color', 'letterSpacing'], cssTextArr);
|
||||
this.collectCSSText(opts, ['fontStyle', 'fontWeight', 'textDecoration', 'cursor', 'color', 'letterSpacing'], cssTextArr);
|
||||
return cssTextArr.join('');
|
||||
}
|
||||
|
||||
@@ -372,10 +372,12 @@ class DecorationCSSRules {
|
||||
|
||||
if (typeof opts !== 'undefined') {
|
||||
this.collectBorderSettingsCSSText(opts, cssTextArr);
|
||||
if (typeof opts.contentIconPath === 'string') {
|
||||
cssTextArr.push(strings.format(_CSS_MAP.contentIconPath, URI.file(opts.contentIconPath).toString().replace(/'/g, '%27')));
|
||||
} else if (opts.contentIconPath instanceof URI) {
|
||||
cssTextArr.push(strings.format(_CSS_MAP.contentIconPath, opts.contentIconPath.toString(true).replace(/'/g, '%27')));
|
||||
if (typeof opts.contentIconPath !== 'undefined') {
|
||||
if (typeof opts.contentIconPath === 'string') {
|
||||
cssTextArr.push(strings.format(_CSS_MAP.contentIconPath, URI.file(opts.contentIconPath).toString().replace(/'/g, '%27')));
|
||||
} else {
|
||||
cssTextArr.push(strings.format(_CSS_MAP.contentIconPath, URI.revive(opts.contentIconPath).toString(true).replace(/'/g, '%27')));
|
||||
}
|
||||
}
|
||||
if (typeof opts.contentText === 'string') {
|
||||
const truncated = opts.contentText.match(/^.*$/m)[0]; // only take first line
|
||||
@@ -383,7 +385,7 @@ class DecorationCSSRules {
|
||||
|
||||
cssTextArr.push(strings.format(_CSS_MAP.contentText, escaped));
|
||||
}
|
||||
this.collectCSSText(opts, ['textDecoration', 'color', 'backgroundColor', 'margin'], cssTextArr);
|
||||
this.collectCSSText(opts, ['fontStyle', 'fontWeight', 'textDecoration', 'color', 'backgroundColor', 'margin'], cssTextArr);
|
||||
if (this.collectCSSText(opts, ['width', 'height'], cssTextArr)) {
|
||||
cssTextArr.push('display:inline-block;');
|
||||
}
|
||||
@@ -405,7 +407,7 @@ class DecorationCSSRules {
|
||||
if (typeof opts.gutterIconPath === 'string') {
|
||||
cssTextArr.push(strings.format(_CSS_MAP.gutterIconPath, URI.file(opts.gutterIconPath).toString()));
|
||||
} else {
|
||||
cssTextArr.push(strings.format(_CSS_MAP.gutterIconPath, opts.gutterIconPath.toString(true).replace(/'/g, '%27')));
|
||||
cssTextArr.push(strings.format(_CSS_MAP.gutterIconPath, URI.revive(opts.gutterIconPath).toString(true).replace(/'/g, '%27')));
|
||||
}
|
||||
if (typeof opts.gutterIconSize !== 'undefined') {
|
||||
cssTextArr.push(strings.format(_CSS_MAP.gutterIconSize, opts.gutterIconSize));
|
||||
|
||||
@@ -62,10 +62,11 @@ export class ViewController {
|
||||
this._execCoreEditorCommandFunc(editorCommand, args);
|
||||
}
|
||||
|
||||
public paste(source: string, text: string, pasteOnNewLine: boolean): void {
|
||||
public paste(source: string, text: string, pasteOnNewLine: boolean, multicursorText: string[]): void {
|
||||
this.commandService.executeCommand(editorCommon.Handler.Paste, {
|
||||
text: text,
|
||||
pasteOnNewLine: pasteOnNewLine,
|
||||
multicursorText: multicursorText
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -450,6 +450,13 @@ export class View extends ViewEventHandler {
|
||||
this._scrollbar.delegateVerticalScrollbarMouseDown(browserEvent);
|
||||
}
|
||||
|
||||
public restoreState(scrollPosition: { scrollLeft: number; scrollTop: number; }): void {
|
||||
this._context.viewLayout.setScrollPositionNow({ scrollTop: scrollPosition.scrollTop });
|
||||
this._renderNow();
|
||||
this.viewLines.updateLineWidths();
|
||||
this._context.viewLayout.setScrollPositionNow({ scrollLeft: scrollPosition.scrollLeft });
|
||||
}
|
||||
|
||||
public getOffsetForColumn(modelLineNumber: number, modelColumn: number): number {
|
||||
let modelPosition = this._context.model.validateModelPosition({
|
||||
lineNumber: modelLineNumber,
|
||||
@@ -472,8 +479,8 @@ export class View extends ViewEventHandler {
|
||||
return this.outgoingEvents;
|
||||
}
|
||||
|
||||
public createOverviewRuler(cssClassName: string, minimumHeight: number, maximumHeight: number): OverviewRuler {
|
||||
return new OverviewRuler(this._context, cssClassName, minimumHeight, maximumHeight);
|
||||
public createOverviewRuler(cssClassName: string): OverviewRuler {
|
||||
return new OverviewRuler(this._context, cssClassName);
|
||||
}
|
||||
|
||||
public change(callback: (changeAccessor: editorBrowser.IViewZoneChangeAccessor) => any): boolean {
|
||||
|
||||
@@ -80,7 +80,7 @@ export class RenderedLinesCollection<T extends ILine> {
|
||||
public getLine(lineNumber: number): T {
|
||||
let lineIndex = lineNumber - this._rendLineNumberStart;
|
||||
if (lineIndex < 0 || lineIndex >= this._lines.length) {
|
||||
throw new Error('Illegal value for lineNumber: ' + lineNumber);
|
||||
throw new Error('Illegal value for lineNumber');
|
||||
}
|
||||
return this._lines[lineIndex];
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ export class CurrentLineHighlightOverlay extends DynamicViewOverlay {
|
||||
private _lineHeight: number;
|
||||
private _renderLineHighlight: 'none' | 'gutter' | 'line' | 'all';
|
||||
private _selectionIsEmpty: boolean;
|
||||
private _primaryCursorIsInEditableRange: boolean;
|
||||
private _primaryCursorLineNumber: number;
|
||||
private _scrollWidth: number;
|
||||
private _contentWidth: number;
|
||||
@@ -30,7 +29,6 @@ export class CurrentLineHighlightOverlay extends DynamicViewOverlay {
|
||||
this._renderLineHighlight = this._context.configuration.editor.viewInfo.renderLineHighlight;
|
||||
|
||||
this._selectionIsEmpty = true;
|
||||
this._primaryCursorIsInEditableRange = true;
|
||||
this._primaryCursorLineNumber = 1;
|
||||
this._scrollWidth = 0;
|
||||
this._contentWidth = this._context.configuration.editor.layoutInfo.contentWidth;
|
||||
@@ -61,11 +59,6 @@ export class CurrentLineHighlightOverlay extends DynamicViewOverlay {
|
||||
public onCursorStateChanged(e: viewEvents.ViewCursorStateChangedEvent): boolean {
|
||||
let hasChanged = false;
|
||||
|
||||
if (this._primaryCursorIsInEditableRange !== e.isInEditableRange) {
|
||||
this._primaryCursorIsInEditableRange = e.isInEditableRange;
|
||||
hasChanged = true;
|
||||
}
|
||||
|
||||
const primaryCursorLineNumber = e.selections[0].positionLineNumber;
|
||||
if (this._primaryCursorLineNumber !== primaryCursorLineNumber) {
|
||||
this._primaryCursorLineNumber = primaryCursorLineNumber;
|
||||
@@ -127,14 +120,12 @@ export class CurrentLineHighlightOverlay extends DynamicViewOverlay {
|
||||
return (
|
||||
(this._renderLineHighlight === 'line' || this._renderLineHighlight === 'all')
|
||||
&& this._selectionIsEmpty
|
||||
&& this._primaryCursorIsInEditableRange
|
||||
);
|
||||
}
|
||||
|
||||
private _willRenderMarginCurrentLine(): boolean {
|
||||
return (
|
||||
(this._renderLineHighlight === 'gutter' || this._renderLineHighlight === 'all')
|
||||
&& this._primaryCursorIsInEditableRange
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.monaco-editor .margin-view-overlays .current-line-margin {
|
||||
.monaco-editor .margin-view-overlays .current-line {
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
@@ -11,6 +11,6 @@
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.monaco-editor .margin-view-overlays .current-line-margin.current-line-margin-both {
|
||||
.monaco-editor .margin-view-overlays .current-line.current-line-margin.current-line-margin-both {
|
||||
border-right: 0;
|
||||
}
|
||||
@@ -18,7 +18,6 @@ export class CurrentLineMarginHighlightOverlay extends DynamicViewOverlay {
|
||||
private _lineHeight: number;
|
||||
private _renderLineHighlight: 'none' | 'gutter' | 'line' | 'all';
|
||||
private _selectionIsEmpty: boolean;
|
||||
private _primaryCursorIsInEditableRange: boolean;
|
||||
private _primaryCursorLineNumber: number;
|
||||
private _contentLeft: number;
|
||||
|
||||
@@ -29,7 +28,6 @@ export class CurrentLineMarginHighlightOverlay extends DynamicViewOverlay {
|
||||
this._renderLineHighlight = this._context.configuration.editor.viewInfo.renderLineHighlight;
|
||||
|
||||
this._selectionIsEmpty = true;
|
||||
this._primaryCursorIsInEditableRange = true;
|
||||
this._primaryCursorLineNumber = 1;
|
||||
this._contentLeft = this._context.configuration.editor.layoutInfo.contentLeft;
|
||||
|
||||
@@ -59,11 +57,6 @@ export class CurrentLineMarginHighlightOverlay extends DynamicViewOverlay {
|
||||
public onCursorStateChanged(e: viewEvents.ViewCursorStateChangedEvent): boolean {
|
||||
let hasChanged = false;
|
||||
|
||||
if (this._primaryCursorIsInEditableRange !== e.isInEditableRange) {
|
||||
this._primaryCursorIsInEditableRange = e.isInEditableRange;
|
||||
hasChanged = true;
|
||||
}
|
||||
|
||||
const primaryCursorLineNumber = e.selections[0].positionLineNumber;
|
||||
if (this._primaryCursorLineNumber !== primaryCursorLineNumber) {
|
||||
this._primaryCursorLineNumber = primaryCursorLineNumber;
|
||||
@@ -98,21 +91,21 @@ export class CurrentLineMarginHighlightOverlay extends DynamicViewOverlay {
|
||||
|
||||
public render(startLineNumber: number, lineNumber: number): string {
|
||||
if (lineNumber === this._primaryCursorLineNumber) {
|
||||
let className = 'current-line';
|
||||
if (this._shouldShowCurrentLine()) {
|
||||
const paintedInContent = this._willRenderContentCurrentLine();
|
||||
const className = 'current-line-margin' + (paintedInContent ? ' current-line-margin-both' : '');
|
||||
return (
|
||||
'<div class="'
|
||||
+ className
|
||||
+ '" style="width:'
|
||||
+ String(this._contentLeft)
|
||||
+ 'px; height:'
|
||||
+ String(this._lineHeight)
|
||||
+ 'px;"></div>'
|
||||
);
|
||||
} else {
|
||||
return '';
|
||||
className = 'current-line current-line-margin' + (paintedInContent ? ' current-line-margin-both' : '');
|
||||
}
|
||||
|
||||
return (
|
||||
'<div class="'
|
||||
+ className
|
||||
+ '" style="width:'
|
||||
+ String(this._contentLeft)
|
||||
+ 'px; height:'
|
||||
+ String(this._lineHeight)
|
||||
+ 'px;"></div>'
|
||||
);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
@@ -120,7 +113,6 @@ export class CurrentLineMarginHighlightOverlay extends DynamicViewOverlay {
|
||||
private _shouldShowCurrentLine(): boolean {
|
||||
return (
|
||||
(this._renderLineHighlight === 'gutter' || this._renderLineHighlight === 'all')
|
||||
&& this._primaryCursorIsInEditableRange
|
||||
);
|
||||
}
|
||||
|
||||
@@ -128,7 +120,6 @@ export class CurrentLineMarginHighlightOverlay extends DynamicViewOverlay {
|
||||
return (
|
||||
(this._renderLineHighlight === 'line' || this._renderLineHighlight === 'all')
|
||||
&& this._selectionIsEmpty
|
||||
&& this._primaryCursorIsInEditableRange
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,7 +202,7 @@ export class DecorationsOverlay extends DynamicViewOverlay {
|
||||
}
|
||||
let lineIndex = lineNumber - startLineNumber;
|
||||
if (lineIndex < 0 || lineIndex >= this._renderResult.length) {
|
||||
throw new Error('Unexpected render request');
|
||||
return '';
|
||||
}
|
||||
return this._renderResult[lineIndex];
|
||||
}
|
||||
|
||||
@@ -99,7 +99,13 @@ export class EditorScrollbar extends ViewPart {
|
||||
const layoutInfo = this._context.configuration.editor.layoutInfo;
|
||||
|
||||
this.scrollbarDomNode.setLeft(layoutInfo.contentLeft);
|
||||
this.scrollbarDomNode.setWidth(layoutInfo.contentWidth + layoutInfo.minimapWidth);
|
||||
|
||||
const side = this._context.configuration.editor.viewInfo.minimap.side;
|
||||
if (side === 'right') {
|
||||
this.scrollbarDomNode.setWidth(layoutInfo.contentWidth + layoutInfo.minimapWidth);
|
||||
} else {
|
||||
this.scrollbarDomNode.setWidth(layoutInfo.contentWidth);
|
||||
}
|
||||
this.scrollbarDomNode.setHeight(layoutInfo.contentHeight);
|
||||
}
|
||||
|
||||
|
||||
@@ -193,8 +193,8 @@ export class GlyphMarginOverlay extends DedupOverlay {
|
||||
}
|
||||
let lineIndex = lineNumber - startLineNumber;
|
||||
if (lineIndex < 0 || lineIndex >= this._renderResult.length) {
|
||||
throw new Error('Unexpected render request');
|
||||
return '';
|
||||
}
|
||||
return this._renderResult[lineIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ export class IndentGuidesOverlay extends DynamicViewOverlay {
|
||||
}
|
||||
let lineIndex = lineNumber - startLineNumber;
|
||||
if (lineIndex < 0 || lineIndex >= this._renderResult.length) {
|
||||
throw new Error('Unexpected render request');
|
||||
return '';
|
||||
}
|
||||
return this._renderResult[lineIndex];
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
'use strict';
|
||||
|
||||
import 'vs/css!./lineNumbers';
|
||||
import { editorLineNumbers } from 'vs/editor/common/view/editorColorRegistry';
|
||||
import { editorLineNumbers, editorActiveLineNumber } from 'vs/editor/common/view/editorColorRegistry';
|
||||
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import { DynamicViewOverlay } from 'vs/editor/browser/view/dynamicViewOverlay';
|
||||
@@ -162,7 +162,7 @@ export class LineNumbersOverlay extends DynamicViewOverlay {
|
||||
}
|
||||
let lineIndex = lineNumber - startLineNumber;
|
||||
if (lineIndex < 0 || lineIndex >= this._renderResult.length) {
|
||||
throw new Error('Unexpected render request');
|
||||
return '';
|
||||
}
|
||||
return this._renderResult[lineIndex];
|
||||
}
|
||||
@@ -175,4 +175,8 @@ registerThemingParticipant((theme, collector) => {
|
||||
if (lineNumbers) {
|
||||
collector.addRule(`.monaco-editor .line-numbers { color: ${lineNumbers}; }`);
|
||||
}
|
||||
const activeLineNumber = theme.getColor(editorActiveLineNumber);
|
||||
if (activeLineNumber) {
|
||||
collector.addRule(`.monaco-editor .current-line ~ .line-numbers { color: ${activeLineNumber}; }`);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -228,9 +228,12 @@ export class ViewLine implements IVisibleLine {
|
||||
isRegularASCII = strings.isBasicASCII(lineData.content);
|
||||
}
|
||||
|
||||
if (isRegularASCII && lineData.content.length < 1000) {
|
||||
if (isRegularASCII && lineData.content.length < 1000 && renderLineInput.lineTokens.getCount() < 100) {
|
||||
// Browser rounding errors have been observed in Chrome and IE, so using the fast
|
||||
// view line only for short lines. Please test before removing the length check...
|
||||
// ---
|
||||
// Another rounding error has been observed on Linux in VSCode, where <span> width
|
||||
// rounding errors add up to an observable large number...
|
||||
renderedViewLine = new FastRenderedViewLine(
|
||||
this._renderedViewLine ? this._renderedViewLine.domNode : null,
|
||||
renderLineInput,
|
||||
@@ -278,8 +281,27 @@ export class ViewLine implements IVisibleLine {
|
||||
}
|
||||
|
||||
public getVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] {
|
||||
startColumn = startColumn | 0; // @perf
|
||||
endColumn = endColumn | 0; // @perf
|
||||
|
||||
startColumn = Math.min(this._renderedViewLine.input.lineContent.length + 1, Math.max(1, startColumn));
|
||||
endColumn = Math.min(this._renderedViewLine.input.lineContent.length + 1, Math.max(1, endColumn));
|
||||
|
||||
const stopRenderingLineAfter = this._renderedViewLine.input.stopRenderingLineAfter | 0; // @perf
|
||||
|
||||
if (stopRenderingLineAfter !== -1 && startColumn > stopRenderingLineAfter && endColumn > stopRenderingLineAfter) {
|
||||
// This range is obviously not visible
|
||||
return null;
|
||||
}
|
||||
|
||||
if (stopRenderingLineAfter !== -1 && startColumn > stopRenderingLineAfter) {
|
||||
startColumn = stopRenderingLineAfter;
|
||||
}
|
||||
|
||||
if (stopRenderingLineAfter !== -1 && endColumn > stopRenderingLineAfter) {
|
||||
endColumn = stopRenderingLineAfter;
|
||||
}
|
||||
|
||||
return this._renderedViewLine.getVisibleRangesForRange(startColumn, endColumn, context);
|
||||
}
|
||||
|
||||
@@ -325,23 +347,6 @@ class FastRenderedViewLine implements IRenderedViewLine {
|
||||
}
|
||||
|
||||
public getVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] {
|
||||
startColumn = startColumn | 0; // @perf
|
||||
endColumn = endColumn | 0; // @perf
|
||||
const stopRenderingLineAfter = this.input.stopRenderingLineAfter | 0; // @perf
|
||||
|
||||
if (stopRenderingLineAfter !== -1 && startColumn > stopRenderingLineAfter && endColumn > stopRenderingLineAfter) {
|
||||
// This range is obviously not visible
|
||||
return null;
|
||||
}
|
||||
|
||||
if (stopRenderingLineAfter !== -1 && startColumn > stopRenderingLineAfter) {
|
||||
startColumn = stopRenderingLineAfter;
|
||||
}
|
||||
|
||||
if (stopRenderingLineAfter !== -1 && endColumn > stopRenderingLineAfter) {
|
||||
endColumn = stopRenderingLineAfter;
|
||||
}
|
||||
|
||||
const startPosition = this._getCharPosition(startColumn);
|
||||
const endPosition = this._getCharPosition(endColumn);
|
||||
return [new HorizontalRange(startPosition, endPosition - startPosition)];
|
||||
@@ -432,23 +437,6 @@ class RenderedViewLine implements IRenderedViewLine {
|
||||
* Visible ranges for a model range
|
||||
*/
|
||||
public getVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] {
|
||||
startColumn = startColumn | 0; // @perf
|
||||
endColumn = endColumn | 0; // @perf
|
||||
const stopRenderingLineAfter = this.input.stopRenderingLineAfter | 0; // @perf
|
||||
|
||||
if (stopRenderingLineAfter !== -1 && startColumn > stopRenderingLineAfter && endColumn > stopRenderingLineAfter) {
|
||||
// This range is obviously not visible
|
||||
return null;
|
||||
}
|
||||
|
||||
if (stopRenderingLineAfter !== -1 && startColumn > stopRenderingLineAfter) {
|
||||
startColumn = stopRenderingLineAfter;
|
||||
}
|
||||
|
||||
if (stopRenderingLineAfter !== -1 && endColumn > stopRenderingLineAfter) {
|
||||
endColumn = stopRenderingLineAfter;
|
||||
}
|
||||
|
||||
if (this._pixelOffsetCache !== null) {
|
||||
// the text is LTR
|
||||
let startOffset = this._readPixelOffset(startColumn, context);
|
||||
|
||||
@@ -14,21 +14,21 @@
|
||||
100% { background-color: none }
|
||||
}*/
|
||||
|
||||
.monaco-editor .lines-content,
|
||||
.monaco-editor .view-line,
|
||||
.monaco-editor .view-lines {
|
||||
.monaco-editor.safari .lines-content,
|
||||
.monaco-editor.safari .view-line,
|
||||
.monaco-editor.safari .view-lines {
|
||||
-webkit-user-select: text;
|
||||
-ms-user-select: text;
|
||||
-khtml-user-select: text;
|
||||
-moz-user-select: text;
|
||||
-o-user-select: text;
|
||||
user-select: text;
|
||||
}
|
||||
|
||||
.monaco-editor.ie .lines-content,
|
||||
.monaco-editor.ie .view-line,
|
||||
.monaco-editor.ie .view-lines {
|
||||
.monaco-editor .lines-content,
|
||||
.monaco-editor .view-line,
|
||||
.monaco-editor .view-lines {
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-o-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
|
||||
@@ -455,6 +455,10 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
|
||||
|
||||
// --- implementation
|
||||
|
||||
public updateLineWidths(): void {
|
||||
this._updateLineWidths(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the max line width if it is fast to compute.
|
||||
* Returns true if all lines were taken into account.
|
||||
|
||||
@@ -82,6 +82,10 @@ class MinimapOptions {
|
||||
|
||||
public readonly lineHeight: number;
|
||||
|
||||
/**
|
||||
* container dom node left position (in CSS px)
|
||||
*/
|
||||
public readonly minimapLeft: number;
|
||||
/**
|
||||
* container dom node width (in CSS px)
|
||||
*/
|
||||
@@ -121,6 +125,7 @@ class MinimapOptions {
|
||||
this.pixelRatio = pixelRatio;
|
||||
this.typicalHalfwidthCharacterWidth = fontInfo.typicalHalfwidthCharacterWidth;
|
||||
this.lineHeight = configuration.editor.lineHeight;
|
||||
this.minimapLeft = layoutInfo.minimapLeft;
|
||||
this.minimapWidth = layoutInfo.minimapWidth;
|
||||
this.minimapHeight = layoutInfo.height;
|
||||
|
||||
@@ -138,6 +143,7 @@ class MinimapOptions {
|
||||
&& this.pixelRatio === other.pixelRatio
|
||||
&& this.typicalHalfwidthCharacterWidth === other.typicalHalfwidthCharacterWidth
|
||||
&& this.lineHeight === other.lineHeight
|
||||
&& this.minimapLeft === other.minimapLeft
|
||||
&& this.minimapWidth === other.minimapWidth
|
||||
&& this.minimapHeight === other.minimapHeight
|
||||
&& this.canvasInnerWidth === other.canvasInnerWidth
|
||||
@@ -456,7 +462,6 @@ export class Minimap extends ViewPart {
|
||||
this._domNode.setPosition('absolute');
|
||||
this._domNode.setAttribute('role', 'presentation');
|
||||
this._domNode.setAttribute('aria-hidden', 'true');
|
||||
this._domNode.setRight(this._context.configuration.editor.layoutInfo.verticalScrollbarWidth);
|
||||
|
||||
this._shadow = createFastDomNode(document.createElement('div'));
|
||||
this._shadow.setClassName('minimap-shadow-hidden');
|
||||
@@ -563,6 +568,7 @@ export class Minimap extends ViewPart {
|
||||
}
|
||||
|
||||
private _applyLayout(): void {
|
||||
this._domNode.setLeft(this._options.minimapLeft);
|
||||
this._domNode.setWidth(this._options.minimapWidth);
|
||||
this._domNode.setHeight(this._options.minimapHeight);
|
||||
this._shadow.setHeight(this._options.minimapHeight);
|
||||
@@ -654,6 +660,8 @@ export class Minimap extends ViewPart {
|
||||
const renderMinimap = this._options.renderMinimap;
|
||||
if (renderMinimap === RenderMinimap.None) {
|
||||
this._shadow.setClassName('minimap-shadow-hidden');
|
||||
this._sliderHorizontal.setWidth(0);
|
||||
this._sliderHorizontal.setHeight(0);
|
||||
return;
|
||||
}
|
||||
if (renderingCtx.scrollLeft + renderingCtx.viewportWidth >= renderingCtx.scrollWidth) {
|
||||
@@ -868,10 +876,9 @@ export class Minimap extends ViewPart {
|
||||
let charIndex = 0;
|
||||
let tabsCharDelta = 0;
|
||||
|
||||
for (let tokenIndex = 0, tokensLen = tokens.length; tokenIndex < tokensLen; tokenIndex++) {
|
||||
const token = tokens[tokenIndex];
|
||||
const tokenEndIndex = token.endIndex;
|
||||
const tokenColorId = token.getForeground();
|
||||
for (let tokenIndex = 0, tokensLen = tokens.getCount(); tokenIndex < tokensLen; tokenIndex++) {
|
||||
const tokenEndIndex = tokens.getEndOffset(tokenIndex);
|
||||
const tokenColorId = tokens.getForeground(tokenIndex);
|
||||
const tokenColor = colorTracker.getColor(tokenColorId);
|
||||
|
||||
for (; charIndex < tokenEndIndex; charIndex++) {
|
||||
@@ -927,4 +934,4 @@ registerThemingParticipant((theme, collector) => {
|
||||
if (shadow) {
|
||||
collector.addRule(`.monaco-editor .minimap-shadow-visible { box-shadow: ${shadow} -6px 0 6px -6px inset; }`);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -207,6 +207,7 @@ export class DecorationsOverviewRuler extends ViewPart {
|
||||
this._domNode.setClassName('decorationsOverviewRuler');
|
||||
this._domNode.setPosition('absolute');
|
||||
this._domNode.setLayerHinting(true);
|
||||
this._domNode.setAttribute('aria-hidden', 'true');
|
||||
|
||||
this._settings = null;
|
||||
this._updateSettings(false);
|
||||
|
||||
@@ -6,37 +6,41 @@
|
||||
|
||||
import { ViewEventHandler } from 'vs/editor/common/viewModel/viewEventHandler';
|
||||
import { IOverviewRuler } from 'vs/editor/browser/editorBrowser';
|
||||
import { OverviewRulerImpl } from 'vs/editor/browser/viewParts/overviewRuler/overviewRulerImpl';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { OverviewRulerPosition } from 'vs/editor/common/config/editorOptions';
|
||||
import { OverviewRulerZone } from 'vs/editor/common/view/overviewZoneManager';
|
||||
import { OverviewRulerZone, OverviewZoneManager, ColorZone } from 'vs/editor/common/view/overviewZoneManager';
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
|
||||
export class OverviewRuler extends ViewEventHandler implements IOverviewRuler {
|
||||
|
||||
private _context: ViewContext;
|
||||
private _overviewRuler: OverviewRulerImpl;
|
||||
private _domNode: FastDomNode<HTMLCanvasElement>;
|
||||
private _zoneManager: OverviewZoneManager;
|
||||
|
||||
constructor(context: ViewContext, cssClassName: string, minimumHeight: number, maximumHeight: number) {
|
||||
constructor(context: ViewContext, cssClassName: string) {
|
||||
super();
|
||||
this._context = context;
|
||||
this._overviewRuler = new OverviewRulerImpl(
|
||||
0,
|
||||
cssClassName,
|
||||
this._context.viewLayout.getScrollHeight(),
|
||||
this._context.configuration.editor.lineHeight,
|
||||
this._context.configuration.editor.pixelRatio,
|
||||
minimumHeight,
|
||||
maximumHeight,
|
||||
(lineNumber: number) => this._context.viewLayout.getVerticalOffsetForLineNumber(lineNumber)
|
||||
);
|
||||
|
||||
this._domNode = createFastDomNode(document.createElement('canvas'));
|
||||
this._domNode.setClassName(cssClassName);
|
||||
this._domNode.setPosition('absolute');
|
||||
this._domNode.setLayerHinting(true);
|
||||
|
||||
this._zoneManager = new OverviewZoneManager((lineNumber: number) => this._context.viewLayout.getVerticalOffsetForLineNumber(lineNumber));
|
||||
this._zoneManager.setDOMWidth(0);
|
||||
this._zoneManager.setDOMHeight(0);
|
||||
this._zoneManager.setOuterHeight(this._context.viewLayout.getScrollHeight());
|
||||
this._zoneManager.setLineHeight(this._context.configuration.editor.lineHeight);
|
||||
|
||||
this._zoneManager.setPixelRatio(this._context.configuration.editor.pixelRatio);
|
||||
|
||||
this._context.addEventHandler(this);
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._context.removeEventHandler(this);
|
||||
this._overviewRuler.dispose();
|
||||
this._zoneManager = null;
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -44,40 +48,118 @@ export class OverviewRuler extends ViewEventHandler implements IOverviewRuler {
|
||||
|
||||
public onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean {
|
||||
if (e.lineHeight) {
|
||||
this._overviewRuler.setLineHeight(this._context.configuration.editor.lineHeight, true);
|
||||
this._zoneManager.setLineHeight(this._context.configuration.editor.lineHeight);
|
||||
this._render();
|
||||
}
|
||||
|
||||
if (e.pixelRatio) {
|
||||
this._overviewRuler.setPixelRatio(this._context.configuration.editor.pixelRatio, true);
|
||||
this._zoneManager.setPixelRatio(this._context.configuration.editor.pixelRatio);
|
||||
this._domNode.setWidth(this._zoneManager.getDOMWidth());
|
||||
this._domNode.setHeight(this._zoneManager.getDOMHeight());
|
||||
this._domNode.domNode.width = this._zoneManager.getCanvasWidth();
|
||||
this._domNode.domNode.height = this._zoneManager.getCanvasHeight();
|
||||
this._render();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public onFlushed(e: viewEvents.ViewFlushedEvent): boolean {
|
||||
this._render();
|
||||
return true;
|
||||
}
|
||||
|
||||
public onScrollChanged(e: viewEvents.ViewScrollChangedEvent): boolean {
|
||||
this._overviewRuler.setScrollHeight(e.scrollHeight, true);
|
||||
return super.onScrollChanged(e) || e.scrollHeightChanged;
|
||||
if (e.scrollHeightChanged) {
|
||||
this._zoneManager.setOuterHeight(e.scrollHeight);
|
||||
this._render();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public onZonesChanged(e: viewEvents.ViewZonesChangedEvent): boolean {
|
||||
this._render();
|
||||
return true;
|
||||
}
|
||||
|
||||
// ---- end view event handlers
|
||||
|
||||
public getDomNode(): HTMLElement {
|
||||
return this._overviewRuler.getDomNode();
|
||||
return this._domNode.domNode;
|
||||
}
|
||||
|
||||
public setLayout(position: OverviewRulerPosition): void {
|
||||
this._overviewRuler.setLayout(position, true);
|
||||
this._domNode.setTop(position.top);
|
||||
this._domNode.setRight(position.right);
|
||||
|
||||
let hasChanged = false;
|
||||
hasChanged = this._zoneManager.setDOMWidth(position.width) || hasChanged;
|
||||
hasChanged = this._zoneManager.setDOMHeight(position.height) || hasChanged;
|
||||
|
||||
if (hasChanged) {
|
||||
this._domNode.setWidth(this._zoneManager.getDOMWidth());
|
||||
this._domNode.setHeight(this._zoneManager.getDOMHeight());
|
||||
this._domNode.domNode.width = this._zoneManager.getCanvasWidth();
|
||||
this._domNode.domNode.height = this._zoneManager.getCanvasHeight();
|
||||
|
||||
this._render();
|
||||
}
|
||||
}
|
||||
|
||||
public setZones(zones: OverviewRulerZone[]): void {
|
||||
this._overviewRuler.setZones(zones, true);
|
||||
this._zoneManager.setZones(zones);
|
||||
this._render();
|
||||
}
|
||||
}
|
||||
|
||||
private _render(): boolean {
|
||||
if (this._zoneManager.getOuterHeight() === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const width = this._zoneManager.getCanvasWidth();
|
||||
const height = this._zoneManager.getCanvasHeight();
|
||||
|
||||
let colorZones = this._zoneManager.resolveColorZones();
|
||||
let id2Color = this._zoneManager.getId2Color();
|
||||
|
||||
let ctx = this._domNode.domNode.getContext('2d');
|
||||
ctx.clearRect(0, 0, width, height);
|
||||
if (colorZones.length > 0) {
|
||||
this._renderOneLane(ctx, colorZones, id2Color, width);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private _renderOneLane(ctx: CanvasRenderingContext2D, colorZones: ColorZone[], id2Color: string[], width: number): void {
|
||||
|
||||
let currentColorId = 0;
|
||||
let currentFrom = 0;
|
||||
let currentTo = 0;
|
||||
|
||||
for (let i = 0, len = colorZones.length; i < len; i++) {
|
||||
const zone = colorZones[i];
|
||||
|
||||
const zoneColorId = zone.colorId;
|
||||
const zoneFrom = zone.from;
|
||||
const zoneTo = zone.to;
|
||||
|
||||
if (zoneColorId !== currentColorId) {
|
||||
ctx.fillRect(0, currentFrom, width, currentTo - currentFrom);
|
||||
|
||||
currentColorId = zoneColorId;
|
||||
ctx.fillStyle = id2Color[currentColorId];
|
||||
currentFrom = zoneFrom;
|
||||
currentTo = zoneTo;
|
||||
} else {
|
||||
if (currentTo >= zoneFrom) {
|
||||
currentTo = Math.max(currentTo, zoneTo);
|
||||
} else {
|
||||
ctx.fillRect(0, currentFrom, width, currentTo - currentFrom);
|
||||
currentFrom = zoneFrom;
|
||||
currentTo = zoneTo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx.fillRect(0, currentFrom, width, currentTo - currentFrom);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,250 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { OverviewRulerLane } from 'vs/editor/common/editorCommon';
|
||||
import { OverviewZoneManager, ColorZone, OverviewRulerZone } from 'vs/editor/common/view/overviewZoneManager';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { OverviewRulerPosition } from 'vs/editor/common/config/editorOptions';
|
||||
import { ThemeType, LIGHT } from 'vs/platform/theme/common/themeService';
|
||||
|
||||
export class OverviewRulerImpl {
|
||||
|
||||
private _canvasLeftOffset: number;
|
||||
private _domNode: FastDomNode<HTMLCanvasElement>;
|
||||
private _lanesCount: number;
|
||||
private _zoneManager: OverviewZoneManager;
|
||||
private _background: Color;
|
||||
|
||||
constructor(
|
||||
canvasLeftOffset: number, cssClassName: string, scrollHeight: number, lineHeight: number,
|
||||
pixelRatio: number, minimumHeight: number, maximumHeight: number,
|
||||
getVerticalOffsetForLine: (lineNumber: number) => number
|
||||
) {
|
||||
this._canvasLeftOffset = canvasLeftOffset;
|
||||
|
||||
this._domNode = createFastDomNode(document.createElement('canvas'));
|
||||
|
||||
this._domNode.setClassName(cssClassName);
|
||||
this._domNode.setPosition('absolute');
|
||||
this._domNode.setLayerHinting(true);
|
||||
|
||||
this._lanesCount = 3;
|
||||
|
||||
this._background = null;
|
||||
|
||||
this._zoneManager = new OverviewZoneManager(getVerticalOffsetForLine);
|
||||
this._zoneManager.setMinimumHeight(minimumHeight);
|
||||
this._zoneManager.setMaximumHeight(maximumHeight);
|
||||
this._zoneManager.setThemeType(LIGHT);
|
||||
this._zoneManager.setDOMWidth(0);
|
||||
this._zoneManager.setDOMHeight(0);
|
||||
this._zoneManager.setOuterHeight(scrollHeight);
|
||||
this._zoneManager.setLineHeight(lineHeight);
|
||||
|
||||
this._zoneManager.setPixelRatio(pixelRatio);
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._zoneManager = null;
|
||||
}
|
||||
|
||||
public setLayout(position: OverviewRulerPosition, render: boolean): void {
|
||||
this._domNode.setTop(position.top);
|
||||
this._domNode.setRight(position.right);
|
||||
|
||||
let hasChanged = false;
|
||||
hasChanged = this._zoneManager.setDOMWidth(position.width) || hasChanged;
|
||||
hasChanged = this._zoneManager.setDOMHeight(position.height) || hasChanged;
|
||||
|
||||
if (hasChanged) {
|
||||
this._domNode.setWidth(this._zoneManager.getDOMWidth());
|
||||
this._domNode.setHeight(this._zoneManager.getDOMHeight());
|
||||
this._domNode.domNode.width = this._zoneManager.getCanvasWidth();
|
||||
this._domNode.domNode.height = this._zoneManager.getCanvasHeight();
|
||||
|
||||
if (render) {
|
||||
this.render(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public getLanesCount(): number {
|
||||
return this._lanesCount;
|
||||
}
|
||||
|
||||
public setLanesCount(newLanesCount: number, render: boolean): void {
|
||||
this._lanesCount = newLanesCount;
|
||||
|
||||
if (render) {
|
||||
this.render(true);
|
||||
}
|
||||
}
|
||||
|
||||
public setThemeType(themeType: ThemeType, render: boolean): void {
|
||||
this._zoneManager.setThemeType(themeType);
|
||||
|
||||
if (render) {
|
||||
this.render(true);
|
||||
}
|
||||
}
|
||||
|
||||
public setUseBackground(background: Color, render: boolean): void {
|
||||
this._background = background;
|
||||
|
||||
if (render) {
|
||||
this.render(true);
|
||||
}
|
||||
}
|
||||
|
||||
public getDomNode(): HTMLCanvasElement {
|
||||
return this._domNode.domNode;
|
||||
}
|
||||
|
||||
public getPixelWidth(): number {
|
||||
return this._zoneManager.getCanvasWidth();
|
||||
}
|
||||
|
||||
public getPixelHeight(): number {
|
||||
return this._zoneManager.getCanvasHeight();
|
||||
}
|
||||
|
||||
public setScrollHeight(scrollHeight: number, render: boolean): void {
|
||||
this._zoneManager.setOuterHeight(scrollHeight);
|
||||
if (render) {
|
||||
this.render(true);
|
||||
}
|
||||
}
|
||||
|
||||
public setLineHeight(lineHeight: number, render: boolean): void {
|
||||
this._zoneManager.setLineHeight(lineHeight);
|
||||
if (render) {
|
||||
this.render(true);
|
||||
}
|
||||
}
|
||||
|
||||
public setPixelRatio(pixelRatio: number, render: boolean): void {
|
||||
this._zoneManager.setPixelRatio(pixelRatio);
|
||||
this._domNode.setWidth(this._zoneManager.getDOMWidth());
|
||||
this._domNode.setHeight(this._zoneManager.getDOMHeight());
|
||||
this._domNode.domNode.width = this._zoneManager.getCanvasWidth();
|
||||
this._domNode.domNode.height = this._zoneManager.getCanvasHeight();
|
||||
if (render) {
|
||||
this.render(true);
|
||||
}
|
||||
}
|
||||
|
||||
public setZones(zones: OverviewRulerZone[], render: boolean): void {
|
||||
this._zoneManager.setZones(zones);
|
||||
if (render) {
|
||||
this.render(false);
|
||||
}
|
||||
}
|
||||
|
||||
public render(forceRender: boolean): boolean {
|
||||
if (this._zoneManager.getOuterHeight() === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const width = this._zoneManager.getCanvasWidth();
|
||||
const height = this._zoneManager.getCanvasHeight();
|
||||
|
||||
let colorZones = this._zoneManager.resolveColorZones();
|
||||
let id2Color = this._zoneManager.getId2Color();
|
||||
|
||||
let ctx = this._domNode.domNode.getContext('2d');
|
||||
if (this._background === null) {
|
||||
ctx.clearRect(0, 0, width, height);
|
||||
} else {
|
||||
ctx.fillStyle = Color.Format.CSS.formatHex(this._background);
|
||||
ctx.fillRect(0, 0, width, height);
|
||||
}
|
||||
|
||||
if (colorZones.length > 0) {
|
||||
let remainingWidth = width - this._canvasLeftOffset;
|
||||
|
||||
if (this._lanesCount >= 3) {
|
||||
this._renderThreeLanes(ctx, colorZones, id2Color, remainingWidth);
|
||||
} else if (this._lanesCount === 2) {
|
||||
this._renderTwoLanes(ctx, colorZones, id2Color, remainingWidth);
|
||||
} else if (this._lanesCount === 1) {
|
||||
this._renderOneLane(ctx, colorZones, id2Color, remainingWidth);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private _renderOneLane(ctx: CanvasRenderingContext2D, colorZones: ColorZone[], id2Color: string[], w: number): void {
|
||||
|
||||
this._renderVerticalPatch(ctx, colorZones, id2Color, OverviewRulerLane.Left | OverviewRulerLane.Center | OverviewRulerLane.Right, this._canvasLeftOffset, w);
|
||||
|
||||
}
|
||||
|
||||
private _renderTwoLanes(ctx: CanvasRenderingContext2D, colorZones: ColorZone[], id2Color: string[], w: number): void {
|
||||
|
||||
let leftWidth = Math.floor(w / 2);
|
||||
let rightWidth = w - leftWidth;
|
||||
let leftOffset = this._canvasLeftOffset;
|
||||
let rightOffset = this._canvasLeftOffset + leftWidth;
|
||||
|
||||
this._renderVerticalPatch(ctx, colorZones, id2Color, OverviewRulerLane.Left | OverviewRulerLane.Center, leftOffset, leftWidth);
|
||||
this._renderVerticalPatch(ctx, colorZones, id2Color, OverviewRulerLane.Right, rightOffset, rightWidth);
|
||||
}
|
||||
|
||||
private _renderThreeLanes(ctx: CanvasRenderingContext2D, colorZones: ColorZone[], id2Color: string[], w: number): void {
|
||||
|
||||
let leftWidth = Math.floor(w / 3);
|
||||
let rightWidth = Math.floor(w / 3);
|
||||
let centerWidth = w - leftWidth - rightWidth;
|
||||
let leftOffset = this._canvasLeftOffset;
|
||||
let centerOffset = this._canvasLeftOffset + leftWidth;
|
||||
let rightOffset = this._canvasLeftOffset + leftWidth + centerWidth;
|
||||
|
||||
this._renderVerticalPatch(ctx, colorZones, id2Color, OverviewRulerLane.Left, leftOffset, leftWidth);
|
||||
this._renderVerticalPatch(ctx, colorZones, id2Color, OverviewRulerLane.Center, centerOffset, centerWidth);
|
||||
this._renderVerticalPatch(ctx, colorZones, id2Color, OverviewRulerLane.Right, rightOffset, rightWidth);
|
||||
}
|
||||
|
||||
private _renderVerticalPatch(ctx: CanvasRenderingContext2D, colorZones: ColorZone[], id2Color: string[], laneMask: number, xpos: number, width: number): void {
|
||||
|
||||
let currentColorId = 0;
|
||||
let currentFrom = 0;
|
||||
let currentTo = 0;
|
||||
|
||||
for (let i = 0, len = colorZones.length; i < len; i++) {
|
||||
let zone = colorZones[i];
|
||||
|
||||
if (!(zone.position & laneMask)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let zoneColorId = zone.colorId;
|
||||
let zoneFrom = zone.from;
|
||||
let zoneTo = zone.to;
|
||||
|
||||
if (zoneColorId !== currentColorId) {
|
||||
ctx.fillRect(xpos, currentFrom, width, currentTo - currentFrom);
|
||||
|
||||
currentColorId = zoneColorId;
|
||||
ctx.fillStyle = id2Color[currentColorId];
|
||||
currentFrom = zoneFrom;
|
||||
currentTo = zoneTo;
|
||||
} else {
|
||||
if (currentTo >= zoneFrom) {
|
||||
currentTo = Math.max(currentTo, zoneTo);
|
||||
} else {
|
||||
ctx.fillRect(xpos, currentFrom, width, currentTo - currentFrom);
|
||||
currentFrom = zoneFrom;
|
||||
currentTo = zoneTo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx.fillRect(xpos, currentFrom, width, currentTo - currentFrom);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -387,7 +387,7 @@ export class SelectionsOverlay extends DynamicViewOverlay {
|
||||
}
|
||||
let lineIndex = lineNumber - startLineNumber;
|
||||
if (lineIndex < 0 || lineIndex >= this._renderResult.length) {
|
||||
throw new Error('Unexpected render request');
|
||||
return '';
|
||||
}
|
||||
return this._renderResult[lineIndex];
|
||||
}
|
||||
|
||||
@@ -23,53 +23,44 @@ export interface IViewCursorRenderData {
|
||||
}
|
||||
|
||||
class ViewCursorRenderData {
|
||||
public readonly top: number;
|
||||
public readonly left: number;
|
||||
public readonly width: number;
|
||||
public readonly textContent: string;
|
||||
|
||||
constructor(top: number, left: number, width: number, textContent: string) {
|
||||
this.top = top;
|
||||
this.left = left;
|
||||
this.width = width;
|
||||
this.textContent = textContent;
|
||||
}
|
||||
constructor(
|
||||
public readonly top: number,
|
||||
public readonly left: number,
|
||||
public readonly width: number,
|
||||
public readonly height: number,
|
||||
public readonly textContent: string
|
||||
) { }
|
||||
}
|
||||
|
||||
export class ViewCursor {
|
||||
private readonly _context: ViewContext;
|
||||
private readonly _isSecondary: boolean;
|
||||
private readonly _domNode: FastDomNode<HTMLElement>;
|
||||
|
||||
private _cursorStyle: TextEditorCursorStyle;
|
||||
private _lineCursorWidth: number;
|
||||
private _lineHeight: number;
|
||||
private _typicalHalfwidthCharacterWidth: number;
|
||||
|
||||
private _isVisible: boolean;
|
||||
|
||||
private _position: Position;
|
||||
private _isInEditableRange: boolean;
|
||||
|
||||
private _lastRenderedContent: string;
|
||||
private _renderData: ViewCursorRenderData;
|
||||
|
||||
constructor(context: ViewContext, isSecondary: boolean) {
|
||||
constructor(context: ViewContext) {
|
||||
this._context = context;
|
||||
this._isSecondary = isSecondary;
|
||||
|
||||
this._cursorStyle = this._context.configuration.editor.viewInfo.cursorStyle;
|
||||
this._lineHeight = this._context.configuration.editor.lineHeight;
|
||||
this._typicalHalfwidthCharacterWidth = this._context.configuration.editor.fontInfo.typicalHalfwidthCharacterWidth;
|
||||
this._lineCursorWidth = Math.min(this._context.configuration.editor.viewInfo.cursorWidth, this._typicalHalfwidthCharacterWidth);
|
||||
|
||||
this._isVisible = true;
|
||||
|
||||
// Create the dom node
|
||||
this._domNode = createFastDomNode(document.createElement('div'));
|
||||
if (this._isSecondary) {
|
||||
this._domNode.setClassName('cursor secondary');
|
||||
} else {
|
||||
this._domNode.setClassName('cursor');
|
||||
}
|
||||
this._domNode.setClassName('cursor');
|
||||
this._domNode.setHeight(this._lineHeight);
|
||||
this._domNode.setTop(0);
|
||||
this._domNode.setLeft(0);
|
||||
@@ -77,7 +68,6 @@ export class ViewCursor {
|
||||
this._domNode.setDisplay('none');
|
||||
|
||||
this.updatePosition(new Position(1, 1));
|
||||
this._isInEditableRange = true;
|
||||
|
||||
this._lastRenderedContent = '';
|
||||
this._renderData = null;
|
||||
@@ -87,10 +77,6 @@ export class ViewCursor {
|
||||
return this._domNode;
|
||||
}
|
||||
|
||||
public getIsInEditableRange(): boolean {
|
||||
return this._isInEditableRange;
|
||||
}
|
||||
|
||||
public getPosition(): Position {
|
||||
return this._position;
|
||||
}
|
||||
@@ -113,23 +99,26 @@ export class ViewCursor {
|
||||
if (e.lineHeight) {
|
||||
this._lineHeight = this._context.configuration.editor.lineHeight;
|
||||
}
|
||||
if (e.viewInfo) {
|
||||
this._cursorStyle = this._context.configuration.editor.viewInfo.cursorStyle;
|
||||
}
|
||||
if (e.fontInfo) {
|
||||
Configuration.applyFontInfo(this._domNode, this._context.configuration.editor.fontInfo);
|
||||
this._typicalHalfwidthCharacterWidth = this._context.configuration.editor.fontInfo.typicalHalfwidthCharacterWidth;
|
||||
}
|
||||
if (e.viewInfo) {
|
||||
this._cursorStyle = this._context.configuration.editor.viewInfo.cursorStyle;
|
||||
this._lineCursorWidth = Math.min(this._context.configuration.editor.viewInfo.cursorWidth, this._typicalHalfwidthCharacterWidth);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public onCursorPositionChanged(position: Position, isInEditableRange: boolean): boolean {
|
||||
public onCursorPositionChanged(position: Position): boolean {
|
||||
this.updatePosition(position);
|
||||
this._isInEditableRange = isInEditableRange;
|
||||
return true;
|
||||
}
|
||||
|
||||
private _prepareRender(ctx: RenderingContext): ViewCursorRenderData {
|
||||
let textContent = '';
|
||||
|
||||
if (this._cursorStyle === TextEditorCursorStyle.Line || this._cursorStyle === TextEditorCursorStyle.LineThin) {
|
||||
const visibleRange = ctx.visibleRangeForPosition(this._position);
|
||||
if (!visibleRange) {
|
||||
@@ -138,12 +127,16 @@ export class ViewCursor {
|
||||
}
|
||||
let width: number;
|
||||
if (this._cursorStyle === TextEditorCursorStyle.Line) {
|
||||
width = dom.computeScreenAwareSize(2);
|
||||
width = dom.computeScreenAwareSize(this._lineCursorWidth > 0 ? this._lineCursorWidth : 2);
|
||||
if (width > 2) {
|
||||
const lineContent = this._context.model.getLineContent(this._position.lineNumber);
|
||||
textContent = lineContent.charAt(this._position.column - 1);
|
||||
}
|
||||
} else {
|
||||
width = dom.computeScreenAwareSize(1);
|
||||
}
|
||||
const top = ctx.getVerticalOffsetForLineNumber(this._position.lineNumber) - ctx.bigNumbersDelta;
|
||||
return new ViewCursorRenderData(top, visibleRange.left, width, '');
|
||||
return new ViewCursorRenderData(top, visibleRange.left, width, this._lineHeight, textContent);
|
||||
}
|
||||
|
||||
const visibleRangeForCharacter = ctx.linesVisibleRangesForRange(new Range(this._position.lineNumber, this._position.column, this._position.lineNumber, this._position.column + 1), false);
|
||||
@@ -156,14 +149,21 @@ export class ViewCursor {
|
||||
const range = visibleRangeForCharacter[0].ranges[0];
|
||||
const width = range.width < 1 ? this._typicalHalfwidthCharacterWidth : range.width;
|
||||
|
||||
let textContent = '';
|
||||
if (this._cursorStyle === TextEditorCursorStyle.Block) {
|
||||
const lineContent = this._context.model.getLineContent(this._position.lineNumber);
|
||||
textContent = lineContent.charAt(this._position.column - 1);
|
||||
}
|
||||
|
||||
const top = ctx.getVerticalOffsetForLineNumber(this._position.lineNumber) - ctx.bigNumbersDelta;
|
||||
return new ViewCursorRenderData(top, range.left, width, textContent);
|
||||
let top = ctx.getVerticalOffsetForLineNumber(this._position.lineNumber) - ctx.bigNumbersDelta;
|
||||
let height = this._lineHeight;
|
||||
|
||||
// Underline might interfere with clicking
|
||||
if (this._cursorStyle === TextEditorCursorStyle.Underline || this._cursorStyle === TextEditorCursorStyle.UnderlineThin) {
|
||||
top += this._lineHeight - 2;
|
||||
height = 2;
|
||||
}
|
||||
|
||||
return new ViewCursorRenderData(top, range.left, width, height, textContent);
|
||||
}
|
||||
|
||||
public prepareRender(ctx: RenderingContext): void {
|
||||
@@ -185,14 +185,14 @@ export class ViewCursor {
|
||||
this._domNode.setTop(this._renderData.top);
|
||||
this._domNode.setLeft(this._renderData.left);
|
||||
this._domNode.setWidth(this._renderData.width);
|
||||
this._domNode.setLineHeight(this._lineHeight);
|
||||
this._domNode.setHeight(this._lineHeight);
|
||||
this._domNode.setLineHeight(this._renderData.height);
|
||||
this._domNode.setHeight(this._renderData.height);
|
||||
|
||||
return {
|
||||
domNode: this._domNode.domNode,
|
||||
position: this._position,
|
||||
contentLeft: this._renderData.left,
|
||||
height: this._lineHeight,
|
||||
height: this._renderData.height,
|
||||
width: 2
|
||||
};
|
||||
}
|
||||
|
||||
@@ -10,9 +10,7 @@
|
||||
.monaco-editor .cursors-layer > .cursor {
|
||||
position: absolute;
|
||||
cursor: text;
|
||||
}
|
||||
.monaco-editor .cursors-layer > .cursor.secondary {
|
||||
opacity: 0.6;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* -- block-outline-style -- */
|
||||
|
||||
@@ -49,7 +49,7 @@ export class ViewCursors extends ViewPart {
|
||||
this._cursorStyle = this._context.configuration.editor.viewInfo.cursorStyle;
|
||||
this._selectionIsEmpty = true;
|
||||
|
||||
this._primaryCursor = new ViewCursor(this._context, false);
|
||||
this._primaryCursor = new ViewCursor(this._context);
|
||||
this._secondaryCursors = [];
|
||||
this._renderData = [];
|
||||
|
||||
@@ -101,15 +101,15 @@ export class ViewCursors extends ViewPart {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
private _onCursorPositionChanged(position: Position, secondaryPositions: Position[], isInEditableRange: boolean): void {
|
||||
this._primaryCursor.onCursorPositionChanged(position, isInEditableRange);
|
||||
private _onCursorPositionChanged(position: Position, secondaryPositions: Position[]): void {
|
||||
this._primaryCursor.onCursorPositionChanged(position);
|
||||
this._updateBlinking();
|
||||
|
||||
if (this._secondaryCursors.length < secondaryPositions.length) {
|
||||
// Create new cursors
|
||||
let addCnt = secondaryPositions.length - this._secondaryCursors.length;
|
||||
for (let i = 0; i < addCnt; i++) {
|
||||
let newCursor = new ViewCursor(this._context, true);
|
||||
let newCursor = new ViewCursor(this._context);
|
||||
this._domNode.domNode.insertBefore(newCursor.getDomNode().domNode, this._primaryCursor.getDomNode().domNode.nextSibling);
|
||||
this._secondaryCursors.push(newCursor);
|
||||
}
|
||||
@@ -123,7 +123,7 @@ export class ViewCursors extends ViewPart {
|
||||
}
|
||||
|
||||
for (let i = 0; i < secondaryPositions.length; i++) {
|
||||
this._secondaryCursors[i].onCursorPositionChanged(secondaryPositions[i], isInEditableRange);
|
||||
this._secondaryCursors[i].onCursorPositionChanged(secondaryPositions[i]);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -132,7 +132,7 @@ export class ViewCursors extends ViewPart {
|
||||
for (let i = 0, len = e.selections.length; i < len; i++) {
|
||||
positions[i] = e.selections[i].getPosition();
|
||||
}
|
||||
this._onCursorPositionChanged(positions[0], positions.slice(1), e.isInEditableRange);
|
||||
this._onCursorPositionChanged(positions[0], positions.slice(1));
|
||||
|
||||
const selectionIsEmpty = e.selections[0].isEmpty();
|
||||
if (this._selectionIsEmpty !== selectionIsEmpty) {
|
||||
@@ -198,7 +198,7 @@ export class ViewCursors extends ViewPart {
|
||||
if (!this._editorHasFocus) {
|
||||
return TextEditorCursorBlinkingStyle.Hidden;
|
||||
}
|
||||
if (this._readOnly || !this._primaryCursor.getIsInEditableRange()) {
|
||||
if (this._readOnly) {
|
||||
return TextEditorCursorBlinkingStyle.Solid;
|
||||
}
|
||||
return this._cursorBlinking;
|
||||
|
||||
@@ -32,6 +32,7 @@ import { editorErrorForeground, editorErrorBorder, editorWarningForeground, edit
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { IMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { ClassName } from 'vs/editor/common/model/intervalTree';
|
||||
import { ITextModel, IModelDecorationOptions } from 'vs/editor/common/model';
|
||||
|
||||
export abstract class CodeEditorWidget extends CommonCodeEditor implements editorBrowser.ICodeEditor {
|
||||
|
||||
@@ -157,8 +158,8 @@ export abstract class CodeEditorWidget extends CommonCodeEditor implements edito
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
public createOverviewRuler(cssClassName: string, minimumHeight: number, maximumHeight: number): editorBrowser.IOverviewRuler {
|
||||
return this._view.createOverviewRuler(cssClassName, minimumHeight, maximumHeight);
|
||||
public createOverviewRuler(cssClassName: string): editorBrowser.IOverviewRuler {
|
||||
return this._view.createOverviewRuler(cssClassName);
|
||||
}
|
||||
|
||||
public getDomNode(): HTMLElement {
|
||||
@@ -326,7 +327,7 @@ export abstract class CodeEditorWidget extends CommonCodeEditor implements edito
|
||||
Configuration.applyFontInfoSlow(target, this._configuration.editor.fontInfo);
|
||||
}
|
||||
|
||||
_attachModel(model: editorCommon.IModel): void {
|
||||
_attachModel(model: ITextModel): void {
|
||||
this._view = null;
|
||||
|
||||
super._attachModel(model);
|
||||
@@ -392,7 +393,17 @@ export abstract class CodeEditorWidget extends CommonCodeEditor implements edito
|
||||
viewEventBus.onKeyDown = (e) => this._onKeyDown.fire(e);
|
||||
}
|
||||
|
||||
protected _detachModel(): editorCommon.IModel {
|
||||
public restoreViewState(s: editorCommon.ICodeEditorViewState): void {
|
||||
super.restoreViewState(s);
|
||||
if (!this.cursor || !this.hasView) {
|
||||
return;
|
||||
}
|
||||
if (s && s.cursorState && s.viewState) {
|
||||
this._view.restoreState(this.viewModel.viewLayout.reduceRestoreState(s.viewState));
|
||||
}
|
||||
}
|
||||
|
||||
protected _detachModel(): ITextModel {
|
||||
let removeDomNode: HTMLElement = null;
|
||||
|
||||
if (this._view) {
|
||||
@@ -420,7 +431,7 @@ export abstract class CodeEditorWidget extends CommonCodeEditor implements edito
|
||||
this._codeEditorService.removeDecorationType(key);
|
||||
}
|
||||
|
||||
protected _resolveDecorationOptions(typeKey: string, writable: boolean): editorCommon.IModelDecorationOptions {
|
||||
protected _resolveDecorationOptions(typeKey: string, writable: boolean): IModelDecorationOptions {
|
||||
return this._codeEditorService.resolveDecorationOptions(typeKey, writable);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import * as objects from 'vs/base/common/objects';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { ISashEvent, IVerticalSashLayoutProvider, Sash } from 'vs/base/browser/ui/sash/sash';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
@@ -24,7 +23,7 @@ import { LineDecoration } from 'vs/editor/common/viewLayout/lineDecorations';
|
||||
import { renderViewLine, RenderLineInput } from 'vs/editor/common/viewLayout/viewLineRenderer';
|
||||
import * as editorBrowser from 'vs/editor/browser/editorBrowser';
|
||||
import { CodeEditor } from 'vs/editor/browser/codeEditor';
|
||||
import { ViewLineToken } from 'vs/editor/common/core/viewLineToken';
|
||||
import { LineTokens } from 'vs/editor/common/core/lineTokens';
|
||||
import { Configuration } from 'vs/editor/browser/config/configuration';
|
||||
import { Position, IPosition } from 'vs/editor/common/core/position';
|
||||
import { Selection, ISelection } from 'vs/editor/common/core/selection';
|
||||
@@ -38,14 +37,15 @@ import { scrollbarShadow, diffInserted, diffRemoved, defaultInsertColor, default
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { OverviewRulerZone } from 'vs/editor/common/view/overviewZoneManager';
|
||||
import { IEditorWhitespace } from 'vs/editor/common/viewLayout/whitespaceComputer';
|
||||
import { ModelDecorationOptions } from 'vs/editor/common/model/textModelWithDecorations';
|
||||
import { ModelDecorationOptions } from 'vs/editor/common/model/textModel';
|
||||
import { DiffReview } from 'vs/editor/browser/widget/diffReview';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { IMessageService } from 'vs/platform/message/common/message';
|
||||
import { IStringBuilder, createStringBuilder } from 'vs/editor/common/core/stringBuilder';
|
||||
import { IModelDeltaDecoration, IModelDecorationsChangeAccessor, ITextModel } from 'vs/editor/common/model';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
|
||||
interface IEditorDiffDecorations {
|
||||
decorations: editorCommon.IModelDeltaDecoration[];
|
||||
decorations: IModelDeltaDecoration[];
|
||||
overviewZones: OverviewRulerZone[];
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ class VisualEditorState {
|
||||
|
||||
// (2) Model decorations
|
||||
if (this._decorations.length > 0) {
|
||||
editor.changeDecorations((changeAccessor: editorCommon.IModelDecorationsChangeAccessor) => {
|
||||
editor.changeDecorations((changeAccessor: IModelDecorationsChangeAccessor) => {
|
||||
changeAccessor.deltaDecorations(this._decorations, []);
|
||||
});
|
||||
}
|
||||
@@ -191,7 +191,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
protected _contextKeyService: IContextKeyService;
|
||||
private _codeEditorService: ICodeEditorService;
|
||||
private _themeService: IThemeService;
|
||||
private readonly _messageService: IMessageService;
|
||||
private _notificationService: INotificationService;
|
||||
|
||||
private _reviewPane: DiffReview;
|
||||
|
||||
@@ -203,16 +203,16 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@ICodeEditorService codeEditorService: ICodeEditorService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IMessageService messageService: IMessageService
|
||||
@INotificationService notificationService: INotificationService
|
||||
) {
|
||||
super();
|
||||
|
||||
this._editorWorkerService = editorWorkerService;
|
||||
this._codeEditorService = codeEditorService;
|
||||
this._contextKeyService = contextKeyService.createScoped(domElement);
|
||||
this._contextKeyService = this._register(contextKeyService.createScoped(domElement));
|
||||
this._contextKeyService.createKey('isInDiffEditor', true);
|
||||
this._themeService = themeService;
|
||||
this._messageService = messageService;
|
||||
this._notificationService = notificationService;
|
||||
|
||||
this.id = (++DIFF_EDITOR_ID);
|
||||
|
||||
@@ -313,14 +313,14 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
this._setStrategy(new DiffEdtorWidgetInline(this._createDataSource(), this._enableSplitViewResizing));
|
||||
}
|
||||
|
||||
this._codeEditorService.addDiffEditor(this);
|
||||
|
||||
this._register(themeService.onThemeChange(t => {
|
||||
if (this._strategy && this._strategy.applyColors(t)) {
|
||||
this._updateDecorationsRunner.schedule();
|
||||
}
|
||||
this._containerDomElement.className = DiffEditorWidget._getClassName(this._themeService.getTheme(), this._renderSideBySide);
|
||||
}));
|
||||
|
||||
this._codeEditorService.addDiffEditor(this);
|
||||
}
|
||||
|
||||
public get ignoreTrimWhitespace(): boolean {
|
||||
@@ -361,14 +361,14 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
this._overviewDomElement.removeChild(this._originalOverviewRuler.getDomNode());
|
||||
this._originalOverviewRuler.dispose();
|
||||
}
|
||||
this._originalOverviewRuler = this.originalEditor.createOverviewRuler('original diffOverviewRuler', 4, Number.MAX_VALUE);
|
||||
this._originalOverviewRuler = this.originalEditor.createOverviewRuler('original diffOverviewRuler');
|
||||
this._overviewDomElement.appendChild(this._originalOverviewRuler.getDomNode());
|
||||
|
||||
if (this._modifiedOverviewRuler) {
|
||||
this._overviewDomElement.removeChild(this._modifiedOverviewRuler.getDomNode());
|
||||
this._modifiedOverviewRuler.dispose();
|
||||
}
|
||||
this._modifiedOverviewRuler = this.modifiedEditor.createOverviewRuler('modified diffOverviewRuler', 4, Number.MAX_VALUE);
|
||||
this._modifiedOverviewRuler = this.modifiedEditor.createOverviewRuler('modified diffOverviewRuler');
|
||||
this._overviewDomElement.appendChild(this._modifiedOverviewRuler.getDomNode());
|
||||
|
||||
this._layoutOverviewRulers();
|
||||
@@ -465,20 +465,37 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
public dispose(): void {
|
||||
this._codeEditorService.removeDiffEditor(this);
|
||||
|
||||
if (this._beginUpdateDecorationsTimeout !== -1) {
|
||||
window.clearTimeout(this._beginUpdateDecorationsTimeout);
|
||||
this._beginUpdateDecorationsTimeout = -1;
|
||||
}
|
||||
|
||||
window.clearInterval(this._measureDomElementToken);
|
||||
|
||||
this._cleanViewZonesAndDecorations();
|
||||
|
||||
this._overviewDomElement.removeChild(this._originalOverviewRuler.getDomNode());
|
||||
this._originalOverviewRuler.dispose();
|
||||
this._overviewDomElement.removeChild(this._modifiedOverviewRuler.getDomNode());
|
||||
this._modifiedOverviewRuler.dispose();
|
||||
this._overviewDomElement.removeChild(this._overviewViewportDomElement.domNode);
|
||||
this._containerDomElement.removeChild(this._overviewDomElement);
|
||||
|
||||
this._containerDomElement.removeChild(this._originalDomNode);
|
||||
this.originalEditor.dispose();
|
||||
|
||||
this._containerDomElement.removeChild(this._modifiedDomNode);
|
||||
this.modifiedEditor.dispose();
|
||||
|
||||
this._strategy.dispose();
|
||||
|
||||
this._containerDomElement.removeChild(this._reviewPane.domNode.domNode);
|
||||
this._containerDomElement.removeChild(this._reviewPane.shadow.domNode);
|
||||
this._containerDomElement.removeChild(this._reviewPane.actionBarContainer.domNode);
|
||||
this._reviewPane.dispose();
|
||||
|
||||
this._domElement.removeChild(this._containerDomElement);
|
||||
|
||||
this._onDidDispose.fire();
|
||||
|
||||
super.dispose();
|
||||
@@ -746,7 +763,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
this.modifiedEditor.trigger(source, handlerId, payload);
|
||||
}
|
||||
|
||||
public changeDecorations(callback: (changeAccessor: editorCommon.IModelDecorationsChangeAccessor) => any): any {
|
||||
public changeDecorations(callback: (changeAccessor: IModelDecorationsChangeAccessor) => any): any {
|
||||
return this.modifiedEditor.changeDecorations(callback);
|
||||
}
|
||||
|
||||
@@ -852,7 +869,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
) {
|
||||
this._lastOriginalWarning = currentOriginalModel.uri;
|
||||
this._lastModifiedWarning = currentModifiedModel.uri;
|
||||
this._messageService.show(Severity.Warning, nls.localize("diff.tooLarge", "Cannot compare files because one file is too large."));
|
||||
this._notificationService.warn(nls.localize("diff.tooLarge", "Cannot compare files because one file is too large."));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1594,6 +1611,7 @@ class DiffEdtorWidgetSideBySide extends DiffEditorWidgetStyle implements IDiffEd
|
||||
}
|
||||
|
||||
_getOriginalEditorDecorations(lineChanges: editorCommon.ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor): IEditorDiffDecorations {
|
||||
const overviewZoneColor = this._removeColor.toString();
|
||||
|
||||
let result: IEditorDiffDecorations = {
|
||||
decorations: [],
|
||||
@@ -1614,16 +1632,10 @@ class DiffEdtorWidgetSideBySide extends DiffEditorWidgetStyle implements IDiffEd
|
||||
result.decorations.push(createDecoration(lineChange.originalStartLineNumber, 1, lineChange.originalEndLineNumber, Number.MAX_VALUE, DECORATIONS.charDeleteWholeLine));
|
||||
}
|
||||
|
||||
let color = this._removeColor.toString();
|
||||
|
||||
result.overviewZones.push(new OverviewRulerZone(
|
||||
lineChange.originalStartLineNumber,
|
||||
lineChange.originalEndLineNumber,
|
||||
editorCommon.OverviewRulerLane.Full,
|
||||
0,
|
||||
color,
|
||||
color,
|
||||
color
|
||||
overviewZoneColor
|
||||
));
|
||||
|
||||
if (lineChange.charChanges) {
|
||||
@@ -1659,6 +1671,7 @@ class DiffEdtorWidgetSideBySide extends DiffEditorWidgetStyle implements IDiffEd
|
||||
}
|
||||
|
||||
_getModifiedEditorDecorations(lineChanges: editorCommon.ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor): IEditorDiffDecorations {
|
||||
const overviewZoneColor = this._insertColor.toString();
|
||||
|
||||
let result: IEditorDiffDecorations = {
|
||||
decorations: [],
|
||||
@@ -1679,15 +1692,10 @@ class DiffEdtorWidgetSideBySide extends DiffEditorWidgetStyle implements IDiffEd
|
||||
if (!isChangeOrDelete(lineChange) || !lineChange.charChanges) {
|
||||
result.decorations.push(createDecoration(lineChange.modifiedStartLineNumber, 1, lineChange.modifiedEndLineNumber, Number.MAX_VALUE, DECORATIONS.charInsertWholeLine));
|
||||
}
|
||||
let color = this._insertColor.toString();
|
||||
result.overviewZones.push(new OverviewRulerZone(
|
||||
lineChange.modifiedStartLineNumber,
|
||||
lineChange.modifiedEndLineNumber,
|
||||
editorCommon.OverviewRulerLane.Full,
|
||||
0,
|
||||
color,
|
||||
color,
|
||||
color
|
||||
overviewZoneColor
|
||||
));
|
||||
|
||||
if (lineChange.charChanges) {
|
||||
@@ -1783,6 +1791,8 @@ class DiffEdtorWidgetInline extends DiffEditorWidgetStyle implements IDiffEditor
|
||||
}
|
||||
|
||||
_getOriginalEditorDecorations(lineChanges: editorCommon.ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor): IEditorDiffDecorations {
|
||||
const overviewZoneColor = this._removeColor.toString();
|
||||
|
||||
let result: IEditorDiffDecorations = {
|
||||
decorations: [],
|
||||
overviewZones: []
|
||||
@@ -1798,15 +1808,10 @@ class DiffEdtorWidgetInline extends DiffEditorWidgetStyle implements IDiffEditor
|
||||
options: DECORATIONS.lineDeleteMargin
|
||||
});
|
||||
|
||||
let color = this._removeColor.toString();
|
||||
result.overviewZones.push(new OverviewRulerZone(
|
||||
lineChange.originalStartLineNumber,
|
||||
lineChange.originalEndLineNumber,
|
||||
editorCommon.OverviewRulerLane.Full,
|
||||
0,
|
||||
color,
|
||||
color,
|
||||
color
|
||||
overviewZoneColor
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -1815,6 +1820,7 @@ class DiffEdtorWidgetInline extends DiffEditorWidgetStyle implements IDiffEditor
|
||||
}
|
||||
|
||||
_getModifiedEditorDecorations(lineChanges: editorCommon.ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor): IEditorDiffDecorations {
|
||||
const overviewZoneColor = this._insertColor.toString();
|
||||
|
||||
let result: IEditorDiffDecorations = {
|
||||
decorations: [],
|
||||
@@ -1833,15 +1839,10 @@ class DiffEdtorWidgetInline extends DiffEditorWidgetStyle implements IDiffEditor
|
||||
options: (renderIndicators ? DECORATIONS.lineInsertWithSign : DECORATIONS.lineInsert)
|
||||
});
|
||||
|
||||
let color = this._insertColor.toString();
|
||||
result.overviewZones.push(new OverviewRulerZone(
|
||||
lineChange.modifiedStartLineNumber,
|
||||
lineChange.modifiedEndLineNumber,
|
||||
editorCommon.OverviewRulerLane.Full,
|
||||
0,
|
||||
color,
|
||||
color,
|
||||
color
|
||||
overviewZoneColor
|
||||
));
|
||||
|
||||
if (lineChange.charChanges) {
|
||||
@@ -1887,7 +1888,7 @@ class DiffEdtorWidgetInline extends DiffEditorWidgetStyle implements IDiffEditor
|
||||
|
||||
class InlineViewZonesComputer extends ViewZonesComputer {
|
||||
|
||||
private originalModel: editorCommon.IModel;
|
||||
private originalModel: ITextModel;
|
||||
private modifiedEditorConfiguration: editorOptions.InternalEditorOptions;
|
||||
private modifiedEditorTabSize: number;
|
||||
private renderIndicators: boolean;
|
||||
@@ -1962,7 +1963,7 @@ class InlineViewZonesComputer extends ViewZonesComputer {
|
||||
};
|
||||
}
|
||||
|
||||
private renderOriginalLine(count: number, originalModel: editorCommon.IModel, config: editorOptions.InternalEditorOptions, tabSize: number, lineNumber: number, decorations: InlineDecoration[], sb: IStringBuilder): void {
|
||||
private renderOriginalLine(count: number, originalModel: ITextModel, config: editorOptions.InternalEditorOptions, tabSize: number, lineNumber: number, decorations: InlineDecoration[], sb: IStringBuilder): void {
|
||||
let lineContent = originalModel.getLineContent(lineNumber);
|
||||
|
||||
let actualDecorations = LineDecoration.filter(decorations, lineNumber, 1, lineContent.length + 1);
|
||||
@@ -1973,6 +1974,12 @@ class InlineViewZonesComputer extends ViewZonesComputer {
|
||||
| (ColorId.DefaultBackground << MetadataConsts.BACKGROUND_OFFSET)
|
||||
) >>> 0;
|
||||
|
||||
const tokens = new Uint32Array(2);
|
||||
tokens[0] = lineContent.length;
|
||||
tokens[1] = defaultMetadata;
|
||||
|
||||
const lineTokens = new LineTokens(tokens, lineContent);
|
||||
|
||||
sb.appendASCIIString('<div class="view-line');
|
||||
if (decorations.length === 0) {
|
||||
// No char changes
|
||||
@@ -1987,7 +1994,7 @@ class InlineViewZonesComputer extends ViewZonesComputer {
|
||||
lineContent,
|
||||
originalModel.mightContainRTL(),
|
||||
0,
|
||||
[new ViewLineToken(lineContent.length, defaultMetadata)],
|
||||
lineTokens,
|
||||
actualDecorations,
|
||||
tabSize,
|
||||
config.fontInfo.spaceWidth,
|
||||
|
||||
@@ -25,7 +25,7 @@ export interface Options {
|
||||
alwaysRevealFirst?: boolean;
|
||||
}
|
||||
|
||||
var defaultOptions: Options = {
|
||||
const defaultOptions: Options = {
|
||||
followsCaret: true,
|
||||
ignoreCharChanges: true,
|
||||
alwaysRevealFirst: true
|
||||
@@ -84,7 +84,7 @@ export class DiffNavigator {
|
||||
}
|
||||
|
||||
private _init(): void {
|
||||
var changes = this._editor.getLineChanges();
|
||||
let changes = this._editor.getLineChanges();
|
||||
if (!changes) {
|
||||
return;
|
||||
}
|
||||
@@ -149,10 +149,10 @@ export class DiffNavigator {
|
||||
}
|
||||
|
||||
private _initIdx(fwd: boolean): void {
|
||||
var found = false;
|
||||
var position = this._editor.getPosition();
|
||||
for (var i = 0, len = this.ranges.length; i < len && !found; i++) {
|
||||
var range = this.ranges[i].range;
|
||||
let found = false;
|
||||
let position = this._editor.getPosition();
|
||||
for (let i = 0, len = this.ranges.length; i < len && !found; i++) {
|
||||
let range = this.ranges[i].range;
|
||||
if (position.isBeforeOrEqual(range.getStartPosition())) {
|
||||
this.nextIdx = i + (fwd ? 0 : -1);
|
||||
found = true;
|
||||
@@ -189,10 +189,10 @@ export class DiffNavigator {
|
||||
}
|
||||
}
|
||||
|
||||
var info = this.ranges[this.nextIdx];
|
||||
let info = this.ranges[this.nextIdx];
|
||||
this.ignoreSelectionChange = true;
|
||||
try {
|
||||
var pos = info.range.getStartPosition();
|
||||
let pos = info.range.getStartPosition();
|
||||
this._editor.setPosition(pos);
|
||||
this._editor.revealPositionInCenter(pos, ScrollType.Smooth);
|
||||
} finally {
|
||||
|
||||
@@ -11,7 +11,7 @@ import * as dom from 'vs/base/browser/dom';
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { renderViewLine2 as renderViewLine, RenderLineInput } from 'vs/editor/common/viewLayout/viewLineRenderer';
|
||||
import { ViewLineToken } from 'vs/editor/common/core/viewLineToken';
|
||||
import { LineTokens } from 'vs/editor/common/core/lineTokens';
|
||||
import { Configuration } from 'vs/editor/browser/config/configuration';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { ColorId, MetadataConsts, FontStyle } from 'vs/editor/common/modes';
|
||||
@@ -28,6 +28,7 @@ import { registerEditorAction, EditorAction, ServicesAccessor } from 'vs/editor/
|
||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { ITextModel, TextModelResolvedOptions } from 'vs/editor/common/model';
|
||||
|
||||
const DIFF_LINES_PADDING = 3;
|
||||
|
||||
@@ -607,8 +608,8 @@ export class DiffReview extends Disposable {
|
||||
|
||||
private static _renderSection(
|
||||
dest: HTMLElement, diffEntry: DiffEntry, modLine: number, width: number,
|
||||
originalOpts: editorOptions.InternalEditorOptions, originalModel: editorCommon.IModel, originalModelOpts: editorCommon.TextModelResolvedOptions,
|
||||
modifiedOpts: editorOptions.InternalEditorOptions, modifiedModel: editorCommon.IModel, modifiedModelOpts: editorCommon.TextModelResolvedOptions
|
||||
originalOpts: editorOptions.InternalEditorOptions, originalModel: ITextModel, originalModelOpts: TextModelResolvedOptions,
|
||||
modifiedOpts: editorOptions.InternalEditorOptions, modifiedModel: ITextModel, modifiedModelOpts: TextModelResolvedOptions
|
||||
): void {
|
||||
|
||||
const type = diffEntry.getType();
|
||||
@@ -722,7 +723,7 @@ export class DiffReview extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
private static _renderLine(model: editorCommon.IModel, config: editorOptions.InternalEditorOptions, tabSize: number, lineNumber: number): string {
|
||||
private static _renderLine(model: ITextModel, config: editorOptions.InternalEditorOptions, tabSize: number, lineNumber: number): string {
|
||||
const lineContent = model.getLineContent(lineNumber);
|
||||
|
||||
const defaultMetadata = (
|
||||
@@ -731,12 +732,18 @@ export class DiffReview extends Disposable {
|
||||
| (ColorId.DefaultBackground << MetadataConsts.BACKGROUND_OFFSET)
|
||||
) >>> 0;
|
||||
|
||||
const tokens = new Uint32Array(2);
|
||||
tokens[0] = lineContent.length;
|
||||
tokens[1] = defaultMetadata;
|
||||
|
||||
const lineTokens = new LineTokens(tokens, lineContent);
|
||||
|
||||
const r = renderViewLine(new RenderLineInput(
|
||||
(config.fontInfo.isMonospace && !config.viewInfo.disableMonospaceOptimizations),
|
||||
lineContent,
|
||||
model.mightContainRTL(),
|
||||
0,
|
||||
[new ViewLineToken(lineContent.length, defaultMetadata)],
|
||||
lineTokens,
|
||||
[],
|
||||
tabSize,
|
||||
config.fontInfo.spaceWidth,
|
||||
|
||||
@@ -15,7 +15,7 @@ import { IConfigurationChangedEvent, IEditorOptions, IDiffEditorOptions } from '
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { DiffEditorWidget } from 'vs/editor/browser/widget/diffEditorWidget';
|
||||
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
|
||||
import { IMessageService } from 'vs/platform/message/common/message';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
|
||||
export class EmbeddedCodeEditorWidget extends CodeEditor {
|
||||
|
||||
@@ -72,9 +72,9 @@ export class EmbeddedDiffEditorWidget extends DiffEditorWidget {
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@ICodeEditorService codeEditorService: ICodeEditorService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IMessageService messageService: IMessageService
|
||||
@INotificationService notificationService: INotificationService
|
||||
) {
|
||||
super(domElement, parentEditor.getRawConfiguration(), editorWorkerService, contextKeyService, instantiationService, codeEditorService, themeService, messageService);
|
||||
super(domElement, parentEditor.getRawConfiguration(), editorWorkerService, contextKeyService, instantiationService, codeEditorService, themeService, notificationService);
|
||||
|
||||
this._parentEditor = parentEditor;
|
||||
this._overwriteOptions = options;
|
||||
|
||||
Reference in New Issue
Block a user