sass 3.2.0.alpha.104 → 3.2.0.alpha.236

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/REVISION +1 -1
  2. data/Rakefile +2 -2
  3. data/VERSION +1 -1
  4. data/lib/sass/engine.rb +8 -1
  5. data/lib/sass/exec.rb +2 -2
  6. data/lib/sass/plugin/compiler.rb +51 -43
  7. data/lib/sass/script/color.rb +4 -9
  8. data/lib/sass/script/funcall.rb +11 -2
  9. data/lib/sass/script/functions.rb +16 -30
  10. data/lib/sass/script/lexer.rb +7 -1
  11. data/lib/sass/script/list.rb +2 -2
  12. data/lib/sass/script/literal.rb +8 -0
  13. data/lib/sass/script/null.rb +34 -0
  14. data/lib/sass/script/operation.rb +4 -0
  15. data/lib/sass/script/parser.rb +4 -2
  16. data/lib/sass/scss/parser.rb +1 -5
  17. data/lib/sass/scss/rx.rb +1 -1
  18. data/lib/sass/tree/directive_node.rb +5 -0
  19. data/lib/sass/tree/media_node.rb +3 -0
  20. data/lib/sass/tree/prop_node.rb +7 -3
  21. data/lib/sass/tree/visitors/base.rb +1 -1
  22. data/lib/sass/tree/visitors/check_nesting.rb +21 -18
  23. data/lib/sass/tree/visitors/convert.rb +1 -0
  24. data/lib/sass/tree/visitors/perform.rb +3 -2
  25. data/lib/sass/tree/visitors/to_css.rb +1 -0
  26. data/lib/sass/util.rb +28 -0
  27. data/test/sass/conversion_test.rb +33 -0
  28. data/test/sass/engine_test.rb +118 -3
  29. data/test/sass/functions_test.rb +56 -24
  30. data/test/sass/script_test.rb +60 -4
  31. data/test/sass/scss/scss_test.rb +10 -0
  32. data/vendor/listen/CHANGELOG.md +19 -1
  33. data/vendor/listen/README.md +27 -12
  34. data/vendor/listen/lib/listen/adapter.rb +9 -1
  35. data/vendor/listen/lib/listen/adapters/linux.rb +18 -7
  36. data/vendor/listen/lib/listen/adapters/windows.rb +7 -8
  37. data/vendor/listen/lib/listen/directory_record.rb +108 -48
  38. data/vendor/listen/lib/listen/listener.rb +28 -11
  39. data/vendor/listen/lib/listen/multi_listener.rb +6 -6
  40. data/vendor/listen/lib/listen/version.rb +1 -1
  41. data/vendor/listen/spec/listen/adapters/linux_spec.rb +11 -0
  42. data/vendor/listen/spec/listen/directory_record_spec.rb +268 -41
  43. data/vendor/listen/spec/listen/listener_spec.rb +8 -4
  44. data/vendor/listen/spec/listen/multi_listener_spec.rb +9 -4
  45. data/vendor/listen/spec/support/adapter_helper.rb +178 -0
  46. data/vendor/listen/spec/support/directory_record_helper.rb +24 -4
  47. data/vendor/listen/spec/support/listeners_helper.rb +11 -0
  48. metadata +11 -11
  49. data/lib/sass/plugin/listener.rb +0 -61
@@ -76,7 +76,7 @@ class SassFunctionTest < Test::Unit::TestCase
76
76
 
77
77
  def test_hsl_checks_bounds
78
78
  assert_error_message("Saturation -114 must be between 0% and 100% for `hsl'", "hsl(10, -114, 12)");
79
- assert_error_message("Lightness 256 must be between 0% and 100% for `hsl'", "hsl(10, 10, 256%)");
79
+ assert_error_message("Lightness 256% must be between 0% and 100% for `hsl'", "hsl(10, 10, 256%)");
80
80
  end
81
81
 
82
82
  def test_hsl_checks_types
@@ -94,7 +94,7 @@ class SassFunctionTest < Test::Unit::TestCase
94
94
 
95
95
  def test_hsla_checks_bounds
96
96
  assert_error_message("Saturation -114 must be between 0% and 100% for `hsla'", "hsla(10, -114, 12, 1)");
