Skip to content

Commit

Permalink
fix #3338 Format Document on save
Browse files Browse the repository at this point in the history
Format on Save is only available when the preference autoSave is "OFF"
and the preference 'editor.formatOnSave' is "true"

Signed-off-by: Jacques Bouthillier <jacques.bouthillier@ericsson.com>
  • Loading branch information
lmcbout committed Nov 27, 2018
1 parent 6286db8 commit 360b9c3
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 22 deletions.
6 changes: 6 additions & 0 deletions packages/editor/src/browser/editor-preferences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,11 @@ export const editorPreferenceSchema: PreferenceSchema = {
'default': false,
'description': 'Enable auto indentation adjustment.'
},
'editor.formatOnSave': {
'type': 'boolean',
'default': false,
'description': 'Enable format on save when the autoSave preference is off.'
},
'editor.formatOnType': {
'type': 'boolean',
'default': false,
Expand Down Expand Up @@ -504,6 +509,7 @@ export interface EditorConfiguration {
'editor.autoClosingBrackets'?: boolean
'editor.autoIndent'?: boolean
'editor.formatOnType'?: boolean
'editor.formatOnSave'?: boolean
'editor.formatOnPaste'?: boolean
'editor.dragAndDrop'?: boolean
'editor.suggestOnTriggerCharacters'?: boolean
Expand Down
1 change: 1 addition & 0 deletions packages/editorconfig/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"dependencies": {
"@theia/core": "^0.3.16",
"@theia/editor": "^0.3.16",
"@theia/languages": "^0.3.16",
"@theia/monaco": "^0.3.16",
"editorconfig": "^0.15.0"
},
Expand Down
63 changes: 41 additions & 22 deletions packages/editorconfig/src/browser/editorconfig-document-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@
import { injectable, inject, postConstruct } from 'inversify';
import { MonacoEditor } from '@theia/monaco/lib/browser/monaco-editor';
import { TextDocumentSaveReason } from '@theia/languages/lib/browser';
import { EditorManager, EditorWidget, TextEditor } from '@theia/editor/lib/browser';
import { EditorManager, EditorWidget, TextEditor, EditorPreferences } from '@theia/editor/lib/browser';
import { EditorconfigService } from '../common/editorconfig-interface';
import { KnownProps } from 'editorconfig';
import { CommandService } from '@theia/core';

@injectable()
export class EditorconfigDocumentManager {
Expand All @@ -29,12 +30,18 @@ export class EditorconfigDocumentManager {
CRLF: '\r\n'
};

@inject(CommandService)
protected readonly commandService: CommandService;

@inject(EditorManager)
protected readonly editorManager: EditorManager;

@inject(EditorconfigService)
protected readonly editorconfigServer: EditorconfigService;

@inject(EditorPreferences)
protected readonly editorPreferences: EditorPreferences;

private properties: { [file: string]: KnownProps } = {};

@postConstruct()
Expand Down Expand Up @@ -62,25 +69,18 @@ export class EditorconfigDocumentManager {
const monacoEditor = MonacoEditor.get(editorWidget);
if (monacoEditor) {
monacoEditor.document.onWillSaveModel(event => {
event.waitUntil(new Promise<monaco.editor.IIdentifiedSingleEditOperation[]>(resolve => {
event.waitUntil(new Promise<monaco.editor.IIdentifiedSingleEditOperation[]>(async resolve => {
const edits: monaco.editor.IIdentifiedSingleEditOperation[] = [];
const uri = monacoEditor.uri.toString();
const properties = this.properties[uri];

const edits = [];
edits.push(...this.getEditsTrimmingTrailingWhitespaces(monacoEditor, properties, event.reason));
// actually format the document (doesn't return an operation)
await this.formatDocument(monacoEditor);

// gather operations
edits.push(...await this.getEditsTrimmingTrailingWhitespaces(monacoEditor, properties, event.reason));
const edit = this.getEditInsertingFinalNewLine(monacoEditor, properties);
if (edit) {
edits.push(edit);

// get current cursor position
const cursor = monacoEditor.cursor;

// and then restore it after resolving the promise
setTimeout(() => {
monacoEditor.cursor = cursor;
}, 0);
}
if (edit) { edits.push(edit); }

resolve(edits);
}));
Expand Down Expand Up @@ -206,10 +206,11 @@ export class EditorconfigDocumentManager {
* preceding newline characters and false to ensure it doesn't.
*/
ensureTrimTrailingWhitespace(editor: MonacoEditor, properties: KnownProps): void {
const edits = this.getEditsTrimmingTrailingWhitespaces(editor, properties);
if (edits.length > 0) {
editor.document.textEditorModel.applyEdits(edits);
}
this.getEditsTrimmingTrailingWhitespaces(editor, properties).then(edits => {
if (edits.length > 0) {
editor.document.textEditorModel.applyEdits(edits);
}
});
}

/**
Expand All @@ -218,14 +219,16 @@ export class EditorconfigDocumentManager {
* @param editor editor
* @param properties editorconfig properties
*/
private getEditsTrimmingTrailingWhitespaces(editor: MonacoEditor, properties: KnownProps, saveReason?: TextDocumentSaveReason): monaco.editor.IIdentifiedSingleEditOperation[] {
private async getEditsTrimmingTrailingWhitespaces(
editor: MonacoEditor, properties: KnownProps, saveReason?: TextDocumentSaveReason
): Promise<monaco.editor.IIdentifiedSingleEditOperation[]> {
const edits = [];

if (MonacoEditor.get(this.editorManager.activeEditor) === editor) {
const trimReason = (saveReason !== TextDocumentSaveReason.Manual) ? 'auto-save' : undefined;
editor.commandService.executeCommand('editor.action.trimTrailingWhitespace', {
await new Promise((resolve, reject) => editor.commandService.executeCommand('editor.action.trimTrailingWhitespace', {
reason: trimReason
});
}).then(resolve, reject));
return [];
}

Expand Down Expand Up @@ -296,4 +299,20 @@ export class EditorconfigDocumentManager {
return undefined;
}

/**
* Format the document when the preference "editor.formatOnSave" is set and the
* "editor.autoSave" is set to "OFF". Only re-format when saving is done manually.
*
* @param editor editor
*/
private async formatDocument(editor: MonacoEditor): Promise<void> {
if (MonacoEditor.get(this.editorManager.activeEditor) === editor) {
if (this.editorPreferences['editor.formatOnSave'] && (this.editorPreferences['editor.autoSave']) === 'off') {
await new Promise((resolve, reject) => {
editor.commandService.executeCommand('editor.action.formatDocument').then(resolve, reject);
});
}
}
}

}

0 comments on commit 360b9c3

Please sign in to comment.