Insert snippet API changes.

This commit is contained in:
Joel Day
2017-01-17 16:09:15 -08:00
parent f7587b3e3a
commit 3c817c7fe2
9 changed files with 63 additions and 62 deletions

View File

@@ -34,7 +34,7 @@ import { IWorkspaceConfigurationValues } from 'vs/workbench/services/configurati
import { IPickOpenEntry, IPickOptions } from 'vs/platform/quickOpen/common/quickOpen';
import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles';
import { IWorkspaceSymbol } from 'vs/workbench/parts/search/common/search';
import { IApplyEditsOptions, TextEditorRevealType, ITextEditorConfigurationUpdate, IResolvedTextEditorConfiguration, ISelectionChangeEvent } from './mainThreadEditorsTracker';
import { IApplyEditsOptions, IInsertSnippetOptions, TextEditorRevealType, ITextEditorConfigurationUpdate, IResolvedTextEditorConfiguration, ISelectionChangeEvent } from './mainThreadEditorsTracker';
import { InternalTreeExplorerNodeContent } from 'vs/workbench/parts/explorers/common/treeExplorerViewModel';
@@ -137,7 +137,7 @@ export abstract class MainThreadEditorsShape {
$tryRevealRange(id: string, range: editorCommon.IRange, revealType: TextEditorRevealType): TPromise<any> { throw ni(); }
$trySetSelections(id: string, selections: editorCommon.ISelection[]): TPromise<any> { throw ni(); }
$tryApplyEdits(id: string, modelVersionId: number, edits: editorCommon.ISingleEditOperation[], opts: IApplyEditsOptions): TPromise<boolean> { throw ni(); }
$tryInsertSnippet(id: string, template: string, posOrRange: editorCommon.IPosition | editorCommon.IRange): TPromise<boolean> { throw ni(); }
$tryInsertSnippet(id: string, template: string, opts: IInsertSnippetOptions): TPromise<boolean> { throw ni(); }
}
export abstract class MainThreadTreeExplorersShape {

View File

@@ -12,8 +12,8 @@ import Event, { Emitter } from 'vs/base/common/event';
import { TPromise } from 'vs/base/common/winjs.base';
import { IThreadService } from 'vs/workbench/services/thread/common/threadService';
import { ExtHostDocuments, ExtHostDocumentData } from 'vs/workbench/api/node/extHostDocuments';
import { Selection, Range, Position, EndOfLine, TextEditorRevealType, TextEditorSelectionChangeKind, TextEditorLineNumbersStyle } from './extHostTypes';
import { ISingleEditOperation, TextEditorCursorStyle, IPosition, IRange } from 'vs/editor/common/editorCommon';
import { Selection, Range, Position, EndOfLine, TextEditorRevealType, TextEditorSelectionChangeKind, TextEditorLineNumbersStyle, SnippetString } from './extHostTypes';
import { ISingleEditOperation, TextEditorCursorStyle } from 'vs/editor/common/editorCommon';
import { IResolvedTextEditorConfiguration, ISelectionChangeEvent, ITextEditorConfigurationUpdate } from 'vs/workbench/api/node/mainThreadEditorsTracker';
import * as TypeConverters from './extHostTypeConverters';
import { MainContext, MainThreadEditorsShape, ExtHostEditorsShape, ITextEditorAddData, ITextEditorPositionData } from './extHost.protocol';
@@ -595,10 +595,17 @@ class ExtHostTextEditor implements vscode.TextEditor {
// ---- editing
edit(callback: (edit: TextEditorEdit) => void, options: { undoStopBefore: boolean; undoStopAfter: boolean; } = { undoStopBefore: true, undoStopAfter: true }): Thenable<boolean> {
let edit = new TextEditorEdit(this._documentData.document, options);
callback(edit);
return this._applyEdit(edit);
edit(callback: (edit: TextEditorEdit) => void, options: { undoStopBefore: boolean; undoStopAfter: boolean; }): Thenable<boolean>;
edit(snippet: SnippetString, options: { undoStopBefore: boolean; undoStopAfter: boolean; }): Thenable<boolean>;
edit(callbackOrSnippet: ((edit: TextEditorEdit) => void) | SnippetString, options: { undoStopBefore: boolean; undoStopAfter: boolean; } = { undoStopBefore: true, undoStopAfter: true }): Thenable<boolean> {
if (SnippetString.isSnippetString(callbackOrSnippet)) {
return this._proxy.$tryInsertSnippet(this._id, callbackOrSnippet.value, options);
} else {
let edit = new TextEditorEdit(this._documentData.document, options);
callbackOrSnippet(edit);
return this._applyEdit(edit);
}
}
_applyEdit(editBuilder: TextEditorEdit): TPromise<boolean> {
@@ -620,22 +627,6 @@ class ExtHostTextEditor implements vscode.TextEditor {
});
}
insertSnippet(template: string, posOrRange: Position | Range) {
let convertedPosOrRange: IPosition | IRange;
if (Position.isPosition(posOrRange)) {
convertedPosOrRange = TypeConverters.fromPosition(posOrRange);
}
else if (Range.isRange(posOrRange)) {
convertedPosOrRange = TypeConverters.fromRange(posOrRange);
}
else {
return TPromise.wrapError(new Error('Unrecognized value for posOrRange'));
}
return this._proxy.$tryInsertSnippet(this._id, template, convertedPosOrRange);
}
// ---- util
private _runOnProxy(callback: () => TPromise<any>, silent: boolean): TPromise<ExtHostTextEditor> {

View File

@@ -519,6 +519,16 @@ export class WorkspaceEdit {
export class SnippetString {
static isSnippetString(thing: any): thing is SnippetString {
if (thing instanceof SnippetString) {
return true;
}
if (!thing) {
return false;
}
return typeof (<SnippetString>thing).value === 'string';
}
private static _escape(value: string): string {
return value.replace(/\$|}|\\/g, '\\$&');
}

View File

@@ -8,13 +8,13 @@ import URI from 'vs/base/common/uri';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { TPromise } from 'vs/base/common/winjs.base';
import { IThreadService } from 'vs/workbench/services/thread/common/threadService';
import { ISingleEditOperation, ISelection, IPosition, IRange, IEditor, EditorType, ICommonCodeEditor, ICommonDiffEditor, IDecorationRenderOptions, IDecorationOptions } from 'vs/editor/common/editorCommon';
import { ISingleEditOperation, ISelection, IRange, IEditor, EditorType, ICommonCodeEditor, ICommonDiffEditor, IDecorationRenderOptions, IDecorationOptions } from 'vs/editor/common/editorCommon';
import { ICodeEditorService } from 'vs/editor/common/services/codeEditorService';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IEditorGroupService } from 'vs/workbench/services/group/common/groupService';
import { Position as EditorPosition } from 'vs/platform/editor/common/editor';
import { IModelService } from 'vs/editor/common/services/modelService';
import { MainThreadEditorsTracker, TextEditorRevealType, MainThreadTextEditor, IApplyEditsOptions, ITextEditorConfigurationUpdate } from 'vs/workbench/api/node/mainThreadEditorsTracker';
import { MainThreadEditorsTracker, TextEditorRevealType, MainThreadTextEditor, IApplyEditsOptions, IInsertSnippetOptions, ITextEditorConfigurationUpdate } from 'vs/workbench/api/node/mainThreadEditorsTracker';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { equals as arrayEquals } from 'vs/base/common/arrays';
import { equals as objectEquals } from 'vs/base/common/objects';
@@ -293,11 +293,11 @@ export class MainThreadEditors extends MainThreadEditorsShape {
return TPromise.as(this._textEditorsMap[id].applyEdits(modelVersionId, edits, opts));
}
$tryInsertSnippet(id: string, template: string, posOrRange: IPosition | IRange): TPromise<boolean> {
$tryInsertSnippet(id: string, template: string, opts: IInsertSnippetOptions): TPromise<boolean> {
if (!this._textEditorsMap[id]) {
return TPromise.wrapError('TextEditor disposed');
}
return TPromise.as(this._textEditorsMap[id].insertSnippet(template, posOrRange));
return TPromise.as(this._textEditorsMap[id].insertSnippet(template, opts));
}
$registerTextEditorDecorationType(key: string, options: IDecorationRenderOptions): void {

View File

@@ -12,7 +12,6 @@ import { IModelService } from 'vs/editor/common/services/modelService';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { RunOnceScheduler } from 'vs/base/common/async';
import { IdGenerator } from 'vs/base/common/idGenerator';
import { Position } from 'vs/editor/common/core/position';
import { Range } from 'vs/editor/common/core/range';
import { Selection } from 'vs/editor/common/core/selection';
import { SnippetController } from 'vs/editor/contrib/snippet/common/snippetController';
@@ -60,12 +59,19 @@ export enum TextEditorRevealType {
InCenterIfOutsideViewport = 2
}
export interface IApplyEditsOptions {
export interface IUndoStopOptions {
undoStopBefore: boolean;
undoStopAfter: boolean;
}
export interface IApplyEditsOptions extends IUndoStopOptions {
setEndOfLine: EndOfLine;
}
export interface IInsertSnippetOptions extends IUndoStopOptions {
}
/**
* Text Editor that is permanently bound to the same model.
* It can be bound or not to a CodeEditor.
@@ -386,24 +392,22 @@ export class MainThreadTextEditor {
return false;
}
insertSnippet(template: string, posOrRange: EditorCommon.IPosition | EditorCommon.IRange) {
insertSnippet(template: string, opts: IInsertSnippetOptions) {
const snippetController = SnippetController.get(this._codeEditor);
if (snippetController.inSnippetMode) {
return false;
}
const range = Range.isIRange(posOrRange) ? Range.lift(posOrRange) : null;
const position = Position.isIPosition(posOrRange) ? Position.lift(posOrRange) : range.getStartPosition();
this._codeEditor.setPosition(position);
this._codeEditor.revealLine(position.lineNumber);
this._codeEditor.focus();
if (range) {
snippetController.insertSnippetWithReplaceRange(template, range);
if (opts.undoStopBefore) {
this._codeEditor.pushUndoStop();
}
else {
snippetController.insertSnippet(template, 0, 0);
snippetController.insertSnippet(template, 0, 0);
if (opts.undoStopAfter) {
this._codeEditor.pushUndoStop();
}
return true;