fusuma 1.11.1 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +49 -7
  3. data/fusuma.gemspec +6 -16
  4. data/lib/fusuma.rb +91 -28
  5. data/lib/fusuma/config.rb +34 -62
  6. data/lib/fusuma/config/index.rb +39 -6
  7. data/lib/fusuma/config/searcher.rb +166 -0
  8. data/lib/fusuma/custom_process.rb +13 -0
  9. data/lib/fusuma/device.rb +22 -7
  10. data/lib/fusuma/environment.rb +6 -4
  11. data/lib/fusuma/hash_support.rb +40 -0
  12. data/lib/fusuma/libinput_command.rb +17 -21
  13. data/lib/fusuma/multi_logger.rb +2 -6
  14. data/lib/fusuma/plugin/base.rb +18 -15
  15. data/lib/fusuma/plugin/buffers/buffer.rb +3 -2
  16. data/lib/fusuma/plugin/buffers/gesture_buffer.rb +34 -25
  17. data/lib/fusuma/plugin/buffers/timer_buffer.rb +46 -0
  18. data/lib/fusuma/plugin/detectors/detector.rb +26 -5
  19. data/lib/fusuma/plugin/detectors/pinch_detector.rb +109 -58
  20. data/lib/fusuma/plugin/detectors/rotate_detector.rb +91 -50
  21. data/lib/fusuma/plugin/detectors/swipe_detector.rb +93 -56
  22. data/lib/fusuma/plugin/events/event.rb +5 -4
  23. data/lib/fusuma/plugin/events/records/context_record.rb +27 -0
  24. data/lib/fusuma/plugin/events/records/gesture_record.rb +9 -6
  25. data/lib/fusuma/plugin/events/records/index_record.rb +46 -14
  26. data/lib/fusuma/plugin/events/records/record.rb +1 -1
  27. data/lib/fusuma/plugin/events/records/text_record.rb +2 -1
  28. data/lib/fusuma/plugin/executors/command_executor.rb +21 -6
  29. data/lib/fusuma/plugin/executors/executor.rb +45 -3
  30. data/lib/fusuma/plugin/filters/filter.rb +1 -1
  31. data/lib/fusuma/plugin/filters/libinput_device_filter.rb +6 -7
  32. data/lib/fusuma/plugin/filters/libinput_timeout_filter.rb +2 -2
  33. data/lib/fusuma/plugin/inputs/input.rb +64 -8
  34. data/lib/fusuma/plugin/inputs/libinput_command_input.rb +19 -9
  35. data/lib/fusuma/plugin/inputs/timer_input.rb +63 -0
  36. data/lib/fusuma/plugin/manager.rb +22 -29
  37. data/lib/fusuma/plugin/parsers/libinput_gesture_parser.rb +10 -8
  38. data/lib/fusuma/plugin/parsers/parser.rb +8 -9
  39. data/lib/fusuma/string_support.rb +16 -0
  40. data/lib/fusuma/version.rb +1 -1
  41. data/spec/helpers/config_helper.rb +20 -0
  42. data/spec/lib/config/searcher_spec.rb +97 -0
  43. data/spec/lib/config_spec.rb +112 -0
  44. data/spec/lib/custom_process_spec.rb +28 -0
  45. data/spec/lib/device_spec.rb +98 -0
  46. data/spec/lib/dummy_config.yml +31 -0
  47. data/spec/lib/fusuma_spec.rb +103 -0
  48. data/spec/lib/libinput-list-devices_iberianpig-XPS-9360.txt +181 -0
  49. data/spec/lib/libinput-list-devices_magic_trackpad.txt +51 -0
  50. data/spec/lib/libinput-list-devices_razer_razer_blade.txt +252 -0
  51. data/spec/lib/libinput-list-devices_thejinx0r.txt +361 -0
  52. data/spec/lib/libinput-list-devices_unavailable.txt +36 -0
  53. data/spec/lib/libinput_command_spec.rb +167 -0
  54. data/spec/lib/plugin/base_spec.rb +74 -0
  55. data/spec/lib/plugin/buffers/buffer_spec.rb +80 -0
  56. data/spec/lib/plugin/buffers/dummy_buffer.rb +20 -0
  57. data/spec/lib/plugin/buffers/gesture_buffer_spec.rb +172 -0
  58. data/spec/lib/plugin/detectors/detector_spec.rb +43 -0
  59. data/spec/lib/plugin/detectors/dummy_detector.rb +24 -0
  60. data/spec/lib/plugin/detectors/pinch_detector_spec.rb +119 -0
  61. data/spec/lib/plugin/detectors/rotate_detector_spec.rb +125 -0
  62. data/spec/lib/plugin/detectors/swipe_detector_spec.rb +118 -0
  63. data/spec/lib/plugin/events/event_spec.rb +30 -0
  64. data/spec/lib/plugin/events/records/gesture_record_spec.rb +22 -0
  65. data/spec/lib/plugin/events/records/record_spec.rb +31 -0
  66. data/spec/lib/plugin/events/records/text_record_spec.rb +26 -0
  67. data/spec/lib/plugin/executors/command_executor_spec.rb +57 -0
  68. data/spec/lib/plugin/executors/executor_spec.rb +160 -0
  69. data/spec/lib/plugin/filters/filter_spec.rb +92 -0
  70. data/spec/lib/plugin/filters/libinput_filter_spec.rb +120 -0
  71. data/spec/lib/plugin/inputs/input_spec.rb +70 -0
  72. data/spec/lib/plugin/inputs/libinput_command_input_spec.rb +120 -0
  73. data/spec/lib/plugin/inputs/timer_input_spec.rb +40 -0
  74. data/spec/lib/plugin/manager_spec.rb +27 -0
  75. data/spec/lib/plugin/parsers/parser_spec.rb +45 -0
  76. data/spec/spec_helper.rb +20 -0
  77. metadata +90 -167
  78. data/.github/FUNDING.yml +0 -8
  79. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -32
  80. data/.github/ISSUE_TEMPLATE/feature_request.md +0 -17
  81. data/.github/pull_request_template.md +0 -9
  82. data/.github/stale.yml +0 -18
  83. data/.gitignore +0 -17
  84. data/.reek.yml +0 -96
  85. data/.rspec +0 -2
  86. data/.rubocop.yml +0 -37
  87. data/.rubocop_todo.yml +0 -40
  88. data/.travis.yml +0 -11
  89. data/CHANGELOG.md +0 -456
  90. data/CODE_OF_CONDUCT.md +0 -74
  91. data/CONTRIBUTING.md +0 -72
  92. data/Gemfile +0 -6
  93. data/Rakefile +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bd9b74b06494e85c0caf6250e0dfeed80c37187098982b4f32c2dd8e727732fb
