Best way to change the TextEditor (TextBuffer) on save when my function is asynchronous?


#1

I am the maintainer of Atom-Beautify. Most of the users have “Beautify On Save” enabled. The problem is I do not know how to prevent Atom from saving immediately (synchronously) and wait for the beautification to complete. Atom-Beautify handles beautification asynchronously, so by the time the beautification has completed the TextEditor – which was originally saved – may actually be closed!

This is the current way “Beautify On Save” is handled: https://github.com/Glavin001/atom-beautify/blob/c8a8f7b3cbf1f4bdeee249586b8531c0179ee680/src/beautify.coffee#L507-L556

  1. On Save event occurs (editor.onDidSave): https://github.com/Glavin001/atom-beautify/blob/c8a8f7b3cbf1f4bdeee249586b8531c0179ee680/src/beautify.coffee#L552-L554
  2. Perform beautification on text: https://github.com/Glavin001/atom-beautify/blob/c8a8f7b3cbf1f4bdeee249586b8531c0179ee680/src/beautify.coffee#L511-L535
  3. Check if Editor is still alive: https://github.com/Glavin001/atom-beautify/blob/c8a8f7b3cbf1f4bdeee249586b8531c0179ee680/src/beautify.coffee#L538
  4. Store reference to editor’s file path: https://github.com/Glavin001/atom-beautify/blob/c8a8f7b3cbf1f4bdeee249586b8531c0179ee680/src/beautify.coffee#L544
  5. Save with new beautified text: https://github.com/Glavin001/atom-beautify/blob/c8a8f7b3cbf1f4bdeee249586b8531c0179ee680/src/beautify.coffee#L545
  6. Remove reference to editor’s file path: https://github.com/Glavin001/atom-beautify/blob/c8a8f7b3cbf1f4bdeee249586b8531c0179ee680/src/beautify.coffee#L546

In the end, the TextEditor has been saved twice: the first time with the original text, and the second time later with the beautified code. Ideally, saving to file system actually occurs only only once and Atom waits on Atom-Beautify to complete. Also ensuring the user does not close the editor thus causing editor.save() to fail.

Any ideas? Thank you in advance!


#2

It’s not a perfect fix, but you could override ctrl-s with a command that waits for atom-beautify to complete and then saves.


#3

I’m not sure if this will help in any way, but https://github.com/atom/atom/pull/14435 will change saving to be async.


#4

This might be exactly what I need! Thanks!


#5

I may investigate it as a last resort ;).


#6

I understand your problem, if you try to solve this issue with current API, I don’t think there is clean and easy solution.
You need to patch TextEditor.prototype.save or TextBuffer.prototype.save.
Using underscore-plus’s helper _.adviceBefore make this monkey match simple and easy to manage.

As far as I can tell, a few of packages already doing this kind of prototype patching( not limited to save ), for example, clipboard history package is basically overriding atom.cliboard.write to spy clipboard.


#7

Is there any error after the update? I mean I can’t seem to save PHP files even if I get a small syntax error in the code.