deploy: current vibn theia state
Made-with: Cursor
This commit is contained in:
10
packages/bulk-edit/.eslintrc.js
Normal file
10
packages/bulk-edit/.eslintrc.js
Normal file
@@ -0,0 +1,10 @@
|
||||
/** @type {import('eslint').Linter.Config} */
|
||||
module.exports = {
|
||||
extends: [
|
||||
'../../configs/build.eslintrc.json'
|
||||
],
|
||||
parserOptions: {
|
||||
tsconfigRootDir: __dirname,
|
||||
project: 'tsconfig.json'
|
||||
}
|
||||
};
|
||||
31
packages/bulk-edit/README.md
Normal file
31
packages/bulk-edit/README.md
Normal file
@@ -0,0 +1,31 @@
|
||||
<div align='center'>
|
||||
|
||||
<br />
|
||||
|
||||
<img src='https://raw.githubusercontent.com/eclipse-theia/theia/master/logo/theia.svg?sanitize=true' alt='theia-ext-logo' width='100px' />
|
||||
|
||||
<h2>ECLIPSE THEIA - BULK EDIT EXTENSION</h2>
|
||||
|
||||
<hr />
|
||||
|
||||
</div>
|
||||
|
||||
## Description
|
||||
|
||||
The `@theia/bulk-edit` extension contributes a `Refactor Preview` widget to the application that displays WorkspaceEdits to end-users.
|
||||
|
||||
## Additional Information
|
||||
|
||||
- [API documentation for `@theia/bulk-edit`](https://eclipse-theia.github.io/theia/docs/next/modules/_theia_bulk-edit.html)
|
||||
- [Theia - GitHub](https://github.com/eclipse-theia/theia)
|
||||
- [Theia - Website](https://theia-ide.org/)
|
||||
|
||||
## License
|
||||
|
||||
- [Eclipse Public License 2.0](http://www.eclipse.org/legal/epl-2.0/)
|
||||
- [一 (Secondary) GNU General Public License, version 2 with the GNU Classpath Exception](https://projects.eclipse.org/license/secondary-gpl-2.0-cp)
|
||||
|
||||
## Trademark
|
||||
|
||||
"Theia" is a trademark of the Eclipse Foundation
|
||||
<https://www.eclipse.org/theia>
|
||||
53
packages/bulk-edit/package.json
Normal file
53
packages/bulk-edit/package.json
Normal file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"name": "@theia/bulk-edit",
|
||||
"version": "1.68.0",
|
||||
"description": "Theia - Bulk Edit Extension",
|
||||
"dependencies": {
|
||||
"@theia/core": "1.68.0",
|
||||
"@theia/editor": "1.68.0",
|
||||
"@theia/filesystem": "1.68.0",
|
||||
"@theia/monaco": "1.68.0",
|
||||
"@theia/monaco-editor-core": "1.96.302",
|
||||
"@theia/workspace": "1.68.0",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"theiaExtensions": [
|
||||
{
|
||||
"frontend": "lib/browser/bulk-edit-frontend-module"
|
||||
}
|
||||
],
|
||||
"keywords": [
|
||||
"theia-extension"
|
||||
],
|
||||
"license": "EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/eclipse-theia/theia.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/eclipse-theia/theia/issues"
|
||||
},
|
||||
"homepage": "https://github.com/eclipse-theia/theia",
|
||||
"files": [
|
||||
"lib",
|
||||
"src"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "theiaext build",
|
||||
"clean": "theiaext clean",
|
||||
"compile": "theiaext compile",
|
||||
"lint": "theiaext lint",
|
||||
"test": "theiaext test",
|
||||
"watch": "theiaext watch"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@theia/ext-scripts": "1.68.0"
|
||||
},
|
||||
"nyc": {
|
||||
"extends": "../../configs/nyc.json"
|
||||
},
|
||||
"gitHead": "21358137e41342742707f660b8e222f940a27652"
|
||||
}
|
||||
34
packages/bulk-edit/src/browser/bulk-edit-commands.ts
Normal file
34
packages/bulk-edit/src/browser/bulk-edit-commands.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
// *****************************************************************************
|
||||
// Copyright (C) 2021 SAP SE or an SAP affiliate company and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// http://www.eclipse.org/legal/epl-2.0.
|
||||
//
|
||||
// This Source Code may also be made available under the following Secondary
|
||||
// Licenses when the conditions for such availability set forth in the Eclipse
|
||||
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
||||
// with the GNU Classpath Exception which is available at
|
||||
// https://www.gnu.org/software/classpath/license.html.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
||||
// *****************************************************************************
|
||||
|
||||
import { codicon } from '@theia/core/lib/browser';
|
||||
import { Command } from '@theia/core/lib/common';
|
||||
|
||||
export namespace BulkEditCommands {
|
||||
export const TOGGLE_VIEW: Command = {
|
||||
id: 'bulk-edit:toggleView'
|
||||
};
|
||||
|
||||
export const APPLY: Command = {
|
||||
id: 'bulk-edit:apply',
|
||||
iconClass: codicon('check')
|
||||
};
|
||||
|
||||
export const DISCARD: Command = {
|
||||
id: 'bulk-edit:discard',
|
||||
iconClass: codicon('clear-all')
|
||||
};
|
||||
}
|
||||
119
packages/bulk-edit/src/browser/bulk-edit-contribution.ts
Normal file
119
packages/bulk-edit/src/browser/bulk-edit-contribution.ts
Normal file
@@ -0,0 +1,119 @@
|
||||
// *****************************************************************************
|
||||
// Copyright (C) 2021 SAP SE or an SAP affiliate company and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// http://www.eclipse.org/legal/epl-2.0.
|
||||
//
|
||||
// This Source Code may also be made available under the following Secondary
|
||||
// Licenses when the conditions for such availability set forth in the Eclipse
|
||||
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
||||
// with the GNU Classpath Exception which is available at
|
||||
// https://www.gnu.org/software/classpath/license.html.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
||||
// *****************************************************************************
|
||||
|
||||
import { injectable, inject, optional, postConstruct } from '@theia/core/shared/inversify';
|
||||
import { Widget } from '@theia/core/lib/browser/widgets/widget';
|
||||
import { CommandRegistry } from '@theia/core/lib/common';
|
||||
import { AbstractViewContribution } from '@theia/core/lib/browser/shell/view-contribution';
|
||||
import { BulkEditCommands } from './bulk-edit-commands';
|
||||
import { MonacoBulkEditService } from '@theia/monaco/lib/browser/monaco-bulk-edit-service';
|
||||
import { TabBarToolbarContribution, TabBarToolbarRegistry } from '@theia/core/lib/browser/shell/tab-bar-toolbar';
|
||||
import { BulkEditTreeWidget, BULK_EDIT_TREE_WIDGET_ID, BULK_EDIT_WIDGET_NAME } from './bulk-edit-tree';
|
||||
import { QuickViewService } from '@theia/core/lib/browser';
|
||||
import { nls } from '@theia/core/lib/common/nls';
|
||||
import { ResourceEdit } from '@theia/monaco-editor-core/esm/vs/editor/browser/services/bulkEditService';
|
||||
|
||||
@injectable()
|
||||
export class BulkEditContribution extends AbstractViewContribution<BulkEditTreeWidget> implements TabBarToolbarContribution {
|
||||
protected edits: ResourceEdit[];
|
||||
|
||||
@inject(QuickViewService) @optional()
|
||||
protected override readonly quickView: QuickViewService;
|
||||
|
||||
@inject(MonacoBulkEditService)
|
||||
protected readonly bulkEditService: MonacoBulkEditService;
|
||||
|
||||
constructor() {
|
||||
super({
|
||||
widgetId: BULK_EDIT_TREE_WIDGET_ID,
|
||||
widgetName: BULK_EDIT_WIDGET_NAME,
|
||||
defaultWidgetOptions: {
|
||||
area: 'bottom'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@postConstruct()
|
||||
protected init(): void {
|
||||
this.bulkEditService.setPreviewHandler((edits: ResourceEdit[]) => this.previewEdit(edits));
|
||||
}
|
||||
|
||||
override registerCommands(registry: CommandRegistry): void {
|
||||
super.registerCommands(registry);
|
||||
this.quickView?.hideItem(BULK_EDIT_WIDGET_NAME);
|
||||
|
||||
registry.registerCommand(BulkEditCommands.APPLY, {
|
||||
isEnabled: widget => this.withWidget(widget, () => true),
|
||||
isVisible: widget => this.withWidget(widget, () => true),
|
||||
execute: widget => this.withWidget(widget, () => this.apply())
|
||||
});
|
||||
registry.registerCommand(BulkEditCommands.DISCARD, {
|
||||
isEnabled: widget => this.withWidget(widget, () => true),
|
||||
isVisible: widget => this.withWidget(widget, () => true),
|
||||
execute: widget => this.withWidget(widget, () => this.discard())
|
||||
});
|
||||
}
|
||||
|
||||
async registerToolbarItems(toolbarRegistry: TabBarToolbarRegistry): Promise<void> {
|
||||
toolbarRegistry.registerItem({
|
||||
id: BulkEditCommands.APPLY.id,
|
||||
command: BulkEditCommands.APPLY.id,
|
||||
tooltip: nls.localizeByDefault('Apply Refactoring'),
|
||||
priority: 0,
|
||||
});
|
||||
toolbarRegistry.registerItem({
|
||||
id: BulkEditCommands.DISCARD.id,
|
||||
command: BulkEditCommands.DISCARD.id,
|
||||
tooltip: nls.localizeByDefault('Discard Refactoring'),
|
||||
priority: 1,
|
||||
});
|
||||
}
|
||||
|
||||
protected withWidget<T>(widget: Widget | undefined = this.tryGetWidget(), cb: (bulkEdit: BulkEditTreeWidget) => T): T | false {
|
||||
if (widget instanceof BulkEditTreeWidget) {
|
||||
return cb(widget);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private async previewEdit(edits: ResourceEdit[]): Promise<ResourceEdit[]> {
|
||||
const widget = await this.openView({ activate: true });
|
||||
|
||||
if (widget) {
|
||||
this.edits = edits;
|
||||
await widget.initModel(edits);
|
||||
}
|
||||
|
||||
return edits;
|
||||
}
|
||||
|
||||
private apply(): void {
|
||||
if (this.edits) {
|
||||
this.edits.forEach(edit => {
|
||||
if (edit.metadata) {
|
||||
edit.metadata.needsConfirmation = false;
|
||||
}
|
||||
});
|
||||
this.bulkEditService.apply(this.edits);
|
||||
}
|
||||
this.closeView();
|
||||
}
|
||||
|
||||
private discard(): void {
|
||||
this.edits = [];
|
||||
this.closeView();
|
||||
}
|
||||
}
|
||||
39
packages/bulk-edit/src/browser/bulk-edit-frontend-module.ts
Normal file
39
packages/bulk-edit/src/browser/bulk-edit-frontend-module.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
// *****************************************************************************
|
||||
// Copyright (C) 2021 SAP SE or an SAP affiliate company and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// http://www.eclipse.org/legal/epl-2.0.
|
||||
//
|
||||
// This Source Code may also be made available under the following Secondary
|
||||
// Licenses when the conditions for such availability set forth in the Eclipse
|
||||
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
||||
// with the GNU Classpath Exception which is available at
|
||||
// https://www.gnu.org/software/classpath/license.html.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
||||
// *****************************************************************************
|
||||
import { ContainerModule } from '@theia/core/shared/inversify';
|
||||
import { WidgetFactory } from '@theia/core/lib/browser/widget-manager';
|
||||
import { BulkEditTreeWidget, BULK_EDIT_TREE_WIDGET_ID, createBulkEditTreeWidget } from './bulk-edit-tree';
|
||||
import { FrontendApplicationContribution, LabelProviderContribution, bindViewContribution } from '@theia/core/lib/browser';
|
||||
import { BulkEditContribution } from './bulk-edit-contribution';
|
||||
import { TabBarToolbarContribution } from '@theia/core/lib/browser/shell/tab-bar-toolbar';
|
||||
import { BulkEditTreeLabelProvider } from './bulk-edit-tree-label-provider';
|
||||
import '../../src/browser/style/bulk-edit.css';
|
||||
|
||||
export default new ContainerModule(bind => {
|
||||
bind(BulkEditTreeWidget).toDynamicValue(ctx =>
|
||||
createBulkEditTreeWidget(ctx.container)
|
||||
);
|
||||
bind(WidgetFactory).toDynamicValue(context => ({
|
||||
id: BULK_EDIT_TREE_WIDGET_ID,
|
||||
createWidget: () => context.container.get(BulkEditTreeWidget)
|
||||
}));
|
||||
bindViewContribution(bind, BulkEditContribution);
|
||||
bind(FrontendApplicationContribution).toService(BulkEditContribution);
|
||||
bind(TabBarToolbarContribution).toService(BulkEditContribution);
|
||||
|
||||
bind(BulkEditTreeLabelProvider).toSelf().inSingletonScope();
|
||||
bind(LabelProviderContribution).toService(BulkEditTreeLabelProvider);
|
||||
});
|
||||
@@ -0,0 +1,71 @@
|
||||
// *****************************************************************************
|
||||
// Copyright (C) 2021 SAP SE or an SAP affiliate company and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// http://www.eclipse.org/legal/epl-2.0.
|
||||
//
|
||||
// This Source Code may also be made available under the following Secondary
|
||||
// Licenses when the conditions for such availability set forth in the Eclipse
|
||||
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
||||
// with the GNU Classpath Exception which is available at
|
||||
// https://www.gnu.org/software/classpath/license.html.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
||||
// *****************************************************************************
|
||||
|
||||
import { injectable, inject } from '@theia/core/shared/inversify';
|
||||
import { LabelProvider, LabelProviderContribution, DidChangeLabelEvent } from '@theia/core/lib/browser/label-provider';
|
||||
import { BulkEditInfoNode } from './bulk-edit-tree';
|
||||
import { TreeLabelProvider } from '@theia/core/lib/browser/tree/tree-label-provider';
|
||||
import { WorkspaceService } from '@theia/workspace/lib/browser';
|
||||
|
||||
@injectable()
|
||||
export class BulkEditTreeLabelProvider implements LabelProviderContribution {
|
||||
|
||||
@inject(LabelProvider)
|
||||
protected readonly labelProvider: LabelProvider;
|
||||
|
||||
@inject(TreeLabelProvider)
|
||||
protected readonly treeLabelProvider: TreeLabelProvider;
|
||||
|
||||
@inject(WorkspaceService)
|
||||
protected readonly workspaceService: WorkspaceService;
|
||||
|
||||
canHandle(element: object): number {
|
||||
return BulkEditInfoNode.is(element) ?
|
||||
this.treeLabelProvider.canHandle(element) + 1 :
|
||||
0;
|
||||
}
|
||||
|
||||
getIcon(node: BulkEditInfoNode): string {
|
||||
return this.labelProvider.getIcon(node.uri);
|
||||
}
|
||||
|
||||
getName(node: BulkEditInfoNode): string {
|
||||
return this.labelProvider.getName(node.uri);
|
||||
}
|
||||
|
||||
getLongName(node: BulkEditInfoNode): string {
|
||||
const description: string[] = [];
|
||||
const rootUri = this.workspaceService.getWorkspaceRootUri(node.uri);
|
||||
// In a multiple-root workspace include the root name to the label before the parent directory.
|
||||
if (this.workspaceService.isMultiRootWorkspaceOpened && rootUri) {
|
||||
description.push(this.labelProvider.getName(rootUri));
|
||||
}
|
||||
// If the given resource is not at the workspace root, include the parent directory to the label.
|
||||
if (rootUri?.toString() !== node.uri.parent.toString()) {
|
||||
description.push(this.labelProvider.getLongName(node.uri.parent));
|
||||
}
|
||||
return description.join(' ● ');
|
||||
}
|
||||
|
||||
getDescription(node: BulkEditInfoNode): string {
|
||||
return this.labelProvider.getLongName(node.uri.parent);
|
||||
}
|
||||
|
||||
affects(node: BulkEditInfoNode, event: DidChangeLabelEvent): boolean {
|
||||
return event.affects(node.uri) || event.affects(node.uri.parent);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
// *****************************************************************************
|
||||
// Copyright (C) 2021 SAP SE or an SAP affiliate company and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// http://www.eclipse.org/legal/epl-2.0.
|
||||
//
|
||||
// This Source Code may also be made available under the following Secondary
|
||||
// Licenses when the conditions for such availability set forth in the Eclipse
|
||||
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
||||
// with the GNU Classpath Exception which is available at
|
||||
// https://www.gnu.org/software/classpath/license.html.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
||||
// *****************************************************************************
|
||||
|
||||
import { SelectionService } from '@theia/core/lib/common/selection-service';
|
||||
import { SelectionCommandHandler } from '@theia/core/lib/common/selection-command-handler';
|
||||
import { ResourceFileEdit, ResourceTextEdit } from '@theia/monaco-editor-core/esm/vs/editor/browser/services/bulkEditService';
|
||||
import { isObject } from '@theia/core/lib/common';
|
||||
|
||||
export interface BulkEditNodeSelection {
|
||||
bulkEdit: ResourceFileEdit | ResourceTextEdit;
|
||||
}
|
||||
export namespace BulkEditNodeSelection {
|
||||
export function is(arg: unknown): arg is BulkEditNodeSelection {
|
||||
return isObject(arg) && 'bulkEdit' in arg;
|
||||
}
|
||||
|
||||
export class CommandHandler extends SelectionCommandHandler<BulkEditNodeSelection> {
|
||||
|
||||
constructor(
|
||||
protected override readonly selectionService: SelectionService,
|
||||
protected override readonly options: SelectionCommandHandler.Options<BulkEditNodeSelection>
|
||||
) {
|
||||
super(
|
||||
selectionService,
|
||||
arg => BulkEditNodeSelection.is(arg) ? arg : undefined,
|
||||
options
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// *****************************************************************************
|
||||
// Copyright (C) 2021 SAP SE or an SAP affiliate company and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// http://www.eclipse.org/legal/epl-2.0.
|
||||
//
|
||||
// This Source Code may also be made available under the following Secondary
|
||||
// Licenses when the conditions for such availability set forth in the Eclipse
|
||||
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
||||
// with the GNU Classpath Exception which is available at
|
||||
// https://www.gnu.org/software/classpath/license.html.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
||||
// *****************************************************************************
|
||||
|
||||
import { interfaces, Container } from '@theia/core/shared/inversify';
|
||||
import { BulkEditTreeWidget } from './bulk-edit-tree-widget';
|
||||
import { BulkEditTree } from './bulk-edit-tree';
|
||||
import { BulkEditTreeModel } from './bulk-edit-tree-model';
|
||||
import { createTreeContainer } from '@theia/core/lib/browser';
|
||||
|
||||
export function createBulkEditContainer(parent: interfaces.Container): Container {
|
||||
const child = createTreeContainer(parent, {
|
||||
tree: BulkEditTree,
|
||||
widget: BulkEditTreeWidget,
|
||||
model: BulkEditTreeModel,
|
||||
});
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
export function createBulkEditTreeWidget(parent: interfaces.Container): BulkEditTreeWidget {
|
||||
return createBulkEditContainer(parent).get(BulkEditTreeWidget);
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// *****************************************************************************
|
||||
// Copyright (C) 2021 SAP SE or an SAP affiliate company and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// http://www.eclipse.org/legal/epl-2.0.
|
||||
//
|
||||
// This Source Code may also be made available under the following Secondary
|
||||
// Licenses when the conditions for such availability set forth in the Eclipse
|
||||
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
||||
// with the GNU Classpath Exception which is available at
|
||||
// https://www.gnu.org/software/classpath/license.html.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
||||
// *****************************************************************************
|
||||
|
||||
import { injectable, inject } from '@theia/core/shared/inversify';
|
||||
import { BulkEditNode, BulkEditTree } from './bulk-edit-tree';
|
||||
import { TreeModelImpl, OpenerService, open, TreeNode } from '@theia/core/lib/browser';
|
||||
import { ResourceEdit } from '@theia/monaco-editor-core/esm/vs/editor/browser/services/bulkEditService';
|
||||
|
||||
@injectable()
|
||||
export class BulkEditTreeModel extends TreeModelImpl {
|
||||
@inject(BulkEditTree) protected override readonly tree: BulkEditTree;
|
||||
@inject(OpenerService) protected readonly openerService: OpenerService;
|
||||
|
||||
protected override doOpenNode(node: TreeNode): void {
|
||||
if (BulkEditNode.is(node)) {
|
||||
open(this.openerService, node.uri, undefined);
|
||||
} else {
|
||||
super.doOpenNode(node);
|
||||
}
|
||||
}
|
||||
|
||||
revealNode(node: TreeNode): void {
|
||||
this.doOpenNode(node);
|
||||
}
|
||||
|
||||
async initModel(edits: ResourceEdit[], fileContents: Map<string, string>): Promise<void> {
|
||||
this.tree.initTree(edits, fileContents);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,231 @@
|
||||
// *****************************************************************************
|
||||
// Copyright (C) 2021 SAP SE or an SAP affiliate company and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// http://www.eclipse.org/legal/epl-2.0.
|
||||
//
|
||||
// This Source Code may also be made available under the following Secondary
|
||||
// Licenses when the conditions for such availability set forth in the Eclipse
|
||||
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
||||
// with the GNU Classpath Exception which is available at
|
||||
// https://www.gnu.org/software/classpath/license.html.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
||||
// *****************************************************************************
|
||||
|
||||
import { injectable, inject, optional } from '@theia/core/shared/inversify';
|
||||
import {
|
||||
DiffUris, TreeWidget, TreeProps, ContextMenuRenderer, TreeNode, TreeModel,
|
||||
CompositeTreeNode, NodeProps, QuickViewService
|
||||
} from '@theia/core/lib/browser';
|
||||
import * as React from '@theia/core/shared/react';
|
||||
import { BulkEditInfoNode, BulkEditNode } from './bulk-edit-tree';
|
||||
import { BulkEditTreeModel } from './bulk-edit-tree-model';
|
||||
import { FileResourceResolver } from '@theia/filesystem/lib/browser';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { EditorWidget, EditorManager, EditorOpenerOptions } from '@theia/editor/lib/browser';
|
||||
import { MEMORY_TEXT } from '@theia/core/lib/common';
|
||||
import { Disposable } from '@theia/core/lib/common/disposable';
|
||||
import { nls } from '@theia/core/lib/common/nls';
|
||||
import { ResourceEdit, ResourceFileEdit, ResourceTextEdit } from '@theia/monaco-editor-core/esm/vs/editor/browser/services/bulkEditService';
|
||||
|
||||
export const BULK_EDIT_TREE_WIDGET_ID = 'bulkedit';
|
||||
export const BULK_EDIT_WIDGET_NAME = nls.localizeByDefault('Refactor Preview');
|
||||
|
||||
@injectable()
|
||||
export class BulkEditTreeWidget extends TreeWidget {
|
||||
private editorWidgets: EditorWidget[] = [];
|
||||
|
||||
@inject(FileResourceResolver)
|
||||
protected readonly fileResourceResolver: FileResourceResolver;
|
||||
|
||||
@inject(EditorManager)
|
||||
protected readonly editorManager: EditorManager;
|
||||
|
||||
@inject(QuickViewService) @optional()
|
||||
protected readonly quickView: QuickViewService;
|
||||
|
||||
constructor(
|
||||
@inject(TreeProps) readonly treeProps: TreeProps,
|
||||
@inject(BulkEditTreeModel) override readonly model: BulkEditTreeModel,
|
||||
@inject(ContextMenuRenderer) override readonly contextMenuRenderer: ContextMenuRenderer
|
||||
) {
|
||||
super(treeProps, model, contextMenuRenderer);
|
||||
|
||||
this.id = BULK_EDIT_TREE_WIDGET_ID;
|
||||
this.title.label = BULK_EDIT_WIDGET_NAME;
|
||||
this.title.caption = BULK_EDIT_WIDGET_NAME;
|
||||
this.title.closable = true;
|
||||
this.addClass('theia-bulk-edit-container');
|
||||
|
||||
this.toDispose.push(Disposable.create(() => {
|
||||
this.disposeEditors();
|
||||
}));
|
||||
}
|
||||
|
||||
async initModel(edits: ResourceEdit[]): Promise<void> {
|
||||
await this.model.initModel(edits, await this.getFileContentsMap(edits));
|
||||
this.quickView?.showItem(BULK_EDIT_WIDGET_NAME);
|
||||
}
|
||||
|
||||
protected override tapNode(node?: TreeNode): void {
|
||||
super.tapNode(node);
|
||||
if (BulkEditNode.is(node)) {
|
||||
this.doOpen(node);
|
||||
}
|
||||
}
|
||||
|
||||
protected override handleDown(event: KeyboardEvent): void {
|
||||
const node = this.model.getNextSelectableNode();
|
||||
super.handleDown(event);
|
||||
if (BulkEditNode.is(node)) {
|
||||
this.doOpen(node);
|
||||
}
|
||||
}
|
||||
|
||||
protected override handleUp(event: KeyboardEvent): void {
|
||||
const node = this.model.getPrevSelectableNode();
|
||||
super.handleUp(event);
|
||||
if (BulkEditNode.is(node)) {
|
||||
this.doOpen(node);
|
||||
}
|
||||
}
|
||||
|
||||
protected override renderTree(model: TreeModel): React.ReactNode {
|
||||
if (CompositeTreeNode.is(model.root) && model.root.children.length > 0) {
|
||||
return super.renderTree(model);
|
||||
}
|
||||
return <div className='theia-widget-noInfo noEdits'>{nls.localizeByDefault('Made no edits')}</div>;
|
||||
}
|
||||
|
||||
protected override renderCaption(node: TreeNode, props: NodeProps): React.ReactNode {
|
||||
if (BulkEditInfoNode.is(node)) {
|
||||
return this.decorateBulkEditInfoNode(node);
|
||||
} else if (BulkEditNode.is(node)) {
|
||||
return this.decorateBulkEditNode(node);
|
||||
}
|
||||
return 'caption';
|
||||
}
|
||||
|
||||
protected decorateBulkEditNode(node: BulkEditNode): React.ReactNode {
|
||||
if (node?.parent && node?.bulkEdit && ('textEdit' in node?.bulkEdit)) {
|
||||
const bulkEdit = node.bulkEdit;
|
||||
const parent = node.parent as BulkEditInfoNode;
|
||||
|
||||
if (parent?.fileContents) {
|
||||
const lines = parent.fileContents.split('\n');
|
||||
const startLineNum = +bulkEdit.textEdit?.range?.startLineNumber;
|
||||
|
||||
if (lines.length > startLineNum) {
|
||||
const startColumn = +bulkEdit.textEdit.range.startColumn;
|
||||
const endColumn = +bulkEdit.textEdit.range.endColumn;
|
||||
const lineText = lines[startLineNum - 1];
|
||||
const beforeMatch = (startColumn > 26 ? '... ' : '') + lineText.substring(0, startColumn - 1).slice(-25);
|
||||
const replacedText = lineText.substring(startColumn - 1, endColumn - 1);
|
||||
const afterMatch = lineText.substring(startColumn - 1 + replacedText.length, startColumn - 1 + replacedText.length + 75);
|
||||
|
||||
return <div className='bulkEditNode'>
|
||||
<div className='message'>
|
||||
{beforeMatch}
|
||||
<span className="replaced-text">{replacedText}</span>
|
||||
<span className="inserted-text">{bulkEdit.textEdit.text}</span>
|
||||
{afterMatch}
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected decorateBulkEditInfoNode(node: BulkEditInfoNode): React.ReactNode {
|
||||
const icon = this.toNodeIcon(node);
|
||||
const name = this.toNodeName(node);
|
||||
const description = this.toNodeDescription(node);
|
||||
const path = this.labelProvider.getLongName(node.uri.withScheme('bulkedit'));
|
||||
return <div title={path} className='bulkEditInfoNode'>
|
||||
{icon && <div className={icon + ' file-icon'}></div>}
|
||||
<div className='name'>{name}</div>
|
||||
<div className='path'>{description}</div>
|
||||
</div>;
|
||||
}
|
||||
|
||||
private async getFileContentsMap(edits: ResourceEdit[]): Promise<Map<string, string>> {
|
||||
const fileContentMap = new Map<string, string>();
|
||||
|
||||
if (edits) {
|
||||
for (const element of edits) {
|
||||
if (element) {
|
||||
const filePath = (('newResource' in element) && (element as ResourceFileEdit).newResource?.path) ||
|
||||
(('resource' in element) && (element as ResourceTextEdit).resource.path);
|
||||
|
||||
if (filePath && !fileContentMap.has(filePath)) {
|
||||
const fileUri = new URI(filePath).withScheme('file');
|
||||
const resource = await this.fileResourceResolver.resolve(fileUri);
|
||||
fileContentMap.set(filePath, await resource.readContents());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return fileContentMap;
|
||||
}
|
||||
|
||||
private async doOpen(node: BulkEditNode): Promise<void> {
|
||||
if (node && node.parent && node.bulkEdit && ('edit' in node.bulkEdit)) {
|
||||
const resultNode = node.parent as BulkEditInfoNode;
|
||||
const leftUri = node.uri;
|
||||
const rightUri = await this.createReplacePreview(resultNode);
|
||||
const diffUri = DiffUris.encode(leftUri, rightUri);
|
||||
const editorWidget = await this.editorManager.open(diffUri, this.getEditorOptions(node));
|
||||
this.editorWidgets.push(editorWidget);
|
||||
}
|
||||
}
|
||||
|
||||
private async createReplacePreview(bulkEditInfoNode: BulkEditInfoNode): Promise<URI> {
|
||||
const fileUri = bulkEditInfoNode.uri;
|
||||
let lines: string[] = [];
|
||||
if (bulkEditInfoNode?.fileContents) {
|
||||
lines = bulkEditInfoNode.fileContents.split('\n');
|
||||
bulkEditInfoNode.children.map((node: BulkEditNode) => {
|
||||
if (node.bulkEdit && ('textEdit' in node.bulkEdit)) {
|
||||
const startLineNum = node.bulkEdit.textEdit.range.startLineNumber;
|
||||
if (lines.length > startLineNum) {
|
||||
const startColumn = node.bulkEdit.textEdit.range.startColumn;
|
||||
const endColumn = node.bulkEdit.textEdit.range.endColumn;
|
||||
const lineText = lines[startLineNum - 1];
|
||||
const beforeMatch = lineText.substring(0, startColumn - 1);
|
||||
const replacedText = lineText.substring(startColumn - 1, endColumn - 1);
|
||||
const afterMatch = lineText.substring(startColumn - 1 + replacedText.length);
|
||||
lines[startLineNum - 1] = beforeMatch + node.bulkEdit.textEdit.text + afterMatch;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return fileUri.withScheme(MEMORY_TEXT).withQuery(lines.join('\n'));
|
||||
}
|
||||
|
||||
private getEditorOptions(node: BulkEditNode): EditorOpenerOptions {
|
||||
let options = {};
|
||||
if (('textEdit' in node.bulkEdit) && node?.bulkEdit?.textEdit?.range) {
|
||||
options = {
|
||||
selection: {
|
||||
start: {
|
||||
line: node.bulkEdit.textEdit.range.startLineNumber - 1,
|
||||
character: node.bulkEdit.textEdit.range.startColumn - 1
|
||||
},
|
||||
end: {
|
||||
line: node.bulkEdit.textEdit.range.endLineNumber - 1,
|
||||
character: node.bulkEdit.textEdit.range.endColumn - 1
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
private disposeEditors(): void {
|
||||
this.editorWidgets.forEach(w => w.dispose());
|
||||
this.quickView?.hideItem(BULK_EDIT_WIDGET_NAME);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
// *****************************************************************************
|
||||
// Copyright (C) 2021 SAP SE or an SAP affiliate company and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// http://www.eclipse.org/legal/epl-2.0.
|
||||
//
|
||||
// This Source Code may also be made available under the following Secondary
|
||||
// Licenses when the conditions for such availability set forth in the Eclipse
|
||||
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
||||
// with the GNU Classpath Exception which is available at
|
||||
// https://www.gnu.org/software/classpath/license.html.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
||||
// *****************************************************************************
|
||||
|
||||
import { enableJSDOM } from '@theia/core/lib/browser/test/jsdom';
|
||||
import * as chai from 'chai';
|
||||
import { ResourceTextEdit } from '@theia/monaco-editor-core/esm/vs/editor/browser/services/bulkEditService';
|
||||
import { URI as Uri } from '@theia/core/shared/vscode-uri';
|
||||
|
||||
let disableJSDOM = enableJSDOM();
|
||||
|
||||
import { FrontendApplicationConfigProvider } from '@theia/core/lib/browser/frontend-application-config-provider';
|
||||
FrontendApplicationConfigProvider.set({});
|
||||
|
||||
import { Container } from '@theia/core/shared/inversify';
|
||||
import { BulkEditInfoNode, BulkEditTree } from './bulk-edit-tree';
|
||||
|
||||
const expect = chai.expect;
|
||||
let bulkEditTree: BulkEditTree;
|
||||
let testContainer: Container;
|
||||
const fileContextsMap = new Map<string, string>();
|
||||
let resourceTextEdits: ResourceTextEdit[];
|
||||
|
||||
disableJSDOM();
|
||||
|
||||
before(() => {
|
||||
disableJSDOM = enableJSDOM();
|
||||
|
||||
testContainer = new Container();
|
||||
testContainer.bind(BulkEditTree).toSelf();
|
||||
bulkEditTree = testContainer.get(BulkEditTree);
|
||||
|
||||
fileContextsMap.set('/c:/test1.ts', 'aaaaaaaaaaaaaaaaaaa');
|
||||
fileContextsMap.set('/c:/test2.ts', 'bbbbbbbbbbbbbbbbbbb');
|
||||
|
||||
resourceTextEdits = <ResourceTextEdit[]><unknown>[
|
||||
{
|
||||
'resource': Uri.file('c:/test1.ts'),
|
||||
'textEdit': {
|
||||
'text': 'AAAAA', 'range': { 'startLineNumber': 1, 'startColumn': 5, 'endLineNumber': 1, 'endColumn': 10 }
|
||||
}
|
||||
},
|
||||
{
|
||||
'resource': Uri.file('c:/test2.ts'),
|
||||
'textEdit': {
|
||||
'text': 'BBBBBB', 'range': { 'startLineNumber': 1, 'startColumn': 3, 'endLineNumber': 1, 'endColumn': 8 }
|
||||
}
|
||||
}
|
||||
];
|
||||
});
|
||||
|
||||
after(() => {
|
||||
disableJSDOM();
|
||||
});
|
||||
|
||||
describe('bulk-edit-tree', () => {
|
||||
it('initialize tree', () => {
|
||||
bulkEditTree.initTree(resourceTextEdits, fileContextsMap);
|
||||
expect((bulkEditTree.root as BulkEditInfoNode).children.length).is.equal(2);
|
||||
});
|
||||
});
|
||||
114
packages/bulk-edit/src/browser/bulk-edit-tree/bulk-edit-tree.ts
Normal file
114
packages/bulk-edit/src/browser/bulk-edit-tree/bulk-edit-tree.ts
Normal file
@@ -0,0 +1,114 @@
|
||||
// *****************************************************************************
|
||||
// Copyright (C) 2021 SAP SE or an SAP affiliate company and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// http://www.eclipse.org/legal/epl-2.0.
|
||||
//
|
||||
// This Source Code may also be made available under the following Secondary
|
||||
// Licenses when the conditions for such availability set forth in the Eclipse
|
||||
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
||||
// with the GNU Classpath Exception which is available at
|
||||
// https://www.gnu.org/software/classpath/license.html.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
||||
// *****************************************************************************
|
||||
|
||||
import { injectable } from '@theia/core/shared/inversify';
|
||||
import { TreeNode, CompositeTreeNode, SelectableTreeNode, ExpandableTreeNode, TreeImpl } from '@theia/core/lib/browser';
|
||||
import { UriSelection } from '@theia/core/lib/common/selection';
|
||||
import { BulkEditNodeSelection } from './bulk-edit-node-selection';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { ResourceFileEdit, ResourceTextEdit } from '@theia/monaco/lib/browser/monaco-workspace';
|
||||
import {
|
||||
ResourceEdit, ResourceFileEdit as MonacoResourceFileEdit, ResourceTextEdit as MonacoResourceTextEdit
|
||||
} from '@theia/monaco-editor-core/esm/vs/editor/browser/services/bulkEditService';
|
||||
|
||||
@injectable()
|
||||
export class BulkEditTree extends TreeImpl {
|
||||
public async initTree(edits: ResourceEdit[], fileContents: Map<string, string>): Promise<void> {
|
||||
this.root = <CompositeTreeNode>{
|
||||
visible: false,
|
||||
id: 'theia-bulk-edit-tree-widget',
|
||||
name: 'BulkEditTree',
|
||||
children: this.getChildren(edits, fileContents),
|
||||
parent: undefined
|
||||
};
|
||||
}
|
||||
|
||||
private getChildren(edits: ResourceEdit[], fileContentsMap: Map<string, string>): BulkEditInfoNode[] {
|
||||
let bulkEditInfos: BulkEditInfoNode[] = [];
|
||||
if (edits) {
|
||||
bulkEditInfos = edits
|
||||
.map(edit => this.getResourcePath(edit))
|
||||
.filter((path, index, arr) => path && arr.indexOf(path) === index)
|
||||
.map((path: string) => this.createBulkEditInfo(path, new URI(path), fileContentsMap.get(path)))
|
||||
.filter(Boolean);
|
||||
|
||||
if (bulkEditInfos.length > 0) {
|
||||
bulkEditInfos.forEach(editInfo => {
|
||||
editInfo.children = edits.filter(edit =>
|
||||
((('resource' in edit) && (edit as MonacoResourceTextEdit)?.resource?.path === editInfo.id)) ||
|
||||
(('newResource' in edit) && (edit as MonacoResourceFileEdit)?.newResource?.path === editInfo.id))
|
||||
.map((edit, index) => this.createBulkEditNode(('resource' in edit ? edit as MonacoResourceTextEdit :
|
||||
edit as MonacoResourceFileEdit), index, editInfo));
|
||||
});
|
||||
}
|
||||
}
|
||||
return bulkEditInfos;
|
||||
}
|
||||
|
||||
private createBulkEditNode(bulkEdit: MonacoResourceFileEdit | MonacoResourceTextEdit, index: number, parent: BulkEditInfoNode): BulkEditNode {
|
||||
const id = parent.id + '_' + index;
|
||||
const existing = this.getNode(id);
|
||||
if (BulkEditNode.is(existing)) {
|
||||
existing.bulkEdit = bulkEdit;
|
||||
return existing;
|
||||
}
|
||||
return {
|
||||
id,
|
||||
name: 'bulkEdit',
|
||||
parent,
|
||||
selected: false,
|
||||
uri: parent.uri,
|
||||
bulkEdit
|
||||
};
|
||||
}
|
||||
|
||||
private createBulkEditInfo(id: string, uri: URI, fileContents: string | undefined): BulkEditInfoNode {
|
||||
return {
|
||||
id,
|
||||
uri,
|
||||
expanded: true,
|
||||
selected: false,
|
||||
parent: this.root as BulkEditInfoNode,
|
||||
fileContents,
|
||||
children: []
|
||||
};
|
||||
}
|
||||
|
||||
private getResourcePath(edit: ResourceEdit): string | undefined {
|
||||
return ResourceTextEdit.is(edit) ? edit.resource.path :
|
||||
ResourceFileEdit.is(edit) && edit.newResource ? edit.newResource.path : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export interface BulkEditNode extends UriSelection, SelectableTreeNode {
|
||||
parent: CompositeTreeNode;
|
||||
bulkEdit: MonacoResourceFileEdit | MonacoResourceTextEdit;
|
||||
}
|
||||
export namespace BulkEditNode {
|
||||
export function is(node: TreeNode | undefined): node is BulkEditNode {
|
||||
return UriSelection.is(node) && SelectableTreeNode.is(node) && BulkEditNodeSelection.is(node);
|
||||
}
|
||||
}
|
||||
|
||||
export interface BulkEditInfoNode extends UriSelection, SelectableTreeNode, ExpandableTreeNode {
|
||||
parent: CompositeTreeNode;
|
||||
fileContents?: string;
|
||||
}
|
||||
export namespace BulkEditInfoNode {
|
||||
export function is(node: unknown): node is BulkEditInfoNode {
|
||||
return ExpandableTreeNode.is(node) && UriSelection.is(node) && 'fileContents' in node;
|
||||
}
|
||||
}
|
||||
21
packages/bulk-edit/src/browser/bulk-edit-tree/index.ts
Normal file
21
packages/bulk-edit/src/browser/bulk-edit-tree/index.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
// *****************************************************************************
|
||||
// Copyright (C) 2021 SAP SE or an SAP affiliate company and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// http://www.eclipse.org/legal/epl-2.0.
|
||||
//
|
||||
// This Source Code may also be made available under the following Secondary
|
||||
// Licenses when the conditions for such availability set forth in the Eclipse
|
||||
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
||||
// with the GNU Classpath Exception which is available at
|
||||
// https://www.gnu.org/software/classpath/license.html.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
||||
// *****************************************************************************
|
||||
|
||||
export * from './bulk-edit-tree';
|
||||
export * from './bulk-edit-tree-model';
|
||||
export * from './bulk-edit-node-selection';
|
||||
export * from './bulk-edit-tree-widget';
|
||||
export * from './bulk-edit-tree-container';
|
||||
66
packages/bulk-edit/src/browser/style/bulk-edit.css
Normal file
66
packages/bulk-edit/src/browser/style/bulk-edit.css
Normal file
@@ -0,0 +1,66 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2021 SAP SE or an SAP affiliate company and others.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0.
|
||||
*
|
||||
* This Source Code may also be made available under the following Secondary
|
||||
* Licenses when the conditions for such availability set forth in the Eclipse
|
||||
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
||||
* with the GNU Classpath Exception which is available at
|
||||
* https://www.gnu.org/software/classpath/license.html.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
||||
********************************************************************************/
|
||||
|
||||
.theia-bulk-edit-container {
|
||||
font-size: var(--theia-ui-font-size1);
|
||||
}
|
||||
|
||||
.theia-bulk-edit-container .bulkEditNode,
|
||||
.theia-bulk-edit-container .bulkEditInfoNode {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.theia-bulk-edit-container .bulkEditNode,
|
||||
.theia-bulk-edit-container .bulkEditInfoNode {
|
||||
width: calc(100% - 32px);
|
||||
}
|
||||
|
||||
.theia-bulk-edit-container .bulkEditNode div,
|
||||
.theia-bulk-edit-container .bulkEditInfoNode div {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.theia-bulk-edit-container .bulkEditInfoNode .name,
|
||||
.theia-bulk-edit-container .bulkEditInfoNode .path {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.theia-bulk-edit-container .bulkEditInfoNode .path {
|
||||
font-size: var(--theia-ui-font-size0);
|
||||
color: var(--theia-descriptionForeground);
|
||||
align-self: flex-end;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.theia-bulk-edit-container .bulkEditNode .message {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.theia-bulk-edit-container .bulkEditNode .message .replaced-text {
|
||||
text-decoration: line-through;
|
||||
background: var(--theia-diffEditor-removedTextBackground);
|
||||
border-color: var(--theia-diffEditor-removedTextBorder);
|
||||
}
|
||||
|
||||
.theia-bulk-edit-container .bulkEditNode .message .inserted-text {
|
||||
background: var(--theia-diffEditor-insertedTextBackground);
|
||||
border: 1px solid var(--theia-diffEditor-insertedTextBorder);
|
||||
}
|
||||
28
packages/bulk-edit/tsconfig.json
Normal file
28
packages/bulk-edit/tsconfig.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"extends": "../../configs/base.tsconfig",
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"rootDir": "src",
|
||||
"outDir": "lib"
|
||||
},
|
||||
"include": [
|
||||
"src"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"path": "../core"
|
||||
},
|
||||
{
|
||||
"path": "../editor"
|
||||
},
|
||||
{
|
||||
"path": "../filesystem"
|
||||
},
|
||||
{
|
||||
"path": "../monaco"
|
||||
},
|
||||
{
|
||||
"path": "../workspace"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user