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 +4 -4
- data/README.md +55 -34
- data/exe/fusuma +4 -0
- data/fusuma.gemspec +3 -2
- data/lib/fusuma/config/index.rb +19 -46
- data/lib/fusuma/config/searcher.rb +68 -60
- data/lib/fusuma/config.rb +43 -6
- data/lib/fusuma/custom_process.rb +34 -2
- data/lib/fusuma/device.rb +1 -0
- data/lib/fusuma/environment.rb +6 -0
- data/lib/fusuma/hash_support.rb +22 -0
- data/lib/fusuma/multi_logger.rb +16 -0
- data/lib/fusuma/plugin/base.rb +16 -7
- data/lib/fusuma/plugin/buffers/gesture_buffer.rb +62 -6
- data/lib/fusuma/plugin/detectors/detector.rb +10 -9
- data/lib/fusuma/plugin/detectors/hold_detector.rb +28 -14
- data/lib/fusuma/plugin/detectors/pinch_detector.rb +10 -10
- data/lib/fusuma/plugin/detectors/rotate_detector.rb +4 -11
- data/lib/fusuma/plugin/detectors/swipe_detector.rb +8 -16
- data/lib/fusuma/plugin/events/records/gesture_record.rb +5 -2
- data/lib/fusuma/plugin/events/records/index_record.rb +1 -1
- data/lib/fusuma/plugin/executors/command_executor.rb +2 -2
- data/lib/fusuma/plugin/executors/executor.rb +1 -4
- data/lib/fusuma/plugin/filters/libinput_device_filter.rb +2 -1
- data/lib/fusuma/plugin/inputs/input.rb +14 -36
- data/lib/fusuma/plugin/inputs/libinput_command_input.yml +3 -0
- data/lib/fusuma/plugin/inputs/timer_input.rb +36 -21
- data/lib/fusuma/plugin/manager.rb +17 -6
- data/lib/fusuma/version.rb +1 -1
- data/lib/fusuma.rb +51 -36
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8ff7ea9fcd08ba0c48e1c08d9eceeb4a1e30684a0616f37fef6f67a3e035c005
|
4
|
+
data.tar.gz: c68adc10a8e2b7fb5396c7c789f941b13bacc9d60d6d669a7d8004c773503d75
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 46fdbcb0b697ba9000e55de86a9550d783c81c6407f13ebe82375c2b741341a591bcf45fe6c707247a9a2017e4f3ca4834111af551a4a65001cc7e944487b28e
|
7
|
+
data.tar.gz: e0e579b0d73ea237202ae17f641c07a1ed7587a771c71bfe12d55edec62b3d9e3281fd010f646e6e7077a6245e0365d0ed73c7042528a8c8c5ac72bbeed956de
|
data/README.md
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
# Fusuma
|
1
|
+
# Fusuma
|
2
|
+
 [](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
|
-
```
|
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
|
-
```
|
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
|
-
```
|
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
|
-
```
|
54
|
+
```sh
|
49
55
|
sudo apt-get install ruby
|
50
56
|
```
|
51
57
|
|
52
58
|
#### 3. Install Fusuma
|
53
59
|
|
54
|
-
```
|
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
|
-
```
|
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
|
-
```
|
73
|
-
sudo pacman -
|
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
|
-
```
|
81
|
-
sudo pacman -
|
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
|
-
```
|
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
|
-
```
|
99
|
-
sudo pacman -
|
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
|
-
```
|
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
|
-
```
|
137
|
+
```sh
|
117
138
|
sudo dnf install ruby
|
118
139
|
```
|
119
140
|
|
120
141
|
#### 3. Install Fusuma
|
121
142
|
|
122
|
-
```
|
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
|
-
```
|
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
|
-
```
|
160
|
+
```sh
|
139
161
|
gsettings set org.gnome.desktop.peripherals.touchpad send-events enabled
|
140
162
|
```
|
141
163
|
|
142
164
|
## Usage
|
143
165
|
|
144
|
-
```
|
166
|
+
```sh
|
145
167
|
fusuma
|
146
168
|
```
|
147
169
|
|
148
170
|
## Update
|
149
171
|
|
150
|
-
```
|
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
|
-
```
|
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
|
-
|
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
|
380
|
-
|
|
381
|
-
| [fusuma-plugin-sendkey](https://github.com/iberianpig/fusuma-plugin-sendkey) |  |  |  |  |  |  | Emulates keyboard events(Wayland compatible) |
|
404
|
+
| [fusuma-plugin-wmctrl](https://github.com/iberianpig/fusuma-plugin-wmctrl) |  | Manages Window and Workspace |
|
405
|
+
| [fusuma-plugin-keypress](https://github.com/iberianpig/fusuma-plugin-keypress) |  | Detecting a combination of key presses and touchpad gestures |
|
406
|
+
| [fusuma-plugin-tap](https://github.com/iberianpig/fusuma-plugin-tap) |  | Detects Tap gesture |
|
407
|
+
| [fusuma-plugin-appmatcher](https://github.com/iberianpig/fusuma-plugin-appmatcher) |  | Configure app-specific gestures |
|
386
408
|
|
387
409
|
|
388
410
|
### Installation of Fusuma plugins
|
389
411
|
|
390
|
-
```
|
412
|
+
```sh
|
391
413
|
# install fusuma-plugin-XXXX
|
392
414
|
sudo gem install fusuma-plugin-XXXXX`
|
393
415
|
```
|
394
|
-
```
|
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.
|
28
|
-
#
|
27
|
+
spec.required_ruby_version = ">= 2.7"
|
28
|
+
# https://packages.ubuntu.com/search?keywords=ruby&searchon=names&exact=1&suite=all§ion=main
|
29
|
+
# support focal (20.04LTS) 2.7
|
29
30
|
end
|
data/lib/fusuma/config/index.rb
CHANGED
@@ -6,17 +6,19 @@ module Fusuma
|
|
6
6
|
# index for config.yml
|
7
7
|
class Index
|
8
8
|
def initialize(keys)
|
9
|
-
@
|
9
|
+
@count = 0
|
10
|
+
case keys
|
10
11
|
when Array
|
11
|
-
keys
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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
|
-
|
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
|
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
|
-
|
74
|
-
|
75
|
-
|
44
|
+
if @skippable
|
45
|
+
"#{@symbol}(skippable)"
|
46
|
+
else
|
47
|
+
@symbol.to_s
|
48
|
+
end
|
76
49
|
end
|
77
50
|
|
78
|
-
attr_reader :symbol, :skippable
|
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 =
|
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
|
-
|
40
|
-
|
39
|
+
value = nil
|
40
|
+
location.find do |conf|
|
41
|
+
value = search(index, location: conf) if conf[:context] == context
|
41
42
|
end
|
42
|
-
|
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
|
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
|
-
|
74
|
+
key.skippable && location
|
75
75
|
].compact
|
76
76
|
end
|
77
77
|
|
78
78
|
class << self
|
79
|
-
|
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.
|
121
|
-
# 2.
|
122
|
-
# 3.
|
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]
|
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]
|
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
|
-
|
145
|
-
|
146
|
-
|
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
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
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
|
-
|
157
|
-
|
158
|
-
|
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 :
|
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
|
-
|
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
|
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
|