sass 3.2.0.alpha.101 → 3.2.0.alpha.102

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/REVISION +1 -1
  2. data/Rakefile +2 -2
  3. data/VERSION +1 -1
  4. data/lib/sass/plugin/compiler.rb +25 -32
  5. data/lib/sass/plugin/listener.rb +59 -0
  6. data/lib/sass/script/lexer.rb +1 -1
  7. data/lib/sass/script/list.rb +1 -0
  8. data/test/sass/conversion_test.rb +10 -0
  9. data/test/sass/scss/css_test.rb +9 -0
  10. data/vendor/listen/CHANGELOG.md +72 -0
  11. data/vendor/listen/Gemfile +35 -0
  12. data/vendor/listen/Guardfile +8 -0
  13. data/vendor/listen/LICENSE +20 -0
  14. data/vendor/listen/README.md +297 -0
  15. data/vendor/listen/Rakefile +47 -0
  16. data/vendor/listen/Vagrantfile +96 -0
  17. data/vendor/listen/lib/listen.rb +38 -0
  18. data/vendor/listen/lib/listen/adapter.rb +159 -0
  19. data/vendor/listen/lib/listen/adapters/darwin.rb +84 -0
  20. data/vendor/listen/lib/listen/adapters/linux.rb +99 -0
  21. data/vendor/listen/lib/listen/adapters/polling.rb +66 -0
  22. data/vendor/listen/lib/listen/adapters/windows.rb +82 -0
  23. data/vendor/listen/lib/listen/directory_record.rb +257 -0
  24. data/vendor/listen/lib/listen/listener.rb +186 -0
  25. data/vendor/listen/lib/listen/multi_listener.rb +121 -0
  26. data/vendor/listen/lib/listen/turnstile.rb +28 -0
  27. data/vendor/listen/lib/listen/version.rb +3 -0
  28. data/vendor/listen/listen.gemspec +26 -0
  29. data/vendor/listen/spec/listen/adapter_spec.rb +142 -0
  30. data/vendor/listen/spec/listen/adapters/darwin_spec.rb +31 -0
  31. data/vendor/listen/spec/listen/adapters/linux_spec.rb +30 -0
  32. data/vendor/listen/spec/listen/adapters/polling_spec.rb +68 -0
  33. data/vendor/listen/spec/listen/adapters/windows_spec.rb +24 -0
  34. data/vendor/listen/spec/listen/directory_record_spec.rb +807 -0
  35. data/vendor/listen/spec/listen/listener_spec.rb +151 -0
  36. data/vendor/listen/spec/listen/multi_listener_spec.rb +151 -0
  37. data/vendor/listen/spec/listen/turnstile_spec.rb +56 -0
  38. data/vendor/listen/spec/listen_spec.rb +73 -0
  39. data/vendor/listen/spec/spec_helper.rb +16 -0
  40. data/vendor/listen/spec/support/adapter_helper.rb +538 -0
  41. data/vendor/listen/spec/support/directory_record_helper.rb +35 -0
  42. data/vendor/listen/spec/support/fixtures_helper.rb +29 -0
  43. data/vendor/listen/spec/support/listeners_helper.rb +133 -0
  44. data/vendor/listen/spec/support/platform_helper.rb +11 -0
  45. metadata +41 -5
data/REVISION CHANGED
@@ -1 +1 @@
1
- 9e96a841ad39832b13e529e22ae8bdfc1e74ce13
1
+ 05235ac9be0f69c6449fef65485e0707c24d7235
data/Rakefile CHANGED
@@ -115,9 +115,9 @@ task :submodules do
115
115
  if File.exist?(File.dirname(__FILE__) + "/.git")
116
116
  sh %{git submodule sync}
117
117
  sh %{git submodule update --init}
118
- elsif !File.exist?(File.dirname(__FILE__) + "/vendor/fssm/lib")
118
+ elsif !File.exist?(File.dirname(__FILE__) + "/vendor/listen/lib")
119
119
  warn <<WARN
