fusuma 2.5.1 → 3.1.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9368eba481cbc496fb561cb449ec99c6b5f1eff8b4c8c4a9c8d61b4e7d5b4cf8
4
- data.tar.gz: 3bea9acc54d3e2061f391ec282f9327ca2b3fd70463fa5f2394063a980b20613
3
+ metadata.gz: 8ff7ea9fcd08ba0c48e1c08d9eceeb4a1e30684a0616f37fef6f67a3e035c005
4
+ data.tar.gz: c68adc10a8e2b7fb5396c7c789f941b13bacc9d60d6d669a7d8004c773503d75
5
5
  SHA512:
6
- metadata.gz: 2af60b07cfa18ca3b3d13eedf9b0271ff5bfdea37776e66a51e59eb33ea2e6bd35fe1fdc4724738ca3ecec37c7a6811c202c4277bf1e4ff341fda81e8fdb9f58
7
- data.tar.gz: 4583ee8007e36e364658f02a42d5f447adb947408e690cb0f554c004672869f0304e2e674335aebc2d9a267abcb01cbe2f559845e604d4acc945620d7fada1a7
6
+ metadata.gz: 46fdbcb0b697ba9000e55de86a9550d783c81c6407f13ebe82375c2b741341a591bcf45fe6c707247a9a2017e4f3ca4834111af551a4a65001cc7e944487b28e
7
+ data.tar.gz: e0e579b0d73ea237202ae17f641c07a1ed7587a771c71bfe12d55edec62b3d9e3281fd010f646e6e7077a6245e0365d0ed73c7042528a8c8c5ac72bbeed956de
data/README.md CHANGED
@@ -1,4 +1,5 @@
1
- # Fusuma [![Gem Version](https://badge.fury.io/rb/fusuma.svg)](https://badge.fury.io/rb/fusuma) [![Build Status](https://github.com/iberianpig/fusuma/actions/workflows/ubuntu.yml/badge.svg)](https://github.com/iberianpig/fusuma/actions/workflows/ubuntu.yml)
1
+ # Fusuma
2
+ ![Gem](https://img.shields.io/gem/v/fusuma?color=brightgreen) [![Build Status](https://github.com/iberianpig/fusuma/actions/workflows/main.yml/badge.svg)](https://github.com/iberianpig/fusuma/actions/workflows/main.yml)
2
3
 
3
4
  Fusuma is multitouch gesture recognizer.
4
5
  This gem makes your linux able to recognize swipes or pinchs and assign commands to them.
@@ -21,23 +22,28 @@ This gem makes your linux able to recognize swipes or pinchs and assign commands
21
22
 
22
23
  **IMPORTANT**: You **MUST** be a member of the **INPUT** group to read touchpad by Fusuma.
23
24
 
24
- ```bash
25
+ ```sh
25
26
  sudo gpasswd -a $USER input
26
27
  ```
27
28
 
28
29
  Then, You apply the change with no logout or reboot.
29
30
 
30
- ```bash
31
+ ```sh
31
32
  newgrp input
32
33
  ```
33
34
 
35
+ **IMPORTANT**: This makes `/dev/input/` readable, so if that's an issue for you for some reason (like for privacy- or securityconcerns etc. or if it causes other parts of your OS to misbehave), **consider this your heads-up.**
36
+
37
+ <details>
38
+ <summary>For Debian Based Distros (Ubuntu, Debian, Mint, Pop!OS)</summary>
39
+
34
40
  ### For Debian Based Distros (Ubuntu, Debian, Mint, Pop!OS)
35
41
 
36
42
  #### 1. Install libinput-tools
37
43
 
38
44
  You need `libinput` release 1.0 or later.
39
45
 
40
- ```bash
46
+ ```sh
41
47
  sudo apt-get install libinput-tools
42
48
  ```
43
49
 
@@ -45,13 +51,13 @@ sudo apt-get install libinput-tools
45
51
 
46
52
  Fusuma runs in Ruby, so you must install it first.
47
53
 
48
- ```bash
54
+ ```sh
49
55
  sudo apt-get install ruby
50
56
  ```
51
57
 
52
58
  #### 3. Install Fusuma
53
59
 
54
- ```bash
60
+ ```sh
55
61
  sudo gem install fusuma
56
62
  ```
57
63
 
@@ -59,26 +65,31 @@ sudo gem install fusuma
59
65
 
60
66
  For sending shortcuts:
61
67
 
62
- ```bash
68
+ ```sh
63
69
  sudo apt-get install xdotool
64
70
  ```
65
71
 
72
+ </details>
73
+
74
+ <details>
75
+ <summary> For Arch Based Distros (Manjaro, Arch) </summary>
76
+
66
77
  ### For Arch Based Distros (Manjaro, Arch)
67
78
 
68
79
  #### 1. Install libinput.
69
80
 
70
81
  You need `libinput` release 1.0 or later. This is most probably installed by default on Manjaro
71
82
 
72
- ```z-h
73
- sudo pacman -S libinput
83
+ ```sh
84
+ sudo pacman -Syu libinput
74
85
  ```
75
86
 
76
87
  #### 2. Install Ruby
77
88
 
78
89
  Fusuma runs in Ruby, so you must install it first.
79
90
 
80
- ```zsh
81
- sudo pacman -S ruby
91
+ ```sh
92
+ sudo pacman -Syu ruby
82
93
  ```
83
94
 
84
95
  #### 3. Install Fusuma
@@ -87,7 +98,7 @@ sudo pacman -S ruby
87
98
 
88
99
  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
100
 
90
- ```zsh
101
+ ```sh
91
102
  sudo gem install fusuma
92
103
  ```
93
104
 
@@ -95,9 +106,19 @@ sudo gem install fusuma
95
106
 
96
107
  For sending shortcuts:
97
108
 
98
- ```zsh
99
- sudo pacman -S xdotool
109
+ ```sh
110
+ sudo pacman -Syu xdotool
100
111
  ```
112
+ **For the truly lazy people:** As with pretty much anything else available as Open-Source-Software, you can install Fusuma via a package from the AUR. As off time of writing (March 2023), the package you would want is called `ruby-fusuma`.
113
+
114
+ Please keep in mind that this community-built package is NOT officially supported here and while it might do the job, it is not the intended way to install.
115
+ Installing Fusuma this way means that if things do not work as intended during or after the installation, you are on your own.
116
+ So please do not bombard the Issues-Page here on Github if Fusuma isn't working correctly after installing it via the AUR.
117
+ Fusuma's plugins as listed below here in this Readme can be installed as optional dependencies also via the AUR, namescheme being `ruby-fusuma-replacewithnameofplugin`.
118
+ </details>
119
+
120
+ <details>
121
+ <summary>For Fedora</summary>
101
122
 
102
123
  ### For Fedora
103
124
 
@@ -105,7 +126,7 @@ sudo pacman -S xdotool
105
126
 
106
127
  You need `libinput` release 1.0 or later.
107
128
 
108
- ```bash
129
+ ```sh
109
130
  sudo dnf install libinput
110
131
  ```
111
132
 
@@ -113,13 +134,13 @@ sudo dnf install libinput
113
134
 
114
135
  Fusuma runs in Ruby, so you must install it first.
115
136
 
116
- ```bash
137
+ ```sh
117
138
  sudo dnf install ruby
118
139
  ```
119
140
 
120
141
  #### 3. Install Fusuma
121
142
 
122
- ```bash
143
+ ```sh
123
144
  sudo gem install fusuma
124
145
  ```
125
146
 
@@ -127,27 +148,28 @@ sudo gem install fusuma
127
148
 
128
149
  For sending shortcuts:
129
150
 
130
- ```bash
151
+ ```sh
131
152
  sudo dnf install xdotool
132
153
  ```
154
+ </details>
133
155
 
134
156
  ### Touchpad not working in GNOME
135
157
 
136
158
  Ensure the touchpad events are being sent to the GNOME desktop by running the following command:
137
159
 
138
- ```bash
160
+ ```sh
139
161
  gsettings set org.gnome.desktop.peripherals.touchpad send-events enabled
140
162
  ```
141
163
 
142
164
  ## Usage
143
165
 
144
- ```bash
166
+ ```sh
145
167
  fusuma
146
168
  ```
147
169
 
148
170
  ## Update
149
171
 
150
- ```bash
172
+ ```sh
151
173
  sudo gem update fusuma
152
174
  ```
153
175
 
@@ -156,7 +178,7 @@ sudo gem update fusuma
156
178
  You can customize the settings for gestures to put and edit `~/.config/fusuma/config.yml`.
157
179
  **NOTE: You will need to create the `~/.config/fusuma` directory if it doesn't exist yet.**
158
180
 
159
- ```bash
181
+ ```sh
160
182
  mkdir -p ~/.config/fusuma # create config directory
161
183
  nano ~/.config/fusuma/config.yml # edit config file.
162
184
  ```
@@ -322,7 +344,6 @@ swipe:
322
344
  #### Alternatives to xdotool
323
345
 
324
346
  - [fusuma-plugin-sendkey](https://github.com/iberianpig/fusuma-plugin-sendkey)
325
-
326
347
  - Emulates keyboard events
327
348
  - Low latency
328
349
  - Wayland compatible
@@ -334,7 +355,8 @@ swipe:
334
355
  - [ydotool](https://github.com/ReimuNotMoe/ydotool)
335
356
  - Wayland compatible
336
357
  - Needs more maintainers.
337
- - Requires only replacing `xdotool` with `ydotool` in fusuma conf.
358
+
359
+
338
360
 
339
361
  ## Options
340
362
 
@@ -376,22 +398,22 @@ Following features are provided as plugins.
376
398
 
377
399
  Fusuma plugins are provided with the `fusuma-plugin-XXXXX` naming convention and hosted on [RubyGems](https://rubygems.org/search?utf8=%E2%9C%93&query=fusuma-plugins).
378
400
 
379
- | Name | Version | About |
380
- | ---------------------------------------------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------- |
381
- | [fusuma-plugin-sendkey](https://github.com/iberianpig/fusuma-plugin-sendkey) | ![Gem Version](https://badge.fury.io/rb/fusuma-plugin-sendkey.svg) | Emulates keyboard events |
382
- | [fusuma-plugin-wmctrl](https://github.com/iberianpig/fusuma-plugin-wmctrl) | ![Gem Version](https://badge.fury.io/rb/fusuma-plugin-wmctrl.svg) | Manages Window and Workspace |
383
- | [fusuma-plugin-keypress](https://github.com/iberianpig/fusuma-plugin-keypress) | ![Gem Version](https://badge.fury.io/rb/fusuma-plugin-keypress.svg) | Detects gestures while pressing multiple keys |
384
- | [fusuma-plugin-tap](https://github.com/iberianpig/fusuma-plugin-tap) | ![Gem Version](https://badge.fury.io/rb/fusuma-plugin-tap.svg) | Detects Tap and Hold gestures |
385
- | [fusuma-plugin-appmatcher](https://github.com/iberianpig/fusuma-plugin-appmatcher) | ![Gem Version](https://badge.fury.io/rb/fusuma-plugin-appmatcher.svg) | Configure app-specific gestures |
401
+ | Name | Version | About |
402
+ | --- | --- | --- |
403
+ | [fusuma-plugin-sendkey](https://github.com/iberianpig/fusuma-plugin-sendkey) | ![Gem](https://img.shields.io/gem/v/fusuma-plugin-sendkey?color=brightgreen) | Emulates keyboard events(Wayland compatible) |
404
+ | [fusuma-plugin-wmctrl](https://github.com/iberianpig/fusuma-plugin-wmctrl) | ![Gem](https://img.shields.io/gem/v/fusuma-plugin-wmctrl?color=brightgreen) | Manages Window and Workspace |
405
+ | [fusuma-plugin-keypress](https://github.com/iberianpig/fusuma-plugin-keypress) | ![Gem](https://img.shields.io/gem/v/fusuma-plugin-keypress?color=brightgreen) | Detecting a combination of key presses and touchpad gestures |
406
+ | [fusuma-plugin-tap](https://github.com/iberianpig/fusuma-plugin-tap) | ![Gem](https://img.shields.io/gem/v/fusuma-plugin-tap?color=brightgreen) | Detects Tap gesture |
407
+ | [fusuma-plugin-appmatcher](https://github.com/iberianpig/fusuma-plugin-appmatcher) | ![Gem](https://img.shields.io/gem/v/fusuma-plugin-appmatcher?color=brightgreen) | Configure app-specific gestures |
386
408
 
387
409
 
388
410
  ### Installation of Fusuma plugins
389
411
 
390
- ```bash
412
+ ```sh
391
413
  # install fusuma-plugin-XXXX
392
414
  sudo gem install fusuma-plugin-XXXXX`
393
415
  ```
394
- ```bash
416
+ ```sh
395
417
  # update
396
418
  sudo gem list fusuma-plugin- | cut -d' ' -f1 | xargs --no-run-if-empty sudo gem update
397
419
  ```
@@ -408,7 +430,6 @@ Currently, my open-source contribution times is not enough.
408
430
  If you like my work and want to contribute and become a sponsor, I will be able to focus on my projects.
409
431
 
410
432
  - [GitHub Sponsors](https://github.com/sponsors/iberianpig)
411
- - [Patreon](https://www.patreon.com/iberianpig)
412
433
 
413
434
  ## Contributing
414
435
 
data/exe/fusuma CHANGED
@@ -27,6 +27,10 @@ opt.on('--log=path/to/file',
27
27
  option[:log_filepath] = v
28
28
  end
29
29
 
30
+ opt.on('--show-config', 'Show config as YAML format which is loaded internally') do |v|
31
+ option[:show_config] = v
32
+ end
33
+
30
34
  opt.on('--device="Device name"',
31
35
  'Open the given device only (DEPRECATED)') do |v|
32
36
  option[:device] = v
data/fusuma.gemspec CHANGED
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
24
24
  "yard.run" => "yri" # use "yard" to build full HTML docs.
25
25
  }
26
26
 
27
- spec.required_ruby_version = ">= 2.5.1" # https://packages.ubuntu.com/search?keywords=ruby&searchon=names&exact=1&suite=all&section=main
28
- # support bionic (18.04LTS) 2.5.1
27
+ spec.required_ruby_version = ">= 2.7"
28
+ # https://packages.ubuntu.com/search?keywords=ruby&searchon=names&exact=1&suite=all&section=main
29
+ # support focal (20.04LTS) 2.7
29
30
  end
@@ -6,17 +6,19 @@ module Fusuma
6
6
  # index for config.yml
7
7
  class Index
8
8
  def initialize(keys)
9
- @keys = case keys
9
+ @count = 0
10
+ case keys
10
11
  when Array
11
- keys.map do |key|
12
- if key.is_a? Key
13
- key
14
- else
15
- Key.new(key)
16
- end
17
- end
12
+ @keys = []
13
+ @cache_key = keys.map do |key|
14
+ key = Key.new(key) if !key.is_a? Key
15
+ @keys << key
16
+ key.symbol
17
+ end.join(",")
18
18
  else
19
- [Key.new(keys)]
19
+ key = Key.new(keys)
20
+ @cache_key = key.symbol
21
+ @keys = [key]
20
22
  end
21
23
  end
22
24
 
@@ -24,36 +26,11 @@ module Fusuma
24
26
  @keys.map(&:inspect)
25
27
  end
26
28
 
27
- attr_reader :keys
28
-
29
- def cache_key
30
- case @keys
31
- when Array
32
- @keys.map(&:symbol).join(",")
33
- when Key
34
- @keys.symbol
35
- else
36
- raise "invalid keys"
37
- end
38
- end
39
-
40
- # @return [Index]
41
- def with_context
42
- keys = @keys.map do |key|
43
- next if Searcher.skip? && key.skippable
44
-
45
- if Searcher.fallback? && key.fallback
46
- key.fallback
47
- else
48
- key
49
- end
50
- end
51
- self.class.new(keys.compact)
52
- end
29
+ attr_reader :keys, :cache_key
53
30
 
54
31
  # Keys in Index
55
32
  class Key
56
- def initialize(symbol_word, skippable: false, fallback: nil)
33
+ def initialize(symbol_word, skippable: false)
57
34
  @symbol = begin
58
35
  symbol_word.to_sym
59
36
  rescue
@@ -61,21 +38,17 @@ module Fusuma
61
38
  end
62
39
 
63
40
  @skippable = skippable
64
-
65
- @fallback = begin
66
- fallback.to_sym
67
- rescue
68
- fallback
69
- end
70
41
  end
71
42
 
72
43
  def inspect
73
- skip_marker = @skippable && Searcher.skip? ? "(skip)" : ""
74
- fallback_marker = @fallback && Searcher.fallback? ? "(fallback)" : ""
75
- "#{@symbol}#{skip_marker}#{fallback_marker}"
44
+ if @skippable
45
+ "#{@symbol}(skippable)"
46
+ else
47
+ @symbol.to_s
48
+ end
76
49
  end
77
50
 
78
- attr_reader :symbol, :skippable, :fallback
51
+ attr_reader :symbol, :skippable
79
52
  end
80
53
  end
81
54
  end
@@ -6,7 +6,7 @@ module Fusuma
6
6
  # Search config.yml
7
7
  class Searcher
8
8
  def initialize
9
- @cache = nil
9
+ @cache = {}
10
10
  end
11
11
 
12
12
  # @param index [Index]
@@ -36,10 +36,11 @@ module Fusuma
36
36
 
37
37
  return search(index, location: location[0]) if context == {}
38
38
 
39
- new_location = location.find do |conf|
40
- search(index, location: conf) if conf[:context] == context
39
+ value = nil
40
+ location.find do |conf|
41
+ value = search(index, location: conf) if conf[:context] == context
41
42
  end
42
- search(index, location: new_location)
43
+ value
43
44
  end
44
45
 
45
46
  # @param index [Index]
@@ -48,13 +49,12 @@ module Fusuma
48
49
  # @return [Hash]
49
50
  # @return [Object]
50
51
  def search_with_cache(index, location:)
51
- cache([index.cache_key, Searcher.context, Searcher.skip?, Searcher.fallback?]) do
52
+ cache([index.cache_key, Searcher.context]) do
52
53
  search_with_context(index, location: location, context: Searcher.context)
53
54
  end
54
55
  end
55
56
 
56
57
  def cache(key)
57
- @cache ||= {}
58
58
  key = key.join(",") if key.is_a? Array
59
59
  if @cache.key?(key)
60
60
  @cache[key]
@@ -71,36 +71,12 @@ module Fusuma
71
71
  def next_location_cadidates(location, key)
72
72
  [
73
73
  location[key.symbol],
74
- Searcher.skip? && key.skippable && location
74
+ key.skippable && location
75
75
  ].compact
76
76
  end
77
77
 
78
78
  class << self
79
- # @return [Hash]
80
- def conditions(&block)
81
- {
82
- nothing: -> { block.call },
83
- skip: -> { Config::Searcher.skip { block.call } }
84
- }
85
- end
86
-
87
- # Execute block with specified conditions
88
- # @param conidtion [Symbol]
89
- # @return [Object]
90
- def with_condition(condition, &block)
91
- conditions(&block)[condition].call
92
- end
93
-
94
- # Execute block with all conditions
95
- # @return [Array<Symbol, Object>]
96
- def find_condition(&block)
97
- conditions(&block).find do |c, l|
98
- result = l.call
99
- return [c, result] if result
100
-
101
- nil
102
- end
103
- end
79
+ attr_reader :context
104
80
 
105
81
  # Search with context from load_streamed Config
106
82
  # @param context [Hash]
@@ -112,52 +88,84 @@ module Fusuma
112
88
  result
113
89
  end
114
90
 
91
+ CONEXT_SEARCH_ORDER = [:no_context, :complete_match_context, :partial_match_context]
115
92
  # Return a matching context from config
116
93
  # @params request_context [Hash]
117
94
  # @return [Hash]
118
- def find_context(request_context, &block)
95
+ def find_context(request_context, fallbacks = CONEXT_SEARCH_ORDER, &block)
119
96
  # Search in blocks in the following order.
120
- # 1. complete match config[:context] == request_context
121
- # 2. partial match config[:context] =~ request_context
122
- # 3. no context
97
+ # 1. primary context(no context)
98
+ # 2. complete match config[:context] == request_context
99
+ # 3. partial match config[:context] =~ request_context
100
+ # no_context?(&block) ||
101
+ # complete_match_context(request_context, &block) ||
102
+ # partial_match_context(request_context, &block)
103
+ fallbacks.each do |method|
104
+ result = send(method, request_context, &block)
105
+ return result if result
106
+ end
107
+ end
108
+
109
+ private
110
+
111
+ # No context(primary context)
112
+ # @return [Hash]
113
+ # @return [NilClass]
114
+ def no_context(_request_context, &block)
115
+ return {} if with_context({}, &block)
116
+ end
117
+
118
+ # Complete match request context
119
+ # @param request_context [Hash]
120
+ # @return [Hash] matched context
121
+ # @return [NilClass] if not matched
122
+ def complete_match_context(request_context, &block)
123
123
  Config.instance.keymap.each do |config|
124
124
  next unless config[:context] == request_context
125
- return config[:context] if with_context(config[:context]) { block.call }
125
+ return config[:context] if with_context(config[:context], &block)
126
126
  end
127
+ nil
128
+ end
129
+
130
+ # One of multiple request contexts matched
131
+ # @param request_context [Hash]
132
+ # @return [Hash] matched context
133
+ # @return [NilClass] if not matched
134
+ def partial_match_context(request_context, &block)
127
135
  if request_context.keys.size > 1
128
136
  Config.instance.keymap.each do |config|
129
137
  next if config[:context].nil?
130
138
 
131
139
  next unless config[:context].all? { |k, v| request_context[k] == v }
132
- return config[:context] if with_context(config[:context]) { block.call }
140
+ return config[:context] if with_context(config[:context], &block)
133
141
  end
142
+ nil
134
143
  end
135
- return {} if with_context({}) { block.call }
136
- end
137
-
138
- attr_reader :context
139
-
140
- def fallback?
141
- @fallback
142
144
  end
143
145
 
144
- def skip?
145
- @skip
146
- end
146
+ # Search context for plugin
147
+ # If the plugin_defaults key is a complete match,
148
+ # it is the default value for that plugin, so it is postponed.
149
+ # This is because prioritize overwriting by other plugins.
150
+ # The search order is as follows
151
+ # 1. complete match config[:context].key?(:plugin_defaults)
152
+ # 2. complete match config[:context] == request_context
153
+ # @param request_context [Hash]
154
+ # @return [Hash] matched context
155
+ # @return [NilClass] if not matched
156
+ def plugin_default_context(request_context, &block)
157
+ complete_match_context = nil
158
+ Config.instance.keymap.each do |config|
159
+ next unless config[:context]&.key?(:plugin_defaults)
147
160
 
148
- # switch context for fallback
149
- def fallback(&block)
150
- @fallback = true
151
- result = block.call
152
- @fallback = false
153
- result
154
- end
161
+ if config[:context][:plugin_defaults] == request_context[:plugin_defaults]
162
+ complete_match_context = config[:context]
163
+ next
164
+ end
155
165
 
156
- def skip(&block)
157
- @skip = true
158
- result = block.call
159
- @skip = false
160
- result
166
+ return config[:context] if with_context(config[:context], &block)
167
+ end
168
+ complete_match_context
161
169
  end
162
170
  end
163
171
  end
data/lib/fusuma/config.rb CHANGED
@@ -4,6 +4,7 @@ require_relative "./multi_logger"
4
4
  require_relative "./config/index"
5
5
  require_relative "./config/searcher"
6
6
  require_relative "./config/yaml_duplication_checker"
7
+ require_relative "./plugin/manager"
7
8
  require_relative "./hash_support"
8
9
  require "singleton"
9
10
  require "yaml"
@@ -32,7 +33,7 @@ module Fusuma
32
33
  end
33
34
  end
34
35
 
35
- attr_reader :keymap, :custom_path, :searcher
36
+ attr_reader :custom_path, :searcher
36
37
 
37
38
  def initialize
38
39
  @searcher = Searcher.new
@@ -45,17 +46,47 @@ module Fusuma
45
46
  reload
46
47
  end
47
48
 
49
+ def keymap
50
+ # FIXME: @keymap is not initialized when called from outside Fusuma::Runner like fusuma-senkey
51
+ @keymap || reload.keymap
52
+ end
53
+
48
54
  def reload
55
+ plugin_defaults = plugin_defaults_paths.map do |default_yml|
56
+ {
57
+ context: {plugin_defaults: default_yml.split("/").last.delete_suffix(".yml")},
58
+ **validate(default_yml)[0]
59
+ }
60
+ end
61
+
62
+ config_path = find_config_filepath
63
+ @keymap = validate(config_path) | plugin_defaults
64
+ MultiLogger.info "reload config: #{config_path}"
65
+
66
+ # reset searcher cache
49
67
  @searcher = Searcher.new
50
- path = find_filepath
51
- MultiLogger.info "reload config: #{path}"
52
- @keymap = validate(path)
68
+
53
69
  self
54
70
  rescue InvalidFileError => e
55
71
  MultiLogger.error e.message
56
72
  exit 1
57
73
  end
58
74
 
75
+ # @param key [Symbol]
76
+ # @param base [Config::Index]
77
+ # @return [Hash]
78
+ def fetch_config_params(key, base)
79
+ request_context = {plugin_defaults: base.keys.last.symbol.to_s}
80
+ fallbacks = [:no_context, :plugin_default_context]
81
+ Config::Searcher.find_context(request_context, fallbacks) do
82
+ ret = Config.search(base)
83
+ if ret&.key?(key)
84
+ return ret
85
+ end
86
+ end
87
+ {}
88
+ end
89
+
59
90
  # @return [Hash] If check passes
60
91
  # @raise [InvalidFileError] If check does not pass
61
92
  def validate(path)
@@ -75,7 +106,6 @@ module Fusuma
75
106
  end
76
107
 
77
108
  # @param index [Index]
78
- # @param context [Hash]
79
109
  def search(index)
80
110
  @searcher.search_with_cache(index, location: keymap)
81
111
  end
@@ -95,7 +125,7 @@ module Fusuma
95
125
 
96
126
  private
97
127
 
98
- def find_filepath
128
+ def find_config_filepath
99
129
  filename = "fusuma/config.yml"
100
130
  if custom_path
101
131
  return expand_custom_path if File.exist?(expand_custom_path)
@@ -120,5 +150,12 @@ module Fusuma
120
150
  def expand_default_path(filename)
121
151
  File.expand_path "../../#{filename}", __FILE__
122
152
  end
153
+
154
+ def plugin_defaults_paths
155
+ Plugin::Manager.load_paths.map do |plugin_path|
156
+ yml = plugin_path.gsub(/\.rb$/, ".yml")
157
+ yml if File.exist?(yml)
158
+ end.compact
159
+ end
123
160
  end
124
161
  end