Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix #3338 Format Document on save #4012

Merged
merged 1 commit into from
Jan 18, 2019
Merged

fix #3338 Format Document on save #4012

merged 1 commit into from
Jan 18, 2019

Conversation

lmcbout
Copy link
Contributor

@lmcbout lmcbout commented Jan 10, 2019

Fix #3338
This is a follow-up of the pr #3640
Since the " [monaco] re-implementation of fireWillSaveModel " on Jan 2nd, it is possible to use the "format on Save" .

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

editor.document.onWillSaveModel(event => {
event.waitUntil(new Promise<monaco.editor.IIdentifiedSingleEditOperation[]>(async resolve => {
// event.reason = 2: TextDocumentSaveReason.AfterDelay means: autoSave
if (event.reason !== 2 && this.editorPreferences['editor.formatOnSave']) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

event.reason !== TextDocumentSaveReason.AfterDelay

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done for the next version, will use event.reason === TextDocumentSaveReason.Manual

@@ -64,7 +64,7 @@ export namespace Saveable {
}
// tslint:disable-next-line:no-any
export async function save(arg: any): Promise<void> {
const saveable = getDirty(arg);
const saveable = get(arg);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it should be reverted right? save should not do anything if a document is not dirty

@@ -308,7 +308,7 @@ export class MonacoEditorModel implements ITextEditorModel, TextEditorDocument {
}

protected async doSave(reason: TextDocumentSaveReason, token: CancellationToken): Promise<void> {
if (token.isCancellationRequested || !this.resource.saveContents || !this.dirty) {
if (token.isCancellationRequested || !this.resource.saveContents) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it should be reverted? save should be aborted if a document is not dirty

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess what @lmcbout wanted to do here is "formatting the file on users hitting CTRL+S even if the file is not dirty" - vsCode does it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is exactly the reason, to allow "CTRL+S" like vscode does

Copy link
Member

@akosyakov akosyakov Jan 15, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please check whether VS Code actually save changes or only try to apply formatting. In cloud case sending unchanged content is expensive and we should avoid doing it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried VSCode with the file (theia/.vscode/launch.json). The file is not dirty. By selecting "CTRL+S", it reformatted the file and saved it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant in our case if formatting does nothing we should not write anything to the disk. It is expensive for large files.

Copy link
Contributor Author

@lmcbout lmcbout Jan 16, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After the formatting, the frontend is using the monaco-editor-model.doSave()
In that method, we check if there is some changes (~ line 320) code:

        const changes = this.popContentChanges();
        if (changes.length === 0) {
            return;
        }

This is the same as testing isDirty(). In fact we could use:

if (this.dirty) return;

to replace those lines above and it would do the same here . So as a resume, the file remains in the frontend if there is no formatting , they are not sent to the backend when there is no changes.

@vince-fugnitto
Copy link
Member

I noticed the command Save All does not work properly.

Say for example I have three .json files with auto-save off.
If I attempt to Save All, all three files are saved, but only the last file in the editor actually gets formatted.

@lmcbout
Copy link
Contributor Author

lmcbout commented Jan 16, 2019

Question:
In this PR, in monaco-editor-providers.createMonacoEditor(), I try to use the action from the editor and use the"Save All" command from the menu, it saves and re-format all files even the one not having the focus, but after that, if I modify the file having the focus, it starts to add the new data in the wrong editor. I can see it by the dirty icon showing on the wrong file.
From this PR , just replace the following line:

await this.commandService.executeCommand('monaco.editor.action.formatDocument');
by
await editor.runAction('editor.action.formatDocument');

Question: is the editor.runAction() broken ?
Note:
Set the pref: "editor.formatOnSave": true
the following video: Started from two files to be re-formatted when selecting "Save All" and after the save , try to enter new data in the file having the focus, but the dirty flag goes to the other file and the new data as well.

wrongeditor2

Format on manual Save when the preference 'editor.formatOnSave' is "true"

Signed-off-by: Jacques Bouthillier <jacques.bouthillier@ericsson.com>
@lmcbout
Copy link
Contributor Author

lmcbout commented Jan 17, 2019

Tested file: ".java, .cpp, .ts, .json"

Note: need to set the preference to format the file: "editor.formatOnSave": true
In monaco-editor-provider.ts
modify method createMonacoEditor(),

if we use the command:

      await this.commandServiceFactory().executeCommand('monaco.editor.action.formatDocument');

it works fine except if we select from the menu "Save All", it saves all files but only format the file having the focus. The other files are just saved.

if we use the command:

      await editor.runAction('editor.action.formatDocument');

works fine with one file. With multiple file to save (Save All), it re-formats all files and saves them, but after, if you type new code , it will end-up in a file not necessary having the focus. (Is an issue if we try to use this command)


To Test:

Preparation : step 1 to 5

  1. set the preference "editor.formatOnSave": false
  2. Open a file (launch.json) + adjust the code to be un-formatted + save
  3. Open a second file (untitled.ts) + adjust the code to be un-formatted + save
  4. reset the preferences "editor.formatOnSave": true + close the preference editor.
  5. Put focus on the second file (Untitled.ts)
  6. testing with the implemented command : await this.commandServiceFactory().executeCommand('monaco.editor.action.formatDocument');

Menu: "Save All" Result:
==> All files are saved, ONLY the file with the focus (Untitled.ts) is re-formatted
Now start typing anything and the data shows in the focus file (Untitled.ts)

  1. testing with the command: await editor.runAction('editor.action.formatDocument');
    Menu: "Save All" Result:
    ==> All files are saved and re-formatted. Focus still on (Untitled.ts) .
    Now start typing anything and the data shows in the other file (launch.json), the other file shows the dirty flag. In the file having the focus (Untitled.ts), it just like it is frozen. Select the "launch.json" , type new code (appear in the focus file) and then select the file "Untitled.ts", now you can type data in it.

@vince-fugnitto
Copy link
Member

I'm fine with Save All not being covered in this pr if it is too complicated at the moment.

I see two ways forward:

  1. either we complete the ability to Save All for all opened editors including their formatting.
  2. we do not cover Save All, and we drop the formatting of the last file in the editor. In my opinion, this behaviour is quite annoying and will definitely lead to unhappy users. (they will attempt to save all the files, and see only a single file actually being formatted without clear knowledge of which file or why).

Also, just curious, with Auto Save set to off, why does the following occur when saving (it only occurs when auto-save is off)?

selection_001

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants