fusuma 2.5.1 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
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