gemini-browser

A text-based gemini browser
git clone git://git.laack.co/gemini-browser.git
Log | Files | Refs | README

key.go (11385B)


      1 // Copyright 2016 The TCell Authors
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use file except in compliance with the License.
      5 // You may obtain a copy of the license at
      6 //
      7 //    http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 package tcell
     16 
     17 import (
     18 	"fmt"
     19 	"strings"
     20 	"time"
     21 )
     22 
     23 // EventKey represents a key press.  Usually this is a key press followed
     24 // by a key release, but since terminal programs don't have a way to report
     25 // key release events, we usually get just one event.  If a key is held down
     26 // then the terminal may synthesize repeated key presses at some predefined
     27 // rate.  We have no control over that, nor visibility into it.
     28 //
     29 // In some cases, we can have a modifier key, such as ModAlt, that can be
     30 // generated with a key press.  (This usually is represented by having the
     31 // high bit set, or in some cases, by sending an ESC prior to the rune.)
     32 //
     33 // If the value of Key() is KeyRune, then the actual key value will be
     34 // available with the Rune() method.  This will be the case for most keys.
     35 // In most situations, the modifiers will not be set.  For example, if the
     36 // rune is 'A', this will be reported without the ModShift bit set, since
     37 // really can't tell if the Shift key was pressed (it might have been CAPSLOCK,
     38 // or a terminal that only can send capitals, or keyboard with separate
     39 // capital letters from lower case letters).
     40 //
     41 // Generally, terminal applications have far less visibility into keyboard
     42 // activity than graphical applications.  Hence, they should avoid depending
     43 // overly much on availability of modifiers, or the availability of any
     44 // specific keys.
     45 type EventKey struct {
     46 	t   time.Time
     47 	mod ModMask
     48 	key Key
     49 	ch  rune
     50 }
     51 
     52 // When returns the time when this Event was created, which should closely
     53 // match the time when the key was pressed.
     54 func (ev *EventKey) When() time.Time {
     55 	return ev.t
     56 }
     57 
     58 // Rune returns the rune corresponding to the key press, if it makes sense.
     59 // The result is only defined if the value of Key() is KeyRune.
     60 func (ev *EventKey) Rune() rune {
     61 	return ev.ch
     62 }
     63 
     64 // Key returns a virtual key code.  We use this to identify specific key
     65 // codes, such as KeyEnter, etc.  Most control and function keys are reported
     66 // with unique Key values.  Normal alphanumeric and punctuation keys will
     67 // generally return KeyRune here; the specific key can be further decoded
     68 // using the Rune() function.
     69 func (ev *EventKey) Key() Key {
     70 	return ev.key
     71 }
     72 
     73 // Modifiers returns the modifiers that were present with the key press.  Note
     74 // that not all platforms and terminals support this equally well, and some
     75 // cases we will not not know for sure.  Hence, applications should avoid
     76 // using this in most circumstances.
     77 func (ev *EventKey) Modifiers() ModMask {
     78 	return ev.mod
     79 }
     80 
     81 // KeyNames holds the written names of special keys. Useful to echo back a key
     82 // name, or to look up a key from a string value.
     83 var KeyNames = map[Key]string{
     84 	KeyEnter:          "Enter",
     85 	KeyBackspace:      "Backspace",
     86 	KeyTab:            "Tab",
     87 	KeyBacktab:        "Backtab",
     88 	KeyEsc:            "Esc",
     89 	KeyBackspace2:     "Backspace2",
     90 	KeyDelete:         "Delete",
     91 	KeyInsert:         "Insert",
     92 	KeyUp:             "Up",
     93 	KeyDown:           "Down",
     94 	KeyLeft:           "Left",
     95 	KeyRight:          "Right",
     96 	KeyHome:           "Home",
     97 	KeyEnd:            "End",
     98 	KeyUpLeft:         "UpLeft",
     99 	KeyUpRight:        "UpRight",
    100 	KeyDownLeft:       "DownLeft",
    101 	KeyDownRight:      "DownRight",
    102 	KeyCenter:         "Center",
    103 	KeyPgDn:           "PgDn",
    104 	KeyPgUp:           "PgUp",
    105 	KeyClear:          "Clear",
    106 	KeyExit:           "Exit",
    107 	KeyCancel:         "Cancel",
    108 	KeyPause:          "Pause",
    109 	KeyPrint:          "Print",
    110 	KeyF1:             "F1",
    111 	KeyF2:             "F2",
    112 	KeyF3:             "F3",
    113 	KeyF4:             "F4",
    114 	KeyF5:             "F5",
    115 	KeyF6:             "F6",
    116 	KeyF7:             "F7",
    117 	KeyF8:             "F8",
    118 	KeyF9:             "F9",
    119 	KeyF10:            "F10",
    120 	KeyF11:            "F11",
    121 	KeyF12:            "F12",
    122 	KeyF13:            "F13",
    123 	KeyF14:            "F14",
    124 	KeyF15:            "F15",
    125 	KeyF16:            "F16",
    126 	KeyF17:            "F17",
    127 	KeyF18:            "F18",
    128 	KeyF19:            "F19",
    129 	KeyF20:            "F20",
    130 	KeyF21:            "F21",
    131 	KeyF22:            "F22",
    132 	KeyF23:            "F23",
    133 	KeyF24:            "F24",
    134 	KeyF25:            "F25",
    135 	KeyF26:            "F26",
    136 	KeyF27:            "F27",
    137 	KeyF28:            "F28",
    138 	KeyF29:            "F29",
    139 	KeyF30:            "F30",
    140 	KeyF31:            "F31",
    141 	KeyF32:            "F32",
    142 	KeyF33:            "F33",
    143 	KeyF34:            "F34",
    144 	KeyF35:            "F35",
    145 	KeyF36:            "F36",
    146 	KeyF37:            "F37",
    147 	KeyF38:            "F38",
    148 	KeyF39:            "F39",
    149 	KeyF40:            "F40",
    150 	KeyF41:            "F41",
    151 	KeyF42:            "F42",
    152 	KeyF43:            "F43",
    153 	KeyF44:            "F44",
    154 	KeyF45:            "F45",
    155 	KeyF46:            "F46",
    156 	KeyF47:            "F47",
    157 	KeyF48:            "F48",
    158 	KeyF49:            "F49",
    159 	KeyF50:            "F50",
    160 	KeyF51:            "F51",
    161 	KeyF52:            "F52",
    162 	KeyF53:            "F53",
    163 	KeyF54:            "F54",
    164 	KeyF55:            "F55",
    165 	KeyF56:            "F56",
    166 	KeyF57:            "F57",
    167 	KeyF58:            "F58",
    168 	KeyF59:            "F59",
    169 	KeyF60:            "F60",
    170 	KeyF61:            "F61",
    171 	KeyF62:            "F62",
    172 	KeyF63:            "F63",
    173 	KeyF64:            "F64",
    174 	KeyCtrlA:          "Ctrl-A",
    175 	KeyCtrlB:          "Ctrl-B",
    176 	KeyCtrlC:          "Ctrl-C",
    177 	KeyCtrlD:          "Ctrl-D",
    178 	KeyCtrlE:          "Ctrl-E",
    179 	KeyCtrlF:          "Ctrl-F",
    180 	KeyCtrlG:          "Ctrl-G",
    181 	KeyCtrlJ:          "Ctrl-J",
    182 	KeyCtrlK:          "Ctrl-K",
    183 	KeyCtrlL:          "Ctrl-L",
    184 	KeyCtrlN:          "Ctrl-N",
    185 	KeyCtrlO:          "Ctrl-O",
    186 	KeyCtrlP:          "Ctrl-P",
    187 	KeyCtrlQ:          "Ctrl-Q",
    188 	KeyCtrlR:          "Ctrl-R",
    189 	KeyCtrlS:          "Ctrl-S",
    190 	KeyCtrlT:          "Ctrl-T",
    191 	KeyCtrlU:          "Ctrl-U",
    192 	KeyCtrlV:          "Ctrl-V",
    193 	KeyCtrlW:          "Ctrl-W",
    194 	KeyCtrlX:          "Ctrl-X",
    195 	KeyCtrlY:          "Ctrl-Y",
    196 	KeyCtrlZ:          "Ctrl-Z",
    197 	KeyCtrlSpace:      "Ctrl-Space",
    198 	KeyCtrlUnderscore: "Ctrl-_",
    199 	KeyCtrlRightSq:    "Ctrl-]",
    200 	KeyCtrlBackslash:  "Ctrl-\\",
    201 	KeyCtrlCarat:      "Ctrl-^",
    202 }
    203 
    204 // Name returns a printable value or the key stroke.  This can be used
    205 // when printing the event, for example.
    206 func (ev *EventKey) Name() string {
    207 	s := ""
    208 	m := []string{}
    209 	if ev.mod&ModShift != 0 {
    210 		m = append(m, "Shift")
    211 	}
    212 	if ev.mod&ModAlt != 0 {
    213 		m = append(m, "Alt")
    214 	}
    215 	if ev.mod&ModMeta != 0 {
    216 		m = append(m, "Meta")
    217 	}
    218 	if ev.mod&ModCtrl != 0 {
    219 		m = append(m, "Ctrl")
    220 	}
    221 
    222 	ok := false
    223 	if s, ok = KeyNames[ev.key]; !ok {
    224 		if ev.key == KeyRune {
    225 			s = "Rune[" + string(ev.ch) + "]"
    226 		} else {
    227 			s = fmt.Sprintf("Key[%d,%d]", ev.key, int(ev.ch))
    228 		}
    229 	}
    230 	if len(m) != 0 {
    231 		if ev.mod&ModCtrl != 0 && strings.HasPrefix(s, "Ctrl-") {
    232 			s = s[5:]
    233 		}
    234 		return fmt.Sprintf("%s+%s", strings.Join(m, "+"), s)
    235 	}
    236 	return s
    237 }
    238 
    239 // NewEventKey attempts to create a suitable event.  It parses the various
    240 // ASCII control sequences if KeyRune is passed for Key, but if the caller
    241 // has more precise information it should set that specifically.  Callers
    242 // that aren't sure about modifier state (most) should just pass ModNone.
    243 func NewEventKey(k Key, ch rune, mod ModMask) *EventKey {
    244 	if k == KeyRune && (ch < ' ' || ch == 0x7f) {
    245 		// Turn specials into proper key codes.  This is for
    246 		// control characters and the DEL.
    247 		k = Key(ch)
    248 		if mod == ModNone && ch < ' ' {
    249 			switch Key(ch) {
    250 			case KeyBackspace, KeyTab, KeyEsc, KeyEnter:
    251 				// these keys are directly typeable without CTRL
    252 			default:
    253 				// most likely entered with a CTRL keypress
    254 				mod = ModCtrl
    255 			}
    256 		}
    257 	}
    258 	return &EventKey{t: time.Now(), key: k, ch: ch, mod: mod}
    259 }
    260 
    261 // ModMask is a mask of modifier keys.  Note that it will not always be
    262 // possible to report modifier keys.
    263 type ModMask int16
    264 
    265 // These are the modifiers keys that can be sent either with a key press,
    266 // or a mouse event.  Note that as of now, due to the confusion associated
    267 // with Meta, and the lack of support for it on many/most platforms, the
    268 // current implementations never use it.  Instead, they use ModAlt, even for
    269 // events that could possibly have been distinguished from ModAlt.
    270 const (
    271 	ModShift ModMask = 1 << iota
    272 	ModCtrl
    273 	ModAlt
    274 	ModMeta
    275 	ModNone ModMask = 0
    276 )
    277 
    278 // Key is a generic value for representing keys, and especially special
    279 // keys (function keys, cursor movement keys, etc.)  For normal keys, like
    280 // ASCII letters, we use KeyRune, and then expect the application to
    281 // inspect the Rune() member of the EventKey.
    282 type Key int16
    283 
    284 // This is the list of named keys.  KeyRune is special however, in that it is
    285 // a place holder key indicating that a printable character was sent.  The
    286 // actual value of the rune will be transported in the Rune of the associated
    287 // EventKey.
    288 const (
    289 	KeyRune Key = iota + 256
    290 	KeyUp
    291 	KeyDown
    292 	KeyRight
    293 	KeyLeft
    294 	KeyUpLeft
    295 	KeyUpRight
    296 	KeyDownLeft
    297 	KeyDownRight
    298 	KeyCenter
    299 	KeyPgUp
    300 	KeyPgDn
    301 	KeyHome
    302 	KeyEnd
    303 	KeyInsert
    304 	KeyDelete
    305 	KeyHelp
    306 	KeyExit
    307 	KeyClear
    308 	KeyCancel
    309 	KeyPrint
    310 	KeyPause
    311 	KeyBacktab
    312 	KeyF1
    313 	KeyF2
    314 	KeyF3
    315 	KeyF4
    316 	KeyF5
    317 	KeyF6
    318 	KeyF7
    319 	KeyF8
    320 	KeyF9
    321 	KeyF10
    322 	KeyF11
    323 	KeyF12
    324 	KeyF13
    325 	KeyF14
    326 	KeyF15
    327 	KeyF16
    328 	KeyF17
    329 	KeyF18
    330 	KeyF19
    331 	KeyF20
    332 	KeyF21
    333 	KeyF22
    334 	KeyF23
    335 	KeyF24
    336 	KeyF25
    337 	KeyF26
    338 	KeyF27
    339 	KeyF28
    340 	KeyF29
    341 	KeyF30
    342 	KeyF31
    343 	KeyF32
    344 	KeyF33
    345 	KeyF34
    346 	KeyF35
    347 	KeyF36
    348 	KeyF37
    349 	KeyF38
    350 	KeyF39
    351 	KeyF40
    352 	KeyF41
    353 	KeyF42
    354 	KeyF43
    355 	KeyF44
    356 	KeyF45
    357 	KeyF46
    358 	KeyF47
    359 	KeyF48
    360 	KeyF49
    361 	KeyF50
    362 	KeyF51
    363 	KeyF52
    364 	KeyF53
    365 	KeyF54
    366 	KeyF55
    367 	KeyF56
    368 	KeyF57
    369 	KeyF58
    370 	KeyF59
    371 	KeyF60
    372 	KeyF61
    373 	KeyF62
    374 	KeyF63
    375 	KeyF64
    376 )
    377 
    378 const (
    379 	// These key codes are used internally, and will never appear to applications.
    380 	keyPasteStart Key = iota + 16384
    381 	keyPasteEnd
    382 )
    383 
    384 // These are the control keys.  Note that they overlap with other keys,
    385 // perhaps.  For example, KeyCtrlH is the same as KeyBackspace.
    386 const (
    387 	KeyCtrlSpace Key = iota
    388 	KeyCtrlA
    389 	KeyCtrlB
    390 	KeyCtrlC
    391 	KeyCtrlD
    392 	KeyCtrlE
    393 	KeyCtrlF
    394 	KeyCtrlG
    395 	KeyCtrlH
    396 	KeyCtrlI
    397 	KeyCtrlJ
    398 	KeyCtrlK
    399 	KeyCtrlL
    400 	KeyCtrlM
    401 	KeyCtrlN
    402 	KeyCtrlO
    403 	KeyCtrlP
    404 	KeyCtrlQ
    405 	KeyCtrlR
    406 	KeyCtrlS
    407 	KeyCtrlT
    408 	KeyCtrlU
    409 	KeyCtrlV
    410 	KeyCtrlW
    411 	KeyCtrlX
    412 	KeyCtrlY
    413 	KeyCtrlZ
    414 	KeyCtrlLeftSq // Escape
    415 	KeyCtrlBackslash
    416 	KeyCtrlRightSq
    417 	KeyCtrlCarat
    418 	KeyCtrlUnderscore
    419 )
    420 
    421 // Special values - these are fixed in an attempt to make it more likely
    422 // that aliases will encode the same way.
    423 
    424 // These are the defined ASCII values for key codes.  They generally match
    425 // with KeyCtrl values.
    426 const (
    427 	KeyNUL Key = iota
    428 	KeySOH
    429 	KeySTX
    430 	KeyETX
    431 	KeyEOT
    432 	KeyENQ
    433 	KeyACK
    434 	KeyBEL
    435 	KeyBS
    436 	KeyTAB
    437 	KeyLF
    438 	KeyVT
    439 	KeyFF
    440 	KeyCR
    441 	KeySO
    442 	KeySI
    443 	KeyDLE
    444 	KeyDC1
    445 	KeyDC2
    446 	KeyDC3
    447 	KeyDC4
    448 	KeyNAK
    449 	KeySYN
    450 	KeyETB
    451 	KeyCAN
    452 	KeyEM
    453 	KeySUB
    454 	KeyESC
    455 	KeyFS
    456 	KeyGS
    457 	KeyRS
    458 	KeyUS
    459 	KeyDEL Key = 0x7F
    460 )
    461 
    462 // These keys are aliases for other names.
    463 const (
    464 	KeyBackspace  = KeyBS
    465 	KeyTab        = KeyTAB
    466 	KeyEsc        = KeyESC
    467 	KeyEscape     = KeyESC
    468 	KeyEnter      = KeyCR
    469 	KeyBackspace2 = KeyDEL
    470 )