120
- WARNING: vendor/fssm doesn't exist, and this isn't a git repository so
120
+ WARNING: vendor/listen doesn't exist, and this isn't a git repository so
121
121
  I can't get it automatically!
122
122
  WARN
123
123
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.2.0.alpha.101
1
+ 3.2.0.alpha.102
@@ -5,6 +5,7 @@ require 'sass'
5
5
  require 'sass/callbacks'
6
6
  require 'sass/plugin/configuration'
7
7
  require 'sass/plugin/staleness_checker'
8
+ require 'sass/plugin/listener'
8
9
 
9
10
  module Sass::Plugin
10
11
 
@@ -218,10 +219,10 @@ module Sass::Plugin
218
219
  #
219
220
  # Before the watching starts in earnest, `watch` calls \{#update\_stylesheets}.
220
221
  #
221
- # Note that `watch` uses the [FSSM](http://github.com/ttilley/fssm) library
222
+ # Note that `watch` uses the [Listen](http://github.com/guard/listen) library
222
223
  # to monitor the filesystem for changes.
223
- # FSSM isn't loaded until `watch` is run.
224
- # The version of FSSM distributed with Sass is loaded by default,
224
+ # Listen isn't loaded until `watch` is run.
225
+ # The version of Listen distributed with Sass is loaded by default,
225
226
  # but if another version has already been loaded that will be used instead.
226
227
  #
227
228
  # @param individual_files [Array<(String, String)>]
@@ -234,15 +235,15 @@ module Sass::Plugin
234
235
  update_stylesheets(individual_files)
235
236
 
236
237
  begin
237
- require 'fssm'
238
+ require 'listen'
238
239
  rescue LoadError => e
239
- dir = Sass::Util.scope("vendor/fssm/lib")
240
+ dir = Sass::Util.scope("vendor/listen/lib")
240
241
  if $LOAD_PATH.include?(dir)
241
242
  e.message << "\n" <<
242
243
  if File.exists?(scope(".git"))
243
244
  'Run "git submodule update --init" to get the recommended version.'
244
245
  else
245
- 'Run "gem install fssm" to get it.'
246
+ 'Run "gem install listen" to get it.'
246
247
  end
247
248
  raise e
248
249
  else
@@ -251,59 +252,51 @@ module Sass::Plugin
251
252
  end
252
253
  end
253
254
 
254
- unless individual_files.empty? && FSSM::Backends::Default.name == "FSSM::Backends::FSEvents"
255
- # As of FSSM 0.1.4, it doesn't support FSevents on individual files,
256
- # but it also isn't smart enough to switch to polling itself.
257
- require 'fssm/backends/polling'
258
- Sass::Util.silence_warnings do
259
- FSSM::Backends.const_set(:Default, FSSM::Backends::Polling)
260
- end
261
- end
262
-
263
255
  # TODO: Keep better track of what depends on what
264
256
  # so we don't have to run a global update every time anything changes.
265
- FSSM.monitor do |mon|
257
+ Sass::Plugin::Listener.new do |l|
266
258
  template_location_array.each do |template_location, css_location|
267
- mon.path template_location do |path|
268
- path.glob '**/*.s[ac]ss'
269
-
270
- path.update do |base, relative|
259
+ l.directory(template_location, {
260
+ :modified => lambda do |base, relative|
261
+ next if relative !~ /\.s[ac]ss$/
271
262
  run_template_modified File.join(base, relative)
272
263
  update_stylesheets(individual_files)
273
- end
264
+ end,
274
265
 
275
- path.create do |base, relative|
266
+ :added => lambda do |base, relative|
267
+ next if relative !~ /\.s[ac]ss$/
276
268
  run_template_created File.join(base, relative)
277
269
  update_stylesheets(individual_files)
278
- end
270
+ end,
279
271
 
280
- path.delete do |base, relative|
272
+ :removed => lambda do |base, relative|
273
+ next if relative !~ /\.s[ac]ss$/
281
274
  run_template_deleted File.join(base, relative)
282
275
  css = File.join(css_location, relative.gsub(/\.s[ac]ss$/, '.css'))
283
276
  try_delete_css css
284
277
  update_stylesheets(individual_files)
285
278
  end
286
- end
279
+ })
287
280
  end
