Class: VER::Keymap

Inherits:
Struct
  • Object
show all
Includes:
Results
Defined in:
lib/ver/keymap.rb

Defined Under Namespace

Modules: Results Classes: MapHash

Constant Summary collapse

MERGER =
proc{|key, v1, v2|
  if v1.respond_to?(:merge) && v2.respond_to?(:merge)
    v1.merge(v2, &MERGER)
  else
    v2
  end
}

Constants inherited from Struct

Struct::CACHE

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Struct

new

Constructor Details

#initialize(keymap = MapHash.new, keys = Set.new) ⇒ Keymap

Returns a new instance of Keymap.



88
89
90
91
# File 'lib/ver/keymap.rb', line 88

def initialize(keymap = MapHash.new, keys = Set.new)
  self.keymap = keymap
  self.keys = keys
end

Instance Attribute Details

#keymapObject

Returns the value of attribute keymap

Returns:

  • (Object)

    the current value of keymap



4
5
6
# File 'lib/ver/keymap.rb', line 4

def keymap
  @keymap
end

#keysObject

Returns the value of attribute keys

Returns:

  • (Object)

    the current value of keys



4
5
6
# File 'lib/ver/keymap.rb', line 4

def keys
  @keys
end

Instance Method Details

#[](*pattern) ⇒ Object



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/ver/keymap.rb', line 119

def [](*pattern)
  pattern = [*pattern].flatten
  remaining = pattern.dup

  current = keymap
  while key = remaining.shift
    previous = current

    if current.key?(key)
      current = current[key]
      break unless current.respond_to?(:key?)
    else
      current.find do |ckey, cvalue|
        next unless ckey.is_a?(Symbol)

        case resolved = MinorMode[ckey].resolve([key, *remaining])
        when Incomplete
          return resolved
        when Impossible
          false
        else
          mode, action = *resolved
          return cvalue.combine(action)
        end
      end

      return Impossible.new(pattern)
    end
  end

  case current
  when MapHash # incomplete
    Incomplete.new(pattern, current)
  else
    current
  end
end

#[]=(*pattern, action) ⇒ Object



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
# File 'lib/ver/keymap.rb', line 93

def []=(*pattern, action)
  pattern = pattern_to_patterns(*pattern)

  case existing = self[pattern]
  when Action
    VER.warn "Redefining %p bound to %p with %p" % [existing, pattern, action]
  when Incomplete
    VER.warn "%p shadows other actions bound to %p: %p" % [action, pattern, existing.choices]
  when Impossible
  end

  top = sub = MapHash.new

  while key = pattern.shift
    self.keys << key if key.respond_to?(:keysym)

    if pattern.empty?
      sub[key] = action
    else
      sub = sub[key] = MapHash.new
    end
  end

  keymap.replace(keymap.merge(top, &MERGER))
end

#actionsObject



168
169
170
# File 'lib/ver/keymap.rb', line 168

def actions
  keymap.deep_each.map{|key, value| value }
end

#merge(keymap) ⇒ Object



157
158
159
160
# File 'lib/ver/keymap.rb', line 157

def merge(keymap)
  merged = keymap.keymap.merge(self.keymap, &MERGER)
  self.class.new(merged, keys + keymap.keys)
end

#merge!(keymap) ⇒ Object



162
163
164
165
166
# File 'lib/ver/keymap.rb', line 162

def merge!(keymap)
  self.keymap = keymap.keymap.merge(self.keymap, &MERGER)
  self.keys += keymap.keys
  keymap
end

#pattern_to_patterns(*patterns) ⇒ Object



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/ver/keymap.rb', line 172

def pattern_to_patterns(*patterns)
  result = []

  patterns.flatten.each do |pattern|
    if pattern.respond_to?(:scan)
      pattern.scan(/<<[^>]+>>|<[^>]+>|(?!\s<)[[:print:]]/) do
        result << Event[$&].pattern
      end
    else
      result << pattern
    end
  end

  result
end