Method: HookApp#select_hook

Defined in:
lib/hook/hookapp.rb

#select_hook(marks) ⇒ Object

Generate a menu of available hooks for selecting one or more hooks to operate on. Revamped to use ‘fzf`, which is embedded as `lib/helpers/fuzzyfilefinder` to avoid any conflicts. Allows multiple selections with tab key, and type-ahead fuzzy filtering of results.



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
# File 'lib/hook/hookapp.rb', line 200

def select_hook(marks)
  # intpad = marks.length.to_s.length + 1
  # marks.each_with_index do |mark, i|
  #   STDERR.printf "%#{intpad}d) %s\n", i + 1, mark[:name]
  # end
  # STDERR.print 'Open which bookmark: '
  # sel = STDIN.gets.strip.to_i
  # raise 'Invalid selection' unless sel.positive? && sel <= marks.length

  # marks[sel - 1]

  options = marks.map do |mark|
    if mark[:name]
      id = mark[:name]
    elsif mark[:path]
      id = mark[:path]
    elsif mark[:url]
      id = mark[:url]
    else
      return false
    end

    if mark[:path]
      loc = File.dirname(mark[:path])
    elsif mark[:url]
      url = URI.parse(mark[:url])
      id = mark[:url]
      loc = "#{url.scheme} + ' - ' + url.hostname"
    else
      loc = ''
    end

    "#{id}\t#{mark[:path]}\t#{mark[:url]}\t#{loc}"
  end

  options.delete_if(&:!)

  raise 'Error processing available hooks' if options.empty?

  args = ['--layout=reverse-list',
          '--header="esc: cancel, tab: multi-select, ctrl-a: select all, return: open"',
          '--bind ctrl-a:select-all',
          '--prompt="  Select hooks > "',
          '--multi',
          '--tabstop=4',
          '--delimiter="\t"',
          '--with-nth=1,4',
          '--height=60%',
          '--min-height=10']

  sel = `echo #{Shellwords.escape(options.join("\n"))} | '#{fzf}' #{args.join(' ')}`.chomp

  res = sel.split(/\n/).map do |s|
    ps = s.split(/\t/)
    { name: ps[0], path: ps[1], url: ps[2] }
  end

  res || []
end