4
- data.tar.gz: eb8c3d19693570b77b26519d7296856480342eec3eba0205ed970e01a4b46a16
3
+ metadata.gz: 3d8572f753f134496b8ffc0f36c3aafbf142357aad913edd9fd5f5d494d32259
4
+ data.tar.gz: 6adf4afa35ca59305efa6bde88b2ccf808c3025b5a577cc917d0b32d6b794058
5
5
  SHA512:
6
- metadata.gz: abe0b55ab9f332d3f67c423b0890135973d57a4cf8b7d6fafc7b01b44874c2489b6752fcb7a66d0b0a625c612879e35ce7d11b6a3b5ce485711b84e8f45e5279
7
- data.tar.gz: 323c35769c6f9827f8a94532a4dd10a25facf6bc6858d85b2b6540a6d78064e9003d4ccb83f4914f214aa6523cea8878b5f63abbe113211b1b0900ce0e203521
6
+ metadata.gz: 68dbe15577eb01891537a573c96ab0a2c532e919588c4fdb62899b236382630d8f575f913c9de282bf9a66b5ae8f91cc820067eedc7ecaa42e839f25d090afd8
7
+ data.tar.gz: cd74e943167bff03bf2eb1d3eaa9d170f28fd921c3736bcc1a981e49f0c7b755de10ecd8b9b6f314bce76377568441e04cd5228222cfe3c3afd32448569a754c
data/README.md CHANGED
@@ -17,7 +17,7 @@ This gem makes your linux able to recognize swipes or pinchs and assign commands
17
17
 
18
18
  ## Installation
19
19
 
20
- ### 1. Grant permission to read the touchpad device
20
+ ### Grant permission to read the touchpad device
21
21
 
22
22
  **IMPORTANT**: You **MUST** be a member of the **INPUT** group to read touchpad by Fusuma.
23
23
 
@@ -25,9 +25,15 @@ This gem makes your linux able to recognize swipes or pinchs and assign commands
25
25
  $ sudo gpasswd -a $USER input
