fancy_gets 0.1.5 → 0.1.6

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: 77bf7ba22ad95c65d42649eb16261214fb9ae5eb
4
- data.tar.gz: 00e074cd4911c829b20128c3da56ff5f48c1e9ab
3
+ metadata.gz: 9efa398b5efae7c257b7db93c326bdca21a590f4
4
+ data.tar.gz: 84b22e1be7a644315a96f6b578638f11d09560da
5
5
  SHA512:
6
- metadata.gz: dc71e4648a88261ecbeaa3239e3bef66c91d1e85a80d7645b5db6a8b6fb72cd24c35723f6143a7cb638c3fbc351d68942ca1c1031b1211013180c4cda290c6b5
7
- data.tar.gz: 68b1d41ee9817c6784022595a0299562d92b57984f3320c9d5ed91df7013829d06613b2634a1ab04659aee592b3d052650ebd599cd323e9d333248ad816274e0
6
+ metadata.gz: bd46857742342f3e1e7a4e875a233c789c80c606bcc2749d7345a65c31224d130b25a7cddf880b1b11a7737831d872c781c196a458a46bc892dccd7074297549
7
+ data.tar.gz: eb1470ff54a0d99c48602af296e4e44f7f6d0b88ed808db05e406739efe4942c5396982727b83957ab5fbadf9debae471d8a85d3bf0c7f891e28c97007f1905d
@@ -55,10 +55,12 @@ module FancyGets
55
55
  end
56
56
  end
57
57
  position = 0
58
- height = words.length unless !height.nil? && height.is_a?(Numeric) && height > 2
58
+ # After tweaking the down arrow code, might work OK with 3 things
59
+ height = words.length unless !height.nil? && height.is_a?(Numeric) && height >= 4
59
60
  winheight = IO.console.winsize.first - 3
61
+ height = words.length if height > words.length
60
62
  height = winheight if height > winheight
61
- offset = (height < words.length) ? 0 : nil
63
+ offset = 0
62
64
  sugg = ""
63
65
  prev_sugg = ""
64
66
 
@@ -79,12 +81,14 @@ module FancyGets
79
81
  " - #{sugg}#{" " * extra_spaces} #{"\b" * ((uncolor.call(sugg).length + 4 + extra_spaces) + string.length - position)}"
80
82
  end
81
83
 
82
- pre_post_length = uncolor.call(prefix + postfix).length
84
+ pre_length = uncolor.call(prefix).length
85
+ post_length = uncolor.call(postfix).length
86
+ pre_post_length = pre_length + post_length
83
87
 
84
88
  # Used for dropdown select / deselect
85
89
  clear_dropdown_info = lambda do
86
90
  print "\b" * (uncolor.call(words[position]).length + pre_post_length)
87
- print (27.chr + 91.chr + 66.chr) * (height - (position - (offset || 0)) - (height < words.length ? 1 : 0))
91
+ print (27.chr + 91.chr + 66.chr) * ((height + offset) - position)
88
92
  info_length = uncolor.call(info).length
89
93
  print " " * info_length + "\b" * info_length
90
94
  end
@@ -94,7 +98,7 @@ module FancyGets
94
98
  if is_select
95
99
  print "#{prefix}#{word}#{postfix}"
96
100
  else
97
- print "#{" " * uncolor.call(prefix).length}#{word}#{" " * uncolor.call(postfix).length}"
101
+ print "#{" " * pre_length}#{word}#{" " * post_length}"
98
102
  end
99
103
  print " " * (max_word_length - uncolor.call(words[position]).length)
100
104
  print "\b" * (max_word_length - uncolor.call(words[position]).length)
@@ -109,7 +113,8 @@ module FancyGets
109
113
  # Might have to trim if it's a little too wide
110
114
  new_info = new_info[0...console_width] if console_width < new_info_length
111
115
  # Arrow down to the info line
112
- print (27.chr + 91.chr + 66.chr) * (height - (position - (offset || 0)) - (height < words.length ? 1 : 0))
116
+ distance_down = (height + offset) - position
117
+ print (27.chr + 91.chr + 66.chr) * distance_down
113
118
  # To start of info line
114
119
  word_length = uncolor.call(words[position]).length + pre_post_length
115
120
  print "\b" * word_length