288
281
 
289
282
  individual_files.each do |template, css|
290
- mon.file template do |path|
291
- path.update do
283
+ l.file(template, {
284
+ :modified => lambda do
292
285
  run_template_modified template
293
286
  update_stylesheets(individual_files)
294
- end
287
+ end,
295
288
 
296
- path.create do
289
+ :added => lambda do
297
290
  run_template_created template
298
291
  update_stylesheets(individual_files)
299
- end
292
+ end,
300
293
 
301
- path.delete do
294
+ :removed => lambda do
302
295
  run_template_deleted template
303
296
  try_delete_css css
304
297
  update_stylesheets(individual_files)
305
298
  end
306
- end
299
+ })
307
300
  end
308
301
  end
309
302
  end
@@ -0,0 +1,59 @@
1
+ # A wrapper around the Listen gem. Adds support for listening to individual
2
+ # files, as well as a somewhat cleaner event dispatch API.
3
+ #
4
+ # @private
5
+ class Sass::Plugin::Listener
6
+ def initialize
7
+ @directories = {}
8
+ yield self
9
+ begin
10
+ start!
11
+ rescue Exception => e
12
+ raise e unless e.is_a?(Interrupt)
13
+ end
14
+ end
15
+
16
+ def directory(path, events)
17
+ (@directories[path] ||= []) << events
18
+ end
19
+
20
+ def file(path, events)
21
+ file_base = File.basename(path)
22
+ directory(File.dirname(path), {
23
+ :modified => file_event_fn(events[:modified], file_base),
24
+ :added => file_event_fn(events[:added], file_base),
25
+ :removed => file_event_fn(events[:removed], file_base)
26
+ })
27
+ end
28
+
29
+ def start!
30
+ listener = Listen::MultiListener.new(*@directories.keys) do |modified, added, removed|
31
+ modified = modified.group_by {|path| File.dirname(path)}
32
+ added = added.group_by {|path| File.dirname(path)}
33
+ removed = removed.group_by {|path| File.dirname(path)}
34
+
35
+ @directories.each do |dir, events|
36
+ events.each do |e|
37
+ run_events(modified[dir], e[:modified], dir)
38
+ run_events(added[dir], e[:added], dir)
39
+ run_events(removed[dir], e[:removed], dir)
40
+ end
41
+ end
42
+ end.start
43
+ end
44
+
45
+ private
46
+
47
+ def file_event_fn(event, file_base)
48
+ lambda do |dir, base|
49
+ next unless event
50
+ next unless base == file_base
51
+ event.call
52
+ end
53
+ end
54
+
55
+ def run_events(paths, event, path)
56
+ return if paths.nil? || event.nil?
57
+ paths.each {|p| event[File.dirname(p), File.basename(p)]}
58
+ end
59
+ end
@@ -293,7 +293,7 @@ MESSAGE
293
293
  end
294
294
 
295
295
  def special_fun
