Added support for Console auto-complete

This commit is contained in:
2019-08-08 20:23:48 -05:00
parent c89586c286
commit a82e71cea7
5 changed files with 71 additions and 8 deletions

View File

@@ -1,5 +1,6 @@
require "fiddle" require "fiddle"
require "yaml" require "yaml"
require "abbrev"
require "opengl" require "opengl"
require "glu" require "glu"

View File

@@ -26,7 +26,10 @@ class IMICFPS
@list ||= [] @list ||= []
@commands = [] @commands = []
@list.each do |subclass| @list.each do |subclass|
@commands << subclass.new cmd = subclass.new
raise "Command '#{cmd.command}' from '#{cmd.class}' already exists!" if @commands.detect { |c| c.command == cmd.command }
@commands << cmd
end end
end end
@@ -58,6 +61,7 @@ class IMICFPS
def setup; end def setup; end
def subcommand(command, type) def subcommand(command, type)
raise "Subcommand '#{command}' for '#{self.command}' already exists!" if @subcommands.detect { |subcmd| subcmd.command == command.to_sym }
@subcommands << SubCommand.new(self, command, type) @subcommands << SubCommand.new(self, command, type)
end end
@@ -81,6 +85,9 @@ class IMICFPS
raise NotImplementedError raise NotImplementedError
end end
def autocomplete(console)
end
def handle_subcommand(arguments, console) def handle_subcommand(arguments, console)
if arguments.size == 0 if arguments.size == 0
console.stdin(usage) console.stdin(usage)
@@ -113,6 +120,11 @@ class IMICFPS
end end
def handle(arguments, console) def handle(arguments, console)
if arguments.size > 1
console.stdin("to many arguments for #{Style.highlight("#{command}")}, got #{Style.error(arguments.size)} expected #{Style.notice(1)}.")
return
end
case @type case @type
when :boolean when :boolean
case arguments.last case arguments.last
@@ -125,6 +137,8 @@ class IMICFPS
when "off" when "off"
var = @parent.set(command.to_sym, false) var = @parent.set(command.to_sym, false)
console.stdin("#{command} => #{Style.highlight(var)}") console.stdin("#{command} => #{Style.highlight(var)}")
else
console.stdin("Invalid argument for #{Style.highlight("#{command}")}, got #{Style.error(arguments.last)} expected #{Style.notice("on")}, or #{Style.notice("off")}.")
end end
when :string when :string
case arguments.last case arguments.last
@@ -141,8 +155,12 @@ class IMICFPS
var = @parent.get(command.to_sym) ? @parent.get(command.to_sym) : "nil" var = @parent.get(command.to_sym) ? @parent.get(command.to_sym) : "nil"
console.stdin("#{command}: #{Style.highlight(var)}") console.stdin("#{command}: #{Style.highlight(var)}")
else else
var = @parent.set(command.to_sym, arguments.last.to_i) begin
console.stdin("#{command} => #{Style.highlight(var)}") var = @parent.set(command.to_sym, Integer(arguments.last))
console.stdin("#{command} => #{Style.highlight(var)}")
rescue ArgumentError
console.stdin("Error: #{Style.error("Expected an integer, got '#{arguments.last}'")}")
end
end end
when :decimal when :decimal
case arguments.last case arguments.last
@@ -150,8 +168,12 @@ class IMICFPS
var = @parent.get(command.to_sym) ? @parent.get(command.to_sym) : "nil" var = @parent.get(command.to_sym) ? @parent.get(command.to_sym) : "nil"
console.stdin("#{command}: #{Style.highlight(var)}") console.stdin("#{command}: #{Style.highlight(var)}")
else else
var = @parent.set(command.to_sym, arguments.last.to_f) begin
console.stdin("#{command} => #{Style.highlight(var)}") var = @parent.set(command.to_sym, Float(arguments.last))
console.stdin("#{command} => #{Style.highlight(var)}")
rescue ArgumentError
console.stdin("Error: #{Style.error("Expected a decimal or integer, got '#{arguments.last}'")}")
end
end end
else else
raise RuntimeError raise RuntimeError
@@ -163,11 +185,11 @@ class IMICFPS
when :boolean when :boolean
"#{Style.highlight(command)} #{Style.notice("[on|off]")}" "#{Style.highlight(command)} #{Style.notice("[on|off]")}"
when :string when :string
"#{Style.highlight(command)} #{Style.notice("[on|off]")}" "#{Style.highlight(command)} #{Style.notice("[string]")}"
when :integer when :integer
"#{Style.highlight(command)} #{Style.notice("[on|off]")}" "#{Style.highlight(command)} #{Style.notice("[0]")}"
when :decimal when :decimal
"#{Style.highlight(command)} #{Style.notice("[on|off]")}" "#{Style.highlight(command)} #{Style.notice("[0.0]")}"
end end
end end
end end

View File

@@ -10,6 +10,11 @@ class IMICFPS
end end
def handle(arguments, console) def handle(arguments, console)
if arguments.size > 1
console.stdin("to many arguments for #{Style.highlight("#{command}")}, got #{Style.error(arguments.size)} expected #{Style.notice(1)}.")
return
end
case arguments.last case arguments.last
when "", nil when "", nil
console.stdin("#{Style.highlight("fps")}: #{$debug.get(:fps)}") console.stdin("#{Style.highlight("fps")}: #{$debug.get(:fps)}")

View File

@@ -17,6 +17,8 @@ class IMICFPS
if command if command
if cmd = Command.find(command) if cmd = Command.find(command)
cmd.usage cmd.usage
else
"#{Style.error(command)} is not a command"
end end
else else
"Available commands:\n#{Command.list_commands.map { |cmd| "#{Style.highlight(cmd.command)}" }.join(', ')}" "Available commands:\n#{Command.list_commands.map { |cmd| "#{Style.highlight(cmd.command)}" }.join(', ')}"

View File

@@ -86,6 +86,24 @@ class IMICFPS
@text_input.text = @command_history[@command_history_index] @text_input.text = @command_history[@command_history_index]
end end
when Gosu::KbTab
split = @text_input.text.split(" ")
if !@text_input.text.end_with?(" ") && split.size == 1
list = command_search(@text_input.text)
if list.size == 1
@text_input.text = "#{list.first} "
else
@history.text += "\n#{list.map { |cmd| Commands::Style.highlight(cmd)}.join(", ")}"
update_history
end
else
if split.size > 0 && cmd = Commands::Command.find(split.first)
cmd.autocomplete(self)
end
end
when Gosu::KbBacktick when Gosu::KbBacktick
# Removed backtick character from input # Removed backtick character from input
if @text_input.text.size > 1 if @text_input.text.size > 1
@@ -112,6 +130,21 @@ class IMICFPS
IMICFPS::Commands::Command.use(command, arguments, self) IMICFPS::Commands::Command.use(command, arguments, self)
end end
def command_search(text)
return [] unless text.length > 0
@command_search ||= Abbrev.abbrev(Commands::Command.list_commands.map { |cmd| cmd.command.to_s})
list = []
@command_search.each do |abbrev, value|
next unless abbrev && abbrev.start_with?(text)
list << value
end
return list.uniq
end
def stdin(string) def stdin(string)
@history.text += "\n#{string}" @history.text += "\n#{string}"
update_history update_history