提交 7d729c9d 编写于 作者: J Joao Moreno

diff: inline actions

上级 c5e3aace
...@@ -101,6 +101,24 @@ ...@@ -101,6 +101,24 @@
"title": "%command.revertSelectedRanges%", "title": "%command.revertSelectedRanges%",
"category": "Git" "category": "Git"
}, },
{
"command": "git.stageChange",
"title": "%command.stageChange%",
"category": "Git",
"icon": {
"light": "resources/icons/light/stage.svg",
"dark": "resources/icons/dark/stage.svg"
}
},
{
"command": "git.revertChange",
"title": "%command.revertChange%",
"category": "Git",
"icon": {
"light": "resources/icons/light/clean.svg",
"dark": "resources/icons/dark/clean.svg"
}
},
{ {
"command": "git.unstage", "command": "git.unstage",
"title": "%command.unstage%", "title": "%command.unstage%",
...@@ -722,6 +740,16 @@ ...@@ -722,6 +740,16 @@
"group": "2_git@3", "group": "2_git@3",
"when": "config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme != merge-conflict.conflict-diff" "when": "config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme != merge-conflict.conflict-diff"
} }
],
"scm/change/title": [
{
"command": "git.stageChange",
"when": "config.git.enabled && originalResourceScheme == git"
},
{
"command": "git.revertChange",
"when": "config.git.enabled && originalResourceScheme == git"
}
] ]
}, },
"configuration": { "configuration": {
......
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
"command.stageAll": "Stage All Changes", "command.stageAll": "Stage All Changes",
"command.stageSelectedRanges": "Stage Selected Ranges", "command.stageSelectedRanges": "Stage Selected Ranges",
"command.revertSelectedRanges": "Revert Selected Ranges", "command.revertSelectedRanges": "Revert Selected Ranges",
"command.stageChange": "Stage Change",
"command.revertChange": "Revert Change",
"command.unstage": "Unstage Changes", "command.unstage": "Unstage Changes",
"command.unstageAll": "Unstage All Changes", "command.unstageAll": "Unstage All Changes",
"command.unstageSelectedRanges": "Unstage Selected Ranges", "command.unstageSelectedRanges": "Unstage Selected Ranges",
......
...@@ -556,8 +556,13 @@ export class CommandCenter { ...@@ -556,8 +556,13 @@ export class CommandCenter {
await repository.add([]); await repository.add([]);
} }
@command('git.stageChange')
async stageChange(change: LineChange): Promise<void> {
await this.stageChanges([change]);
}
@command('git.stageSelectedRanges', { diff: true }) @command('git.stageSelectedRanges', { diff: true })
async stageSelectedRanges(diffs: LineChange[]): Promise<void> { async stageChanges(changes: LineChange[]): Promise<void> {
const textEditor = window.activeTextEditor; const textEditor = window.activeTextEditor;
if (!textEditor) { if (!textEditor) {
...@@ -574,7 +579,7 @@ export class CommandCenter { ...@@ -574,7 +579,7 @@ export class CommandCenter {
const originalUri = toGitUri(modifiedUri, '~'); const originalUri = toGitUri(modifiedUri, '~');
const originalDocument = await workspace.openTextDocument(originalUri); const originalDocument = await workspace.openTextDocument(originalUri);
const selectedLines = toLineRanges(textEditor.selections, modifiedDocument); const selectedLines = toLineRanges(textEditor.selections, modifiedDocument);
const selectedDiffs = diffs const selectedDiffs = changes
.map(diff => selectedLines.reduce<LineChange | null>((result, range) => result || intersectDiffWithRange(modifiedDocument, diff, range), null)) .map(diff => selectedLines.reduce<LineChange | null>((result, range) => result || intersectDiffWithRange(modifiedDocument, diff, range), null))
.filter(d => !!d) as LineChange[]; .filter(d => !!d) as LineChange[];
...@@ -587,8 +592,13 @@ export class CommandCenter { ...@@ -587,8 +592,13 @@ export class CommandCenter {
await this.runByRepository(modifiedUri, async (repository, resource) => await repository.stage(resource, result)); 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]);
}
@command('git.revertSelectedRanges', { diff: true }) @command('git.revertSelectedRanges', { diff: true })
async revertSelectedRanges(diffs: LineChange[]): Promise<void> { async revertChanges(diffs: LineChange[]): Promise<void> {
const textEditor = window.activeTextEditor; const textEditor = window.activeTextEditor;
if (!textEditor) { if (!textEditor) {
......
...@@ -39,17 +39,20 @@ ...@@ -39,17 +39,20 @@
height: 100%; height: 100%;
} }
.monaco-editor .peekview-widget .head .peekview-actions > .monaco-action-bar .action-label { .monaco-editor .peekview-widget .head .peekview-actions > .monaco-action-bar .action-item {
line-height: inherit; margin-left: 4px;
} }
.monaco-editor .peekview-widget .head .peekview-actions > .monaco-action-bar .action-label.octicon { .monaco-editor .peekview-widget .head .peekview-actions > .monaco-action-bar .action-label {
width: 16px;
height: 100%;
margin: 0; margin: 0;
line-height: inherit;
background-repeat: no-repeat;
background-position: center center;
} }
.monaco-editor .peekview-widget .head .peekview-actions .action-label { .monaco-editor .peekview-widget .head .peekview-actions > .monaco-action-bar .action-label.octicon {
width: 16px;
height: 100%;
margin: 0; margin: 0;
} }
......
...@@ -53,6 +53,7 @@ export class MenuId { ...@@ -53,6 +53,7 @@ export class MenuId {
static readonly SCMSourceControl = new MenuId(); static readonly SCMSourceControl = new MenuId();
static readonly SCMResourceGroupContext = new MenuId(); static readonly SCMResourceGroupContext = new MenuId();
static readonly SCMResourceContext = new MenuId(); static readonly SCMResourceContext = new MenuId();
static readonly SCMChangeContext = new MenuId();
static readonly CommandPalette = new MenuId(); static readonly CommandPalette = new MenuId();
static readonly ViewTitle = new MenuId(); static readonly ViewTitle = new MenuId();
static readonly ViewItemContext = new MenuId(); static readonly ViewItemContext = new MenuId();
......
...@@ -40,6 +40,7 @@ namespace schema { ...@@ -40,6 +40,7 @@ namespace schema {
case 'scm/sourceControl': return MenuId.SCMSourceControl; case 'scm/sourceControl': return MenuId.SCMSourceControl;
case 'scm/resourceGroup/context': return MenuId.SCMResourceGroupContext; case 'scm/resourceGroup/context': return MenuId.SCMResourceGroupContext;
case 'scm/resourceState/context': return MenuId.SCMResourceContext; case 'scm/resourceState/context': return MenuId.SCMResourceContext;
case 'scm/change/title': return MenuId.SCMChangeContext;
case 'view/title': return MenuId.ViewTitle; case 'view/title': return MenuId.ViewTitle;
case 'view/item/context': return MenuId.ViewItemContext; case 'view/item/context': return MenuId.ViewItemContext;
} }
......
...@@ -16,7 +16,7 @@ import * as ext from 'vs/workbench/common/contributions'; ...@@ -16,7 +16,7 @@ import * as ext from 'vs/workbench/common/contributions';
import * as common from 'vs/editor/common/editorCommon'; import * as common from 'vs/editor/common/editorCommon';
import { CodeEditor } from 'vs/editor/browser/codeEditor'; import { CodeEditor } from 'vs/editor/browser/codeEditor';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IMessageService } from 'vs/platform/message/common/message'; import { IMessageService, Severity } from 'vs/platform/message/common/message';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { ITextModelService } from 'vs/editor/common/services/resolverService'; import { ITextModelService } from 'vs/editor/common/services/resolverService';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
...@@ -43,10 +43,27 @@ import { KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRe ...@@ -43,10 +43,27 @@ import { KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRe
import { peekViewBorder, peekViewTitleBackground, peekViewTitleForeground, peekViewTitleInfoForeground } from 'vs/editor/contrib/referenceSearch/browser/referencesWidget'; import { peekViewBorder, peekViewTitleBackground, peekViewTitleForeground, peekViewTitleInfoForeground } from 'vs/editor/contrib/referenceSearch/browser/referencesWidget';
import { EmbeddedDiffEditorWidget } from 'vs/editor/browser/widget/embeddedCodeEditorWidget'; import { EmbeddedDiffEditorWidget } from 'vs/editor/browser/widget/embeddedCodeEditorWidget';
import { IDiffEditorOptions } from 'vs/editor/common/config/editorOptions'; import { IDiffEditorOptions } from 'vs/editor/common/config/editorOptions';
import { Action } from 'vs/base/common/actions'; import { Action, IAction } from 'vs/base/common/actions';
import { IActionBarOptions, ActionsOrientation } from 'vs/base/browser/ui/actionbar/actionbar'; import { IActionBarOptions, ActionsOrientation, IActionItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { basename } from 'vs/base/common/paths'; import { basename } from 'vs/base/common/paths';
import { MenuId, IMenuService, IMenu, MenuItemAction } from 'vs/platform/actions/common/actions';
import { fillInActions, MenuItemActionItem } from 'vs/platform/actions/browser/menuItemActionItem';
// TODO@Joao
// Need to subclass MenuItemActionItem in order to respect
// the action context coming from any action bar, without breaking
// existing users
class DiffMenuItemActionItem extends MenuItemActionItem {
onClick(event: MouseEvent): void {
event.preventDefault();
event.stopPropagation();
this.actionRunner.run(this._commandAction, this._context)
.done(undefined, err => this._messageService.show(Severity.Error, err));
}
}
export interface IModelRegistry { export interface IModelRegistry {
getModel(editorModel: common.IEditorModel): DirtyDiffModel; getModel(editorModel: common.IEditorModel): DirtyDiffModel;
...@@ -115,22 +132,31 @@ class DirtyDiffWidget extends PeekViewWidget { ...@@ -115,22 +132,31 @@ class DirtyDiffWidget extends PeekViewWidget {
private diffEditor: EmbeddedDiffEditorWidget; private diffEditor: EmbeddedDiffEditorWidget;
private title: string; private title: string;
private menu: IMenu;
private change: common.IChange; private change: common.IChange;
private didLayout = false; private didLayout = false;
private contextKeyService: IContextKeyService;
constructor( constructor(
editor: ICodeEditor, editor: ICodeEditor,
private model: DirtyDiffModel, private model: DirtyDiffModel,
themeService: IThemeService, @IThemeService themeService: IThemeService,
private instantiationService: IInstantiationService @IInstantiationService private instantiationService: IInstantiationService,
@IMenuService private menuService: IMenuService,
@IKeybindingService private keybindingService: IKeybindingService,
@IMessageService private messageService: IMessageService,
@IContextKeyService contextKeyService: IContextKeyService
) { ) {
super(editor, { isResizeable: true }); super(editor, { isResizeable: true });
themeService.onThemeChange(this._applyTheme, this, this._disposables); themeService.onThemeChange(this._applyTheme, this, this._disposables);
this._applyTheme(themeService.getTheme()); this._applyTheme(themeService.getTheme());
this.create(); this.contextKeyService = contextKeyService.createScoped();
this.contextKeyService.createKey('originalResourceScheme', this.model.original.uri.scheme);
this.menu = menuService.createMenu(MenuId.SCMChangeContext, this.contextKeyService);
this.create();
this.title = basename(editor.getModel().uri.fsPath); this.title = basename(editor.getModel().uri.fsPath);
this.setTitle(this.title); this.setTitle(this.title);
} }
...@@ -161,7 +187,7 @@ class DirtyDiffWidget extends PeekViewWidget { ...@@ -161,7 +187,7 @@ class DirtyDiffWidget extends PeekViewWidget {
: localize('change', "{0} of {1} change", index + 1, this.model.changes.length); : localize('change', "{0} of {1} change", index + 1, this.model.changes.length);
this.setTitle(this.title, detail); this.setTitle(this.title, detail);
this._actionbarWidget.context = change;
this.show(position, height); this.show(position, height);
} }
...@@ -174,14 +200,27 @@ class DirtyDiffWidget extends PeekViewWidget { ...@@ -174,14 +200,27 @@ class DirtyDiffWidget extends PeekViewWidget {
this._disposables.push(previous); this._disposables.push(previous);
this._disposables.push(next); this._disposables.push(next);
this._actionbarWidget.push([previous, next], { label: false, icon: true }); this._actionbarWidget.push([previous, next], { label: false, icon: true });
const actions: IAction[] = [];
fillInActions(this.menu, { shouldForwardArgs: true }, actions);
this._actionbarWidget.push(actions, { label: false, icon: true });
} }
protected _getActionBarOptions(): IActionBarOptions { protected _getActionBarOptions(): IActionBarOptions {
return { return {
actionItemProvider: action => this.getActionItem(action),
orientation: ActionsOrientation.HORIZONTAL_REVERSE orientation: ActionsOrientation.HORIZONTAL_REVERSE
}; };
} }
getActionItem(action: IAction): IActionItem {
if (!(action instanceof MenuItemAction)) {
return undefined;
}
return new DiffMenuItemActionItem(action, this.keybindingService, this.messageService);
}
protected _fillBody(container: HTMLElement): void { protected _fillBody(container: HTMLElement): void {
const options: IDiffEditorOptions = { const options: IDiffEditorOptions = {
scrollBeyondLastLine: true, scrollBeyondLastLine: true,
...@@ -395,7 +434,7 @@ export class DirtyDiffController implements common.IEditorContribution { ...@@ -395,7 +434,7 @@ export class DirtyDiffController implements common.IEditorContribution {
this.changeIndex = -1; this.changeIndex = -1;
this.model = model; this.model = model;
this.widget = new DirtyDiffWidget(this.editor, model, this.themeService, this.instantiationService); this.widget = this.instantiationService.createInstance(DirtyDiffWidget, this.editor, model);
this.isDirtyDiffVisible.set(true); this.isDirtyDiffVisible.set(true);
// TODO react on model changes // TODO react on model changes
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册