Simple, usable FSEvents API
Switch branches/tags


= fsevents


  This is intended as a simple, usable FSEvents API. Rather than directly using the Carbon framework and a bunch of methods on OSX, you can pretend you're using a normal Ruby object.

  Much of this was inspired by or almost directly taken from various sources:
  * Ezwan Aizat bin Abdullah Faiz's excellent article on using FSEvents with autotest instead of polling --
    This was a major inspiration, especially because (no offense intended) it's so nasty. It shows just how much setup is necessary to do something that should be simple.
  * Rucola's fsevents.rb --
    I was tempted to use this directly, but it's not yet part of the gem. On top of that, requiring Rucola only to use FSEvents seems a little much.
  * rubaidh's fsevent at master -- -- which gave me a few ideas for organization.
  If you bother to look, you'll notice the license includes names other than my own. I may have made some improvements and done it all in BDD style, but I had a good foundation to work on. In the words of Isaac Newton, "If I have seen a little further it is by standing on the shoulders of Giants."

  It doesn't take much to set up an FSEvent stream. At its simplest, it looks like this:
      require 'fsevents'
      stream ='/tmp') { |events|  p events }
  That will enter a loop that continually watches the stream and prints out the events. Try it and make some new files in /tmp.
  You may want more details on the events, so just give it a better block.
      require 'fsevents'
      stream ='/tmp') do |events|
        events.each do |event|
          p event.modified_files
  Try that and make some new files in /tmp. Exciting, isn't it?
  And for the common case of wanting to process every modified file no matter which subdirectory it happens to be under, the events array is extended for your convenience.
      require 'fsevents'
      stream ='/tmp') do |events|
        p events.modified_files
      end takes some options, most of which I fully admit I don't understand because I have little desire to read the documentation on FSEvents itself. One obvious option is latency, which the number of seconds to wait until an event is reported. A higher number allows FSEvents to bundle events.
      stream ='/tmp', :latency => 15) {}  # default is 1.0
      # Like I said, I don't know what this means. The default is 0, though.
      stream ='/tmp', :flags => 27) {}
      stream ='/tmp', '/usr/local') {}  # Yes, you can give multiple paths
      stream =  # no path means watch Dir.pwd is probably the most common entry point, but there are others. You can simply initialize an FSEvents::Stream object with .new, but then the stream needs to be created, scheduled and started. There are a few convenience methods defined to make this easier. The following blocks of code are all equivalent.
      stream ='/tmp') {}
      stream ='/tmp') {}
      stream = FSEvents::Stream.create('/tmp') {}
      stream ='/tmp') {}

  Just as a stream can be started, it can also be stopped (paused, more like, since apparently you can resume it later).
  A stream can also be invalidated and released.
      stream.shutdown  # stops, invalidates, and releases the stream
  From what I can tell, entering the run loop requires an interrupt to get back out. Bear that in mind.

  * OS X, of course. How exactly were you expecting to use FSEvents?
  * RubyCocoa
  Note that the easiest way to have this work is use the stock Ruby install with Leopard.


  sudo gem install fsvents