97
- assert_error_message("Lightness 256 must be between 0% and 100% for `hsla'", "hsla(10, 10, 256%, 0)");
97
+ assert_error_message("Lightness 256% must be between 0% and 100% for `hsla'", "hsla(10, 10, 256%, 0)");
98
98
  assert_error_message("Alpha channel -0.1 must be between 0 and 1 for `hsla'", "hsla(10, 10, 10, -0.1)");
99
99
  assert_error_message("Alpha channel 1.1 must be between 0 and 1 for `hsla'", "hsla(10, 10, 10, 1.1)");
100
100
  end
@@ -189,24 +189,24 @@ class SassFunctionTest < Test::Unit::TestCase
189
189
  end
190
190
 
191
191
  def test_rgb_tests_bounds
192
- assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgb'",
192
+ assert_error_message("Color value 256 must be between 0 and 255 for `rgb'",
193
193
  "rgb(256, 1, 1)")
194
- assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgb'",
194
+ assert_error_message("Color value 256 must be between 0 and 255 for `rgb'",
195
195
  "rgb(1, 256, 1)")
196
- assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgb'",
196
+ assert_error_message("Color value 256 must be between 0 and 255 for `rgb'",
197
197
  "rgb(1, 1, 256)")
198
- assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgb'",
198
+ assert_error_message("Color value 256 must be between 0 and 255 for `rgb'",
199
199
  "rgb(1, 256, 257)")
