提交 ee9d4212 编写于 作者: J Johannes Rieken

first cut of panel and changes tree

上级 94a46931
......@@ -30,6 +30,10 @@
"name": "vs/workbench/api/common",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/contrib/bulkEdit",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/contrib/cli",
"project": "vscode-workbench"
......
......@@ -10,6 +10,7 @@ import { escape } from 'vs/base/common/strings';
export interface IHighlight {
start: number;
end: number;
extraClasses?: string;
}
export class HighlightedLabel {
......@@ -69,7 +70,7 @@ export class HighlightedLabel {
htmlContent += '</span>';
pos = highlight.end;
}
htmlContent += '<span class="highlight">';
htmlContent += `<span class="highlight ${highlight.extraClasses || ''}">`;
const substring = this.text.substring(highlight.start, highlight.end);
htmlContent += this.supportCodicons ? renderCodicons(escape(substring)) : escape(substring);
htmlContent += '</span>';
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
import { Registry } from 'vs/platform/registry/common/platform';
import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions';
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
import { IBulkEditService } from 'vs/editor/browser/services/bulkEditService';
import { WorkspaceEdit } from 'vs/editor/common/modes';
import { BulkEditPanel } from 'vs/workbench/contrib/bulkEdit/browser/bulkEditPanel';
import { Extensions as PanelExtensions, PanelDescriptor, PanelRegistry } from 'vs/workbench/browser/panel';
import { localize } from 'vs/nls';
class BulkEditPreviewContribution {
constructor(
@IPanelService private _panelService: IPanelService,
@IBulkEditService bulkEditService: IBulkEditService,
) {
bulkEditService.setPreviewHandler(edit => this._previewEdit(edit));
}
private async _previewEdit(edit: WorkspaceEdit) {
const panel = this._panelService.openPanel(BulkEditPanel.ID, true);
if (!(panel instanceof BulkEditPanel)) {
// error?
return edit;
}
const apply = await panel.setInput(edit);
if (!apply) {
return { edits: [] };
}
// todo@joh get 'real' edit
return edit;
}
}
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(
BulkEditPreviewContribution, LifecyclePhase.Ready
);
Registry.as<PanelRegistry>(PanelExtensions.Panels).registerPanel(PanelDescriptor.create(
BulkEditPanel,
BulkEditPanel.ID,
localize('panel', "Refactor Preview"),
'bulkEditPanel',
10
));
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
.monaco-workbench .bulk-edit-panel .highlight.remove {
text-decoration: line-through;
}
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./bulkEdit';
import { Panel } from 'vs/workbench/browser/panel';
import { Dimension, addClass } from 'vs/base/browser/dom';
import { WorkbenchAsyncDataTree } from 'vs/platform/list/browser/listService';
import { WorkspaceEdit } from 'vs/editor/common/modes';
import { Edit, BulkEditDelegate, TextEditElementRenderer, FileElementRenderer, BulkEditDataSource, BulkEditIdentityProvider } from 'vs/workbench/contrib/bulkEdit/browser/bulkEditTree';
import { FuzzyScore } from 'vs/base/common/filters';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IThemeService, registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { Action, IAction } from 'vs/base/common/actions';
import { diffInserted, diffRemoved } from 'vs/platform/theme/common/colorRegistry';
export class BulkEditPanel extends Panel {
static readonly ID = 'BulkEditPanel';
private static EmptyWorkspaceEdit = { edits: [] };
private _tree!: WorkbenchAsyncDataTree<WorkspaceEdit, Edit, FuzzyScore>;
private _acceptAction: IAction;
private _discardAction: IAction;
constructor(
@IInstantiationService private readonly _instaService: IInstantiationService,
@ITelemetryService telemetryService: ITelemetryService,
@IThemeService themeService: IThemeService,
@IStorageService storageService: IStorageService
) {
super(BulkEditPanel.ID, telemetryService, themeService, storageService);
this._acceptAction = new Action('ok', 'Apply', 'codicon-check', false, async () => this._done(true));
this._discardAction = new Action('ok', 'Discard', 'codicon-trash', false, async () => this._done(false));
}
create(parent: HTMLElement): void {
super.create(parent);
addClass(parent, 'bulk-edit-panel');
const treeContainer = document.createElement('div');
treeContainer.style.width = '100%';
treeContainer.style.height = '100%';
parent.appendChild(treeContainer);
this._tree = this._instaService.createInstance(
WorkbenchAsyncDataTree, this.getId(), treeContainer,
new BulkEditDelegate(),
[new TextEditElementRenderer(), this._instaService.createInstance(FileElementRenderer)],
this._instaService.createInstance(BulkEditDataSource),
{
identityProvider: new BulkEditIdentityProvider()
}
);
}
layout(dimension: Dimension): void {
this._tree.layout(dimension.height, dimension.width);
}
private _currentResolve?: (apply: boolean) => void;
setInput(edit: WorkspaceEdit): Promise<boolean> {
if (this._currentResolve) {
this._currentResolve(false);
this._currentResolve = undefined;
}
this._acceptAction.enabled = true;
this._discardAction.enabled = true;
return new Promise(async resolve => {
this._currentResolve = resolve;
await this._tree.setInput(edit);
this._tree.domFocus();
this._tree.focusFirst();
});
}
private _done(accept: boolean): void {
if (this._currentResolve) {
this._currentResolve(accept);
this._acceptAction.enabled = false;
this._discardAction.enabled = false;
this._tree.setInput(BulkEditPanel.EmptyWorkspaceEdit);
}
}
getActions() {
return [this._acceptAction, this._discardAction];
}
}
registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
const diffInsertedColor = theme.getColor(diffInserted);
if (diffInsertedColor) {
collector.addRule(`.monaco-workbench .bulk-edit-panel .highlight.insert { background-color: ${diffInsertedColor}; }`);
}
const diffRemovedColor = theme.getColor(diffRemoved);
if (diffRemovedColor) {
collector.addRule(`.monaco-workbench .bulk-edit-panel .highlight.remove { background-color: ${diffRemovedColor}; }`);
}
});
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// import { IAsyncDataSource, ITreeRenderer, ITreeNode } from 'vs/base/browser/ui/tree/tree';
// import * as modes from 'vs/editor/common/modes';
// import { ITextModelContentProvider, ITextModelService } from 'vs/editor/common/services/resolverService';
// import { URI } from 'vs/base/common/uri';
// import { ITextModel } from 'vs/editor/common/model';
// import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
// import { IModeService } from 'vs/editor/common/services/modeService';
// import { IModelService } from 'vs/editor/common/services/modelService';
// import { createTextBufferFactoryFromSnapshot } from 'vs/editor/common/model/textModel';
// export class BulkEditPreviewProvider implements ITextModelContentProvider {
// static readonly Schema = 'vscode-bulkeditpreview';
// static asPreviewUri(uri: URI): URI {
// return URI.from({ scheme: BulkEditPreviewProvider.Schema, path: uri.toString() });
// }
// static fromPreviewUri(uri: URI): URI {
// return URI.parse(uri.path);
// }
// constructor(
// @IModeService private readonly _modeService: IModeService,
// @IModelService private readonly _modelService: IModelService,
// @ITextModelService private readonly textModelResolverService: ITextModelService
// ) {
// this.textModelResolverService.registerTextModelContentProvider(BulkEditPreviewProvider.Schema, this);
// }
// async provideTextContent(previewUri: URI) {
// const resourceUri = BulkEditPreviewProvider.fromPreviewUri(previewUri);
// const ref = await this.textModelResolverService.createModelReference(resourceUri);
// const sourceModel = ref.object.textEditorModel;
// const previewModel = this._modelService.createModel(
// createTextBufferFactoryFromSnapshot(sourceModel.createSnapshot()),
// this._modeService.create(sourceModel.getLanguageIdentifier().language),
// previewUri
// );
// return null;
// }
// }
......@@ -29,7 +29,7 @@ export class FileElement {
}
export class TextEditElement {
constructor(readonly line: string, readonly highlight: IHighlight, readonly edit: modes.TextEdit) { }
constructor(readonly edit: modes.TextEdit, readonly prefix: string, readonly selecting: string, readonly inserting: string, readonly suffix: string) { }
}
export type Edit = FileElement | TextEditElement;
......@@ -64,17 +64,14 @@ export class BulkEditDataSource implements IAsyncDataSource<modes.WorkspaceEdit,
const result = element.edit.edits.map(edit => {
const range = Range.lift(edit.range);
const start = textModel.getOffsetAt(range.getStartPosition());
const end = textModel.getOffsetAt(range.getEndPosition());
const len = end - start;
const previewStart = textModel.getPositionAt(start - 20);
const previewEnd = textModel.getPositionAt(end + 30);
const preview = textModel.getValueInRange(Range.fromPositions(previewStart, previewEnd));
const previewOffset = start - textModel.getOffsetAt(previewStart);
return new TextEditElement(preview, { start: previewOffset, end: previewOffset + len }, edit);
return new TextEditElement(
edit,
textModel.getValueInRange(new Range(range.startLineNumber, 1, range.startLineNumber, range.startColumn)), // line start to edit start,
textModel.getValueInRange(range),
edit.text,
textModel.getValueInRange(new Range(range.endLineNumber, range.endColumn, range.endLineNumber, range.endColumn + 20))
);
});
return result;
......@@ -148,14 +145,24 @@ export class TextEditElementRenderer implements ITreeRenderer<TextEditElement, F
return new TextEditElementTemplate(label);
}
renderElement(node: ITreeNode<TextEditElement, FuzzyScore>, _index: number, template: TextEditElementTemplate): void {
template.label.set(node.element.line, [node.element.highlight], undefined, true);
renderElement({ element }: ITreeNode<TextEditElement, FuzzyScore>, _index: number, template: TextEditElementTemplate): void {
let value = '';
value += element.prefix;
value += element.selecting;
value += element.inserting;
value += element.suffix;
let selectHighlight: IHighlight = { start: element.prefix.length, end: element.prefix.length + element.selecting.length, extraClasses: 'remove' };
let insertHighlight: IHighlight = { start: selectHighlight.end, end: selectHighlight.end + element.inserting.length, extraClasses: 'insert' };
template.label.set(value, [selectHighlight, insertHighlight], undefined, true);
}
disposeTemplate(_template: TextEditElementTemplate): void { }
}
export class Delegate implements IListVirtualDelegate<Edit> {
export class BulkEditDelegate implements IListVirtualDelegate<Edit> {
getHeight(): number {
return 23;
......
......@@ -150,6 +150,9 @@ import 'vs/workbench/contrib/files/browser/files.contribution';
// Backup
import 'vs/workbench/contrib/backup/common/backup.contribution';
// bulkEdit
import 'vs/workbench/contrib/bulkEdit/browser/bulkEdit.contribution';
// Search
import 'vs/workbench/contrib/search/browser/search.contribution';
import 'vs/workbench/contrib/search/browser/searchView';
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册