fancy_gets 0.1.4 → 0.1.5

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
  SHA1:
3
- metadata.gz: 41007873e8755595379093dbcd5f1764b73148ab
4
- data.tar.gz: 633febcbd5720208eceeef1ca32c975ec7257eac
3
+ metadata.gz: 77bf7ba22ad95c65d42649eb16261214fb9ae5eb
4
+ data.tar.gz: 00e074cd4911c829b20128c3da56ff5f48c1e9ab
5
5
  SHA512:
6
- metadata.gz: 2a86edaed276de4def2109e9aa9acf6f40abbb956358c8255175ba3d3a614a184a80548acf1b82f969ef6b6d238ad63cf9d418c4fa96f6cde3a6312eef75c332
7
- data.tar.gz: aac9199698385c4724f159335aebccf5574e28eea79feac353a617f47c3b39a17b919f05818aa27dd19a7b753e79d09f61e1e8d597695802c017cbab61b8270a
6
+ metadata.gz: dc71e4648a88261ecbeaa3239e3bef66c91d1e85a80d7645b5db6a8b6fb72cd24c35723f6143a7cb638c3fbc351d68942ca1c1031b1211013180c4cda290c6b5
7
+ data.tar.gz: 68b1d41ee9817c6784022595a0299562d92b57984f3320c9d5ed91df7013829d06613b2634a1ab04659aee592b3d052650ebd599cd323e9d333248ad816274e0
@@ -1,3 +1,3 @@
1
1
  module FancyGets
2
- VERSION = "0.1.4"
2
+ VERSION = "0.1.5"
3
3
  end
data/lib/fancy_gets.rb CHANGED
@@ -12,6 +12,8 @@ module FancyGets
12
12
 
13
13
  # Show a list of stuff, potentially some highlighted, and allow people to up-down arrow around and pick stuff
14
14
  def gets_list(words, is_multiple = false, chosen = nil, prefix = "> ", postfix = " <", info = nil, height = nil)
15
+ on_change = nil
16
+ on_select = nil
15
17
  if words.is_a? Hash
16
18
  is_multiple = words[:is_multiple] || false
17
19
  chosen = words[:chosen]
@@ -19,7 +21,9 @@ module FancyGets
19
21
  postfix = words[:postfix] || " <"
20
22
  info = words[:info]
21
23
  height = words[:height] || nil
22
- words = words[:words]
24
+ on_change = words[:on_change]
25
+ on_select = words[:on_select]
26
+ words = words[:list]
23
27
  else
24
28
  # Trying to supply parameters but left out a "true" for is_multiple?
25
29
  if is_multiple.is_a?(Enumerable) || is_multiple.is_a?(String) || is_multiple.is_a?(Fixnum)
@@ -29,11 +33,11 @@ module FancyGets
29
33
  end
30
34
  # Slightly inclined to ditch this in case the things they're choosing really are Enumerable
31
35
  is_multiple = true if chosen.is_a?(Enumerable)
32
- FancyGets.gets_internal_core(true, is_multiple, words, chosen, prefix, postfix, info, height)
36
+ FancyGets.gets_internal_core(true, is_multiple, words, chosen, prefix, postfix, info, height, on_change, on_select)
33
37
  end
34
38
 
35
39
  # The internal routine that makes all the magic happen
36
- def self.gets_internal_core(is_list, is_password, word_objects = nil, chosen = nil, prefix = "> ", postfix = " <", info = nil, height = nil)
40
+ def self.gets_internal_core(is_list, is_password, word_objects = nil, chosen = nil, prefix = "> ", postfix = " <", info = nil, height = nil, on_change = nil, on_select = nil)
37
41
  # OK -- second parameter, is_password, means is_multiple when is_list is true
38
42
  is_multiple = is_list & is_password
39
43
  unless word_objects.nil? || is_list
@@ -80,7 +84,7 @@ module FancyGets
80
84
  # Used for dropdown select / deselect
81
85
  clear_dropdown_info = lambda do
82
86
  print "\b" * (uncolor.call(words[position]).length + pre_post_length)
83
- print (27.chr + 91.chr + 66.chr) * (words.length - position)
87
+ print (27.chr + 91.chr + 66.chr) * (height - (position - (offset || 0)) - (height < words.length ? 1 : 0))
84
88
  info_length = uncolor.call(info).length
85
89
  print " " * info_length + "\b" * info_length
86
90
  end
@@ -97,8 +101,50 @@ module FancyGets
97
101
  print "\b" * (uncolor.call(word).length + pre_post_length) if is_end_at_front
98
102
  end
99
103
 
