提交 1f058ae1 编写于 作者: J Joao Moreno

diff: fix stage/revert ranges

上级 90fc26ca
......@@ -5,7 +5,7 @@
'use strict';
import { Uri, commands, Disposable, window, workspace, QuickPickItem, OutputChannel, Range, WorkspaceEdit, Position, LineChange, SourceControlResourceState, TextDocumentShowOptions, ViewColumn, ProgressLocation } from 'vscode';
import { Uri, commands, Disposable, window, workspace, QuickPickItem, OutputChannel, Range, WorkspaceEdit, Position, LineChange, SourceControlResourceState, TextDocumentShowOptions, ViewColumn, ProgressLocation, TextEditor } from 'vscode';
import { Ref, RefType, Git, GitErrorCodes, Branch } from './git';
import { Repository, Resource, Status, CommitOptions, ResourceGroupType } from './repository';
import { Model } from './model';
......@@ -557,12 +557,18 @@ export class CommandCenter {
}
@command('git.stageChange')
async stageChange(change: LineChange): Promise<void> {
await this.stageChanges([change]);
async stageChange(uri: Uri, changes: LineChange[], index: number): Promise<void> {
const textEditor = window.visibleTextEditors.filter(e => e.document.uri.toString() === uri.toString())[0];
if (!textEditor) {
return;
}
await this._stageChanges(textEditor, [changes[index]]);
}
@command('git.stageSelectedRanges', { diff: true })
async stageChanges(changes: LineChange[]): Promise<void> {
async stageSelectedChanges(changes: LineChange[]): Promise<void> {
const textEditor = window.activeTextEditor;
if (!textEditor) {
......@@ -570,35 +576,46 @@ export class CommandCenter {
}
const modifiedDocument = textEditor.document;
const modifiedUri = modifiedDocument.uri;
const selectedLines = toLineRanges(textEditor.selections, modifiedDocument);
const selectedChanges = changes
.map(diff => selectedLines.reduce<LineChange | null>((result, range) => result || intersectDiffWithRange(modifiedDocument, diff, range), null))
.filter(d => !!d) as LineChange[];
if (modifiedUri.scheme !== 'file') {
if (!selectedChanges.length) {
return;
}
const originalUri = toGitUri(modifiedUri, '~');
const originalDocument = await workspace.openTextDocument(originalUri);
const selectedLines = toLineRanges(textEditor.selections, modifiedDocument);
const selectedDiffs = changes
.map(diff => selectedLines.reduce<LineChange | null>((result, range) => result || intersectDiffWithRange(modifiedDocument, diff, range), null))
.filter(d => !!d) as LineChange[];
await this._stageChanges(textEditor, selectedChanges);
}
if (!selectedDiffs.length) {
private async _stageChanges(textEditor: TextEditor, changes: LineChange[]): Promise<void> {
const modifiedDocument = textEditor.document;
const modifiedUri = modifiedDocument.uri;
if (modifiedUri.scheme !== 'file') {
return;
}
const result = applyLineChanges(originalDocument, modifiedDocument, selectedDiffs);
const originalUri = toGitUri(modifiedUri, '~');
const originalDocument = await workspace.openTextDocument(originalUri);
const result = applyLineChanges(originalDocument, modifiedDocument, changes);
await this.runByRepository(modifiedUri, async (repository, resource) => await repository.stage(resource, result));
}
@command('git.revertChange')
async revertChange(change: LineChange): Promise<void> {
await this.revertChanges([change]);
async revertChange(uri: Uri, changes: LineChange[], index: number): Promise<void> {
const textEditor = window.visibleTextEditors.filter(e => e.document.uri.toString() === uri.toString())[0];
if (!textEditor) {
return;
}
await this._revertChanges(textEditor, [...changes.slice(0, index), ...changes.slice(index + 1)]);
}
@command('git.revertSelectedRanges', { diff: true })
async revertChanges(diffs: LineChange[]): Promise<void> {
async revertSelectedRanges(changes: LineChange[]): Promise<void> {
const textEditor = window.activeTextEditor;
if (!textEditor) {
......@@ -606,27 +623,32 @@ export class CommandCenter {
}
const modifiedDocument = textEditor.document;
const modifiedUri = modifiedDocument.uri;
const selections = textEditor.selections;
const selectedChanges = changes.filter(change => {
const modifiedRange = change.modifiedEndLineNumber === 0
? new Range(modifiedDocument.lineAt(change.modifiedStartLineNumber - 1).range.end, modifiedDocument.lineAt(change.modifiedStartLineNumber).range.start)
: new Range(modifiedDocument.lineAt(change.modifiedStartLineNumber - 1).range.start, modifiedDocument.lineAt(change.modifiedEndLineNumber - 1).range.end);
if (modifiedUri.scheme !== 'file') {
return selections.every(selection => !selection.intersection(modifiedRange));
});
if (selectedChanges.length === changes.length) {
return;
}
const originalUri = toGitUri(modifiedUri, '~');
const originalDocument = await workspace.openTextDocument(originalUri);
const selections = textEditor.selections;
const selectedDiffs = diffs.filter(diff => {
const modifiedRange = diff.modifiedEndLineNumber === 0
? new Range(modifiedDocument.lineAt(diff.modifiedStartLineNumber - 1).range.end, modifiedDocument.lineAt(diff.modifiedStartLineNumber).range.start)
: new Range(modifiedDocument.lineAt(diff.modifiedStartLineNumber - 1).range.start, modifiedDocument.lineAt(diff.modifiedEndLineNumber - 1).range.end);
await this._revertChanges(textEditor, selectedChanges);
}
return selections.every(selection => !selection.intersection(modifiedRange));
});
private async _revertChanges(textEditor: TextEditor, changes: LineChange[]): Promise<void> {
const modifiedDocument = textEditor.document;
const modifiedUri = modifiedDocument.uri;
if (selectedDiffs.length === diffs.length) {
if (modifiedUri.scheme !== 'file') {
return;
}
const originalUri = toGitUri(modifiedUri, '~');
const originalDocument = await workspace.openTextDocument(originalUri);
const basename = path.basename(modifiedUri.fsPath);
const message = localize('confirm revert', "Are you sure you want to revert the selected changes in {0}?", basename);
const yes = localize('revert', "Revert Changes");
......@@ -636,10 +658,11 @@ export class CommandCenter {
return;
}
const result = applyLineChanges(originalDocument, modifiedDocument, selectedDiffs);
const result = applyLineChanges(originalDocument, modifiedDocument, changes);
const edit = new WorkspaceEdit();
edit.replace(modifiedUri, new Range(new Position(0, 0), modifiedDocument.lineAt(modifiedDocument.lineCount - 1).range.end), result);
workspace.applyEdit(edit);
await modifiedDocument.save();
}
@command('git.unstage')
......
......@@ -42,7 +42,7 @@ import { KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRe
import { peekViewBorder, peekViewTitleBackground, peekViewTitleForeground, peekViewTitleInfoForeground } from 'vs/editor/contrib/referenceSearch/browser/referencesWidget';
import { EmbeddedDiffEditorWidget } from 'vs/editor/browser/widget/embeddedCodeEditorWidget';
import { IDiffEditorOptions } from 'vs/editor/common/config/editorOptions';
import { Action, IAction } from 'vs/base/common/actions';
import { Action, IAction, ActionRunner } from 'vs/base/common/actions';
import { IActionBarOptions, ActionsOrientation, IActionItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { basename } from 'vs/base/common/paths';
......@@ -66,6 +66,17 @@ class DiffMenuItemActionItem extends MenuItemActionItem {
}
}
class DiffActionRunner extends ActionRunner {
runAction(action: IAction, context: any): TPromise<any> {
if (action instanceof MenuItemAction) {
return action.run(...context);
}
return super.runAction(action, context);
}
}
export interface IModelRegistry {
getModel(editorModel: IEditorModel): DirtyDiffModel;
}
......@@ -188,7 +199,7 @@ class DirtyDiffWidget extends PeekViewWidget {
const height = getChangeHeight(change) + /* padding */ 8;
this.renderTitle();
this._actionbarWidget.context = change;
this._actionbarWidget.context = [this.model.modified.uri, this.model.changes, index];
this.show(position, height);
}
......@@ -217,6 +228,7 @@ class DirtyDiffWidget extends PeekViewWidget {
protected _getActionBarOptions(): IActionBarOptions {
return {
actionRunner: new DiffActionRunner(),
actionItemProvider: action => this.getActionItem(action),
orientation: ActionsOrientation.HORIZONTAL_REVERSE
};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册