@@ -120,7 +125,7 @@ module FancyGets
120
125
  print new_info + " " * difference
121
126
  info = new_info
122
127
  # Go up to where we originated
123
- print (27.chr + 91.chr + 65.chr) * (height - (position - (offset || 0)) - (height < words.length ? 1 : 0))
128
+ print (27.chr + 91.chr + 65.chr) * distance_down
124
129
  # Arrow left or right to get to the right spot again
125
130
  new_info_length += difference
126
131
  print (new_info_length > word_length ? "\b" : (27.chr + 91.chr + 67.chr)) * (new_info_length - word_length).abs
@@ -142,19 +147,27 @@ module FancyGets
142
147
  end
143
148
  end
144
149
 
150
+ # **********************************************
151
+ # ******************** DOWN ********************
152
+ # Doesn't work with a height of 3 when there's more than 3 in the list
153
+ # (somehow up arrow can work OK with this)
145
154
  arrow_down = lambda do
146
155
  if position < words.length - 1
147
- handle_on_select.call(word_objects[position + 1])
148
156
  is_shift = false
157
+ handle_on_select.call(word_objects[position + 1])
149
158
  # Now moving down past the bottom of the shown window?
150
- if !offset.nil? && position >= offset + (height - 3)
159
+ is_before_end = height + offset < words.length
160
+ if is_before_end && position == (height - 2) + offset
151
161
  print "\b" * (uncolor.call(words[position]).length + pre_post_length)
152
- print (27.chr + 91.chr + 65.chr) * (height - (offset > 0 ? 3 : 3))
162
+ print (27.chr + 91.chr + 65.chr) * (height - 3)
163
+ if offset == 0
164
+ print (27.chr + 91.chr + 65.chr)
165
+ puts "#{" " * pre_length}#{"↑" * max_word_length}"
166
+ end
153
167
  offset += 1
154
- # Add 1 if offset + height == (words.length - 1)
155
- (offset...(offset + height - 4)).each do |i|
168
+ ((offset + 1)..(offset + (height - 4))).each do |i|
156
169
  end_fill = max_word_length - uncolor.call(words[i]).length
157
- puts (is_multiple && chosen.include?(i)) ? "#{prefix}#{words[i]}#{postfix}#{" " * end_fill}" : "#{" " * uncolor.call(prefix).length}#{words[i]}#{" " * (end_fill + uncolor.call(postfix).length)}"
170
+ puts (is_multiple && chosen.include?(i)) ? "#{prefix}#{words[i]}#{postfix}#{" " * end_fill}" : "#{" " * pre_length}#{words[i]}#{" " * (end_fill + post_length)}"
158
171
  end
159
172
  is_shift = true
160
173
  end
@@ -163,6 +176,13 @@ module FancyGets
163
176
  position += 1
164
177
  print 27.chr + 91.chr + 66.chr
165
178
  if is_shift || !is_multiple
179
+ if is_shift && height + offset == words.length # Go down and write the last one
180
+ print 27.chr + 91.chr + 66.chr
181
+ position += 1
182
+ make_select.call(is_shift && chosen.include?(position), false, true)
183
+ print 27.chr + 91.chr + 65.chr # And back up
184
+ position -= 1
185
+ end
166
186
  make_select.call((chosen.include?(position) && is_shift) || !is_multiple)
167
187
  else
168
188
  w2 = uncolor.call(words[position]).length
@@ -171,28 +191,42 @@ module FancyGets
171
191
  end
172
192
  end
173
193
 
194
+ # **********************************************
195
+ # ********************** UP ********************
174
196
  arrow_up = lambda do
175
197
  if position > 0
176
- handle_on_select.call(word_objects[position - 1])
177
198
  is_shift = false
199
+ handle_on_select.call(word_objects[position - 1])
178
200
  # Now moving up past the top of the shown window?
179
- if position <= (offset || 0)
201
+ if position > 1 && position <= offset + 1 # - (offset > 1 ? 0 : -1)
180
202
  print "\b" * (uncolor.call(words[position]).length + pre_post_length)
181
203
  offset -= 1