296
- return unless str1 = scan(/((-[\w-]+-)?calc|expression|progid:[a-z\.]*)\(/i)
296
+ return unless str1 = scan(/((-[\w-]+-)?(calc|element)|expression|progid:[a-z\.]*)\(/i)
297
297
  str2, _ = Sass::Shared.balance(@scanner, ?(, ?), 1)
298
298
  c = str2.count("\n")
299
299
  old_line = @line
@@ -46,6 +46,7 @@ module Sass::Script
46
46
 
47
47
  # @see Node#to_sass
48
48
  def to_sass(opts = {})
49
+ return "()" if value.empty?
49
50
  precedence = Sass::Script::Parser.precedence_of(separator)
50
51
  value.map do |v|
51
52
  if v.is_a?(List) && Sass::Script::Parser.precedence_of(v.separator) <= precedence
@@ -1515,6 +1515,16 @@ SCSS
1515
1515
  end
1516
1516
 
1517
1517
 
1518
+ ## Regression Tests
1519
+
1520
+ def test_empty_lists
1521
+ assert_renders(<<SASS, <<SCSS)
1522
+ $foo: ()
1523
+ SASS
1524
+ $foo: ();
1525
+ SCSS
1526
+ end
1527
+
1518
1528
  private
1519
1529
 
1520
1530
  def assert_sass_to_sass(sass, options = {})
@@ -412,6 +412,15 @@ foo {
412
412
  SCSS
413
413
  end
414
414
 
415
+ def test_element_function
416
+ assert_parses <<SCSS
417
+ foo {
418
+ a: -moz-element(#foo);
419
+ b: -webkit-element(#foo);
420
+ b: -foobar-element(#foo); }
421
+ SCSS
422
+ end
423
+
415
424
  def test_unary_ops
416
425
  assert_equal <<CSS, render(<<SCSS)
417
426
  foo {
@@ -0,0 +1,72 @@
1
+ ## 0.4.1 - April 15, 2012
2
+
3
+ ### Bug fixes
4
+
5
+ - [#18](https://github.com/guard/listen/issues/18): Listener crashes when removing directories with nested paths (reported by [@daemonza][], fixed by [@Maher4Ever][])
6
+
7
+ ## 0.4.0 - April 9, 2012
8
+
9
+ ### New features
10
+
11
+ - Add `wait_for_callback` method to all adapters. ([@Maher4Ever][])
12
+ - Add `Listen::MultiListener` class to listen to multiple directories at once. ([@Maher4Ever][])
13
+ - Allow passing multiple directories to the `Listen.to` method. ([@Maher4Ever][])
14
+ - Add `blocking` option to `Listen#start` which can be used to disable blocking the current thread upon starting. ([@Maher4Ever][])
15
+ - Use absolute-paths in callbacks by default instead of relative-paths. ([@Maher4Ever][])
16
+ - Add `relative_paths` option to `Listen::Listener` to retain the old functionality. ([@Maher4Ever][])
17
+
18
+ ### Improvements
19
+
20
+ - Encapsulate thread spawning in the linux-adapter. ([@Maher4Ever][])
21
+ - Encapsulate thread spawning in the darwin-adapter. ([@Maher4Ever][] with [@scottdavis][] help)
22
+ - Encapsulate thread spawning in the windows-adapter. ([@Maher4Ever][])
23
+ - Fix linux-adapter bug where Listen would report file-modification events on the parent-directory. ([@Maher4Ever][])
24
+
25
+ ### Removals
26
+
27
+ - Remove `wait_until_listening` as adapters doesn't need to run inside threads anymore ([@Maher4Ever][])
28
+
29
+ ## 0.3.3 - March 6, 2012
30
+
31
+ ### Improvements
32
+
33
+ - Improve pause/unpause. ([@thibaudgg][])
34
+
35
+ ## 0.3.2 - March 4, 2012
36
+
37
+ ### New features
38
+
39
+ - Add pause/unpause listener's methods. ([@thibaudgg][])
40
+
41
+ ## 0.3.1 - February 22, 2012
42
+
43
+ ### Bug fix
44
+
45
+ - [#9](https://github.com/guard/listen/issues/9): Ignore doesn't seem to work. (reported by [@markiz][], fixed by [@thibaudgg][])
46
+
47
+ ## 0.3.0 - February 21, 2012
48
+
49
+ ### New features
50
+
51
+ - Add automatic fallback to polling if system adapter doesn't work (like a DropBox folder). ([@thibaudgg][])
52
+ - Add latency and force_polling options. ([@Maher4Ever][])
53
+
54
+ ## 0.2.0 - February 13, 2012
55
+
56
+ ### New features
57
+
58
+ - Add checksum comparaison support for detecting consecutive file modifications made during the same second. ([@thibaudgg][])
59
+ - Add rb-fchange support. ([@thibaudgg][])
60
+ - Add rb-inotify support. ([@thibaudgg][] with [@Maher4Ever][] help)
61
+ - Add rb-fsevent support. ([@thibaudgg][])
62
+ - Add non-recursive diff with multiple directories support. ([@thibaudgg][])
63
+ - Ignore .DS_Store by default. ([@thibaudgg][])
64
+
65
+ ## 0.1.0 - January 28, 2012
66
+
67
+ - First version with only a polling adapter and basic features set (ignore & filter). ([@thibaudgg][])
68
+
69
+ [@markiz]: https://github.com/markiz
70
+ [@thibaudgg]: https://github.com/thibaudgg
71
+ [@Maher4Ever]: https://github.com/Maher4Ever
72
+ [@daemonza]: https://github.com/daemonza
@@ -0,0 +1,35 @@
1
+ source :rubygems
2
+
3
+ gemspec
4
+
5
+ gem 'rake'
6
+
7
+ group :development do
8
+ platform :ruby do
9
+ gem 'rb-readline'
10
+ end
11
+
12
+ require 'rbconfig'
13
+ case RbConfig::CONFIG['target_os']
14
+ when /darwin/i
15
+ # gem 'ruby_gntp', '~> 0.3.4', :require => false
16
+ gem 'growl', :require => false
17
+ when /linux/i
18
+ gem 'libnotify', '~> 0.7.1', :require => false
19
+ when /mswin|mingw/i
20
+ gem 'win32console', :require => false
21
+ gem 'rb-notifu', '>= 0.0.4', :require => false
22
+ end
23
+
24
+ gem 'guard', '~> 1.0.0'
25
+ gem 'guard-rspec', '~> 0.7.0'
26
+ gem 'yard'
27
+ gem 'redcarpet'
28
+ gem 'pry'
29
+
30
+ gem 'vagrant'
31
+ end
32
+
33
+ group :test do
34
+ gem 'rspec', '~> 2.9.0'
35
+ end
@@ -0,0 +1,8 @@
1
+ guard :rspec, :all_on_start => false, :all_after_pass => false, :cli => '--fail-fast --format doc' do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
4
+ watch('spec/support/adapter_helper.rb') { "spec/listen/adapters" }
5
+ watch('spec/support/listener_helper.rb') { "spec/listen/listener_spec.rb" }
6
+ watch('spec/support/fixtures_helper.rb') { "spec" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+ end
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Thibaud Guillaume-Gentil
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,297 @@
1
+ # Listen [![Build Status](https://secure.travis-ci.org/guard/listen.png?branch=master)](http://travis-ci.org/guard/listen)
2
+
3
+ The Listen gem listens to file modifications and notifies you about the changes.
4
+
5
+ ## Features
6
+
7
+ * Works everywhere!
8
+ * Supports watching multiple directories from a single listener.
9
+ * OS-specific adapters for Mac OS X 10.6+, Linux and Windows.
10
+ * Automatic fallback to polling if OS-specific adapter doesn't work.
11
+ * Detects files modification, addidation and removal.
12
+ * Checksum comparaison for modifications made under the same second.
13
+ * Allows ignoring paths and supplying filters for better results.
14
+ * Tested on all Ruby environments via [travis-ci](http://travis-ci.org/guard/listen).
15
+
16
+ ## Install
17
+
18
+ ``` bash
19
+ gem install listen
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ There are **two ways** to use Listen:
25
+
26
+ 1. Call `Listen.to` with either a single directory or multiple directories, then define the `change` callback in a block.
27
+ 2. Create a `listener` object and use it in an (ARel style) chainable way.
28
+
29
+ Feel free to give your feeback via [Listen issues](https://github.com/guard/listener/issues)
30
+
31
+ ### Block API
32
+
33
+ ``` ruby
34
+ # Listen to a single directory.
35
+ Listen.to('dir/path/to/listen', filter: /.*\.rb/, ignore: '/ignored/path') do |modified, added, removed|
36
+ # ...
37
+ end
38
+
39
+ # Listen to multiple directories.
40
+ Listen.to('dir/to/awesome_app', 'dir/to/other_app', filter: /.*\.rb/, latency: 0.1) do |modified, added, removed|
41
+ # ...
42
+ end
43
+ ```
44
+
45
+ ### "Object" API
46
+
47
+ ``` ruby
48
+ listener = Listen.to('dir/path/to/listen')
49
+ listener = listener.ignore('/ignored/path')
50
+ listener = listener.filter(/.*\.rb/)
51
+ listener = listener.latency(0.5)
52
+ listener = listener.force_polling(true)
53
+ listener = listener.polling_fallback_message(false)
54
+ listener = listener.change(&callback)
55
+ listener.start # blocks execution!
56
+ ```
57
+
58
+ ### Chainable
59
+
60
+ ``` ruby
61
+ Listen.to('dir/path/to/listen')
62
+ .ignore('/ignored/path')
63
+ .filter(/.*\.rb/)
64
+ .latency(0.5)
65
+ .force_polling(true)
66
+ .polling_fallback_message('custom message')
67
+ .change(&callback)
68
+ .start # blocks execution!
69
+ ```
70
+
71
+ ### Pause/Unpause
72
+
73
+ Listener can also easily be paused/unpaused:
74
+
75
+ ``` ruby
76
+ listener = Listen.to('dir/path/to/listen')
77
+ listener.start(false) # non-blocking mode
78
+ listener.pause # stop listening to changes
79
+ listener.paused? # => true
80
+ listener.unpause
81
+ listener.stop
82
+ ```
83
+
84
+ ## Listening to changes on multiple directories
85
+
86
+ The Listen gem provides the `MultiListener` class to watch multiple directories and
87
+ handle their changes from a single listener:
88
+
89
+ ```ruby
90
+ listener = Listen::MultiListener.new('app/css', 'app/js')
91
+ listener.latency(0.5)
92
+
93
+ # Configure the listener to your needs...
94
+
95
+ listener.start # blocks execution!
96
+ ````
97
+
98
+ For an easier access, the `Listen.to` method can also be used to create a multi-listener:
99
+
100
+ ``` ruby
101
+ listener = Listen.to('app/css', 'app/js')
102
+ .ignore('vendor') # both js/vendor and css/vendor will be ignored
103
+ .change(&assets_callback)
104
+
105
+ listener.start # blocks execution!
106
+ ```
107
+
108
+ ## Changes callback
109
+
110
+ Changes to the listened-to directories gets reported back to the user in a callback.
111
+ The registered callback gets invoked, when there are changes, with **three** parameters:
112
+ `modified_paths`, `added_paths` and `removed_paths` in that particular order.
113
+
114
+ You can register a callback in two ways. The first way is by passing a block when calling
115
+ the `Listen.to` method or when initializing a listener object:
116
+
117
+ ```ruby
118
+ Listen.to('path/to/app') do |modified, added, removed|
119
+ # This block will be called when there are changes.
120
+ end
121
+
122
+ # or ...
123
+
124
+ listener = Listen::Listener.new('path/to/app') do |modified, added, removed|
125
+ # This block will be called when there are changes.
126
+ end
127
+
128
+ ```
129
+
130
+ The second way to register a callback is be calling the `change` method on any
131
+ listener passing it a block:
132
+
133
+ ```ruby
134
+ # Create a callback
135
+ callback = Proc.new do |modified, added, removed|
136
+ # This proc will be called when there are changes.
137
+ end
138
+
139
+ listener = Listen.to('dir')
140
+ listener.change(&callback) # convert the callback to a block and register it
141
+
142
+ listener.start # blocks execution
143
+ ```
144
+
145
+ ### Paths in callbacks
146
+
147
+ Listeners invoke callbacks passing them absolute paths by default:
148
+
149
+ ```ruby
150
+ # Assume someone changes the 'style.css' file in '/home/user/app/css' after creating
151
+ # the listener.
152
+ Listen.to('/home/user/app/css') do |modified, added, removed|
153
+ modified.inspect # => ['/home/user/app/css/style.css']
154
+ end
155
+ ```
156
+
157
+ #### Relative paths in callbacks
158
+
159
+ When creating a listener for a **single** path (more specifically a `Listen::Listener` instance),
160
+ you can pass `:relative_paths => true` as an option to get relative paths in
161
+ your callback:
162
+
163
+ ```ruby
164
+ # Assume someone changes the 'style.css' file in '/home/user/app/css' after creating
165
+ # the listener.
166
+ Listen.to('/home/user/app/css', :relative_paths => true) do |modified, added, removed|
167
+ modified.inspect # => ['style.css']
168
+ end
169
+ ```
170
+
171
+ Passing the `:relative_paths => true` option won't work when listeneing to multiple
172
+ directories:
173
+
174
+ ```ruby
175
+ # Assume someone changes the 'style.css' file in '/home/user/app/css' after creating
176
+ # the listener.
177
+ Listen.to('/home/user/app/css', '/home/user/app/js', :relative_paths => true) do |modified, added, removed|
178
+ modified.inspect # => ['/home/user/app/css/style.css']
179
+ end
180
+ ```
181
+
182
+ ## Options
183
+
184
+ These options can be set through `Listen.to` params or via methods (see the "Object" API)
185
+
186
+ ```ruby
187
+ :filter => /.*\.rb/, /.*\.coffee/ # Filter files to listen to via a regexps list.
188
+ # default: none
189
+
190
+ :ignore => 'path1', 'path2' # Ignore a list of paths (root directory or sub-dir)
191
+ # default: '.bundle', '.git', '.DS_Store', 'log', 'tmp', 'vendor'
192
+
193
+ :latency => 0.5 # Set the delay (**in seconds**) between checking for changes
194
+ # default: 0.1 sec (1.0 sec for polling)
195
+
196
+ :force_polling => true # Force the use of the polling adapter
197
+ # default: none
198
+
199
+ :polling_fallback_message => 'custom message' # Set a custom polling fallback message (or disable it with `false`)
200
+ # default: "WARNING: Listen fallen back to polling, learn more at https://github.com/guard/listen#fallback."
201
+ ```
202
+
203
+ ### Non-blocking listening to changes
204
+
205
+ Starting a listener blocks the current thread by default. That means any code after the
206
+ `start` call won't be run until the listener is stopped (which needs to be done from another thread).
207
+
208
+ For advanced usage there is an option to disable this behavior and have the listener start working
209
+ in the background without blocking. To enable non-blocking listening the `start` method of
210
+ the listener (be it `Listener` or `MultiListener`) needs to be called with `false` as a parameter.
211
+
212
+ Here is an example of using a listener in the non-blocking mode:
213
+
214
+ ```ruby
215
+ listener = Listen.to('dir/path/to/listen')
216
+ listener.start(false) # doesn't block execution
217
+
218
+ # Code here will run immediately after starting the listener
219
+
220
+ ```
221
+
222
+ **note**: Using the `Listen.to` helper-method with a callback-block will always
223
+ block execution. See the "Block API" section for an example.
224
+
225
+ ## Listen adapters
226
+
227
+ The Listen gem has a set of adapters to notify it when there are changes.
228
+ There are 3 OS-specific adapters to support Mac, Linux and Windows. These adapters are fast
229
+ as they use some system-calls to implement the notifying function.
230
+
231
+ There is also a polling adapter which is a cross-platform adapter and it will
232
+ work on any system. This adapter is unfortunately slower than the rest of the adapters.
233
+
234
+ The Listen gem will choose the best and working adapter for your machine automatically. If you
235
+ want to force the use of the polling adapter, either use the `:force_polling` option
236
+ while initializing the listener or call the `force_polling` method on your listener
237
+ before starting it.
238
+
239
+ <a name="fallback"/>
240
+ ## Polling fallback
241
+
242
+ When a OS-specific adapter doesn't work the Listen gem automatically falls back to the polling adapter.
243
+ Here are some things you could try to avoid the polling fallback:
244
+
245
+ * [Update your Dropbox client](http://www.dropbox.com/downloading) (if used).
246
+ * Increase latency. (Please [open an issue](https://github.com/guard/listen/issues/new) if you think that default is too low.)
247
+ * Move or rename the listened folder.
248
+ * Update/reboot your OS.
249
+
250
+ If your application keeps using the polling-adapter and you can't figure out why, feel free to [open an issue](https://github.com/guard/listen/issues/new) (and be sure to give all the details).
251
+
252
+ ## Development [![Dependency Status](https://gemnasium.com/guard/listen.png?branch=master)](https://gemnasium.com/guard/listen)
253
+
254
+ * Documentation hosted at [RubyDoc](http://rubydoc.info/github/guard/listen/master/frames).
255
+ * Source hosted at [GitHub](https://github.com/guard/listen).
256
+
257
+ Pull requests are very welcome! Please try to follow these simple rules if applicable:
258
+
259
+ * Please create a topic branch for every separate change you make.
260
+ * Make sure your patches are well tested. All specs run with `rake spec:portability` must pass.
261
+ * Update the [Yard](http://yardoc.org/) documentation.
262
+ * Update the README.
263
+ * Update the CHANGELOG for noteworthy changes.
264
+ * Please **do not change** the version number.
265
+
266
+ For questions please join us in our [Google group](http://groups.google.com/group/guard-dev) or on
267
+ `#guard` (irc.freenode.net).
268
+
269
+ ## Acknowledgment
270
+
271
+ * [Michael Kessler (netzpirat)][] for having written the [initial specs](https://github.com/guard/listen/commit/1e457b13b1bb8a25d2240428ce5ed488bafbed1f).
272
+ * [Travis Tilley (ttilley)][] for this awesome work on [fssm][] & [rb-fsevent][].
273
+ * [Nathan Weizenbaum (nex3)][] for [rb-inotify][], a thorough inotify wrapper.
274
+ * [stereobooster][] for [rb-fchange][], windows support wouldn't exist without him.
275
+ * [Yehuda Katz (wycats)][] for [vigilo][], that has been a great source of inspiration.
276
+
277
+ ## Authors
278
+
279
+ * [Thibaud Guillaume-Gentil][] ([@thibaudgg](http://twitter.com/thibaudgg))
280
+ * [Maher Sallam][] ([@mahersalam](http://twitter.com/mahersalam))
281
+
282
+ ## Contributors
283
+
284
+ [https://github.com/guard/listen/contributors](https://github.com/guard/listen/contributors)
285
+
286
+ [Thibaud Guillaume-Gentil]: https://github.com/thibaudgg
287
+ [Maher Sallam]: https://github.com/Maher4Ever
288
+ [Michael Kessler (netzpirat)]: https://github.com/netzpirat
289
+ [Travis Tilley (ttilley)]: https://github.com/ttilley
290
+ [fssm]: https://github.com/ttilley/fssm
291
+ [rb-fsevent]: https://github.com/thibaudgg/rb-fsevent
292
+ [Nathan Weizenbaum (nex3)]: https://github.com/nex3
293
+ [rb-inotify]: https://github.com/nex3/rb-inotify
294
+ [stereobooster]: https://github.com/stereobooster
295
+ [rb-fchange]: https://github.com/stereobooster/rb-fchange
296
+ [Yehuda Katz (wycats)]: https://github.com/wycats
297
+ [vigilo]: https://github.com/wycats/vigilo