defmodule FsNotify do @moduledoc """ Filesystem watcher backed by notify-rs (via Rustler). Watch one or more paths and receive each filesystem event in your process as `{:fs_notify_event, %FsNotify.Event{}}` (mirroring notify-rs: one message per event, carrying all affected `paths`). {:ok, ref} = FsNotify.watch("/some/dir", recursive: true) {:ok, ref} = FsNotify.watch(["/dir/a", "/dir/b"]) receive do {:fs_notify_event, %FsNotify.Event{kind: kind, paths: paths}} -> handle(kind, paths) end FsNotify.unwatch(ref) The watch is tied to the subscriber process: it stops automatically when that process dies (and also if `ref` is garbage-collected). `unwatch/1` stops it eagerly. """ @doc """ Start watching `path` (a path or a list of paths). Returns `{:ok, ref}`; keep `ref` for as long as you want to watch. Options: * `:recursive` (default `true`) — watch subdirectories * `:subscriber` (default: the calling process) — process that receives events * `:debounce` (default `0`) — coalesce events over this many ms (notify-rs debouncer); `0` disables debouncing * `:backend` (default `:recommended`) — `:recommended` (the OS-native backend) or `:poll` (portable polling watcher) * `:poll_interval` (default `0`) — poll interval in ms for the `:poll` backend; `0` uses notify's default ## Examples {:ok, ref} = FsNotify.watch("/tmp/dir", recursive: true) {:ok, ref} = FsNotify.watch(["/tmp/a", "/tmp/b"], debounce: 100) {:ok, ref} = FsNotify.watch("/tmp/dir", backend: :poll, poll_interval: 200) """ @spec watch(binary() | [binary()], keyword()) :: {:ok, reference()} | {:error, binary()} def watch(path, opts \\ []) do subscriber = Keyword.get(opts, :subscriber, self()) native_opts = %{ recursive: Keyword.get(opts, :recursive, true), debounce: Keyword.get(opts, :debounce, 0), backend: Keyword.get(opts, :backend, :recommended), poll_interval: Keyword.get(opts, :poll_interval, 0) } FsNotify.Native.watch(subscriber, List.wrap(path), native_opts) end @doc """ Stop the watcher identified by `ref`. ## Examples {:ok, ref} = FsNotify.watch("/tmp/dir") :ok = FsNotify.unwatch(ref) """ @spec unwatch(reference()) :: :ok def unwatch(ref), do: FsNotify.Native.unwatch(ref) end