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 11, 2019
1 parent 928e1e0 commit 57917f7
Showing 1 changed file with 38 additions and 1 deletion.
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 57917f7

Please sign in to comment.