182
- # print (27.chr + 91.chr + 65.chr) if offset == 0
183
- (offset...(offset + height - 2)).each do |i|
204
+ # Up next to the top, and write the first word over the up arrows
205
+ if offset == 0
206
+ print (27.chr + 91.chr + 65.chr)
207
+ end_fill = max_word_length - uncolor.call(words[0]).length
208
+ puts (is_multiple && chosen.include?(0)) ? "#{prefix}#{words[0]}#{postfix}#{" " * end_fill}" : "#{" " * pre_length}#{words[0]}#{" " * (end_fill + post_length)}"
209
+ end
210
+ ((offset + 1)..(offset + height - 2)).each do |i|
184
211
  end_fill = max_word_length - uncolor.call(words[i]).length
185
- puts (is_multiple && chosen.include?(i)) ? "#{prefix}#{words[i]}#{postfix}#{" " * end_fill}" : "#{" " * uncolor.call(prefix).length}#{words[i]}#{" " * (end_fill + uncolor.call(postfix).length)}"
212
+ puts ((!is_multiple && i == (offset + 1)) || (is_multiple && chosen.include?(i))) ? "#{prefix}#{words[i]}#{postfix}#{" " * end_fill}" : "#{" " * pre_length}#{words[i]}#{" " * (end_fill + post_length)}"
213
+ end
214
+ if offset == words.length - height - 1
215
+ puts "#{" " * pre_length}#{"↓" * max_word_length}"
216
+ print (27.chr + 91.chr + 65.chr)
186
217
  end
187
- print (27.chr + 91.chr + 65.chr) * (height - (offset > 0 ? 3 : 3))
218
+ print (27.chr + 91.chr + 65.chr) * (height - 2)
188
219
  is_shift = true
220
+ position -= 1
221
+ w1 = -pre_post_length
222
+ else
223
+ make_select.call(chosen.include?(position) && is_shift && is_multiple, true, true) if is_shift || !is_multiple
224
+ w1 = uncolor.call(words[position]).length
225
+ position -= 1
226
+ print 27.chr + 91.chr + 65.chr
189
227
  end
190
- make_select.call(chosen.include?(position) && is_shift && is_multiple, true, true) if is_shift || !is_multiple
191
- w1 = uncolor.call(words[position]).length
192
- position -= 1
193
- print 27.chr + 91.chr + 65.chr
194
- if is_shift || !is_multiple
195
- make_select.call((chosen.include?(position) && is_shift) || !is_multiple)
228
+ if !is_shift && !is_multiple
229
+ make_select.call(chosen.include?(position) || !is_multiple)
196
230
  else
197
231
  w2 = uncolor.call(words[position]).length
198
232
  print (w1 > w2 ? "\b" : (27.chr + 91.chr + 67.chr)) * (w1 - w2).abs
@@ -200,6 +234,7 @@ module FancyGets
200
234
  end
201
235
  end
202
236
 
237
+ # Initialize everything
203
238
  if is_list
204
239
  # Maybe confirm the height is adequate by checking out IO.console.winsize
205
240
  case chosen.class.name
@@ -234,28 +269,29 @@ module FancyGets
234
269
  chosen = [0] if chosen == [] && !is_multiple
235
270
  position = chosen.first if chosen.length > 0
236
271
  # If there's more options than we can fit at once
237
- unless offset.nil?
272
+ if height < words.length
238
273
  # ... put the chosen one a third of the way down the screen
239
274
  offset = position - (height / 3)
240
- offset = 0 if offset < 0
275
+ offset = words.length - height if offset > words.length - height
241
276
  end
277
+
278
+ # **********************************************
279
+ # **********************************************
280
+ # **********************************************
281
+ # **********************************************
282
+ # **********************************************
283
+
242
284
  # Scrolled any amount downwards?
243
- # was: if (offset || 0) > 0
244
- puts "#{" " * uncolor.call(prefix).length}#{"↑" * max_word_length}" if height < words.length
245
- # was: ((offset || 0) > 1 ? 2 : 1)
246
- top_bottom_reserved = offset.nil? ? 0 : 2
247
- last_word = (offset || 0) + height - top_bottom_reserved
248
- # Maybe we can fit it all
249
- last_word = words.length if last_word > words.length
285
+ # was: if height < words.length
286
+ puts "#{" " * pre_length}#{"↑" * max_word_length}" if offset > 0
287
+ last_word = (height - 2) + offset + (height + offset < words.length ? 0 : 1)
250
288
  # Write all the visible words
