Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions packages/components/src/button/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import classNames from 'classnames';
import React from 'react';

import { Dropdown } from '../dropdown';
import { Placement } from '../dropdown/dropdown';
import { Icon, DefaultIconKeys, getIcon } from '../icon';
import './style.less';

Expand All @@ -27,6 +28,8 @@ interface MoreActionProps {
more?: boolean;
moreIconClass?: string;
menu?: React.ReactNode;
moreVisible?: boolean;
placement?: Placement;
onVisibleChange?: (visible: boolean) => void;
}

Expand Down Expand Up @@ -95,6 +98,8 @@ export const Button = React.memo(
more,
moreIconClass,
menu,
moreVisible,
placement,
title,
onVisibleChange,
...otherProps
Expand Down Expand Up @@ -127,9 +132,16 @@ export const Button = React.memo(

const iconNode = iconClass ? <Icon iconClass={iconClass} disabled={disabled} /> : null;

if (more) {
if (menu) {
return (
<Dropdown className={'kt-menu'} overlay={menu} trigger={['click']} onVisibleChange={onVisibleChange}>
<Dropdown
visible={moreVisible}
className={'kt-menu'}
overlay={menu}
trigger={['click']}
onVisibleChange={onVisibleChange}
placement={placement}
>
<button
{...otherProps}
disabled={disabled}
Expand Down
2 changes: 1 addition & 1 deletion packages/components/src/button/style.less
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@
color: var(--kt-button-disableForeground) !important;
background-color: var(--kt-button-disableBackground) !important;
// 这里是用 box-shadow 来实现边框的,因为 border 会破坏盒模型
box-shadow: var(--kt-button-disableBorder) 0px 0px 0px 1px;
box-shadow: var(--kt-button-disableBorder) 0px 0px 0px 1px inset;
cursor: not-allowed;

& > .@{prefix}-button-secondary-more {
Expand Down
2 changes: 1 addition & 1 deletion packages/components/src/dropdown/dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { tuple } from '../utils/type';
import { warning } from '../utils/warning';

const Placements = tuple('topLeft', 'topCenter', 'topRight', 'bottomLeft', 'bottomCenter', 'bottomRight');
type Placement = (typeof Placements)[number];
export type Placement = (typeof Placements)[number];

type OverlayFunc = () => React.ReactNode;

Expand Down
1 change: 1 addition & 0 deletions packages/core-browser/src/common/common.command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ export namespace COMMON_COMMANDS {

export const OPEN_LAUNCH_CONFIGURATION: Command = {
id: 'core.launchConfiguration.open',
label: '%debug.action.open.configuration%',
};

export const ENVIRONMENT_VARIABLE: Command = {
Expand Down
12 changes: 12 additions & 0 deletions packages/core-browser/src/menu/next/menu.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,18 @@ export class SeparatorMenuItemNode extends MenuNode {
}
}

// 只展示 label 的 menu node
export class LabelMenuItemNode extends MenuNode {
static readonly ID = 'menu.item.node.label';

constructor(label: string) {
super({
id: LabelMenuItemNode.ID,
label,
});
}
}

export interface IMenu extends IDisposable {
/**
* menu-id
Expand Down
11 changes: 11 additions & 0 deletions packages/core-browser/src/utils/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { Ajv } from 'ajv';

let _ajv;
export const acquireAjv = (): Ajv | undefined => {
if (!_ajv) {
const Ajv = require('ajv');
_ajv = new Ajv();
return _ajv;
}
return _ajv;
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { DebugConfigurationManager } from '@opensumi/ide-debug/lib/browser/debug
import { DebugPreferences } from '@opensumi/ide-debug/lib/browser/debug-preferences';
import { createBrowserInjector } from '@opensumi/ide-dev-tool/src/injector-helper';
import { WorkbenchEditorService } from '@opensumi/ide-editor';
import { IEditorDocumentModelService } from '@opensumi/ide-editor/lib/browser';
import { IFileServiceClient } from '@opensumi/ide-file-service';
import { IWorkspaceService } from '@opensumi/ide-workspace';

Expand All @@ -35,6 +36,11 @@ describe('Debug Configuration Manager', () => {
const mockMonacoEditorModel = {
getLineLastNonWhitespaceColumn: jest.fn(),
getPositionAt: jest.fn(() => 1),
getValue: jest.fn(
() => `{
"version": "0.2.0",
"configurations": [`,
),
};

const mockMonacoEditor = {
Expand Down Expand Up @@ -165,6 +171,21 @@ describe('Debug Configuration Manager', () => {
useValue: () => mockDebugStorage,
});

mockInjector.overrideProviders({
token: IEditorDocumentModelService,
useValue: {
createModelReference: (uri) => ({
instance: {
uri,
getMonacoModel: () => ({
getValue: jest.fn(() => ''),
}),
},
dispose: jest.fn(),
}),
},
});

debugConfigurationManager = mockInjector.get(DebugConfigurationManager);

await debugConfigurationManager.whenReady;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { DebugPreferences } from '@opensumi/ide-debug/lib/browser/debug-preferen
import { DebugModelManager } from '@opensumi/ide-debug/lib/browser/editor';
import { createBrowserInjector } from '@opensumi/ide-dev-tool/src/injector-helper';
import { EditorCollectionService, WorkbenchEditorService } from '@opensumi/ide-editor';
import { IEditorDocumentModelService } from '@opensumi/ide-editor/lib/browser';
import { IFileServiceClient } from '@opensumi/ide-file-service';
import { IWorkspaceStorageService, IWorkspaceService } from '@opensumi/ide-workspace';

Expand Down Expand Up @@ -82,6 +83,11 @@ describe('Debug Model Manager', () => {
useValue: {},
});

mockInjector.overrideProviders({
token: IEditorDocumentModelService,
useValue: {},
});

debugModelManager = mockInjector.get(DebugModelManager);
});

Expand Down
3 changes: 3 additions & 0 deletions packages/debug/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
"@opensumi/ide-file-service": "workspace:*",
"@opensumi/ide-task": "workspace:*",
"@opensumi/ide-terminal-next": "workspace:*",
"@rjsf/core": "^5.5.2",
"@rjsf/utils": "^5.5.2",
"@rjsf/validator-ajv8": "^5.5.2",
"anser": "^1.4.9",
"btoa": "^1.2.1"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@
position: absolute;
right: 50px;
bottom: 30px;

* + * {
margin-left: 12px;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ import { DebugConfigurationService } from '../../view/configuration/debug-config
import styles from './index.module.less';

export const FloatingClickWidget = (_: React.HtmlHTMLAttributes<HTMLDivElement>) => {
const { addConfiguration } = useInjectable<DebugConfigurationService>(DebugConfigurationService);
const { addConfiguration, openLaunchEditor } = useInjectable<DebugConfigurationService>(DebugConfigurationService);

return (
<div className={styles.floating_click_widget}>
<Button onClick={addConfiguration} size='large'>
{localize('debug.action.add.configuration')}
</Button>
<Button onClick={openLaunchEditor} size='large'>
{localize('debug.action.open.launch.editor')}
</Button>
</div>
);
};
100 changes: 82 additions & 18 deletions packages/debug/src/browser/debug-configuration-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,22 @@ import {
CommonLanguageId,
} from '@opensumi/ide-core-browser';
import { WorkbenchEditorService, IOpenResourceResult } from '@opensumi/ide-editor';
import { EditorCollectionService, IEditorDocumentModelService } from '@opensumi/ide-editor/lib/browser/index';
import { IFileServiceClient } from '@opensumi/ide-file-service';
import { FileSystemError } from '@opensumi/ide-file-service';
import { EOL } from '@opensumi/ide-monaco';
import { ITextModel } from '@opensumi/ide-monaco/lib/browser/monaco-api/types';
import { QuickPickService } from '@opensumi/ide-quick-open';
import { IWorkspaceService } from '@opensumi/ide-workspace';
import { WorkspaceVariableContribution } from '@opensumi/ide-workspace/lib/browser/workspace-variable-contribution';
import { EditOperation } from '@opensumi/monaco-editor-core/esm/vs/editor/common/core/editOperation';
import * as monaco from '@opensumi/monaco-editor-core/esm/vs/editor/editor.api';

import { DebugServer, IDebugServer, IDebuggerContribution, launchSchemaUri } from '../common';
import { DebugSessionOptions } from '../common';
import { DebugConfiguration } from '../common';

import { CONTEXT_DEBUGGERS_AVAILABLE } from './../common/constants';
import { CONTEXT_DEBUGGERS_AVAILABLE, LAUNCH_VIEW_SCHEME } from './../common/constants';
import { DebugConfigurationModel } from './debug-configuration-model';
import { DebugPreferences } from './debug-preferences';

Expand Down Expand Up @@ -87,6 +90,12 @@ export class DebugConfigurationManager {
@Autowired(DebugPreferences)
protected readonly debugPreferences: DebugPreferences;

@Autowired(IEditorDocumentModelService)
protected readonly documentService: IEditorDocumentModelService;

@Autowired(EditorCollectionService)
protected readonly editorCollectionService: EditorCollectionService;

private contextDebuggersAvailable: IContextKey<boolean>;

// 用于存储支持断点的语言
Expand Down Expand Up @@ -266,46 +275,101 @@ export class DebugConfigurationManager {
}
}

async addConfiguration(uri?: string): Promise<void> {
let model: DebugConfigurationModel | undefined;
if (uri) {
model = this.getModelByUri(uri);
} else {
model = this.model;
}
if (!model) {
async openLaunchEditor(): Promise<void> {
if (!this.model) {
return;
}
const resouce = await this.doOpen(model);
if (!resouce) {
return;
}
const { group } = resouce;
const editor = group.codeEditor.monacoEditor;
if (!editor) {

const uri = this.model.uri;
if (!uri) {
return;
}

await this.workbenchEditorService.open(uri.withScheme(LAUNCH_VIEW_SCHEME), {
disableNavigate: true,
});
}

private visitConfigurationsEditor(model: ITextModel): monaco.Position | undefined {
let position: monaco.Position | undefined;
let depthInArray = 0;
let lastProperty = '';
visit(editor.getValue(), {
visit(model.getValue(), {
onObjectProperty: (property) => {
lastProperty = property;
},
onArrayBegin: (offset) => {
if (lastProperty === 'configurations' && depthInArray === 0) {
position = editor.getModel()!.getPositionAt(offset + 1);
position = model.getPositionAt(offset + 1);
}
depthInArray++;
},
onArrayEnd: () => {
depthInArray--;
},
});

return position;
}

async insertConfiguration(uri: URI, configuration: DebugConfiguration): Promise<void> {
let ref = this.documentService.getModelReference(uri);
if (!ref) {
ref = await this.documentService.createModelReference(uri);
}

const model = ref.instance.getMonacoModel();
const eol = model.getEOL();
const position: monaco.Position | undefined = this.visitConfigurationsEditor(model);
if (!position) {
return;
}

const { indentSize, insertSpaces } = model.getOptions();
// 获取 configurations 字符串前面的空格个数
const spacesMatch = model.getLineContent(position.lineNumber).match(/^\s*/);
const leadingSpaces = spacesMatch ? spacesMatch[0].length : 0;
const indent = insertSpaces ? ' '.repeat(indentSize + leadingSpaces) : '\t';

const decompose = JSON.stringify(configuration, null, indentSize).split(EOL.LF);
const length = decompose.length;
const indentContent = decompose.reduce(
(pre, cur, index) => pre + indent + cur + (index === length - 1 ? '' : EOL.LF),
'',
);

model.pushEditOperations(
null,
[EditOperation.insert(position, eol), EditOperation.insert(position, indentContent + ',')],
() => null,
);
}

async addConfiguration(uri?: string): Promise<void> {
let model: DebugConfigurationModel | undefined;
if (uri) {
model = this.getModelByUri(uri);
} else {
model = this.model;
}
if (!model) {
return;
}
const resouce = await this.doOpen(model);
if (!resouce) {
return;
}
const { group } = resouce;
const editor = group.codeEditor.monacoEditor;
if (!editor) {
return;
}

const position: monaco.Position | undefined = this.visitConfigurationsEditor(editor.getModel()!);
if (!position) {
return;
}

// 判断在"configurations": [后是否有字符,如果有则新建一行
if (editor.getModel()!.getLineLastNonWhitespaceColumn(position.lineNumber) > position.column) {
editor.setPosition(position);
Expand Down
Loading