Class: VER::MinorMode
- Inherits:
-
Struct
- Object
- Struct
- VER::MinorMode
- Includes:
- Keymap::Results
- Defined in:
- lib/ver/minor_mode.rb
Overview
A minor mode contains modifications for major modes. It supports unidirectional inheritance to form a tree-like structure together with other instance of MinorMode. Every minor mode maintains its own keymap and performs lookup within that. When no match can be found, the parents will be asked until a definite result is returned.
A MinorMode is expected to interact with the WidgetMajorMode only, not with MajorMode directly.
Modification of a MinorMode will not be fully reflected until the
- WidgetMajorMode#synchronize
-
method has been called and the minor mode is
part of the tree of minors of this major mode.
Constant Summary collapse
- MODES =
{}
Instance Attribute Summary collapse
-
#enter_action ⇒ Object
Returns the value of attribute enter_action.
-
#fallback_action ⇒ Object
Returns the value of attribute fallback_action.
-
#keymap ⇒ Object
Returns the value of attribute keymap.
-
#leave_action ⇒ Object
Returns the value of attribute leave_action.
-
#name ⇒ Object
Returns the value of attribute name.
-
#parents ⇒ Object
Returns the value of attribute parents.
-
#receiver ⇒ Object
Returns the value of attribute receiver.
Class Method Summary collapse
-
.[](name) ⇒ Object
Find or create the minor mode for the given name.
-
.clear ⇒ Object
Delete all minor modes.
Instance Method Summary collapse
- #actions ⇒ Object
- #become(other, *sequences) ⇒ Object
- #enter(invocation, &block) ⇒ Object
- #handler(object) ⇒ Object
-
#inherits(*names) ⇒ Object
Add a parent for this minor mode.
-
#initialize(name) ⇒ MinorMode
constructor
A new instance of MinorMode.
- #inspect ⇒ Object
- #leave(invocation, &block) ⇒ Object
- #map(invocation, *sequences, &block) ⇒ Object
- #missing(invocation, &block) ⇒ Object
- #replace_parent(widget_major, old, new) ⇒ Object
- #replaced_by(widget_major, other) ⇒ Object
- #replaces(widget_major, other) ⇒ Object
- #replacing(widget_major, other) ⇒ Object
-
#resolve(sequence) ⇒ Object
recursively try to find the sequence in the minor mode and its parents.
- #synchronize(widget_major) ⇒ Object
- #synchronize_recursively(widget_major) ⇒ Object
- #to_camel_case ⇒ Object
- #to_sym ⇒ Object
- #unfold(all = [self]) ⇒ Object
Constructor Details
Instance Attribute Details
#enter_action ⇒ Object
Returns the value of attribute enter_action
21 22 23 |
# File 'lib/ver/minor_mode.rb', line 21 def enter_action @enter_action end |
#fallback_action ⇒ Object
Returns the value of attribute fallback_action
21 22 23 |
# File 'lib/ver/minor_mode.rb', line 21 def fallback_action @fallback_action end |
#keymap ⇒ Object
Returns the value of attribute keymap
21 22 23 |
# File 'lib/ver/minor_mode.rb', line 21 def keymap @keymap end |
#leave_action ⇒ Object
Returns the value of attribute leave_action
21 22 23 |
# File 'lib/ver/minor_mode.rb', line 21 def leave_action @leave_action end |
#name ⇒ Object
Returns the value of attribute name
21 22 23 |
# File 'lib/ver/minor_mode.rb', line 21 def name @name end |
#parents ⇒ Object
Returns the value of attribute parents
21 22 23 |
# File 'lib/ver/minor_mode.rb', line 21 def parents @parents end |
#receiver ⇒ Object
Returns the value of attribute receiver
21 22 23 |
# File 'lib/ver/minor_mode.rb', line 21 def receiver @receiver end |
Class Method Details
.[](name) ⇒ Object
Find or create the minor mode for the given name.
28 29 30 31 32 33 34 35 36 |
# File 'lib/ver/minor_mode.rb', line 28 def self.[](name) name = name.to_sym if MODES.key?(name) MODES[name] else new(name) end end |
.clear ⇒ Object
Delete all minor modes.
39 40 41 |
# File 'lib/ver/minor_mode.rb', line 39 def self.clear MODES.clear end |
Instance Method Details
#actions ⇒ Object
192 193 194 |
# File 'lib/ver/minor_mode.rb', line 192 def actions unfold.map{|minor| minor.keymap.actions } end |
#become(other, *sequences) ⇒ Object
89 90 91 92 93 94 95 |
# File 'lib/ver/minor_mode.rb', line 89 def become(other, *sequences) action = Action.new(receiver, :minor_mode, [self, other]) sequences.each do |sequence| keymap[sequence] = action end end |
#enter(invocation, &block) ⇒ Object
113 114 115 116 |
# File 'lib/ver/minor_mode.rb', line 113 def enter(invocation, &block) action = Action.new(receiver, *invocation, &block) self.enter_action = action end |
#handler(object) ⇒ Object
123 124 125 |
# File 'lib/ver/minor_mode.rb', line 123 def handler(object) self.receiver = object end |
#inherits(*names) ⇒ Object
Add a parent for this minor mode.
81 82 83 84 85 86 87 |
# File 'lib/ver/minor_mode.rb', line 81 def inherits(*names) names.each do |name| minor = self.class[name] self.parents << minor unless minor == self end self.parents.uniq! end |
#inspect ⇒ Object
200 201 202 |
# File 'lib/ver/minor_mode.rb', line 200 def inspect "#<VER::MinorMode name=%p>" % [name] end |
#leave(invocation, &block) ⇒ Object
118 119 120 121 |
# File 'lib/ver/minor_mode.rb', line 118 def leave(invocation, &block) action = Action.new(receiver, *invocation, &block) self.leave_action = action end |
#map(invocation, *sequences, &block) ⇒ Object
97 98 99 100 101 102 103 |
# File 'lib/ver/minor_mode.rb', line 97 def map(invocation, *sequences, &block) action = Action.new(receiver, *invocation, &block) sequences.each do |sequence| keymap[sequence] = action end end |
#missing(invocation, &block) ⇒ Object
105 106 107 108 109 110 111 |
# File 'lib/ver/minor_mode.rb', line 105 def missing(invocation, &block) action = Action.new(receiver, *invocation, &block) self.fallback_action = action (KEYSYMS.values - keymap.keys.to_a).each do |name| keymap[name] = action end end |
#replace_parent(widget_major, old, new) ⇒ Object
127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/ver/minor_mode.rb', line 127 def replace_parent(, old, new) parents.dup.each do |parent| if parent == old new.replaces , old do parents[parents.index(old)] = new end else parent.replace_parent(, old, new) end end end |
#replaced_by(widget_major, other) ⇒ Object
145 146 147 148 149 150 151 152 |
# File 'lib/ver/minor_mode.rb', line 145 def replaced_by(, other) return unless .respond_to?(:widget) = . leave_action.call(, self, other) if leave_action Tk::Event.generate(, "<<LeaveMode>>", data: name) Tk::Event.generate(, "<<LeaveMinorMode>>", data: name) Tk::Event.generate(, "<<LeaveMinorMode#{to_camel_case}>>", data: name) end |
#replaces(widget_major, other) ⇒ Object
139 140 141 142 143 |
# File 'lib/ver/minor_mode.rb', line 139 def replaces(, other) other.replaced_by(, self) if other yield if block_given? self.replacing(, other) end |
#replacing(widget_major, other) ⇒ Object
154 155 156 157 158 159 160 161 |
# File 'lib/ver/minor_mode.rb', line 154 def replacing(, other) return unless .respond_to?(:widget) = . enter_action.call(, other, self) if enter_action Tk::Event.generate(, "<<EnterMinorMode#{to_camel_case}>>", data: name) Tk::Event.generate(, "<<EnterMinorMode>>", data: name) Tk::Event.generate(, "<<EnterMode>>", data: name) end |
#resolve(sequence) ⇒ Object
recursively try to find the sequence in the minor mode and its parents.
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/ver/minor_mode.rb', line 53 def resolve(sequence) case found = keymap[sequence] when Incomplete parents.each do |parent| next if parent == self case resolved = parent.resolve(sequence) when Incomplete found.merge!(resolved) end end when Impossible parents.find do |parent| next if parent == self found = parent.resolve(sequence) !found.kind_of?(Impossible) end else found = [self, found] end if found.kind_of?(Impossible) && fa = self.fallback_action return self, fa else return found end end |
#synchronize(widget_major) ⇒ Object
169 170 171 172 173 |
# File 'lib/ver/minor_mode.rb', line 169 def synchronize() keymap.keys.each do |key| .bind_key(key) end end |
#synchronize_recursively(widget_major) ⇒ Object
163 164 165 166 167 |
# File 'lib/ver/minor_mode.rb', line 163 def synchronize_recursively() unfold.each do |minor| minor.synchronize() end end |
#to_camel_case ⇒ Object
188 189 190 |
# File 'lib/ver/minor_mode.rb', line 188 def to_camel_case name.to_s.split('_').map{|e| e.capitalize}.join end |
#to_sym ⇒ Object
196 197 198 |
# File 'lib/ver/minor_mode.rb', line 196 def to_sym name end |
#unfold(all = [self]) ⇒ Object
175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/ver/minor_mode.rb', line 175 def unfold(all = [self]) pending = self.parents.dup while current = pending.shift unless all.include?(current) all << current pending.concat(current.unfold(all)).flatten! end end all end |