Method: HackTree::Instance#completion_logic

Defined in:
lib/hack_tree/instance.rb

#completion_logic(input, options = {}) ⇒ Object

Perform logic needed to do IRB completion. Returns Array if completion is handled successfully, nil if input is not related to HackTree.

completion_logic("c.he", :enabled_as => :c)    # => ["c.hello"]

Raises:

  • (ArgumentError)


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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/hack_tree/instance.rb', line 59

def completion_logic(input, options = {})
  o = {}
  options = options.dup

  o[k = :enabled_as] = options.delete(k)

  raise ArgumentError, "Unknown option(s): #{options.inspect}" if not options.empty?
  raise ArgumentError, "options[:enabled_as] must be given" if not o[:enabled_as]

  # Check if this input is related to us.
  if not mat = input.match(/\A#{o[:enabled_as]}\.((?:[^.].*)|)\z/)
    return nil
  end

  lookup = mat[1]

  # Parse lookup string into node name and prefix.
  global_name, prefix = if mat = lookup.match(/\A(?:([^.]*)|(.+)\.(.*?))\z/)
    if mat[1]
      # "something".
      ["", mat[1]]
    else
      # "something.other", "something.other.other.".
      [mat[2], mat[3]]
    end
  else
    # Handle no match just in case.
    ["", ""]
  end

  base = if global_name == ""
    # Base is root.
    nil
  else
    # Find a named base node. If not found, return no candidates right away.
    find_node(global_name) or return []
  end
  
  # Select sub-nodes.
  candidates = children_of(base).select do |node|
    # Select those matching `prefix`.
    node.name.to_s.index(prefix) == 0
  end.map do |node|
    # Provide 1+ candidates per item.
    case node
    when Node::Group
      # A neat trick to prevent IRB from appending a " " after group name.
      [node.name, "#{node.name}."]
    else
      [node.name]
    end.map(&:to_s)
  end.flatten(1).map do |s|
    # Convert to final names.
    [
      "#{o[:enabled_as]}.",
      ("#{global_name}." if global_name != ""),
      s,
    ].compact.join
  end

  candidates
end