26
26
  ```
27
27
 
28
- Then, You **MUST** **REBOOT** to assign this group.
28
+ Then, You apply the change with no logout or reboot.
29
29
 
30
- ### 2. Install libinput-tools
30
+ ```bash
31
+ $ newgrp input
32
+ ```
33
+
34
+ ### For Debian Based Distros (Ubuntu, Debian, Mint, Pop!OS)
35
+
36
+ #### 1. Install libinput-tools
31
37
 
32
38
  You need `libinput` release 1.0 or later.
33
39
 
@@ -35,7 +41,7 @@ You need `libinput` release 1.0 or later.
35
41
  $ sudo apt-get install libinput-tools
36
42
  ```
37
43
 
38
- ### 3. Install Ruby
44
+ #### 2. Install Ruby
39
45
 
40
46
  Fusuma runs in Ruby, so you must install it first.
41
47
 
@@ -43,13 +49,13 @@ Fusuma runs in Ruby, so you must install it first.
43
49
  $ sudo apt-get install ruby
44
50
  ```
45
51
 
46
- ### 4. Install Fusuma
52
+ #### 3. Install Fusuma
47
53
 
48
54
  ```bash
49
55
  $ sudo gem install fusuma
50
56
  ```
51
57
 
52
- ### 5. Install xdotool (optional)
58
+ #### 4. Install xdotool (optional)
53
59
 
54
60
  For sending shortcuts:
55
61
 
@@ -57,6 +63,42 @@ For sending shortcuts:
57
63
  $ sudo apt-get install xdotool
58
64
  ```
59
65
 
