SkillAgentSearch skills...

Listen

The Listen gem listens to file modifications and notifies you about the changes.

Install / Use

/learn @guard/Listen
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Listen

The listen gem listens to file modifications and notifies you about the changes.

Development Status Gem Version Code Climate Coverage Status

Features

  • OS-optimized adapters on MRI for Mac OS X 10.6+, Linux, *BSD and Windows, more info below.
  • Detects file modification, addition and removal.
  • You can watch multiple directories.
  • Regexp-patterns for ignoring paths for more accuracy and speed
  • Increased change detection accuracy on OS X HFS and VFAT volumes.
  • Continuous Integration: tested on selected Ruby environments via Github Workflows.

Issues / limitations

  • Limited support for symlinked directories (#279):
    • Symlinks are always followed (#25).
    • Symlinked directories pointing within a watched directory are not supported (#273.
  • No directory/adapter-specific configuration options.
  • Support for plugins planned for future.
  • TCP functionality was removed in listen 3.0.0 (#319, #218). There are plans to extract this feature to separate gems (#258), until this is finished, you can use by locking the listen gem to version '~> 2.10'.
  • Some filesystems won't work without polling (VM/Vagrant Shared folders, NFS, Samba, sshfs, etc.).
  • Windows and *BSD adapter aren't continuously and automatically tested.
  • OSX adapter has some performance limitations (#342).
  • Listeners do not notify across forked processes, if you wish for multiple processes to receive change notifications you must listen inside of each process.

Pull requests or help is very welcome for these.

Install

The simplest way to install listen is to use Bundler.

gem 'listen'

Complete Example

Here is a complete example of using the listen gem:

require 'listen'

listener = Listen.to('/srv/app') do |modified, added, removed|
  puts(modified: modified, added: added, removed: removed)
end
listener.start
sleep

Running the above in the background, you can see the callback block being called in response to each command:

$ cd /srv/app
$ touch a.txt
{:modified=>[], :added=>["/srv/app/a.txt"], :removed=>[]}

$ echo more >> a.txt
{:modified=>["/srv/app/a.txt"], :added=>[], :removed=>[]}

$ mv a.txt b.txt
{:modified=>[], :added=>["/srv/app/b.txt"], :removed=>["/srv/app/a.txt"]}

$ vi b.txt
# add a line to this new file and press ZZ to save and exit
{:modified=>["/srv/app/b.txt"], :added=>[], :removed=>[]}

$ vi c.txt
# add a line and press ZZ to save and exit
{:modified=>[], :added=>["/srv/app/c.txt"], :removed=>[]}

$ rm b.txt c.txt
{:modified=>[], :added=>[], :removed=>["/srv/app/b.txt", "/srv/app/c.txt"]}

Usage

Call Listen.to with one or more directories and the "changes" callback passed as a block.

listener = Listen.to('dir/to/listen', 'dir/to/listen2') do |modified, added, removed|
  puts "modified absolute path array: #{modified}"
  puts "added absolute path array: #{added}"
  puts "removed absolute path array: #{removed}"
end
listener.start # starts a listener thread--does not block

# do whatever you want here...just don't exit the process :)

sleep

Changes Callback

Changes to the listened-to directories are reported by the listener thread in a callback. The callback receives three array parameters: modified, added and removed, in that order. Each of these three is always an array with 0 or more entries. Each array entry is an absolute path.

Pause / start / stop

Listeners can also be easily paused and later un-paused with start:

listener = Listen.to('dir/path/to/listen') { |modified, added, removed| puts 'handle changes here...' }

listener.start
listener.paused?     # => false
listener.processing? # => true

listener.pause       # stops processing changes (but keeps on collecting them)
listener.paused?     # => true
listener.processing? # => false

listener.start       # resumes processing changes
listener.stop        # stop both listening to changes and processing them

Note: While paused, listen keeps on collecting changes in the background - to clear them, call stop.

Note: You should keep track of all started listeners and stop them properly on finish.

Ignore / ignore!

Listen ignores some directories and extensions by default (See DEFAULT_IGNORED_FILES and DEFAULT_IGNORED_EXTENSIONS in Listen::Silencer). You can add ignoring patterns with the ignore option/method or overwrite default with ignore! option/method.

listener = Listen.to('dir/path/to/listen', ignore: /\.txt/) { |modified, added, removed| # ... }
listener.start
listener.ignore! /\.pkg/ # overwrite all patterns and only ignore pkg extension.
listener.ignore /\.rb/   # ignore rb extension in addition of pkg.
sleep

Note: :ignore regexp patterns are evaluated against relative paths.

Note: Ignoring paths does not improve performance, except when Polling (#274).

Only

Listen watches all files (less the ignored ones) by default. If you want to only listen to a specific type of file (i.e., just .rb extension), you should use the only option/method.

listener = Listen.to('dir/path/to/listen', only: /\.rb$/) { |modified, added, removed| # ... }
listener.start
listener.only /_spec\.rb$/ # overwrite all existing only patterns.
sleep

Note: :only regexp patterns are evaluated only against relative file paths.

Options

All the following options can be set through the Listen.to after the directory path(s) params.

ignore: [%r{/foo/bar}, /\.pid$/, /\.coffee$/]   # Ignore a list of paths
                                                # default: See DEFAULT_IGNORED_FILES and DEFAULT_IGNORED_EXTENSIONS in Listen::Silencer

ignore!: %r{/foo/bar}                           # Same as ignore options, but overwrite default ignored paths.

only: %r{.rb$}                                  # Only listen to specific files
                                                # default: none

latency: 0.5                                    # Set the delay (**in seconds**) between checking for changes
                                                # default: 0.25 sec (1.0 sec for polling)

wait_for_delay: 4                               # Set the delay (**in seconds**) between calls to the callback when changes exist
                                                # default: 0.10 sec

force_polling: true                             # Force the use of the polling adapter
                                                # default: none

relative: false                                 # Whether changes should be relative to current dir or not
                                                # default: false

polling_fallback_message: 'custom message'      # Set a custom polling fallback message (or disable it with false)
                                                # default: "Listen will be polling for changes. Learn more at https://github.com/guard/listen#listen-adapters."

Logging and Debugging

Listen logs its activity to Listen.logger. This is the primary method of debugging.

Custom Logger

You can call Listen.logger = to set a custom listen logger for the process. For example:

Listen.logger = Rails.logger

Default Logger

If no custom logger is set, a default listen logger which logs to to STDERR will be created and assigned to Listen.logger.

The default logger defaults to the error logging level (severity). You can override the logging level by setting the environment variable LISTEN_GEM_DEBUGGING=<level>. For <level>, all standard ::Logger levels are supported, with any mix of upper-/lower-case:

export LISTEN_GEM_DEBUGGING=debug # or 2 [deprecated]
export LISTEN_GEM_DEBUGGING=info  # or 1 or true or yes [deprecated]
export LISTEN_GEM_DEBUGGING=warn
export LISTEN_GEM_DEBUGGING=fatal
export LISTEN_GEM_DEBUGGING=error

The default of error will be used if an unsupported value is set.

Note: The alternate values 1, 2, true and yes shown above are deprecated and will be removed from listen v4.0.

Disabling Logging

If you want to disable listen logging, set

Listen.logger = ::Logger.new('/dev/null')

Adapter Warnings

If listen is having trouble with the underlying adapter, it will display warnings with Kernel#warn by default, which in turn writes to STDERR. Sometimes this is not desirable, for example in an environment where STDERR is ignored. For these reasons, the behavior can be configured using Listen.adapter_warn_behavior =:

Listen.adapter_warn_behavior = :warn   # default (true means the same)
Listen.adapter_warn_behavior = :log    # send to logger.warn
Listen.adapter_warn_behavior = :silent # suppress all adapter warnings (nil or false mean the same)

Also there are some cases where specific warnings are not helpful. For example, if you are using the polling adapter--and expect to--you can suppress the warning about it by providing a callable object like a lambda or proc that determines the behavior

View on GitHub
GitHub Stars2.0k
CategoryDevelopment
Updated23h ago
Forks248

Languages

Ruby

Security Score

95/100

Audited on Mar 30, 2026

No findings