Skip to content

Commit

Permalink
Fix indentation when using preferences tree
Browse files Browse the repository at this point in the history
Fixes #5052

- fixes the indentation when updating/setting a preference using the
`preferences-tree` widget.
- the current implementation had a hardcoded value of `tabSize`=3 and `insertSpaces`=true which
meant that if the `settings.json` file had different formatting, it would insert incorrectly.
- added a new method `detectIndentation` which attempts to detect the current indentation
(tabSize and indent type) based on the content of the file.

Signed-off-by: vince-fugnitto <vincent.fugnitto@ericsson.com>
  • Loading branch information
vince-fugnitto committed Dec 12, 2019
1 parent 928e1e0 commit d681787
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 14 deletions.
34 changes: 21 additions & 13 deletions packages/debug/src/browser/preferences/launch-preferences.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ import { bindUserStorage } from '@theia/userstorage/lib/browser/user-storage-fro
import { FileSystemWatcherServer } from '@theia/filesystem/lib/common/filesystem-watcher-protocol';
import { MockFilesystemWatcherServer } from '@theia/filesystem/lib/common/test/mock-filesystem-watcher-server';
import { bindLaunchPreferences } from './launch-preferences';
import { EditorManager } from '@theia/editor/lib/browser/editor-manager';
import URI from '@theia/core/lib/common/uri';
import { EditorWidget } from '@theia/editor/lib/browser/editor-widget';

disableJSDOM();

Expand Down Expand Up @@ -333,12 +336,12 @@ describe('Launch Preferences', () => {
function testLaunchAndSettingsSuite({
name, expectation, launch, only, configMode
}: {
name: string,
expectation: any,
launch?: any,
only?: boolean,
configMode?: ConfigMode
}): void {
name: string,
expectation: any,
launch?: any,
only?: boolean,
configMode?: ConfigMode
}): void {
testSuite({
name: name + ' Launch Configuration',
launch,
Expand Down Expand Up @@ -398,13 +401,13 @@ describe('Launch Preferences', () => {
function testConfigSuite({
configMode, expectation, inspectExpectation, settings, launch, only
}: {
configMode: ConfigMode
expectation: any,
inspectExpectation?: any,
launch?: any,
settings?: any,
only?: boolean
}): void {
configMode: ConfigMode
expectation: any,
inspectExpectation?: any,
launch?: any,
settings?: any,
only?: boolean
}): void {

describe(JSON.stringify(configMode, undefined, 2), () => {

Expand Down Expand Up @@ -458,6 +461,11 @@ describe('Launch Preferences', () => {
bindPreferenceProviders(bind, unbind);
bindWorkspacePreferences(bind);
container.bind(WorkspaceService).toSelf().inSingletonScope();
container.bind(EditorManager).toConstantValue(<EditorManager>{
getByUri(uri: URI): Promise<EditorWidget | undefined> {
return Promise.resolve(undefined);
}
});
container.bind(WindowService).toConstantValue(new MockWindowService());

const workspaceServer = new MockWorkspaceServer();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ import { MessageService, Resource, ResourceProvider, Disposable } from '@theia/c
import { PreferenceProvider, PreferenceSchemaProvider, PreferenceScope, PreferenceProviderDataChange } from '@theia/core/lib/browser';
import URI from '@theia/core/lib/common/uri';
import { PreferenceConfigurations } from '@theia/core/lib/browser/preferences/preference-configurations';
import { EditorManager, TextEditorDocument } from '@theia/editor/lib/browser';

@injectable()
export abstract class AbstractResourcePreferenceProvider extends PreferenceProvider {

protected preferences: { [key: string]: any } = {};
protected resource: Promise<Resource>;

@inject(EditorManager) protected readonly editorManager: EditorManager;
@inject(ResourceProvider) protected readonly resourceProvider: ResourceProvider;
@inject(MessageService) protected readonly messageService: MessageService;
@inject(PreferenceSchemaProvider) protected readonly schemaProvider: PreferenceSchemaProvider;
Expand Down Expand Up @@ -102,9 +104,15 @@ export abstract class AbstractResourcePreferenceProvider extends PreferenceProvi
return true;
}
try {
const editor = await this.editorManager.getByUri(new URI(resourceUri!));
let tabSize: number = 0;
let insertSpaces: boolean = true;
if (editor) {
[tabSize, insertSpaces] = this.detectIndentation(editor.editor.document);
}
let newContent = '';
if (path.length || value !== undefined) {
const formattingOptions = { tabSize: 3, insertSpaces: true, eol: '' };
const formattingOptions = { tabSize, insertSpaces, eol: '' };
const edits = jsoncparser.modify(content, path, value, { formattingOptions });
newContent = jsoncparser.applyEdits(content, edits);
}
Expand Down Expand Up @@ -221,4 +229,33 @@ export abstract class AbstractResourcePreferenceProvider extends PreferenceProvi
}
}

/**
* Detect the minimum indentation and type of indentation to be used
* as formatting options when using `jsoncparser`.
* @param text the preference text editor document.
*
* @returns a tuple representing the indentation size, and if it spaces.
*/
protected detectIndentation(text: TextEditorDocument): [number, boolean] {
// Get the number of lines present in the text document.
const lineCount = text.lineCount;
// Store the current index which will be used iterate over the document.
let index = 0;
// Iterate over the each line in the text document, getting the first indentation that is not zero.
while (index < lineCount) {
// Get the line content of the document a the given index.
const line = text.getLineContent(index + 1);
// Determine how many leading spaces are present in the document.
const indentation = line.search(/\S|$/);
// Return the first non-zero indentation.
if (indentation > 0) {
// Determine if the line is indented with spaces or tabs.
const isSpaces = !line.startsWith('\t');
return [indentation, isSpaces];
}
index++;
}
return [0, true];
}

}

0 comments on commit d681787

Please sign in to comment.