Class: KeyboardMap
- Inherits:
-
Object
- Object
- KeyboardMap
- Defined in:
- lib/keyboard_map.rb,
lib/keyboard_map/version.rb
Defined Under Namespace
Classes: Event
Constant Summary collapse
- SINGLE_KEY_EVENT =
{ "\t" => :tab, "\r" => :enter, "\u001F" => Event.new(:_,:ctrl), "\u007F" => :backspace }.freeze
- CSI_BASIC_MAP =
e[ starts a CSI sequence. This maps the final character in the CSI sequence to a key and how to interpret the parameters.
{ "A" => :up, "B" => :down, "C" => :right, "D" => :left, "E" => :keypad_5, "F" => :end, "H" => :home, "J" => :ctrl_end, # st reports this "L" => :ctrl_insert, # st reports this "P" => :delete, "Q" => :f2, "R" => :f3, "S" => :f4 }.freeze
- CSI_TILDE_MAP =
e[parameter1;…~ from parameter1 => key
{ "2" => :insert, "3" => :delete, "4" => :end, # st reports this "5" => :page_up, "6" => :page_down, "11" => :f1, "12" => :f2, "13" => :f3, "14" => :f4, "15" => :f5, "16" => :f6, "17" => :f7, "18" => :f8, "19" => :f9, "20" => :f10, "21" => :f11, "22" => :f12, "200" => :start_paste, "201" => :end_paste, }.freeze
- ESCAPE_MAP =
Map of simple/non-parameterised escape sequences to symbols
{ "\e[Z" => event(:tab,:shift), "\eOP" => :f1, "\eOQ" => :f2, "\eOR" => :f3, "\eOS" => :f4, "\e[M" => event(:delete,:ctrl), # st reports this "\e[4h" => :insert, # st reports this "\e\x7f" => event(:backspace, :meta), }.freeze
- CSI_FINAL_BYTE =
0x40..0x7e
- ESC =
"\e"- VERSION =
"0.2.3"- @@key_events =
{}
Instance Attribute Summary collapse
-
#buf ⇒ Object
readonly
Returns the value of attribute buf.
-
#state ⇒ Object
readonly
Returns the value of attribute state.
Class Method Summary collapse
Instance Method Summary collapse
- #call(input, opt = nil) ⇒ Object
- #csi(ch) ⇒ Object
- #esc(ch) ⇒ Object
- #event(key, *modifiers) ⇒ Object
- #finish ⇒ Object
-
#initialize ⇒ KeyboardMap
constructor
A new instance of KeyboardMap.
- #map_csi(seq) ⇒ Object
- #map_escape(seq) ⇒ Object
- #map_modifiers(mod) ⇒ Object
- #meta(key) ⇒ Object
- #run ⇒ Object
- #ss3(ch) ⇒ Object
- #text(ch) ⇒ Object
Constructor Details
#initialize ⇒ KeyboardMap
Returns a new instance of KeyboardMap.
127 128 129 130 131 |
# File 'lib/keyboard_map.rb', line 127 def initialize @tmp = "" @buf = "" @state = :text end |
Instance Attribute Details
#buf ⇒ Object (readonly)
Returns the value of attribute buf.
8 9 10 |
# File 'lib/keyboard_map.rb', line 8 def buf @buf end |
#state ⇒ Object (readonly)
Returns the value of attribute state.
8 9 10 |
# File 'lib/keyboard_map.rb', line 8 def state @state end |
Class Method Details
.event(key, *modifiers) ⇒ Object
88 89 90 91 92 93 94 |
# File 'lib/keyboard_map.rb', line 88 def self.event(key,*modifiers) e = key if key.kind_of?(Event) e ||= Event.new(key,*modifiers) k = e.to_sym @@key_events[k] ||= e @@key_events[k] end |
Instance Method Details
#call(input, opt = nil) ⇒ Object
137 138 139 140 |
# File 'lib/keyboard_map.rb', line 137 def call(input, opt = nil) @buf << input opt == :finished ? finish : run end |
#csi(ch) ⇒ Object
191 192 193 194 195 196 197 198 |
# File 'lib/keyboard_map.rb', line 191 def csi(ch) @tmp << ch return nil if !CSI_FINAL_BYTE.member?(ch.ord) @state = :text tmp = @tmp @tmp = "" return map_csi(tmp) end |
#esc(ch) ⇒ Object
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/keyboard_map.rb', line 200 def esc(ch) if ch == "[" @state = :csi @tmp << ch return nil elsif ch == "O" @state = :ss3 @tmp << ch return nil elsif ch == "\t" @state = :text @tmp = "" return event(:tab, :meta) elsif ch == "\e" return :esc end @state = :text @tmp = "" return (ch) end |
#event(key, *modifiers) ⇒ Object
96 97 98 |
# File 'lib/keyboard_map.rb', line 96 def event(key, *modifiers) self.class.event(key,*modifiers) end |
#finish ⇒ Object
133 134 135 |
# File 'lib/keyboard_map.rb', line 133 def finish run || (@state == :esc ? :esc : nil) end |
#map_csi(seq) ⇒ Object
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/keyboard_map.rb', line 167 def map_csi(seq) if sym = ESCAPE_MAP[seq] return sym end final = seq[-1] params = String(seq[2..-2]).split(";") modifiers = [] if final == "~" key = CSI_TILDE_MAP[params[0]] if key modifiers = map_modifiers(params[1]) end elsif final == "m" || final == "M" # Mouse reporting return Event.new(final == "M" ? :mouse_down : :mouse_up, args: [params[0][1..-1].to_i, params[1].to_i, params[2].to_i]) else key = CSI_BASIC_MAP[final] modifiers = map_modifiers(params[1]) if key && params.first == "1" && params.size == 2 end return Event.new(key,*Array(modifiers)) if key return Event.new((params << final).join("_"), :csi) end |
#map_escape(seq) ⇒ Object
142 143 144 145 146 147 |
# File 'lib/keyboard_map.rb', line 142 def map_escape(seq) if sym = ESCAPE_MAP[seq] return sym end return Event.new(seq,:esc) end |
#map_modifiers(mod) ⇒ Object
157 158 159 160 161 162 163 164 165 |
# File 'lib/keyboard_map.rb', line 157 def map_modifiers(mod) return [] if mod.nil? mod = mod.to_i - 1 [].tap do |m| m << :shift if (mod & 1) == 1 m << :meta if (mod & 2) == 2 m << :ctrl if (mod & 4) == 4 end end |
#meta(key) ⇒ Object
114 115 116 117 118 119 120 121 122 123 |
# File 'lib/keyboard_map.rb', line 114 def (key) mod = [:meta] if SINGLE_KEY_EVENT[key] key = SINGLE_KEY_EVENT[key] elsif key.ord < 32 mod << :ctrl key = (key.ord+96).chr end self.class.event(key,*mod) end |
#run ⇒ Object
248 249 250 251 252 253 254 255 256 257 258 259 260 |
# File 'lib/keyboard_map.rb', line 248 def run out = [] while !@buf.empty? ch = @buf.slice!(0) r = send(@state,ch) out.concat(Array(r)) if r end if !@tmp.empty? && @state == :text out << @tmp @tmp = "" end out end |
#ss3(ch) ⇒ Object
149 150 151 152 153 154 155 |
# File 'lib/keyboard_map.rb', line 149 def ss3(ch) tmp = @tmp tmp << ch @tmp = "" @state = :text return map_escape(tmp) end |
#text(ch) ⇒ Object
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
# File 'lib/keyboard_map.rb', line 221 def text(ch) if ch == ESC @state = :esc out = @tmp.empty? ? nil : @tmp @tmp = ESC.dup return out end if m = SINGLE_KEY_EVENT[ch] tmp = @tmp @tmp = "" return [self.class.event(m)] if tmp.empty? return [tmp, self.class.event(m)] end if ch.ord < 32 tmp = @tmp @tmp = "" ev = self.class.event((ch.ord+96).chr,:ctrl) return [ev] if tmp.empty? return [tmp,ev] end @tmp << ch nil end |