251
- ((offset || 0)...last_word).each { |i| puts chosen.include?(i) ? "#{prefix}#{words[i]}#{postfix}" : "#{" " * uncolor.call(prefix).length}#{words[i]}" }
289
+ ((offset + (offset > 0 ? 1 : 0))..last_word).each { |i| puts chosen.include?(i) ? "#{prefix}#{words[i]}#{postfix}" : "#{" " * pre_length}#{words[i]}" }
252
290
  # Can't fit it all?
253
- # was: if last_word < (words.length - top_bottom_reserved)
254
- puts "#{" " * uncolor.call(prefix).length}#{"↓" * max_word_length}" if height < words.length
291
+ puts "#{" " * pre_length}#{"↓" * max_word_length}" if height + offset < words.length
255
292
 
256
293
  info ||= "Use arrow keys#{is_multiple ? ", spacebar to toggle, and ENTER to save" : " and ENTER to make a choice"}"
257
- # %%% used to be (words.length - position), and then (last_word <= words.length)
258
- print info + (27.chr + 91.chr + 65.chr) * (height - (position - (offset || 0)) - (height < words.length ? 1 : 0))
294
+ print info + (27.chr + 91.chr + 65.chr) * ((last_word - position) + (height + offset < words.length ? 2 : 1))
259
295
  # To end of text on starting line
260
296
  info_length = uncolor.call(info).length
261
297
  word_length = uncolor.call(words[position]).length + pre_post_length
@@ -274,6 +310,7 @@ module FancyGets
274
310
  case code
275
311
  when 3 # CTRL-C
276
312
  clear_dropdown_info.call if is_list
313
+ # puts "o: #{offset} p: #{position} h: #{height} wl: #{words.length}"
277
314
  exit
278
315
  when 13 # ENTER
279
316
  if is_list
@@ -362,11 +399,22 @@ module FancyGets
362
399
  does_include = chosen.include?(position)
363
400
  is_rejected = false
364
401
  if on_change.is_a? Proc
365
- response = on_change.call({chosen: chosen, changed: word_objects[position], is_chosen: !does_include})
402
+ # Generate what would happen if this change goes through
403
+ if does_include
404
+ new_chosen = chosen - [position]
405
+ else
406
+ new_chosen = chosen + [position]
407
+ end
408
+ chosen_objects = new_chosen.sort.map{|choice| word_objects[choice]}
409
+ response = on_change.call({chosen: chosen_objects, changed: word_objects[position], is_chosen: !does_include})
366
410
  new_info = nil
367
411
  if response.is_a? Hash
368
412
  is_rejected = response[:is_rejected]
369
- chosen = response[:chosen] || chosen
413
+ # If they told us exactly what the choices should now be, make that happen
414
+ if !response.nil? && response[:chosen].is_a?(Enumerable)
415
+ chosen = response[:chosen].map {|choice| word_objects.index(choice)}
416
+ is_rejected = true
417
+ end
370
418
  new_info = response[:info]
371
419
  elsif response.is_a? String
372
420
  new_info = response
@@ -383,6 +431,10 @@ module FancyGets
383
431
  end
384
432
  make_select.call(!does_include, true)
385
433
  end
434
+ else
435
+ # Allows Windows to have a way to at least use single-select lists
436
+ clear_dropdown_info.call
437
+ break
386
438
  end
387
439
  when "j" # Down
388
440
  arrow_down.call
@@ -406,7 +458,7 @@ module FancyGets
406
458
 
407
459
  if is_list
408
460
  # Put chosen stuff in same order as it's listed in the words array
409
- is_multiple ? chosen.map {|c| word_objects[c] } : word_objects[position]
461
+ is_multiple ? chosen.sort.map {|c| word_objects[c] } : word_objects[position]
410
462
  else
411
463
  sugg.empty? ? string : word_objects[words.index(sugg)]
412
464
  end
@@ -1,3 +1,3 @@
1
1
  module FancyGets
2
- VERSION = "0.1.5"
2
+ VERSION = "0.1.6"
3
3
  end
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.5
4
+ version: 0.1.6
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-11 00:00:00.000000000 Z
11
+ date: 2016-09-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler