exfuz 0.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 +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +44 -0
- data/README.md +88 -0
- data/Rakefile +8 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/exe/exfuz +4 -0
- data/exfuz.gemspec +24 -0
- data/lib/exfuz/body.rb +105 -0
- data/lib/exfuz/book_name.rb +36 -0
- data/lib/exfuz/candidate.rb +48 -0
- data/lib/exfuz/candidates.rb +53 -0
- data/lib/exfuz/cell.rb +82 -0
- data/lib/exfuz/command.rb +11 -0
- data/lib/exfuz/configuration.rb +86 -0
- data/lib/exfuz/event.rb +17 -0
- data/lib/exfuz/fuzzy_finder_command.rb +37 -0
- data/lib/exfuz/group.rb +34 -0
- data/lib/exfuz/jump.rb +29 -0
- data/lib/exfuz/key_map.rb +116 -0
- data/lib/exfuz/main.rb +59 -0
- data/lib/exfuz/operator.ps1 +62 -0
- data/lib/exfuz/parser.rb +67 -0
- data/lib/exfuz/position.rb +63 -0
- data/lib/exfuz/query.rb +103 -0
- data/lib/exfuz/screen.rb +228 -0
- data/lib/exfuz/sheet_name.rb +31 -0
- data/lib/exfuz/status.rb +25 -0
- data/lib/exfuz/util.rb +26 -0
- data/lib/exfuz/version.rb +5 -0
- data/lib/exfuz.rb +27 -0
- metadata +76 -0
data/lib/exfuz/screen.rb
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'curses'
|
|
4
|
+
|
|
5
|
+
module Exfuz
|
|
6
|
+
class Screen
|
|
7
|
+
attr_reader :query
|
|
8
|
+
|
|
9
|
+
def initialize(status = nil, key_map = nil, candidates = nil)
|
|
10
|
+
@conf = Exfuz::Configuration.instance
|
|
11
|
+
|
|
12
|
+
@status = status
|
|
13
|
+
@prev_loaded = @status.loaded
|
|
14
|
+
@key_map = key_map
|
|
15
|
+
@prompt = '>'
|
|
16
|
+
@query = Exfuz::Query.new([0, @prompt.size])
|
|
17
|
+
@cmd = Exfuz::FuzzyFinderCommand.new(command_type: @conf.fuzzy_finder_command_type)
|
|
18
|
+
@candidates = candidates
|
|
19
|
+
|
|
20
|
+
@description = Exfuz::Body.new(top: 1, bottom: 1, texts: ['please input query'])
|
|
21
|
+
@list = Exfuz::Body.new(top: 2, bottom: 4)
|
|
22
|
+
|
|
23
|
+
register_event
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def status
|
|
27
|
+
@status.to_s
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def init
|
|
31
|
+
Curses.init_screen
|
|
32
|
+
# キー入力の文字を画面に反映させない
|
|
33
|
+
Curses.noecho
|
|
34
|
+
# 入力の待機時間(milliseconds)
|
|
35
|
+
Curses.timeout = 100
|
|
36
|
+
|
|
37
|
+
@list.bottom = Curses.lines - @list.top + 1
|
|
38
|
+
draw
|
|
39
|
+
Curses.refresh
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def rerender
|
|
43
|
+
@prev_loaded = @status.loaded
|
|
44
|
+
refresh
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def refresh
|
|
48
|
+
draw
|
|
49
|
+
Curses.refresh
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def wait_input
|
|
53
|
+
@ch = Curses.getch
|
|
54
|
+
# 待機時間内に入力されない場合
|
|
55
|
+
return unless @ch
|
|
56
|
+
|
|
57
|
+
handle_event(@ch)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# 表示内容の変更検知を判定する
|
|
61
|
+
def changed_state?
|
|
62
|
+
@prev_loaded < @status.loaded
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def closed?
|
|
66
|
+
Curses.closed?
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def close
|
|
70
|
+
Curses.close_screen
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# event
|
|
74
|
+
def start_cmd
|
|
75
|
+
filtered = @candidates.filter({ textable: @query.text })
|
|
76
|
+
@cmd.run do |fiber|
|
|
77
|
+
filtered.positions.each_with_index do |position, idx|
|
|
78
|
+
value_text = position.textable.value.to_s
|
|
79
|
+
line = [
|
|
80
|
+
idx,
|
|
81
|
+
position.book_name.relative_path,
|
|
82
|
+
position.sheet_name.name,
|
|
83
|
+
position.textable.position_s(format: @conf.cell_position_format),
|
|
84
|
+
@conf.split_new_line ? value_text : value_text.gsub(/\R+/) { '\n' }
|
|
85
|
+
].join(@conf.line_sep)
|
|
86
|
+
fiber.resume(line)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
selected_positions = @cmd.selected.map do |s|
|
|
91
|
+
idx = s.split(@conf.line_sep).first.to_i
|
|
92
|
+
filtered.positions[idx]
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
if Exfuz::Util.wsl? && @conf.jump_positions?
|
|
96
|
+
jump = Exfuz::Jump.new(selected_positions)
|
|
97
|
+
jump.run
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
@list.change_all(@cmd.selected)
|
|
101
|
+
|
|
102
|
+
Curses.clear
|
|
103
|
+
init
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def delete_char
|
|
107
|
+
@query.delete
|
|
108
|
+
refresh
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def move_left
|
|
112
|
+
@query.left
|
|
113
|
+
refresh
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def move_right
|
|
117
|
+
@query.right
|
|
118
|
+
refresh
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def move_prev_page
|
|
122
|
+
@list.move_prev
|
|
123
|
+
refresh
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def move_next_page
|
|
127
|
+
@list.move_next
|
|
128
|
+
refresh
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def finish
|
|
132
|
+
close
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def insert_char(char)
|
|
136
|
+
@query.add(char)
|
|
137
|
+
refresh
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
private
|
|
141
|
+
|
|
142
|
+
def handle_event(ch)
|
|
143
|
+
input = if Exfuz::Key.can_convert_to_name_and_char?(ch)
|
|
144
|
+
ch
|
|
145
|
+
else
|
|
146
|
+
chs = [ch]
|
|
147
|
+
# スレッドセーフでないかも
|
|
148
|
+
# 稀に正常にchが読み込めない場合があった
|
|
149
|
+
loop do
|
|
150
|
+
remaining = Curses.getch
|
|
151
|
+
break if remaining.nil?
|
|
152
|
+
|
|
153
|
+
chs << remaining
|
|
154
|
+
end
|
|
155
|
+
chs
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
name, char = Exfuz::Key.input_to_name_and_char(input)
|
|
159
|
+
|
|
160
|
+
char.nil? ? @key_map.pressed(name) : @key_map.pressed(name, char)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def register_event
|
|
164
|
+
@key_map.add_event_handler(Exfuz::Key::CTRL_R, self, func: :start_cmd)
|
|
165
|
+
@key_map.add_event_handler(Exfuz::Key::CTRL_E, self, func: :finish)
|
|
166
|
+
@key_map.add_event_handler(Exfuz::Key::CTRL_L, self, func: :move_next_page)
|
|
167
|
+
@key_map.add_event_handler(Exfuz::Key::CTRL_H, self, func: :move_prev_page)
|
|
168
|
+
@key_map.add_event_handler(Exfuz::Key::LEFT, self, func: :move_left)
|
|
169
|
+
@key_map.add_event_handler(Exfuz::Key::RIGHT, self, func: :move_right)
|
|
170
|
+
@key_map.add_event_handler(Exfuz::Key::BACKSPACE, self, func: :delete_char)
|
|
171
|
+
@key_map.add_event_handler(Exfuz::Key::CHAR, self, func: :insert_char)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def draw
|
|
175
|
+
print_head_line
|
|
176
|
+
|
|
177
|
+
print_description
|
|
178
|
+
|
|
179
|
+
print_body
|
|
180
|
+
|
|
181
|
+
reset_caret
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def reset_caret
|
|
185
|
+
Curses.setpos(*@query.caret)
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def print_head_line
|
|
189
|
+
# 前回の入力内容を保持してないためクエリの全文字を再描画
|
|
190
|
+
Curses.setpos(0, 0)
|
|
191
|
+
Curses.addstr(@prompt + @query.line)
|
|
192
|
+
|
|
193
|
+
col = Curses.cols - status.size
|
|
194
|
+
Curses.setpos(0, col)
|
|
195
|
+
Curses.addstr(status)
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def print_description
|
|
199
|
+
@description.lines.each do |row, line|
|
|
200
|
+
print_line(row: row, line: line)
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def print_body
|
|
205
|
+
@list.lines(overwrite: true).each do |row, line|
|
|
206
|
+
print_line(row: row, line: line)
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def print_line(row:, line:)
|
|
211
|
+
Curses.setpos(row, 0)
|
|
212
|
+
Curses.addstr(line)
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def main
|
|
218
|
+
require_relative './status'
|
|
219
|
+
screen = Exfuz::Screen.new(Exfuz::Status.new(10))
|
|
220
|
+
screen.init
|
|
221
|
+
until screen.closed?
|
|
222
|
+
# キー入力を待機
|
|
223
|
+
screen.handle_input
|
|
224
|
+
end
|
|
225
|
+
screen.close
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
main if __FILE__ == $0
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Exfuz
|
|
4
|
+
class SheetName
|
|
5
|
+
def self.name
|
|
6
|
+
:sheet_name
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
attr_reader :name
|
|
10
|
+
|
|
11
|
+
include Exfuz::Util
|
|
12
|
+
|
|
13
|
+
def initialize(name)
|
|
14
|
+
@name = @text = name
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def ==(other)
|
|
18
|
+
return false if other.nil? || !other.instance_of?(Exfuz::SheetName)
|
|
19
|
+
|
|
20
|
+
name == other.name
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def hash
|
|
24
|
+
@name.hash
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def jump_info
|
|
28
|
+
{ Exfuz::SheetName.name => @name }
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
data/lib/exfuz/status.rb
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Exfuz
|
|
4
|
+
class Status
|
|
5
|
+
attr_reader :loaded, :max
|
|
6
|
+
|
|
7
|
+
def initialize(max)
|
|
8
|
+
@loaded = 0
|
|
9
|
+
@max = max
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def update(num)
|
|
13
|
+
@loaded += num
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def finished?
|
|
17
|
+
@loaded == @max
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# TODO: メソッド名を変更すること
|
|
21
|
+
def to_s
|
|
22
|
+
"[#{@loaded}/#{@max}]"
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
data/lib/exfuz/util.rb
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'etc'
|
|
4
|
+
|
|
5
|
+
module Exfuz
|
|
6
|
+
module Util
|
|
7
|
+
def match?(word)
|
|
8
|
+
regexp = Regexp.new(word.downcase, Regexp::IGNORECASE)
|
|
9
|
+
@text.match?(regexp)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
module_function
|
|
13
|
+
|
|
14
|
+
def wsl?
|
|
15
|
+
Etc.uname[:release].match?(/.*microsoft.*/)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def wsl_to_windows(path)
|
|
19
|
+
nil unless wsl?
|
|
20
|
+
|
|
21
|
+
raise ArgumentError, 'not exists path' unless File.exist?(path)
|
|
22
|
+
|
|
23
|
+
`wslpath -w #{path}`.chomp
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
data/lib/exfuz.rb
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'exfuz/version'
|
|
4
|
+
|
|
5
|
+
module Exfuz
|
|
6
|
+
class Error < StandardError; end
|
|
7
|
+
autoload :BookName, 'exfuz/book_name'
|
|
8
|
+
autoload :Body, 'exfuz/body'
|
|
9
|
+
autoload :Candidate, 'exfuz/candidate'
|
|
10
|
+
autoload :Candidates, 'exfuz/candidates'
|
|
11
|
+
autoload :Cell, 'exfuz/cell'
|
|
12
|
+
autoload :Configuration, 'exfuz/configuration'
|
|
13
|
+
autoload :Command, 'exfuz/command'
|
|
14
|
+
autoload :Event, 'exfuz/event'
|
|
15
|
+
autoload :FuzzyFinderCommand, 'exfuz/fuzzy_finder_command'
|
|
16
|
+
autoload :Group, 'exfuz/group'
|
|
17
|
+
autoload :Jump, 'exfuz/jump'
|
|
18
|
+
autoload :Key, 'exfuz/key_map'
|
|
19
|
+
autoload :KeyMap, 'exfuz/key_map'
|
|
20
|
+
autoload :Parser, 'exfuz/parser'
|
|
21
|
+
autoload :Position, 'exfuz/position'
|
|
22
|
+
autoload :Query, 'exfuz/query'
|
|
23
|
+
autoload :Screen, 'exfuz/screen'
|
|
24
|
+
autoload :SheetName, 'exfuz/sheet_name'
|
|
25
|
+
autoload :Status, 'exfuz/status'
|
|
26
|
+
autoload :Util, 'exfuz/util'
|
|
27
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: exfuz
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- wata00913
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: exe
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2023-01-31 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: Fuzzy finder excel. This uses a fuzzy finder such as peco or fzf.
|
|
14
|
+
email:
|
|
15
|
+
- 175d8639@gmail.com
|
|
16
|
+
executables:
|
|
17
|
+
- exfuz
|
|
18
|
+
extensions: []
|
|
19
|
+
extra_rdoc_files: []
|
|
20
|
+
files:
|
|
21
|
+
- ".gitignore"
|
|
22
|
+
- ".rspec"
|
|
23
|
+
- Gemfile
|
|
24
|
+
- Gemfile.lock
|
|
25
|
+
- README.md
|
|
26
|
+
- Rakefile
|
|
27
|
+
- bin/console
|
|
28
|
+
- bin/setup
|
|
29
|
+
- exe/exfuz
|
|
30
|
+
- exfuz.gemspec
|
|
31
|
+
- lib/exfuz.rb
|
|
32
|
+
- lib/exfuz/body.rb
|
|
33
|
+
- lib/exfuz/book_name.rb
|
|
34
|
+
- lib/exfuz/candidate.rb
|
|
35
|
+
- lib/exfuz/candidates.rb
|
|
36
|
+
- lib/exfuz/cell.rb
|
|
37
|
+
- lib/exfuz/command.rb
|
|
38
|
+
- lib/exfuz/configuration.rb
|
|
39
|
+
- lib/exfuz/event.rb
|
|
40
|
+
- lib/exfuz/fuzzy_finder_command.rb
|
|
41
|
+
- lib/exfuz/group.rb
|
|
42
|
+
- lib/exfuz/jump.rb
|
|
43
|
+
- lib/exfuz/key_map.rb
|
|
44
|
+
- lib/exfuz/main.rb
|
|
45
|
+
- lib/exfuz/operator.ps1
|
|
46
|
+
- lib/exfuz/parser.rb
|
|
47
|
+
- lib/exfuz/position.rb
|
|
48
|
+
- lib/exfuz/query.rb
|
|
49
|
+
- lib/exfuz/screen.rb
|
|
50
|
+
- lib/exfuz/sheet_name.rb
|
|
51
|
+
- lib/exfuz/status.rb
|
|
52
|
+
- lib/exfuz/util.rb
|
|
53
|
+
- lib/exfuz/version.rb
|
|
54
|
+
homepage: https://github.com/wata00913/exfuz
|
|
55
|
+
licenses: []
|
|
56
|
+
metadata: {}
|
|
57
|
+
post_install_message:
|
|
58
|
+
rdoc_options: []
|
|
59
|
+
require_paths:
|
|
60
|
+
- lib
|
|
61
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
62
|
+
requirements:
|
|
63
|
+
- - ">="
|
|
64
|
+
- !ruby/object:Gem::Version
|
|
65
|
+
version: 2.4.0
|
|
66
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
67
|
+
requirements:
|
|
68
|
+
- - ">="
|
|
69
|
+
- !ruby/object:Gem::Version
|
|
70
|
+
version: '0'
|
|
71
|
+
requirements: []
|
|
72
|
+
rubygems_version: 3.2.22
|
|
73
|
+
signing_key:
|
|
74
|
+
specification_version: 4
|
|
75
|
+
summary: excel fuzzy finder
|
|
76
|
+
test_files: []
|