66
+ ### For Arch Based Distros (Manjaro, Arch)
67
+
68
+ #### 1. Install libinput.
69
+
70
+ You need `libinput` release 1.0 or later. This is most probably installed by default on Manjaro
71
+
72
+ ```z-h
73
+ $ sudo pacman -S libinput
74
+ ```
75
+
76
+ #### 2. Install Ruby
77
+
78
+ Fusuma runs in Ruby, so you must install it first.
79
+
80
+ ```zsh
81
+ $ sudo pacman -S ruby
82
+ ```
83
+
84
+ #### 3. Install Fusuma
85
+
86
+ **Note:** By default in Arch Linux, when running ```gem```, gems are installed per-user (into ```~/.gem/ruby/```), instead of system-wide (into ```/usr/lib/ruby/gems/```). This is considered the best way to manage gems on Arch, because otherwise they might interfere with gems installed by Pacman. (From Arch Wiki)
87
+
88
+ To install gems system-wide, see any of the methods listed on [Arch Wiki](https://wiki.archlinux.org/index.php/ruby#Installing_gems_system-wide)
89
+
90
+ ```zsh
91
+ $ sudo gem install fusuma
92
+ ```
93
+
94
+ #### 4. Install xdotool (optional)
95
+
96
+ For sending shortcuts:
97
+
98
+ ```zsh
99
+ $ sudo pacman -S xdotool
100
+ ```
101
+
60
102
  ### Touchpad not working in GNOME
61
103
 
62
104
  Ensure the touchpad events are being sent to the GNOME desktop by running the following command:
@@ -242,7 +284,7 @@ swipe:
242
284
  - [ydotool](https://github.com/ReimuNotMoe/ydotool)
243
285
  - Wayland compatible
244
286
  - Needs more maintainers.
245
- - Requires only replacing `xdotool` with `ydotool` in in fusuma conf.
287
+ - Requires only replacing `xdotool` with `ydotool` in fusuma conf.
246
288
 
247
289
  ## Options
248
290
 
data/fusuma.gemspec CHANGED
@@ -10,29 +10,19 @@ Gem::Specification.new do |spec|
10
10
  spec.authors = ['iberianpig']
11
11
  spec.email = ['yhkyky@gmail.com']
12
12
 
13
- spec.summary = 'Multitouch gestures with libinput dirver on X11, Linux'
13
+ spec.summary = 'Multitouch gestures with libinput driver, Linux'
14
14
  spec.description = 'Fusuma is multitouch gesture recognizer. This gem makes your touchpad on Linux able to recognize swipes or pinchs and assign command to them. Read installation on Github(https://github.com/iberianpig/fusuma#installation).'
15
15
  spec.homepage = 'https://github.com/iberianpig/fusuma'
16
16
  spec.license = 'MIT'
17
17
 
18
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
19
- f.match(%r{^(test|spec|features)/})
20
- end
18
+ spec.files = Dir.glob('{bin,lib,exe}/**/*') + %w[LICENSE README.md fusuma.gemspec]
19
+ spec.test_files = Dir.glob("{test,spec,features}/**/*")
21
20
  spec.bindir = 'exe'
22
21
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
22
  spec.require_paths = ['lib']
24
23
  spec.metadata['yard.run'] = 'yri' # use "yard" to build full HTML docs.
25
24
 
26
- spec.required_ruby_version = '>= 2.3' # https://packages.ubuntu.com/search?keywords=ruby&searchon=names&exact=1&suite=all&section=main
27
- spec.add_development_dependency 'bundler'
28
- spec.add_development_dependency 'coveralls'
29
- spec.add_development_dependency 'github_changelog_generator', '~> 1.14'
30
- spec.add_development_dependency 'pry-byebug', '~> 3.4'
31
- spec.add_development_dependency 'pry-doc'
32
- spec.add_development_dependency 'pry-inline'
33
- spec.add_development_dependency 'rake', '~> 13.0'
34
- spec.add_development_dependency 'reek'
35
- spec.add_development_dependency 'rspec', '~> 3.0'
36
- spec.add_development_dependency 'rubocop'
37
- spec.add_development_dependency 'yard'
25
+ spec.required_ruby_version = '>= 2.5.1' # https://packages.ubuntu.com/search?keywords=ruby&searchon=names&exact=1&suite=all&section=main
26
+ # support bionic (18.04LTS) 2.5.1
27
+ spec.add_dependency 'posix-spawn'
38
28
  end
data/lib/fusuma.rb CHANGED
@@ -2,10 +2,10 @@
2
2
 
3
3
  require_relative './fusuma/version'
4
4
  require_relative './fusuma/multi_logger'
5
- require_relative './fusuma/config.rb'
6
- require_relative './fusuma/environment.rb'
7
- require_relative './fusuma/device.rb'
8
- require_relative './fusuma/plugin/manager.rb'
5
+ require_relative './fusuma/config'
6
+ require_relative './fusuma/environment'
7
+ require_relative './fusuma/device'
8
+ require_relative './fusuma/plugin/manager'
9
9
 
10
10
  # this is top level module
11
11
  module Fusuma
@@ -16,6 +16,8 @@ module Fusuma
16
16
  set_trap
17
17
  read_options(option)
18
18
  instance = new
19
+ ## NOTE: Uncomment following line to measure performance
20
+ # instance.run_with_lineprof
19
21
  instance.run
20
22
  end
21
23
 
@@ -62,59 +64,120 @@ module Fusuma
62
64
  end
63
65
 
64
66
  def run
65
- # TODO: run with multi thread
66
- @inputs.first.run do |event|
67
- clear_expired_events
68
- filtered = filter(event) || next
69
- parsed = parse(filtered) || next
70
- buffered = buffer(parsed) || next
71
- detected = detect(buffered) || next
72
- merged = merge(detected) || next
73
- execute(merged)
67
+ loop { pipeline }
68
+ end
69
+
70
+ def pipeline
71
+ event = input || return
72
+ clear_expired_events
73
+ filtered = filter(event) || return
74
+ parsed = parse(filtered) || return
75
+ buffered = buffer(parsed) || return
76
+ detected = detect(buffered) || return
77
+ condition, context, event = merge(detected) || return
78
+ execute(condition, context, event)
79
+ end
80
+
81
+ # For performance monitoring
82
+ def run_with_lineprof(count: 1000)
83
+ require 'rblineprof'
84
+ require 'rblineprof-report'
85
+
86
+ profile = lineprof(%r{#{Pathname.new(__FILE__).parent}/.}) do
87
+ count.times { pipeline }
74
88
  end
89
+ LineProf.report(profile)
90
+ exit 0
75
91
  end
76
92
 
93
+ # @return [Plugin::Events::Event]
94
+ def input
95
+ Plugin::Inputs::Input.select(@inputs)
96
+ end
97
+
98
+ # @param [Plugin::Events::Event]
99
+ # @return [Plugin::Events::Event]
77
100
  def filter(event)
78
101
  event if @filters.any? { |f| f.filter(event) }
79
102
  end
80
103
 
104
+ # @param [Plugin::Events::Event]
105
+ # @return [Plugin::Events::Event]
81
106
  def parse(event)
82
107
  @parsers.reduce(event) { |e, p| p.parse(e) if e }
83
108
  end
84
109
 
110
+ # @param [Plugin::Events::Event]
111
+ # @return [Array<Plugin::Buffers::Buffer>]
112
+ # @return [NilClass]
85
113
  def buffer(event)
86
- @buffers.any? { |b| b.buffer(event) } && @buffers
114
+ @buffers.select { |b| b.buffer(event) }
87
115
  end
88
116
 
89
117
  # @param buffers [Array<Buffer>]
90
118
  # @return [Array<Event>]
91
119
  def detect(buffers)
92
- @detectors.each_with_object([]) do |detector, detected|
93
- if (event = detector.detect(buffers))
94
- detected << event
95
- end
120
+ matched_detectors = @detectors.select do |detector|
121
+ detector.watch? ||
122
+ buffers.any? { |b| detector.sources.include?(b.type) }
123
+ end
124
+
125
+ events = matched_detectors.each_with_object([]) do |detector, detected|
126
+ Array(detector.detect(@buffers)).each { |e| detected << e }
96
127
  end
128
+
129
+ return if events.empty?
130
+
131
+ events
97
132
  end
98
133
 
99
- # @param events [Array<Event>]
100
- # @return [Event] a Event merged all records from arguments
134
+ # @param events [Array<Plugin::Events::Event>]
135
+ # @return [Plugin::Events::Event] Event merged all records from arguments
101
136
  # @return [NilClass] when event is NOT given
102
137
  def merge(events)
103
- main_events, modifiers = events.partition { |event| event.record.mergable? }
104
- return nil unless (main_event = main_events.first)
138
+ index_events, context_events = events.partition { |event| event.record.type == :index }
139
+ main_events, modifiers = index_events.partition { |event| event.record.mergable? }
140
+ request_context = context_events.each_with_object({}) do |e, results|
141
+ results[e.record.name] = e.record.value
142
+ end
143
+ main_events.sort_by! { |e| e.record.trigger_priority }
144
+
145
+ condition = nil
146
+ matched_context = nil
147
+ event = main_events.find do |main_event|
148
+ matched_context = Config::Searcher.find_context(request_context) do
149
+ condition, index_record = Config::Searcher.find_condition do
150
+ main_event.record.merge(records: modifiers.map(&:record))
151
+ end
152
+ main_event if index_record
153
+ end
154
+ end
155
+ return if event.nil?
105
156
 
106
- main_event.record.merge(records: modifiers.map(&:record))
107
- main_event
157
+ [condition, matched_context, event]
108
158
  end
109
159
 
110
- def execute(event)
160
+ # @param event [Plugin::Events::Event]
161
+ def execute(condition, context, event)
111
162
  return unless event
112
163
 
113
- executor = @executors.find do |e|
114
- e.executable?(event)
164
+ # Find executable condition and executor
165
+ executor = Config::Searcher.with_context(context) do
166
+ Config::Searcher.with_condition(condition) do
167
+ @executors.find { |e| e.executable?(event) }
168
+ end
115
169
  end
116
170
 
117
- executor&.execute(event)
171
+ return if executor.nil?
172
+
173
+ # Check interval and execute
174
+ Config::Searcher.with_context(context) do
175
+ Config::Searcher.with_condition(condition) do
176
+ executor.enough_interval?(event) &&
177
+ executor.update_interval(event) &&
178
+ executor.execute(event)
179
+ end
180
+ end
118
181
  end
119
182
 
120
183
  def clear_expired_events
data/lib/fusuma/config.rb CHANGED
@@ -1,8 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative './multi_logger.rb'
4
- require_relative './config/index.rb'
5
- require_relative './config/yaml_duplication_checker.rb'
3
+ require_relative './multi_logger'
4
+ require_relative './config/index'
5
+ require_relative './config/searcher'
6
+ require_relative './config/yaml_duplication_checker'
7
+ require_relative './hash_support'
6
8
  require 'singleton'
7
9
  require 'yaml'
8
10
 
@@ -11,13 +13,18 @@ module Fusuma
11
13
  # read keymap from yaml file
12
14
  class Config
13
15
  class NotFoundError < StandardError; end
16
+
14
17
  class InvalidFileError < StandardError; end
15
18
 
16
19
  include Singleton
17
20
 
18
21
  class << self
19
- def search(keys)
20
- instance.search(keys)
22
+ def search(index)
23
+ instance.search(index)
24
+ end
25
+
26
+ def find_execute_key(index)
27
+ instance.find_execute_key(index)
21
28
  end
22
29
 
23
30
  def custom_path=(new_path)
@@ -25,12 +32,11 @@ module Fusuma
25
32
  end
26
33
  end
27
34
 
28
- attr_reader :keymap
29
- attr_reader :custom_path
35
+ attr_reader :keymap, :custom_path, :searcher
30
36
 
31
37
  def initialize
38
+ @searcher = Searcher.new
32
39
  @custom_path = nil
33
- @cache = nil
34
40
  @keymap = nil
35
41
  end
36
42
 
@@ -40,15 +46,15 @@ module Fusuma
40
46
  end
41
47
 
42
48
  def reload
43
- @cache = nil
49
+ @searcher = Searcher.new
44
50
  path = find_filepath
45
51
  MultiLogger.info "reload config: #{path}"
46
52
  @keymap = validate(path)
47
53
  self
48
54
  end
49
55
 
50
- # @return [Hash]
51
- # @raise [InvalidError]
56
+ # @return [Hash] If check passes
57
+ # @raise [InvalidFileError] If check does not pass
52
58
  def validate(path)
53
59
  duplicates = []
54
60
  YAMLDuplicationChecker.check(File.read(path), path) do |ignored, duplicate|
@@ -57,33 +63,30 @@ module Fusuma
57
63
  end
58
64
  raise InvalidFileError, "Detect duplicate keys #{duplicates}" unless duplicates.empty?
59
65
 
60
- yaml = YAML.load_file(path)
61
-
62
- raise InvalidFileError, 'Invaid YAML file' unless yaml.is_a? Hash
63
-
64
- yaml.deep_symbolize_keys
66
+ yamls = YAML.load_stream(File.read(path)).compact
67
+ yamls.map(&:deep_symbolize_keys)
65
68
  rescue StandardError => e
66
69
  MultiLogger.error e.message
67
70
  raise InvalidFileError, e.message
68
71
  end
69
72
 
70
73
  # @param index [Index]
74
+ # @param context [Hash]
71
75
  def search(index)
72
- cache(index.cache_key) do
73
- index.keys.reduce(keymap) do |location, key|
74
- if location.is_a?(Hash)
75
- begin
76
- if key.skippable
77
- location.fetch(key.symbol, location)
78
- else
79
- location.fetch(key.symbol, nil)
80
- end
81
- end
82
- else
83
- location
84
- end
85
- end
86
- end
76
+ @searcher.search_with_cache(index, location: keymap)
77
+ end
78
+
79
+ # @param index [Config::Index]
80
+ # @return Symbol
81
+ def find_execute_key(index)
82
+ @execute_keys ||= Plugin::Executors::Executor.plugins.map do |executor|
83
+ executor.new.execute_keys
84
+ end.flatten
85
+
86
+ execute_params = search(index)
87
+ return if execute_params.nil?
88
+
89
+ @execute_keys.find { |k| execute_params.keys.include?(k) }
87
90
  end
88
91
 
89
92
  private
@@ -113,36 +116,5 @@ module Fusuma
113
116
  def expand_default_path(filename)
114
117
  File.expand_path "../../#{filename}", __FILE__
115
118
  end
116
-
117
- def cache(key)
118
- @cache ||= {}
119
- key = key.join(',') if key.is_a? Array
120
- if @cache.key?(key)
121
- @cache[key]
122
- else
123
- @cache[key] = block_given? ? yield : nil
124
- end
125
- end
126
- end
127
- end
128
-
129
- # activesupport-4.1.1/lib/active_support/core_ext/hash/keys.rb
130
- class Hash
131
- def deep_symbolize_keys
132
- deep_transform_keys do |key|
133
- begin
134
- key.to_sym
135
- rescue StandardError
136
- key
137
- end
138
- end
139
- end
140
-
141
- def deep_transform_keys(&block)
142
- result = {}
143
- each do |key, value|
144
- result[yield(key)] = value.is_a?(Hash) ? value.deep_transform_keys(&block) : value
145
- end
146
- result
147
119
  end
148
120
  end