Skip to content

Commit

Permalink
Use Monaco when creating files in DebugConfigurationManager
Browse files Browse the repository at this point in the history
Signed-off-by: Colin Grant <[email protected]>
  • Loading branch information
colin-grant-work committed May 24, 2021
1 parent 2fda70e commit 38f176a
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 18 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Change Log

## v1.14.0 - unreleased

[1.14.0 Milestone](https://github.com/eclipse-theia/theia/milestone/20)

- [debug] Fix behavior of `Add Configurations` command when empty `launch.json` present. [#9467](https://github.com/eclipse-theia/theia/pull/9467)

<a name="breaking_changes_1.14.0">[Breaking Changes:](#breaking_changes_1.14.0)</a>

- [debug] `DebugConfigurationManager` no longer `@injects()` the `FileService` and now uses `MonacoTextModelService` instead. [#9467](https://github.com/eclipse-theia/theia/pull/9467)

## v1.13.0 - 4/29/2021

[1.13.0 Milestone](https://github.com/eclipse-theia/theia/milestone/19)
Expand Down
51 changes: 33 additions & 18 deletions packages/debug/src/browser/debug-configuration-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@
*--------------------------------------------------------------------------------------------*/

import debounce = require('p-debounce');
import { visit } from 'jsonc-parser';
import { visit, parse } from 'jsonc-parser';
import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
import URI from '@theia/core/lib/common/uri';
import { Emitter, Event, WaitUntilEvent } from '@theia/core/lib/common/event';
import { EditorManager, EditorWidget } from '@theia/editor/lib/browser';
import { MonacoEditor } from '@theia/monaco/lib/browser/monaco-editor';
import { PreferenceService, StorageService } from '@theia/core/lib/browser';
import { PreferenceService, StorageService, PreferenceScope } from '@theia/core/lib/browser';
import { QuickPickService } from '@theia/core/lib/common/quick-pick-service';
import { WorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
import { DebugConfigurationModel } from './debug-configuration-model';
Expand All @@ -36,7 +36,7 @@ import { ContextKey, ContextKeyService } from '@theia/core/lib/browser/context-k
import { DebugConfiguration } from '../common/debug-common';
import { WorkspaceVariableContribution } from '@theia/workspace/lib/browser/workspace-variable-contribution';
import { PreferenceConfigurations } from '@theia/core/lib/browser/preferences/preference-configurations';
import { FileService } from '@theia/filesystem/lib/browser/file-service';
import { MonacoTextModelService } from '@theia/monaco/lib/browser/monaco-text-model-service';

export interface WillProvideDebugConfiguration extends WaitUntilEvent {
}
Expand All @@ -56,8 +56,8 @@ export class DebugConfigurationManager {
@inject(ContextKeyService)
protected readonly contextKeyService: ContextKeyService;

@inject(FileService)
protected readonly fileService: FileService;
@inject(MonacoTextModelService)
protected readonly textModelService: MonacoTextModelService;

@inject(PreferenceService)
protected readonly preferences: PreferenceService;
Expand Down Expand Up @@ -253,28 +253,43 @@ export class DebugConfigurationManager {
}

protected async doOpen(model: DebugConfigurationModel): Promise<EditorWidget> {
let uri = model.uri;
if (!uri) {
uri = await this.doCreate(model);
}
const uri = await this.doCreate(model);

return this.editorManager.open(uri, {
mode: 'activate'
});
}

protected async doCreate(model: DebugConfigurationModel): Promise<URI> {
await this.preferences.set('launch', {}); // create dummy launch.json in the correct place
const { configUri } = this.preferences.resolve('launch'); // get uri to write content to it
let uri: URI;
if (configUri && configUri.path.base === 'launch.json') {
uri = configUri;
} else { // fallback
uri = new URI(model.workspaceFolderUri).resolve(`${this.preferenceConfigurations.getPaths()[0]}/launch.json`);
const uri = model.uri ?? this.preferences.getConfigUri(PreferenceScope.Folder, model.workspaceFolderUri, 'launch');
if (!uri) { // Since we are requesting information about a known workspace folder, this should never happen.
throw new Error('PreferenceService.getConfigUri has returned undefined when a URI was expected.');
}
await this.ensureContent(uri, model);
return uri;
}

/**
* Checks whether a `launch.json` file contains the minimum necessary content.
* If content not found, provides content and populates the file using Monaco.
*/
protected async ensureContent(uri: URI, model: DebugConfigurationModel): Promise<void> {
const textModel = await this.textModelService.createModelReference(uri);
const currentContent = textModel.object.getText();
try { // Look for the minimal well-formed launch.json content: {configurations: []}
const parsedContent = parse(currentContent);
if (Array.isArray(parsedContent.configurations)) {
return;
}
} catch {
// Just keep going
}

const debugType = await this.selectDebugType();
const configurations = debugType ? await this.provideDebugConfigurations(debugType, model.workspaceFolderUri) : [];
const content = this.getInitialConfigurationContent(configurations);
await this.fileService.write(uri, content);
return uri;
textModel.object.textEditorModel.setValue(content); // Will clobber anything the user has entered!
await textModel.object.save();
}

protected async provideDebugConfigurations(debugType: string, workspaceFolderUri: string | undefined): Promise<DebugConfiguration[]> {
Expand Down

0 comments on commit 38f176a

Please sign in to comment.