200
- assert_error_message("Color value -1 must be between 0 and 255 inclusive for `rgb'",
200
+ assert_error_message("Color value -1 must be between 0 and 255 for `rgb'",
201
201
  "rgb(-1, 1, 1)")
202
202
  end
203
203
 
204
204
  def test_rgb_test_percent_bounds
205
- assert_error_message("Color value 100.1% must be between 0% and 100% inclusive for `rgb'",
205
+ assert_error_message("Color value 100.1% must be between 0% and 100% for `rgb'",
206
206
  "rgb(100.1%, 0, 0)")
207
- assert_error_message("Color value -0.1% must be between 0% and 100% inclusive for `rgb'",
207
+ assert_error_message("Color value -0.1% must be between 0% and 100% for `rgb'",
208
208
  "rgb(0, -0.1%, 0)")
209
- assert_error_message("Color value 101% must be between 0% and 100% inclusive for `rgb'",
209
+ assert_error_message("Color value 101% must be between 0% and 100% for `rgb'",
210
210
  "rgb(0, 0, 101%)")
211
211
  end
212
212
 
@@ -224,19 +224,19 @@ class SassFunctionTest < Test::Unit::TestCase
224
224
  end
225
225
 
226
226
  def test_rgb_tests_bounds
227
- assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgba'",
227
+ assert_error_message("Color value 256 must be between 0 and 255 for `rgba'",
228
228
  "rgba(256, 1, 1, 0.3)")
229
- assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgba'",
229
+ assert_error_message("Color value 256 must be between 0 and 255 for `rgba'",
230
230
  "rgba(1, 256, 1, 0.3)")
231
- assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgba'",
231
+ assert_error_message("Color value 256 must be between 0 and 255 for `rgba'",
232
232
  "rgba(1, 1, 256, 0.3)")
233
- assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgba'",
233
+ assert_error_message("Color value 256 must be between 0 and 255 for `rgba'",
234
234
  "rgba(1, 256, 257, 0.3)")
235
- assert_error_message("Color value -1 must be between 0 and 255 inclusive for `rgba'",
235
+ assert_error_message("Color value -1 must be between 0 and 255 for `rgba'",
236
236
  "rgba(-1, 1, 1, 0.3)")
237
- assert_error_message("Alpha channel -0.2 must be between 0 and 1 inclusive for `rgba'",
237
+ assert_error_message("Alpha channel -0.2 must be between 0 and 1 for `rgba'",
238
238
  "rgba(1, 1, 1, -0.2)")
239
- assert_error_message("Alpha channel 1.2 must be between 0 and 1 inclusive for `rgba'",
239
+ assert_error_message("Alpha channel 1.2 must be between 0 and 1 for `rgba'",
240
240
  "rgba(1, 1, 1, 1.2)")
241
241
  end
242
242
 
@@ -733,15 +733,15 @@ class SassFunctionTest < Test::Unit::TestCase
733
733
 
734
734
  def test_change_color_argument_errors
735
735
  # Range
736
- assert_error_message("Saturation must be between 0 and 100 for `change-color'",
736
+ assert_error_message("Saturation 101% must be between 0% and 100% for `change-color'",
737
737
  "change-color(blue, $saturation: 101%)")
738
- assert_error_message("Lightness must be between 0 and 100 for `change-color'",
738
+ assert_error_message("Lightness 101% must be between 0% and 100% for `change-color'",
739
739
  "change-color(blue, $lightness: 101%)")
740
- assert_error_message("Red value must be between 0 and 255 for `change-color'",
740
+ assert_error_message("Red value -1 must be between 0 and 255 for `change-color'",
741
741
  "change-color(blue, $red: -1)")
742
- assert_error_message("Green value must be between 0 and 255 for `change-color'",
742
+ assert_error_message("Green value 256 must be between 0 and 255 for `change-color'",
743
743
  "change-color(blue, $green: 256)")
744
- assert_error_message("Blue value must be between 0 and 255 for `change-color'",
744
+ assert_error_message("Blue value 500 must be between 0 and 255 for `change-color'",
745
745
  "change-color(blue, $blue: 500)")
746
746
 
747
747
  # Unknown argument
@@ -871,6 +871,7 @@ MSG
871
871
  assert_equal("bool", evaluate("type-of(true)"))
872
872
  assert_equal("color", evaluate("type-of(#fff)"))
873
873
  assert_equal("color", evaluate("type-of($value: #fff)"))
874
+ assert_equal("null", evaluate("type-of(null)"))
874
875
  end
875
876
 
876
877
  def test_unit
@@ -1011,6 +1012,7 @@ MSG
1011
1012
  def test_if
1012
1013
  assert_equal("1px", evaluate("if(true, 1px, 2px)"))
1013
1014
  assert_equal("2px", evaluate("if(false, 1px, 2px)"))
1015
+ assert_equal("2px", evaluate("if(null, 1px, 2px)"))
1014
1016
  end
1015
1017
 
1016
1018
  def test_keyword_args_rgb
@@ -1023,23 +1025,47 @@ MSG
1023
1025
  end
1024
1026
 
1025
1027
  def test_keyword_args_rgba_with_extra_args
1026
- assert_equal(%Q{rgba(255, 255, 255, 0.5)}, evaluate("rgba($red: 255, $green: 255, $blue: 255, $alpha: 0.5, $extra: error)"))
1028
+ evaluate("rgba($red: 255, $green: 255, $blue: 255, $alpha: 0.5, $extra: error)")
1029
+ flunk("Expected exception")
1027
1030
  rescue Sass::SyntaxError => e
1028
- assert_equal("Function rgba doesn't take an argument named $extra", e.message)
1031
+ assert_equal("Function rgba doesn't have an argument named $extra", e.message)
1029
1032
  end
1030
1033
 
1031
1034
  def test_keyword_args_must_have_signature
1032
1035
  evaluate("no-kw-args($fake: value)")
1036
+ flunk("Expected exception")
1033
1037
  rescue Sass::SyntaxError => e
1034
1038
  assert_equal("Function no_kw_args doesn't support keyword arguments", e.message)
1035
1039
  end
1036
1040
 
1037
1041
  def test_keyword_args_with_missing_argument
1038
1042
  evaluate("rgb($red: 255, $green: 255)")
1043
+ flunk("Expected exception")
1039
1044
  rescue Sass::SyntaxError => e
1040
1045
  assert_equal("Function rgb requires an argument named $blue", e.message)
1041
1046
  end
1042
1047
 
1048
+ def test_keyword_args_with_extra_argument
1049
+ evaluate("rgb($red: 255, $green: 255, $blue: 255, $purple: 255)")
1050
+ flunk("Expected exception")
1051
+ rescue Sass::SyntaxError => e
1052
+ assert_equal("Function rgb doesn't have an argument named $purple", e.message)
1053
+ end
1054
+
1055
+ def test_keyword_args_with_positional_and_keyword_argument
1056
+ evaluate("rgb(255, 255, 255, $red: 255)")
1057
+ flunk("Expected exception")
1058
+ rescue Sass::SyntaxError => e
1059
+ assert_equal("Function rgb was passed argument $red both by position and by name", e.message)
1060
+ end
1061
+
1062
+ def test_keyword_args_with_keyword_before_positional_argument
1063
+ evaluate("rgb($red: 255, 255, 255)")
1064
+ flunk("Expected exception")
1065
+ rescue Sass::SyntaxError => e
1066
+ assert_equal("Positional arguments must come before keyword arguments", e.message)
1067
+ end
1068
+
1043
1069
  def test_only_var_args
1044
1070
  assert_equal "only-var-args(2px, 3px, 4px)", evaluate("only-var-args(1px, 2px, 3px)")
1045
1071
  end
@@ -1048,6 +1074,12 @@ MSG
1048
1074
  assert_equal "only-kw-args(a, b, c)", evaluate("only-kw-args($a: 1, $b: 2, $c: 3)")
1049
1075
  end
1050
1076
 
1077
+ ## Regression Tests
1078
+
1079
+ def test_saturation_bounds
1080
+ assert_equal "#fbfdff", evaluate("hsl(hue(#fbfdff), saturation(#fbfdff), lightness(#fbfdff))")
1081
+ end
1082
+
1051
1083
  private
1052
1084
 
1053
1085
  def evaluate(value)
@@ -21,13 +21,13 @@ class SassScriptTest < Test::Unit::TestCase
21
21
  include Sass::Script
22
22
 
23
23
  def test_color_checks_input
24
- assert_raise_message(ArgumentError, "Blue value must be between 0 and 255") {Color.new([1, 2, -1])}
25
- assert_raise_message(ArgumentError, "Red value must be between 0 and 255") {Color.new([256, 2, 3])}
24
+ assert_raise_message(ArgumentError, "Blue value -1 must be between 0 and 255") {Color.new([1, 2, -1])}
25
+ assert_raise_message(ArgumentError, "Red value 256 must be between 0 and 255") {Color.new([256, 2, 3])}
26
26
  end
27
27
 
28
28
  def test_color_checks_rgba_input
29
- assert_raise_message(ArgumentError, "Alpha channel must be between 0 and 1") {Color.new([1, 2, 3, 1.1])}
30
- assert_raise_message(ArgumentError, "Alpha channel must be between 0 and 1") {Color.new([1, 2, 3, -0.1])}
29
+ assert_raise_message(ArgumentError, "Alpha channel 1.1 must be between 0 and 1") {Color.new([1, 2, 3, 1.1])}
30
+ assert_raise_message(ArgumentError, "Alpha channel -0.1 must be between 0 and 1") {Color.new([1, 2, 3, -0.1])}
31
31
  end
32
32
 
33
33
  def test_string_escapes
@@ -263,6 +263,10 @@ SASS
263
263
  assert_equal "false", resolve("false")
264
264
  end
265
265
 
266
+ def test_null
267
+ assert_equal "", resolve("null")
268
+ end
269
+
266
270
  def test_boolean_ops
267
271
  assert_equal "true", resolve("true and true")
268
272
  assert_equal "true", resolve("false or true")
@@ -281,6 +285,18 @@ SASS
281
285
  assert_equal "false", resolve("false and 1")
282
286
  assert_equal "2", resolve("2 or 3")
283
287
  assert_equal "3", resolve("2 and 3")
288
+
289
+ assert_equal "true", resolve("null or true")
290
+ assert_equal "true", resolve("true or null")
291
+ assert_equal "", resolve("null or null")
292
+ assert_equal "", resolve("null and true")
293
+ assert_equal "", resolve("true and null")
294
+ assert_equal "", resolve("null and null")
295
+
296
+ assert_equal "true", resolve("not null")
297
+
298
+ assert_equal "1", resolve("null or 1")
299
+ assert_equal "", resolve("null and 1")
284
300
  end
285
301
 
286
302
  def test_arithmetic_ops
@@ -326,6 +342,37 @@ SASS
326
342
  assert_equal "false", resolve("3 <= 2")
327
343
  end
328
344
 
345
+ def test_null_ops
346
+ assert_raise_message(Sass::SyntaxError,
347
+ 'Invalid null operation: "null plus 1".') {eval("null + 1")}
348
+ assert_raise_message(Sass::SyntaxError,
349
+ 'Invalid null operation: "null minus 1".') {eval("null - 1")}
350
+ assert_raise_message(Sass::SyntaxError,
351
+ 'Invalid null operation: "null times 1".') {eval("null * 1")}
352
+ assert_raise_message(Sass::SyntaxError,
353
+ 'Invalid null operation: "null div 1".') {eval("null / 1")}
354
+ assert_raise_message(Sass::SyntaxError,
355
+ 'Invalid null operation: "null mod 1".') {eval("null % 1")}
356
+ assert_raise_message(Sass::SyntaxError,
357
+ 'Invalid null operation: "1 plus null".') {eval("1 + null")}
358
+ assert_raise_message(Sass::SyntaxError,
359
+ 'Invalid null operation: "1 minus null".') {eval("1 - null")}
360
+ assert_raise_message(Sass::SyntaxError,
361
+ 'Invalid null operation: "1 times null".') {eval("1 * null")}
362
+ assert_raise_message(Sass::SyntaxError,
363
+ 'Invalid null operation: "1 div null".') {eval("1 / null")}
364
+ assert_raise_message(Sass::SyntaxError,
365
+ 'Invalid null operation: "1 mod null".') {eval("1 % null")}
366
+ assert_raise_message(Sass::SyntaxError,
367
+ 'Invalid null operation: "1 gt null".') {eval("1 > null")}
368
+ assert_raise_message(Sass::SyntaxError,
369
+ 'Invalid null operation: "null lt 1".') {eval("null < 1")}
370
+ assert_raise_message(Sass::SyntaxError,
371
+ 'Invalid null operation: "null plus null".') {eval("null + null")}
372
+ assert_raise_message(Sass::SyntaxError,
373
+ 'Invalid null operation: ""foo" plus null".') {eval("foo + null")}
374
+ end
375
+
329
376
  def test_equals
330
377
  assert_equal("true", resolve('"foo" == $foo', {},
331
378
  env("foo" => Sass::Script::String.new("foo"))))
@@ -424,6 +471,15 @@ SASS
424
471
  assert_raise_message(Sass::SyntaxError, "() isn't a valid CSS value.") {resolve("nth(append((), ()), 1)")}
425
472
  end
426
473
 
474
+ def test_list_with_nulls
475
+ assert_equal "1, 2, 3", resolve("1, 2, null, 3")
476
+ assert_equal "1 2 3", resolve("1 2 null 3")
477
+ assert_equal "1, 2, 3", resolve("1, 2, 3, null")
478
+ assert_equal "1 2 3", resolve("1 2 3 null")
479
+ assert_equal "1, 2, 3", resolve("null, 1, 2, 3")
480
+ assert_equal "1 2 3", resolve("null 1 2 3")
481
+ end
482
+
427
483
  def test_deep_argument_error_not_unwrapped
428
484
  assert_raise_message(ArgumentError, 'wrong number of arguments (0 for 1)') {resolve("arg-error()")}
429
485
  end
@@ -850,6 +850,16 @@ $zzz: zzz;
850
850
  SCSS
851
851
  end
852
852
 
853
+ def test_selector_interpolation_at_attr_end
854
+ assert_equal <<CSS, render(<<SCSS)
855
+ [foo=zzz] {
856
+ a: b; }
857
+ CSS
858
+ $zzz: zzz;
859
+ [foo=\#{$zzz}] { a: b; }
860
+ SCSS
861
+ end
862
+
853
863
  def test_selector_interpolation_at_dashes
854
864
  assert_equal <<CSS, render(<<SCSS)
855
865
  div {
@@ -1,8 +1,23 @@
1
+ ## 0.4.2 - May 1, 2012
2
+
3
+ ### Bug fixes
4
+
5
+ - [#21](https://github.com/guard/listen/issues/21): Issues when listening to changes in relative paths. (reported by [@akerbos][], fixed by [@Maher4Ever][])
6
+ - [#27](https://github.com/guard/listen/issues/27): Wrong reports for files modifications. (reported by [@cobychapple][], fixed by [@Maher4Ever][])
7
+ - Fix segmentation fault when profiling on Windows. ([@Maher4Ever][])
8
+ - Fix redundant watchers on Windows. ([@Maher4Ever][])
9
+
10
+ ### Improvements
11
+
12
+ - [#17](https://github.com/guard/listen/issues/17): Use regexp-patterns with the `ignore` method instead of supplying paths. (reported by [@fny][], added by [@Maher4Ever][])
13
+ - Speed improvement when listening to changes in directories with ignored paths. ([@Maher4Ever][])
14
+ - Added `.rbx` and `.svn` to ignored directories. ([@Maher4Ever][])
15
+
1
16
  ## 0.4.1 - April 15, 2012
2
17
 
3
18
  ### Bug fixes
4
19
 
5
- - [#18](https://github.com/guard/listen/issues/18): Listener crashes when removing directories with nested paths (reported by [@daemonza][], fixed by [@Maher4Ever][])
20
+ - [#18]((https://github.com/guard/listen/issues/18): Listener crashes when removing directories with nested paths. (reported by [@daemonza][], fixed by [@Maher4Ever][])
6
21
 
7
22
  ## 0.4.0 - April 9, 2012
8
23
 
@@ -70,3 +85,6 @@
70
85
  [@thibaudgg]: https://github.com/thibaudgg
71
86
  [@Maher4Ever]: https://github.com/Maher4Ever
72
87
  [@daemonza]: https://github.com/daemonza
88
+ [@akerbos]: https://github.com/akerbos
89
+ [@fny]: https://github.com/fny
90
+ [@cobychapple]: https://github.com/cobychapple
@@ -10,7 +10,7 @@ The Listen gem listens to file modifications and notifies you about the changes.
10
10
  * Automatic fallback to polling if OS-specific adapter doesn't work.
11
11
  * Detects files modification, addidation and removal.
12
12
  * Checksum comparaison for modifications made under the same second.
13
- * Allows ignoring paths and supplying filters for better results.
13
+ * Allows supplying regexp-patterns to ignore and filter paths for better results.
14
14
  * Tested on all Ruby environments via [travis-ci](http://travis-ci.org/guard/listen).
15
15
 
16
16
  ## Install
@@ -26,18 +26,18 @@ There are **two ways** to use Listen:
26
26
  1. Call `Listen.to` with either a single directory or multiple directories, then define the `change` callback in a block.
27
27
  2. Create a `listener` object and use it in an (ARel style) chainable way.
28
28
 
29
- Feel free to give your feeback via [Listen issues](https://github.com/guard/listener/issues)
29
+ Feel free to give your feeback via [Listen issues](https://github.com/guard/listen/issues)
30
30
 
31
31
  ### Block API
32
32
 
33
33
  ``` ruby
34
34
  # Listen to a single directory.
35
- Listen.to('dir/path/to/listen', filter: /.*\.rb/, ignore: '/ignored/path') do |modified, added, removed|
35
+ Listen.to('dir/path/to/listen', filter: /\.rb$/, ignore: %r{ignored/path/}) do |modified, added, removed|
36
36
  # ...
37
37
  end
38
38
 
39
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|
40
+ Listen.to('dir/to/awesome_app', 'dir/to/other_app', filter: /\.rb$/, latency: 0.1) do |modified, added, removed|
41
41
  # ...
42
42
  end
43
43
  ```
@@ -46,8 +46,8 @@ end
46
46
 
47
47
  ``` ruby
48
48
  listener = Listen.to('dir/path/to/listen')
49
- listener = listener.ignore('/ignored/path')
50
- listener = listener.filter(/.*\.rb/)
49
+ listener = listener.ignore(%r{^ignored/path/})
50
+ listener = listener.filter(/\.rb$/)
51
51
  listener = listener.latency(0.5)
52
52
  listener = listener.force_polling(true)
53
53
  listener = listener.polling_fallback_message(false)
@@ -59,8 +59,8 @@ listener.start # blocks execution!
59
59
 
60
60
  ``` ruby
61
61
  Listen.to('dir/path/to/listen')
62
- .ignore('/ignored/path')
63
- .filter(/.*\.rb/)
62
+ .ignore(%r{^ignored/path/})
63
+ .filter(/\.rb$/)
64
64
  .latency(0.5)
65
65
  .force_polling(true)
66
66
  .polling_fallback_message('custom message')
@@ -99,7 +99,7 @@ For an easier access, the `Listen.to` method can also be used to create a multi-
99
99
 
100
100
  ``` ruby
101
101
  listener = Listen.to('app/css', 'app/js')
102
- .ignore('vendor') # both js/vendor and css/vendor will be ignored
102
+ .ignore(%r{^vendor/}) # both js/vendor and css/vendor will be ignored
103
103
  .change(&assets_callback)
104
104
 
105
105
  listener.start # blocks execution!
@@ -184,15 +184,18 @@ end
184
184
  These options can be set through `Listen.to` params or via methods (see the "Object" API)
185
185
 
186
186
  ```ruby
187
- :filter => /.*\.rb/, /.*\.coffee/ # Filter files to listen to via a regexps list.
187
+ :filter => /\.rb$/, /\.coffee$/ # Filter files to listen to via a regexps list.
188
188
  # default: none
189
189
 
190
- :ignore => 'path1', 'path2' # Ignore a list of paths (root directory or sub-dir)
191
- # default: '.bundle', '.git', '.DS_Store', 'log', 'tmp', 'vendor'
190
+ :ignore => %r{app/CMake/}, /\.pid$/ # Ignore a list of paths (root directory or sub-dir)
191
+ # default: See DEFAULT_IGNORED_DIRECTORIES and DEFAULT_IGNORED_EXTENSIONS in Listen::DirectoryRecord
192
192
 
193
193
  :latency => 0.5 # Set the delay (**in seconds**) between checking for changes
194
194
  # default: 0.1 sec (1.0 sec for polling)
195
195
 
196
+ :relative_paths => true # Enable the use of relative paths in the callback.
197
+ # default: false
198
+
196
199
  :force_polling => true # Force the use of the polling adapter
197
200
  # default: none
198
201
 
@@ -200,6 +203,18 @@ These options can be set through `Listen.to` params or via methods (see the "Obj
200
203
  # default: "WARNING: Listen fallen back to polling, learn more at https://github.com/guard/listen#fallback."
201
204
  ```
202
205
 
206
+ ### The patterns for filtering and ignoring paths
207
+
208
+ Just like the unix convention of beginning absolute paths with the
209
+ directory-separator (forward slash `/` in unix) and with no prefix for relative paths,
210
+ Listen doesn't prefix relative paths (to the watched directory) with a directory-separator.
211
+
212
+ Therefore make sure _NOT_ to prefix your regexp-patterns for filtering or ignoring paths
213
+ with a directory-separator, otherwise they won't work as expected.
214
+
215
+ As an example: to ignore the `build` directory in a C-project, use `%r{build/}`
216
+ and not `%r{/build/}`.
217
+
203
218
  ### Non-blocking listening to changes
204
219
 
205
220
  Starting a listener blocks the current thread by default. That means any code after the
@@ -83,6 +83,14 @@ module Listen
83
83
  @turnstile.signal # ensure no thread is blocked
84
84
  end
85
85
 
86
+ # Returns whether the adapter is statred or not
87
+ #
88
+ # @return [Boolean] whether the adapter is started or not
89
+ #
90
+ def started?
91
+ @stop.nil? ? false : !@stop
92
+ end
93
+
86
94
  # Blocks the main thread until the poll thread
87
95
  # calls the callback.
88
96
  #
@@ -129,7 +137,7 @@ module Listen
129
137
  ensure
130
138
  Thread.kill(t) if t
131
139
  FileUtils.rm(test_file) if File.exists?(test_file)
132
- adapter.stop
140
+ adapter.stop if adapter && adapter.started?
133
141
  end
134
142
 
135
143
  private
@@ -1,22 +1,33 @@
1
1
  module Listen
2
2
  module Adapters
3
3
 
4
- # Watched INotify EVENTS
5
- #
6
- # @see http://www.tin.org/bin/man.cgi?section=7&topic=inotify
7
- # @see https://github.com/nex3/rb-inotify/blob/master/lib/rb-inotify/notifier.rb#L99-L177
8
- #
9
- EVENTS = %w[recursive attrib close modify move create delete delete_self move_self]
10
-
11
4
  # Listener implementation for Linux `inotify`.
12
5
  #
13
6
  class Linux < Adapter
14
7
 
8
+ # Watched inotify events
9
+ #
10
+ # @see http://www.tin.org/bin/man.cgi?section=7&topic=inotify
11
+ # @see https://github.com/nex3/rb-inotify/blob/master/lib/rb-inotify/notifier.rb#L99-L177
12
+ #
13
+ EVENTS = %w[recursive attrib close modify move create delete delete_self move_self]
14
+
15
+ # The message to show when the limit of inotify watchers is not enough
16
+ #
17
+ INOTIFY_LIMIT_MESSAGE = <<-EOS.gsub(/^\s*/, '')
18
+ Listen error: unable to monitor directories for changes.
19
+
20
+ Please head to https://github.com/guard/listen/wiki/Increasing-the-amount-of-inotify-watchers
21
+ for information on how to solve this issue.
22
+ EOS
23
+
15
24
  # Initializes the Adapter. See {Listen::Adapter#initialize} for more info.
16
25
  #
17
26
  def initialize(directories, options = {}, &callback)
18
27
  super
19
28
  @worker = init_worker
29
+ rescue Errno::ENOSPC
30
+ abort(INOTIFY_LIMIT_MESSAGE)
20
31
  end
21
32
 
22
33
  # Starts the adapter.