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 Dec 10, 2018
1 parent 558d4b5 commit c769974
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 20 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
61 changes: 42 additions & 19 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 All @@ -61,25 +68,22 @@ export class EditorconfigDocumentManager {
protected addOnSaveHandler(editorWidget: EditorWidget) {
const monacoEditor = MonacoEditor.get(editorWidget);
if (monacoEditor) {
console.log('editor-config just before onWillSaveModel');
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);
console.log('editor-config gather operations inside onWillSaveModel');

// 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);
}

resolve(edits);
Expand Down Expand Up @@ -206,10 +210,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 +223,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 +303,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);
// });
// }
// }
// }

}
2 changes: 1 addition & 1 deletion packages/monaco/src/browser/monaco-editor-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ export interface MonacoModelContentChangedEvent {
readonly model: MonacoEditorModel;
readonly contentChanges: TextDocumentContentChangeEvent[];
}

export class MonacoEditorModel implements ITextEditorModel, TextEditorDocument {

autoSave: 'on' | 'off' = 'on';
Expand Down Expand Up @@ -164,6 +163,7 @@ export class MonacoEditorModel implements ITextEditorModel, TextEditorDocument {
}

save(): Promise<void> {
console.log('--JB monaco model SAVE, NEXT at the scheduleSave ---');
return this.scheduleSave(TextDocumentSaveReason.Manual);
}

Expand Down
25 changes: 25 additions & 0 deletions packages/monaco/src/browser/monaco-editor-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,17 @@ import { MonacoWorkspace } from './monaco-workspace';
import { MonacoBulkEditService } from './monaco-bulk-edit-service';

import IEditorOverrideServices = monaco.editor.IEditorOverrideServices;
import { CommandService } from '@theia/core';

@injectable()
export class MonacoEditorProvider {

@inject(MonacoBulkEditService)
protected readonly bulkEditService: MonacoBulkEditService;

@inject(CommandService)
protected readonly commandService: CommandService;

constructor(
@inject(MonacoEditorService) protected readonly codeEditorService: MonacoEditorService,
@inject(MonacoTextModelService) protected readonly textModelService: MonacoTextModelService,
Expand Down Expand Up @@ -101,6 +105,27 @@ export class MonacoEditorProvider {
const options = this.createMonacoEditorOptions(model);
const editor = new MonacoEditor(uri, model, document.createElement('div'), this.m2p, this.p2m, options, override);
toDispose.push(this.editorPreferences.onPreferenceChanged(event => this.updateMonacoEditorOptions(editor, event)));
editor.document.onWillSaveModel(async event => {
// await this.commandService.executeCommand('editor.action.formatDocument');
console.log('-----------------JBJBJB MONACO - on willSave DID SAVE-------------- reason: ', event.reason);
// preference:
console.log(`---JB editor.formatOnSave in monaco provider ${this.editorPreferences['editor.formatOnSave']}`);
if (event.reason !== 2 && this.editorPreferences['editor.formatOnSave']) {
await this.commandService.executeCommand('monaco.editor.action.formatDocument');

// await new Promise((resolve, reject) => editor.commandService.executeCommand('editor.action.trimTrailingWhitespace', {
// resolve: console.log('--JB provider.execute command in promise: monaco.editor.action.formatDocument', resolve)
// }).then(resolve, reject));

console.log('--JB MONACO provider.execute command AFTER: monaco.editor.action.formatDocument');
}

});
console.log('---JBJB---onDidSaveModel BEGIN ----------------------');
editor.document.onDidSaveModel(event => {
console.log('--JB MONACO onDidSaveModel event: ', event);
console.log('---JBJB-------------------------');
});
return editor;
}
protected createMonacoEditorOptions(model: MonacoEditorModel): MonacoEditor.IOptions {
Expand Down

0 comments on commit c769974

Please sign in to comment.