104
+ write_info = lambda do |new_info|
105
+ # Put the response into the info line, as long as it's short enough!
106
+ new_info.gsub!("\n", " ")
107
+ new_info_length = uncolor.call(new_info).length
108
+ console_width = IO.console.winsize.last
109
+ # Might have to trim if it's a little too wide
110
+ new_info = new_info[0...console_width] if console_width < new_info_length
111
+ # Arrow down to the info line
112
+ print (27.chr + 91.chr + 66.chr) * (height - (position - (offset || 0)) - (height < words.length ? 1 : 0))
113
+ # To start of info line
114
+ word_length = uncolor.call(words[position]).length + pre_post_length
115
+ print "\b" * word_length
116
+ # Write out the new response
117
+ prev_info_length = uncolor.call(info).length
118
+ difference = prev_info_length - new_info_length
119
+ difference = 0 if difference < 0
120
+ print new_info + " " * difference
121
+ info = new_info
122
+ # Go up to where we originated
123
+ print (27.chr + 91.chr + 65.chr) * (height - (position - (offset || 0)) - (height < words.length ? 1 : 0))
124
+ # Arrow left or right to get to the right spot again
125
+ new_info_length += difference
126
+ print (new_info_length > word_length ? "\b" : (27.chr + 91.chr + 67.chr)) * (new_info_length - word_length).abs
127
+ end
128
+
129
+ handle_on_select = lambda do |focused|
130
+ if on_select.is_a? Proc
131
+ response = on_select.call({chosen: chosen, focused: focused})
132
+ new_info = nil
133
+ if response.is_a? Hash
134
+ chosen = response[:chosen] || chosen
135
+ new_info = response[:info]
136
+ elsif response.is_a? String
137
+ new_info = response
138
+ end
139
+ unless new_info.nil?
140
+ write_info.call(new_info)
141
+ end
142
+ end
143
+ end
144
+
100
145
  arrow_down = lambda do
101
146
  if position < words.length - 1
147
+ handle_on_select.call(word_objects[position + 1])
102
148
  is_shift = false
103
149
  # Now moving down past the bottom of the shown window?
104
150
  if !offset.nil? && position >= offset + (height - 3)
@@ -127,6 +173,7 @@ module FancyGets
127
173
 
128
174
  arrow_up = lambda do
129
175
  if position > 0
176
+ handle_on_select.call(word_objects[position - 1])
130
177
  is_shift = false
131
178
  # Now moving up past the top of the shown window?
132
179
  if position <= (offset || 0)
@@ -164,6 +211,24 @@ module FancyGets
164
211
  else
165
212
  chosen = []
166
213
  end
214
+ when "Array"
215
+ chosen.each_with_index do |item, i|
216
+ case item.class.name
217
+ when "String"
218
+ chosen[i] = words.index(item)
219
+ when "Fixnum"
220
+ chosen[i] = nil if item < 0 || item >= words.length
221
+ else
222
+ chosen[i] = word_objects.index(item)
223
+ end
224
+ end
225
+ chosen.select{|item| !item.nil?}.uniq
226
+ else
227
+ if word_objects.include?(chosen)
228
+ chosen = [word_objects.index(chosen)]
229
+ else
230
+ chosen = []
231
+ end
167
232
  end
168
233
  chosen ||= []
169
234
  chosen = [0] if chosen == [] && !is_multiple
@@ -295,12 +360,29 @@ module FancyGets
295
360
  if is_multiple
296
361
  # Toggle this entry
297
362
  does_include = chosen.include?(position)
298
- if does_include
299
- chosen -= [position]
300
- else
301
- chosen += [position]
363
+ is_rejected = false
364
+ if on_change.is_a? Proc
365
+ response = on_change.call({chosen: chosen, changed: word_objects[position], is_chosen: !does_include})
366
+ new_info = nil
367
+ if response.is_a? Hash
368
+ is_rejected = response[:is_rejected]
369
+ chosen = response[:chosen] || chosen
370
+ new_info = response[:info]
371
+ elsif response.is_a? String
372
+ new_info = response
373
+ end
374
+ unless new_info.nil?
375
+ write_info.call(new_info)
376
+ end
377
+ end
378
+ unless is_rejected
379
+ if does_include
380
+ chosen -= [position]
381
+ else
382
+ chosen += [position]
383
+ end
384
+ make_select.call(!does_include, true)
302
385
  end
303
- make_select.call(!does_include, true)
304
386
  end
305
387
  when "j" # Down
306
388
  arrow_down.call
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fancy_gets
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lorin Thwaits
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-09-10 00:00:00.000000000 Z
11
+ date: 2016-09-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler