mirror of
https://github.com/Microsoft/vscode
synced 2024-09-18 01:58:27 +00:00
✨ registerDiffInformationCommand instead of computeDiff
This commit is contained in:
parent
79a7e30685
commit
acb29bf425
|
@ -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;
|
||||
}
|
||||
|
||||
function command(commandId: string, skipModelCheck = false): Function {
|
||||
const Commands: Command[] = [];
|
||||
|
||||
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
|
||||
|
|
21
src/vs/vscode.proposed.d.ts
vendored
21
src/vs/vscode.proposed.d.ts
vendored
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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 {
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* 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());
|
||||
}
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue