lux-hammer 0.3.21 → 0.3.23

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
  SHA256:
3
- metadata.gz: 84a9d6339d8a34112c31a210823398ea9122959fff9d3522562f840147e8a130
4
- data.tar.gz: f7483553452c4e33d18dad6d9d4e2b764cb13a49a4080ea90f4227689f9fc211
3
+ metadata.gz: 74dd44bca6cf689dcfe0396d90e05e51b0605821314fb6d5b742502662f4e8e8
4
+ data.tar.gz: a84eaa4fcce83f951905bab3419d18adfcce409cd0f9d2f23db910569443a2ce
5
5
  SHA512:
6
- metadata.gz: e5158a762b7cb292535f58e33b0a8ae84c2f9affe473501cce701784d5a690bebf5c187e3c588df66821a5cd3f3177f83d655149e84426ea8e9a12c578e7e5c8
7
- data.tar.gz: 5711d908d489770a4ede0507224f0a6cf3dbe761edddaed0f6c4591b0e1a1e070e4727f8000829c861cc215be8baf238933b6591d996bb8ee500742d70d22aa5
6
+ metadata.gz: 044a31c525aba212012888f39d938fa37dc2e69e59097fa10f1dda53723b0a267dae2dad0e77887c19ad801a64fcb47e03b8aa95d916b04474d5239628a9b8f0
7
+ data.tar.gz: 3ec9940429c06e4bfb00669184fe3d4f78fff0ed693f857fcd37c682bf89b70a214f3a7e92e24826a1ab5889c62de26f05e0f9b78fe22c1c65b12227d4a18681
data/.version CHANGED
@@ -1 +1 @@
1
- 0.3.21
1
+ 0.3.23
data/lib/hammer/shell.rb CHANGED
@@ -88,26 +88,43 @@ class Hammer
88
88
  #
89
89
  # idx = choose 'Pick env', %w[dev staging prod]
90
90
  # say.green "chose #{ %w[dev staging prod][idx] }" if idx
91
- def choose(prompt, items)
91
+ #
92
+ # `skip` marks rows that are shown but never landed on, so a list can
93
+ # carry its own headings and rules. They are drawn in gray, the cursor
94
+ # steps over them, and the returned index still counts every row:
95
+ #
96
+ # choose 'Pick', ['-- fast --', 'dev', '-- slow --', 'prod'],
97
+ # skip: ->(item) { item.start_with?('--') }
98
+ def choose(prompt, items, skip: nil)
92
99
  items = items.to_a
93
100
  error 'choose needs at least one item' if items.empty?
94
101
 
102
+ live = items.each_index.reject { |i| skip&.call(items[i]) }
103
+ error 'choose needs at least one selectable item' if live.empty?
104
+
95
105
  say.cyan prompt
96
106
 
97
- return choose_numbered(items) unless $stdin.tty? && $stdin.respond_to?(:raw)
107
+ return choose_numbered(items, live) unless $stdin.tty? && $stdin.respond_to?(:raw)
98
108
 
99
- selected = 0
109
+ selected = live.first
100
110
  # In raw mode \n is not translated to \r\n, so the picker uses \r\n
101
111
  # explicitly. The initial draw happens in cooked mode but \r\n is
102
112
  # harmless there.
103
113
  redraw = lambda do |highlight = :cyan|
104
114
  items.each_with_index do |item, i|
105
- line = i == selected ? paint("> #{item}", highlight) : " #{item}"
115
+ line = if !live.include?(i) then paint(" #{item}", :gray)
116
+ elsif i == selected then paint("> #{item}", highlight)
117
+ else " #{item}"
118
+ end
106
119
  $stdout.print "#{line}\r\n"
107
120
  end
108
121
  end
109
122
  redraw.call
110
123
 
124
+ # Move by position among the selectable rows, so skipped ones are
125
+ # stepped over in both directions and the wrap-around still works.
126
+ step = ->(dir) { live[(live.index(selected) + dir) % live.size] }
127
+
111
128
  $stdout.print "\e[?25l" # hide cursor
112
129
  begin
113
130
  $stdin.raw do |io|
@@ -126,15 +143,15 @@ class Hammer
126
143
  # ESC may stand alone or start an arrow sequence \e[A / \e[B.
127
144
  if IO.select([io], nil, nil, 0.01) && io.getch == '['
128
145
  case io.getch
129
- when 'A' then selected = (selected - 1) % items.size
130
- when 'B' then selected = (selected + 1) % items.size
146
+ when 'A' then selected = step.call(-1)
147
+ when 'B' then selected = step.call(1)
131
148
  end
132
149
  else
133
150
  $stdout.print "\e[#{items.size}A\r\e[J"
134
151
  return nil
135
152
  end
136
- when 'k' then selected = (selected - 1) % items.size
137
- when 'j' then selected = (selected + 1) % items.size
153
+ when 'k' then selected = step.call(-1)
154
+ when 'j' then selected = step.call(1)
138
155
  end
139
156
  $stdout.print "\e[#{items.size}A\r\e[J"
140
157
  redraw.call
@@ -146,13 +163,17 @@ class Hammer
146
163
  end
147
164
 
148
165
  # Fallback for non-TTY stdin (pipes, tests). Returns the index or nil.
149
- def choose_numbered(items)
150
- items.each_with_index { |item, i| puts " #{i + 1}) #{item}" }
151
- print paint("select [1-#{items.size}]: ", :cyan)
166
+ # Skipped rows are still printed, just without a number to type.
167
+ def choose_numbered(items, live = items.each_index.to_a)
168
+ items.each_with_index do |item, i|
169
+ n = live.index(i)
170
+ puts n ? " #{n + 1}) #{item}" : " #{item}"
171
+ end
172
+ print paint("select [1-#{live.size}]: ", :cyan)
152
173
  line = $stdin.gets
153
174
  return nil if line.nil?
154
175
  idx = line.strip.to_i - 1
155
- idx.between?(0, items.size - 1) ? idx : nil
176
+ idx.between?(0, live.size - 1) ? live[idx] : nil
156
177
  end
157
178
 
158
179
  # Run a shell command. Echoes the command in gray, raises