Capture diff on save


#1

I would like a way to capture all diffs on a file whenever it is saved from within a package. I feel like there should be an easy way to do this especially if the file is in a git repo but I don’t see anything in the docs… Suggestions?


#2

What do you mean from within a package? Are the save events triggered in a programmatic way, or are they triggered by the user the normal way?

If the user triggers the saving events you’re interested in, you could save the status of your buffer in a variable and add something like this to your package:

@subscriptions.add atom.commands.onDidDispatch (event) =>
  if event.type isnt 'core:save' then return
  # do all your stuff here

Please consider this is not really the best solution, since it checks every command that fires in Atom.

Maybe you can find something better in the Text Editor APIs.


#3

Hi b3by! I actually saw your post related to this issue before posting here. Any luck there? Yes I’m looking to capture diffs whenever a user saves the file. I was hoping to find a solution that would react to the didSave or willSave hooks and capture the diff relative to the last save. One idea was to look at the “undoStack” when willSave is fired but that seems to be composed of an array of odd “markerLayers” that I’m not sure how to deal with.

My end goal is to capture all the diffs over time so that the “evolution” of the code can be played back later.


#4

I think my problem was similar to yours. I needed to keep track of all deleted and saved files within a project, so I used onWillDispatch and onDidDispatch on atom.commands in order to intercept all the events like core:save or tree-view:remove. Unfortunately, I couldn’t find any out-of-the-box solution for this. Still, this approach does not force me to use a watcher over my project (around 5k files, so it’s a good thing).

Since your problems seems to be strictly related with git, may I suggest you give a look at the Git Repository APIs, in particular at this one? It allows you to get the diffs for a specific file, so you could:

  • set a callback for onWillDispatch, catching all the core:save events
  • retrieve the git differences for all the files that belong to your project

Let me know if this helps!


#5

Yes that does seem like it would work for git linked projects but I’d like a solution that didn’t depend on git since not all projects will be linked to a repo.

Now that i’m thinking about it perhaps I could listen to the willSave hook… then take what’s in the buffer and use one of the many diff modules to capture the diffs between the buffer and what’s on disk. What do you think? I’m not sure how that would affect performance though.


#6

The onWillSave event should be set on TextBuffer, so I guess you should set it for every open TextBuffer, and disable if when TextBuffers are being closed.

According to my experience, using Atom events is way less resources-consuming than a file watcher, so your approach could be optimal. Still, a major downside could regard large files. What if I work with a very large file, saving it a lot? The bottleneck would be the tool you adopt to evaluate the diff.


#7

good points. I’m going to test it out and see how it performs… Perhaps the diff could be executed in a separate thread but that might invoke a race condition since the on disk file will be changing… I’ll report back