Class: Tabry::Replty::Builder

Inherits:
Object
  • Object
show all
Defined in:
lib/tabry/replty/builder.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config, repl) ⇒ Builder

TODO: implement before_action, after_action, sub-REPLs; share code in run_result with CLI::Builder



15
16
17
18
# File 'lib/tabry/replty/builder.rb', line 15

def initialize(config, repl)
  @runner = Tabry::Runner.new(config: config)
  @repl = repl
end

Instance Attribute Details

#replObject (readonly)

Returns the value of attribute repl.



11
12
13
# File 'lib/tabry/replty/builder.rb', line 11

def repl
  @repl
end

#runnerObject (readonly)

Returns the value of attribute runner.



11
12
13
# File 'lib/tabry/replty/builder.rb', line 11

def runner
  @runner
end

Instance Method Details

#load_history(file) ⇒ Object



27
28
29
30
31
32
33
34
35
36
# File 'lib/tabry/replty/builder.rb', line 27

def load_history(file)
  return unless file

  File.open(file) do |f|
    f.each do |l|
      Readline::HISTORY.push l.chomp
    end
  end
rescue Errno::ENOENT # rubocop:disable Lint/SuppressedException
end

#readlineObject



20
21
22
23
24
25
# File 'lib/tabry/replty/builder.rb', line 20

def readline
  Readline.readline(repl.tabry_prompt, true)
rescue Interrupt
  puts "^C"
  retry
end

#run(history_file: nil, tokenizer: ShellTokenizer) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/tabry/replty/builder.rb', line 53

def run(history_file: nil, tokenizer: ShellTokenizer)
  history_file = history_file&.gsub(%r{^~/}, "#{Dir.home}/")
  load_history(history_file)

  Readline.completion_proc = proc do
    cmd, args, last_arg = tokenizer.split_with_comppoint(Readline.line_buffer, Readline.point)
    options = runner.options([cmd, *args].compact, last_arg)
    options.map do |opt|
      # if opt is a symbol, it's a "opts method" option type -- where a REPL method returns the options.
      # TODO: a bit weird since the REPL's "args" and "flags" are wrong/old when that completion method is run
      # also filter to start_with? is more appropriate in tabry, not here, but whatever
      opt.is_a?(Symbol) ? repl.send(opt)&.select { |x| x.start_with?(last_arg) } : opt
    end.flatten
  end

  while (cmdline = readline)
    raw_args = tokenizer.split(cmdline)
    next if raw_args.empty?

    result = runner.parse(raw_args)
    # TODO: usage has "myrepl" (command name) in; also, "got 1 args" is confusing when command doesn't exist
    if result.help?
      puts result.usage
    elsif result.invalid_usage_reason
      puts "Invalid usage: #{result.invalid_usage_reason}"
      puts
      puts result.usage
    else
      run_result(raw_args, result)
    end
  end

  save_history(history_file)
end

#run_result(raw_args, result) ⇒ Object



88
89
90
91
92
93
94
95
96
97
# File 'lib/tabry/replty/builder.rb', line 88

def run_result(raw_args, result)
  met = result.state.subcommand_stack.join("__").gsub("-", "_")
  repl.internals = ::Tabry::CLI::Internals.new(
    runner: runner, raw_args: raw_args,
    state: result.state, met: met, result: result
  )
  catch(:tabry_replty_command_exit) do
    repl.send(met.to_sym)
  end
end

#save_history(file, max_size = 10_000) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/tabry/replty/builder.rb', line 38

def save_history(file, max_size = 10_000)
  return unless file

  history = Readline::HISTORY.each

  # Skip over excess elements:
  (Readline::HISTORY.length - max_size).times do
    history.next
  end

  File.open(file, "w") do |f|
    loop { f.puts history.next }
  end
end