提交 acb29bf4 编写于 作者: J Joao Moreno

registerDiffInformationCommand instead of computeDiff

上级 79a7e306
......@@ -5,7 +5,7 @@
'use strict';
import { Uri, commands, scm, Disposable, window, workspace, QuickPickItem, OutputChannel, computeDiff, Range, WorkspaceEdit, Position } from 'vscode';
import { Uri, commands, scm, Disposable, window, workspace, QuickPickItem, OutputChannel, Range, WorkspaceEdit, Position, LineChange } from 'vscode';
import { Ref, RefType, Git } from './git';
import { Model, Resource, Status, CommitOptions } from './model';
import * as staging from './staging';
......@@ -60,15 +60,23 @@ class CheckoutRemoteHeadItem extends CheckoutItem {
}
}
const Commands: { commandId: string; key: string; method: Function; skipModelCheck: boolean; }[] = [];
interface Command {
commandId: string;
key: string;
method: Function;
skipModelCheck: boolean;
requiresDiffInformation: boolean;
}
const Commands: Command[] = [];
function command(commandId: string, skipModelCheck = false): Function {
function command(commandId: string, skipModelCheck = false, requiresDiffInformation = false): Function {
return (target: any, key: string, descriptor: any) => {
if (!(typeof descriptor.value === 'function')) {
throw new Error('not supported');
}
Commands.push({ commandId, key, method: descriptor.value, skipModelCheck });
Commands.push({ commandId, key, method: descriptor.value, skipModelCheck, requiresDiffInformation });
};
}
......@@ -88,7 +96,15 @@ export class CommandCenter {
}
this.disposables = Commands
.map(({ commandId, key, method, skipModelCheck }) => commands.registerCommand(commandId, this.createCommand(commandId, key, method, skipModelCheck)));
.map(({ commandId, key, method, skipModelCheck, requiresDiffInformation }) => {
const command = this.createCommand(commandId, key, method, skipModelCheck);
if (requiresDiffInformation) {
return commands.registerDiffInformationCommand(commandId, command);
} else {
return commands.registerCommand(commandId, command);
}
});
}
@command('git.refresh')
......@@ -288,8 +304,8 @@ export class CommandCenter {
return await this.model.add();
}
@command('git.stageSelectedRanges')
async stageSelectedRanges(): Promise<void> {
@command('git.stageSelectedRanges', false, true)
async stageSelectedRanges(diffs: LineChange[]): Promise<void> {
const textEditor = window.activeTextEditor;
if (!textEditor) {
......@@ -305,7 +321,6 @@ export class CommandCenter {
const originalUri = modifiedUri.with({ scheme: 'git', query: '~' });
const originalDocument = await workspace.openTextDocument(originalUri);
const diffs = await computeDiff(originalDocument, modifiedDocument);
const selections = textEditor.selections;
const selectedDiffs = diffs.filter(diff => {
const modifiedRange = diff.modifiedEndLineNumber === 0
......@@ -323,8 +338,8 @@ export class CommandCenter {
await this.model.stage(modifiedUri, result);
}
@command('git.revertSelectedRanges')
async revertSelectedRanges(): Promise<void> {
@command('git.revertSelectedRanges', false, true)
async revertSelectedRanges(diffs: LineChange[]): Promise<void> {
const textEditor = window.activeTextEditor;
if (!textEditor) {
......@@ -340,7 +355,6 @@ export class CommandCenter {
const originalUri = modifiedUri.with({ scheme: 'git', query: '~' });
const originalDocument = await workspace.openTextDocument(originalUri);
const diffs = await computeDiff(originalDocument, modifiedDocument);
const selections = textEditor.selections;
const selectedDiffs = diffs.filter(diff => {
const modifiedRange = diff.modifiedEndLineNumber === 0
......@@ -385,8 +399,8 @@ export class CommandCenter {
return await this.model.revertFiles();
}
@command('git.unstageSelectedRanges')
async unstageSelectedRanges(): Promise<void> {
@command('git.unstageSelectedRanges', false, true)
async unstageSelectedRanges(diffs: LineChange[]): Promise<void> {
const textEditor = window.activeTextEditor;
if (!textEditor) {
......@@ -402,7 +416,6 @@ export class CommandCenter {
const originalUri = modifiedUri.with({ scheme: 'git', query: 'HEAD' });
const originalDocument = await workspace.openTextDocument(originalUri);
const diffs = await computeDiff(originalDocument, modifiedDocument);
const selections = textEditor.selections;
const selectedDiffs = diffs.filter(diff => {
const modifiedRange = diff.modifiedEndLineNumber === 0
......
......@@ -639,5 +639,22 @@ declare module 'vscode' {
readonly modifiedEndLineNumber: number;
}
export function computeDiff(oneDocument: TextDocument, otherDocument: TextDocument): Thenable<LineChange[]>;
}
export namespace commands {
/**
* Registers a diff information command that can be invoked via a keyboard shortcut,
* a menu item, an action, or directly.
*
* Diff information commands are different from ordinary [commands](#commands.registerCommand) as
* they only execute when there is an active diff editor when the command is called, and the diff
* information has been computed. Also, the command handler of an editor command has access to
* the diff information.
*
* @param command A unique identifier for the command.
* @param callback A command handler function with access to the [diff information](#LineChange).
* @param thisArg The `this` context used when invoking the handler function.
* @return Disposable which unregisters this command on disposal.
*/
export function registerDiffInformationCommand(command: string, callback: (diff: LineChange[], ...args: any[]) => any, thisArg?: any): Disposable;
}
}
\ No newline at end of file
......@@ -33,7 +33,6 @@ import { ExtHostEditors } from 'vs/workbench/api/node/extHostTextEditors';
import { ExtHostLanguages } from 'vs/workbench/api/node/extHostLanguages';
import { ExtHostLanguageFeatures } from 'vs/workbench/api/node/extHostLanguageFeatures';
import { ExtHostApiCommands } from 'vs/workbench/api/node/extHostApiCommands';
import { computeDiff } from 'vs/workbench/api/node/extHostFunctions';
import { ExtHostTask } from 'vs/workbench/api/node/extHostTask';
import * as extHostTypes from 'vs/workbench/api/node/extHostTypes';
import URI from 'vs/base/common/uri';
......@@ -167,6 +166,18 @@ export function createApiFactory(initData: IInitData, threadService: IThreadServ
});
});
},
registerDiffInformationCommand(id: string, callback: (diff: vscode.LineChange[], ...args: any[]) => any, thisArg?: any): vscode.Disposable {
return extHostCommands.registerCommand(id, async (...args: any[]) => {
let activeTextEditor = extHostEditors.getActiveTextEditor();
if (!activeTextEditor) {
console.warn('Cannot execute ' + id + ' because there is no active text editor.');
return undefined;
}
const diff = await extHostEditors.getDiffInformation(activeTextEditor.id);
callback.apply(thisArg, [diff, ...args]);
});
},
executeCommand<T>(id: string, ...args: any[]): Thenable<T> {
return extHostCommands.executeCommand(id, ...args);
},
......@@ -499,7 +510,6 @@ export function createApiFactory(initData: IInitData, threadService: IThreadServ
ViewColumn: extHostTypes.ViewColumn,
WorkspaceEdit: extHostTypes.WorkspaceEdit,
// functions
computeDiff,
FileLocationKind: extHostTypes.FileLocationKind,
ApplyToKind: extHostTypes.ApplyToKind,
RevealKind: extHostTypes.RevealKind,
......
......@@ -140,6 +140,7 @@ export abstract class MainThreadEditorsShape {
$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, selections: editorCommon.IRange[], opts: IUndoStopOptions): TPromise<any> { throw ni(); }
$getDiffInformation(id: string): TPromise<editorCommon.ILineChange[]> { throw ni(); }
}
export abstract class MainThreadTreeExplorersShape {
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as vscode from 'vscode';
import { toThenable } from 'vs/base/common/async';
import { DiffComputer } from 'vs/editor/common/diff/diffComputer';
function getTextDocumentLines(document: vscode.TextDocument): string[] {
const result = [];
for (let i = 0; i < document.lineCount; i++) {
result.push(document.lineAt(i).text);
}
return result;
}
export function computeDiff(oneDocument: vscode.TextDocument, otherDocument: vscode.TextDocument): Thenable<vscode.LineChange[]> {
const oneLines = getTextDocumentLines(oneDocument);
const otherLines = getTextDocumentLines(otherDocument);
const computer = new DiffComputer(oneLines, otherLines, {
shouldPostProcessCharChanges: false,
shouldIgnoreTrimWhitespace: false, // options?
shouldConsiderTrimWhitespaceInEmptyCase: false
});
return toThenable(computer.computeDiff());
}
\ No newline at end of file
......@@ -322,6 +322,8 @@ export class ExtHostTextEditor implements vscode.TextEditor {
private _viewColumn: vscode.ViewColumn;
private _disposed: boolean = false;
get id(): string { return this._id; }
constructor(proxy: MainThreadEditorsShape, id: string, document: ExtHostDocumentData, selections: Selection[], options: IResolvedTextEditorConfiguration, viewColumn: vscode.ViewColumn) {
this._proxy = proxy;
this._id = id;
......
......@@ -6,12 +6,13 @@
import URI from 'vs/base/common/uri';
import Event, { Emitter } from 'vs/base/common/event';
import { toThenable } from 'vs/base/common/async';
import { TPromise } from 'vs/base/common/winjs.base';
import { IThreadService } from 'vs/workbench/services/thread/common/threadService';
import { TextEditorSelectionChangeKind } from './extHostTypes';
import { IResolvedTextEditorConfiguration, ISelectionChangeEvent } from 'vs/workbench/api/node/mainThreadEditor';
import * as TypeConverters from './extHostTypeConverters';
import { TextEditorDecorationType } from './extHostTextEditor';
import { TextEditorDecorationType, ExtHostTextEditor } from './extHostTextEditor';
import { ExtHostDocumentsAndEditors } from './extHostDocumentsAndEditors';
import { MainContext, MainThreadEditorsShape, ExtHostEditorsShape, ITextEditorPositionData } from './extHost.protocol';
import * as vscode from 'vscode';
......@@ -46,7 +47,7 @@ export class ExtHostEditors extends ExtHostEditorsShape {
this._extHostDocumentsAndEditors.onDidChangeActiveTextEditor(e => this._onDidChangeActiveTextEditor.fire(e));
}
getActiveTextEditor(): vscode.TextEditor {
getActiveTextEditor(): ExtHostTextEditor {
return this._extHostDocumentsAndEditors.activeEditor();
}
......@@ -102,4 +103,8 @@ export class ExtHostEditors extends ExtHostEditorsShape {
}
}
}
getDiffInformation(id: string): Thenable<vscode.LineChange[]> {
return toThenable(this._proxy.$getDiffInformation(id));
}
}
......@@ -8,7 +8,7 @@ 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, IRange, IDecorationRenderOptions, IDecorationOptions } from 'vs/editor/common/editorCommon';
import { ISingleEditOperation, ISelection, IRange, IDecorationRenderOptions, IDecorationOptions, ILineChange } 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';
......@@ -200,6 +200,24 @@ export class MainThreadEditors extends MainThreadEditorsShape {
$removeTextEditorDecorationType(key: string): void {
this._codeEditorService.removeDecorationType(key);
}
$getDiffInformation(id: string): TPromise<ILineChange[]> {
const editor = this._documentsAndEditors.getEditor(id);
if (!editor) {
return TPromise.wrapError('No such TextEditor');
}
const codeEditor = editor.getCodeEditor();
const codeEditorId = codeEditor.getId();
const diffEditors = this._codeEditorService.listDiffEditors();
const [diffEditor] = diffEditors.filter(d => d.getOriginalEditor().getId() === codeEditorId || d.getModifiedEditor().getId() === codeEditorId);
if (!diffEditor) {
return TPromise.as([]);
}
return TPromise.as(diffEditor.getLineChanges());
}
}
......@@ -64,7 +64,8 @@ suite('ExtHostTextEditorOptions', () => {
$tryRevealRange: undefined,
$trySetSelections: undefined,
$tryApplyEdits: undefined,
$tryInsertSnippet: undefined
$tryInsertSnippet: undefined,
$getDiffInformation: undefined
};
opts = new ExtHostTextEditorOptions(mockProxy, '1', {
tabSize: 4,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册