Skip to content

Instantly share code, notes, and snippets.

@narutaro
Created September 6, 2020 02:26
Show Gist options
  • Save narutaro/137c39c483cdde4fdbaedf6f6c73452c to your computer and use it in GitHub Desktop.
Save narutaro/137c39c483cdde4fdbaedf6f6c73452c to your computer and use it in GitHub Desktop.
[Tab completion with multi-command] #repl #tab
require "readline"
require "yaml"
command_tree = {"pet"=>
{"buy"=>{"dog"=>nil, "cat"=>nil},
"sell"=>{"bird"=>nil, "fox"=>nil},
"sellGroup"=>{"pig"=>nil, "kingfisher"=>nil},
"list"=>{"all"=>nil, "filter_by"=>nil}},
"store"=>
{"find"=>{"by_name"=>nil, "by_tag"=>nil, "by_address"=>nil}, "list"=>nil},
"user"=>{"login"=>nil, "logout"=>nil, "sign_up"=>nil},
"petGroup"=>{"login"=>nil, "loout"=>nil, "sign_up"=>nil},
}
pp command_tree
def get_current_option(command_tree, line_buffer)
current_option = command_tree.keys
commands = line_buffer.split
commands.each_with_index do |command, i|
# Don't go down to the lower level(and return current_option) in case current command matches two candidates such as "pet" and "petGroup"
return current_option if i == commands.size-1 and !line_buffer.end_with?("\s")
# Go down
if command_tree.has_key?(command)
if command_tree[command].nil? # invalid command or key at leaf
current_option = []
else
command_tree = command_tree[command]
current_option = command_tree.keys
end
end
end
current_option
end
# Evaluate the proc when pressing <tab>
comp = proc do |input|
get_current_option(command_tree, Readline.line_buffer).select { |name| name.to_s.start_with?(input) }
end
Readline.completion_proc = comp
#Readline.completion_append_character = " "
while input = Readline.readline("$ ", true)
break if input == "q"
p Readline.line_buffer.split if !input.empty?
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment