Skip to content

Commit

Permalink
[WIP] issue #3338 Format on save
Browse files Browse the repository at this point in the history
Seems to work when only reformat is selected if
there is some extra char at end of line and
re-format, then no.
Also, may need two save to reset the dirty flag,
seems the re-format occurs after and make the file dirty again.

Signed-off-by: Jacques Bouthillier <jacques.bouthillier@ericsson.com>
  • Loading branch information
lmcbout committed Nov 22, 2018
1 parent fb5ec9a commit 910da32
Show file tree
Hide file tree
Showing 3 changed files with 124 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
123 changes: 101 additions & 22 deletions packages/editorconfig/src/browser/editorconfig-document-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +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 +29,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,29 +67,63 @@ export class EditorconfigDocumentManager {
protected addOnSaveHandler(editorWidget: EditorWidget) {
const monacoEditor = MonacoEditor.get(editorWidget);
if (monacoEditor) {
monacoEditor.document.onDidSaveModel(event => {
// monacoEditor.document.save();
console.log(`onDidSaveModel dirty: ${monacoEditor.document.dirty}`);
});
monacoEditor.document.onWillSaveModel(event => {
console.log('onWillSaveModel should be first');
// this.formatDocument(monacoEditor).then(() => {
console.log(`------------command should have been done----------------- event: ${event}`);
event.waitUntil(new Promise<monaco.editor.IIdentifiedSingleEditOperation[]>(resolve => {
const uri = monacoEditor.uri.toString();
const properties = this.properties[uri];

const edits = [];
edits.push(...this.getEditsTrimmingTrailingWhitespaces(monacoEditor, properties, event.reason));

const edits: monaco.editor.IIdentifiedSingleEditOperation[] = [];
// edits.push(...this.getEditsTrimmingTrailingWhitespaces(monacoEditor, properties, event.reason));
const edit = this.getEditInsertingFinalNewLine(monacoEditor, properties);
if (edit) {
edits.push(edit);
return Promise.all([
this.getEditsTrimmingTrailingWhitespaces(monacoEditor, properties, event.reason),
this.formatDocument(monacoEditor)
]).then(() => {
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);
}
console.log('JB --- reformat should have been done');
return resolve(edits);
});
// return this.formatDocument(monacoEditor).then(() => {
// // if (this.editorPreferences['editor.formatOnSave']) {
// // monacoEditor.commandService.executeCommand('editor.action.formatDocument').then(() => {

// get current cursor position
const cursor = monacoEditor.cursor;
// if (edit) {
// edits.push(edit);

// and then restore it after resolving the promise
setTimeout(() => {
monacoEditor.cursor = cursor;
}, 0);
}
// // get current cursor position
// const cursor = monacoEditor.cursor;

resolve(edits);
// // and then restore it after resolving the promise
// setTimeout(() => {
// monacoEditor.cursor = cursor;
// }, 0);
// }
// console.log('JB --- reformat should have been done');
// return resolve(edits);
// });

// }

// resolve(edits);
}));
// });
});
}
}
Expand Down Expand Up @@ -206,10 +246,16 @@ 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);
}
// 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 +264,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 +344,35 @@ 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) {
// console.log(`--JB formatOnSave: ${this.editorPreferences['editor.formatOnSave']} editor.autoSave: ${this.editorPreferences['editor.autoSave']} `);
// if (this.editorPreferences['editor.formatOnSave'] && (this.editorPreferences['editor.autoSave']) === 'off') {
// await editor.commandService.executeCommand('editor.action.formatDocument', {
// aa: console.log('-----JBJB format document -------JBJB'),
// });
// } else {
// console.log('-----===== JB **NO** FORMAT on save');
// }
if (this.editorPreferences['editor.formatOnSave'] && (this.editorPreferences['editor.autoSave']) === 'off') {
await new Promise((resolve, reject) => {
editor.commandService.executeCommand('editor.action.formatDocument').then(() => {
console.log('----------------formatDocument JB----------------');
resolve();
}, () => {
console.log('command rejected');
reject();
});
});

}
}
}

}
17 changes: 17 additions & 0 deletions packages/workspace/src/browser/workspace-commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,11 @@ export namespace WorkspaceCommands {
category: WORKSPACE_CATEGORY,
label: 'Save Workspace As...'
};
export const LIANG_COM: Command = {
id: 'workspace:liang',
category: WORKSPACE_CATEGORY,
label: 'Run Liang Command'
};
}

@injectable()
Expand Down Expand Up @@ -293,6 +298,18 @@ export class WorkspaceCommandContribution implements CommandContribution {
}
}
}));
registry.registerCommand(WorkspaceCommands.LIANG_COM, this.newMultiUriAwareCommandHandler({
isEnabled: () => true,
isVisible: () => true,
execute: async uris =>
new Promise(resolve => {
setTimeout(() => {
console.log('Liang promise resolved');
resolve();
}, 5000);
}
)
}));
this.preferences.ready.then(() => {
registry.registerCommand(WorkspaceCommands.ADD_FOLDER, this.newMultiUriAwareCommandHandler({
isEnabled: () => this.workspaceService.isMultiRootWorkspaceOpened,
Expand Down

0 comments on commit 910da32

Please sign in to comment.