summaryrefslogtreecommitdiffhomepage
path: root/dragon/console_prompt.rb
diff options
context:
space:
mode:
authorAmir Rajan <[email protected]>2020-07-25 16:46:32 -0500
committerAmir Rajan <[email protected]>2020-07-25 16:46:32 -0500
commit7fb2ac99d77e6f8c7506271f56cfdce766d5b2e3 (patch)
tree0a989bf292764a52da5ab1c888161a46750a31ea /dragon/console_prompt.rb
parentaac51e8b318920de32fca1c0dd82a0fbc5a1bbfd (diff)
downloaddragonruby-game-toolkit-contrib-7fb2ac99d77e6f8c7506271f56cfdce766d5b2e3.tar.gz
dragonruby-game-toolkit-contrib-7fb2ac99d77e6f8c7506271f56cfdce766d5b2e3.zip
added current docs
Diffstat (limited to 'dragon/console_prompt.rb')
-rw-r--r--dragon/console_prompt.rb157
1 files changed, 157 insertions, 0 deletions
diff --git a/dragon/console_prompt.rb b/dragon/console_prompt.rb
new file mode 100644
index 0000000..dd454f7
--- /dev/null
+++ b/dragon/console_prompt.rb
@@ -0,0 +1,157 @@
+# Copyright 2019 DragonRuby LLC
+# MIT License
+# console_prompt.rb has been released under MIT (*only this file*).
+
+# Contributors outside of DragonRuby who also hold Copyright:
+# - Kevin Fischer: https://github.com/kfischer-okarin
+
+module GTK
+ class Console
+ class Prompt
+ attr_accessor :current_input_str, :font_style, :console_text_width
+
+ def initialize(font_style:, text_color:, console_text_width:)
+ @prompt = '-> '
+ @current_input_str = ''
+ @font_style = font_style
+ @text_color = text_color
+ @cursor_color = Color.new [187, 21, 6]
+ @console_text_width = console_text_width
+
+ @last_autocomplete_prefix = nil
+ @next_candidate_index = 0
+ end
+
+ def <<(str)
+ @current_input_str << str
+ reset_autocomplete
+ end
+
+ def backspace
+ @current_input_str.chop!
+ reset_autocomplete
+ end
+
+ def clear
+ @current_input_str = ''
+ reset_autocomplete
+ end
+
+ def autocomplete
+ if !@last_autocomplete_prefix
+ @last_autocomplete_prefix = calc_autocomplete_prefix
+
+ puts "* AUTOCOMPLETE CANDIDATES: #{current_input_str}.."
+ pretty_print_strings_as_table method_candidates(@last_autocomplete_prefix)
+ else
+ candidates = method_candidates(@last_autocomplete_prefix)
+ return if candidates.empty?
+
+ candidate = candidates[@next_candidate_index]
+ candidate = candidate[0..-2] + " = " if candidate.end_with? '='
+ @next_candidate_index += 1
+ @next_candidate_index = 0 if @next_candidate_index >= candidates.length
+ self.current_input_str = display_autocomplete_candidate(candidate)
+ end
+ end
+
+ def pretty_print_strings_as_table items
+ if items.length == 0
+ puts <<-S.strip
++--------+
+| (none) |
++--------+
+S
+ else
+ # figure out the largest string
+ string_width = items.sort_by { |c| -c.to_s.length }.first
+
+ # add spacing to each side of the string which represents the cell width
+ cell_width = string_width.length + 2
+
+ # add spacing to each side of the cell to represent the column width
+ column_width = cell_width + 2
+
+ # determine the max number of columns that can fit on the screen
+ columns = @console_text_width.idiv column_width
+ columns = items.length if items.length < columns
+
+ # partition the original list of items into a string to be printed
+ items.each_slice(columns).each_with_index do |cells, i|
+ pretty_print_row_seperator string_width, cell_width, column_width, columns
+ pretty_print_row cells, string_width, cell_width, column_width, columns
+ end
+
+ pretty_print_row_seperator string_width, cell_width, column_width, columns
+ end
+ end
+
+ def pretty_print_row cells, string_width, cell_width, column_width, columns
+ # if the number of cells doesn't match the number of columns, then pad the array with empty values
+ cells += (columns - cells.length).map { "" }
+
+ # right align each cell value
+ formated_row = "|" + cells.map do |c|
+ "#{" " * (string_width.length - c.length) } #{c} |"
+ end.join
+
+ # remove seperators between empty values
+ formated_row = formated_row.gsub(" | ", " ")
+
+ puts formated_row
+ end
+
+ def pretty_print_row_seperator string_width, cell_width, column_width, columns
+ # this is a joint: +--------
+ column_joint = "+#{"-" * cell_width}"
+
+ # multiple joints create a row seperator: +----+----+
+ puts (column_joint * columns) + "+"
+ end
+
+ def render(args, x:, y:)
+ args.outputs.reserved << font_style.label(x: x, y: y, text: "#{@prompt}#{current_input_str}", color: @text_color)
+ args.outputs.reserved << font_style.label(x: x - 2, y: y + 3, text: (" " * (@prompt.length + current_input_str.length)) + "|", color: @cursor_color)
+ end
+
+ private
+
+ def last_period_index
+ current_input_str.rindex('.')
+ end
+
+ def calc_autocomplete_prefix
+ if last_period_index
+ current_input_str[(last_period_index + 1)..-1]
+ else
+ current_input_str
+ end
+ end
+
+ def current_object
+ return Kernel unless last_period_index
+
+ Kernel.eval(current_input_str[0...last_period_index])
+ rescue NameError
+ nil
+ end
+
+ def method_candidates(prefix)
+ current_object.autocomplete_methods.map(&:to_s).select { |m| m.start_with? prefix }
+ end
+
+ def display_autocomplete_candidate(candidate)
+ if last_period_index
+ @current_input_str[0..last_period_index] + candidate.to_s
+ else
+ candidate.to_s
+ end
+ end
+
+ def reset_autocomplete
+ @last_autocomplete_prefix = nil
+ @next_candidate_index = 0
+ end
+ end
+ end
+end