key.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  1. package tea
  2. import (
  3. "context"
  4. "fmt"
  5. "io"
  6. "regexp"
  7. "strings"
  8. "unicode/utf8"
  9. )
  10. // KeyMsg contains information about a keypress. KeyMsgs are always sent to
  11. // the program's update function. There are a couple general patterns you could
  12. // use to check for keypresses:
  13. //
  14. // // Switch on the string representation of the key (shorter)
  15. // switch msg := msg.(type) {
  16. // case KeyMsg:
  17. // switch msg.String() {
  18. // case "enter":
  19. // fmt.Println("you pressed enter!")
  20. // case "a":
  21. // fmt.Println("you pressed a!")
  22. // }
  23. // }
  24. //
  25. // // Switch on the key type (more foolproof)
  26. // switch msg := msg.(type) {
  27. // case KeyMsg:
  28. // switch msg.Type {
  29. // case KeyEnter:
  30. // fmt.Println("you pressed enter!")
  31. // case KeyRunes:
  32. // switch string(msg.Runes) {
  33. // case "a":
  34. // fmt.Println("you pressed a!")
  35. // }
  36. // }
  37. // }
  38. //
  39. // Note that Key.Runes will always contain at least one character, so you can
  40. // always safely call Key.Runes[0]. In most cases Key.Runes will only contain
  41. // one character, though certain input method editors (most notably Chinese
  42. // IMEs) can input multiple runes at once.
  43. type KeyMsg Key
  44. // String returns a string representation for a key message. It's safe (and
  45. // encouraged) for use in key comparison.
  46. func (k KeyMsg) String() (str string) {
  47. return Key(k).String()
  48. }
  49. // Key contains information about a keypress.
  50. type Key struct {
  51. Type KeyType
  52. Runes []rune
  53. Alt bool
  54. Paste bool
  55. }
  56. // String returns a friendly string representation for a key. It's safe (and
  57. // encouraged) for use in key comparison.
  58. //
  59. // k := Key{Type: KeyEnter}
  60. // fmt.Println(k)
  61. // // Output: enter
  62. func (k Key) String() (str string) {
  63. var buf strings.Builder
  64. if k.Alt {
  65. buf.WriteString("alt+")
  66. }
  67. if k.Type == KeyRunes {
  68. if k.Paste {
  69. // Note: bubbles/keys bindings currently do string compares to
  70. // recognize shortcuts. Since pasted text should never activate
  71. // shortcuts, we need to ensure that the binding code doesn't
  72. // match Key events that result from pastes. We achieve this
  73. // here by enclosing pastes in '[...]' so that the string
  74. // comparison in Matches() fails in that case.
  75. buf.WriteByte('[')
  76. }
  77. buf.WriteString(string(k.Runes))
  78. if k.Paste {
  79. buf.WriteByte(']')
  80. }
  81. return buf.String()
  82. } else if s, ok := keyNames[k.Type]; ok {
  83. buf.WriteString(s)
  84. return buf.String()
  85. }
  86. return ""
  87. }
  88. // KeyType indicates the key pressed, such as KeyEnter or KeyBreak or KeyCtrlC.
  89. // All other keys will be type KeyRunes. To get the rune value, check the Rune
  90. // method on a Key struct, or use the Key.String() method:
  91. //
  92. // k := Key{Type: KeyRunes, Runes: []rune{'a'}, Alt: true}
  93. // if k.Type == KeyRunes {
  94. //
  95. // fmt.Println(k.Runes)
  96. // // Output: a
  97. //
  98. // fmt.Println(k.String())
  99. // // Output: alt+a
  100. //
  101. // }
  102. type KeyType int
  103. func (k KeyType) String() (str string) {
  104. if s, ok := keyNames[k]; ok {
  105. return s
  106. }
  107. return ""
  108. }
  109. // Control keys. We could do this with an iota, but the values are very
  110. // specific, so we set the values explicitly to avoid any confusion.
  111. //
  112. // See also:
  113. // https://en.wikipedia.org/wiki/C0_and_C1_control_codes
  114. const (
  115. keyNUL KeyType = 0 // null, \0
  116. keySOH KeyType = 1 // start of heading
  117. keySTX KeyType = 2 // start of text
  118. keyETX KeyType = 3 // break, ctrl+c
  119. keyEOT KeyType = 4 // end of transmission
  120. keyENQ KeyType = 5 // enquiry
  121. keyACK KeyType = 6 // acknowledge
  122. keyBEL KeyType = 7 // bell, \a
  123. keyBS KeyType = 8 // backspace
  124. keyHT KeyType = 9 // horizontal tabulation, \t
  125. keyLF KeyType = 10 // line feed, \n
  126. keyVT KeyType = 11 // vertical tabulation \v
  127. keyFF KeyType = 12 // form feed \f
  128. keyCR KeyType = 13 // carriage return, \r
  129. keySO KeyType = 14 // shift out
  130. keySI KeyType = 15 // shift in
  131. keyDLE KeyType = 16 // data link escape
  132. keyDC1 KeyType = 17 // device control one
  133. keyDC2 KeyType = 18 // device control two
  134. keyDC3 KeyType = 19 // device control three
  135. keyDC4 KeyType = 20 // device control four
  136. keyNAK KeyType = 21 // negative acknowledge
  137. keySYN KeyType = 22 // synchronous idle
  138. keyETB KeyType = 23 // end of transmission block
  139. keyCAN KeyType = 24 // cancel
  140. keyEM KeyType = 25 // end of medium
  141. keySUB KeyType = 26 // substitution
  142. keyESC KeyType = 27 // escape, \e
  143. keyFS KeyType = 28 // file separator
  144. keyGS KeyType = 29 // group separator
  145. keyRS KeyType = 30 // record separator
  146. keyUS KeyType = 31 // unit separator
  147. keyDEL KeyType = 127 // delete. on most systems this is mapped to backspace, I hear
  148. )
  149. // Control key aliases.
  150. const (
  151. KeyNull KeyType = keyNUL
  152. KeyBreak KeyType = keyETX
  153. KeyEnter KeyType = keyCR
  154. KeyBackspace KeyType = keyDEL
  155. KeyTab KeyType = keyHT
  156. KeyEsc KeyType = keyESC
  157. KeyEscape KeyType = keyESC
  158. KeyCtrlAt KeyType = keyNUL // ctrl+@
  159. KeyCtrlA KeyType = keySOH
  160. KeyCtrlB KeyType = keySTX
  161. KeyCtrlC KeyType = keyETX
  162. KeyCtrlD KeyType = keyEOT
  163. KeyCtrlE KeyType = keyENQ
  164. KeyCtrlF KeyType = keyACK
  165. KeyCtrlG KeyType = keyBEL
  166. KeyCtrlH KeyType = keyBS
  167. KeyCtrlI KeyType = keyHT
  168. KeyCtrlJ KeyType = keyLF
  169. KeyCtrlK KeyType = keyVT
  170. KeyCtrlL KeyType = keyFF
  171. KeyCtrlM KeyType = keyCR
  172. KeyCtrlN KeyType = keySO
  173. KeyCtrlO KeyType = keySI
  174. KeyCtrlP KeyType = keyDLE
  175. KeyCtrlQ KeyType = keyDC1
  176. KeyCtrlR KeyType = keyDC2
  177. KeyCtrlS KeyType = keyDC3
  178. KeyCtrlT KeyType = keyDC4
  179. KeyCtrlU KeyType = keyNAK
  180. KeyCtrlV KeyType = keySYN
  181. KeyCtrlW KeyType = keyETB
  182. KeyCtrlX KeyType = keyCAN
  183. KeyCtrlY KeyType = keyEM
  184. KeyCtrlZ KeyType = keySUB
  185. KeyCtrlOpenBracket KeyType = keyESC // ctrl+[
  186. KeyCtrlBackslash KeyType = keyFS // ctrl+\
  187. KeyCtrlCloseBracket KeyType = keyGS // ctrl+]
  188. KeyCtrlCaret KeyType = keyRS // ctrl+^
  189. KeyCtrlUnderscore KeyType = keyUS // ctrl+_
  190. KeyCtrlQuestionMark KeyType = keyDEL // ctrl+?
  191. )
  192. // Other keys.
  193. const (
  194. KeyRunes KeyType = -(iota + 1)
  195. KeyUp
  196. KeyDown
  197. KeyRight
  198. KeyLeft
  199. KeyShiftTab
  200. KeyHome
  201. KeyEnd
  202. KeyPgUp
  203. KeyPgDown
  204. KeyCtrlPgUp
  205. KeyCtrlPgDown
  206. KeyDelete
  207. KeyInsert
  208. KeySpace
  209. KeyCtrlUp
  210. KeyCtrlDown
  211. KeyCtrlRight
  212. KeyCtrlLeft
  213. KeyCtrlHome
  214. KeyCtrlEnd
  215. KeyShiftUp
  216. KeyShiftDown
  217. KeyShiftRight
  218. KeyShiftLeft
  219. KeyShiftHome
  220. KeyShiftEnd
  221. KeyCtrlShiftUp
  222. KeyCtrlShiftDown
  223. KeyCtrlShiftLeft
  224. KeyCtrlShiftRight
  225. KeyCtrlShiftHome
  226. KeyCtrlShiftEnd
  227. KeyF1
  228. KeyF2
  229. KeyF3
  230. KeyF4
  231. KeyF5
  232. KeyF6
  233. KeyF7
  234. KeyF8
  235. KeyF9
  236. KeyF10
  237. KeyF11
  238. KeyF12
  239. KeyF13
  240. KeyF14
  241. KeyF15
  242. KeyF16
  243. KeyF17
  244. KeyF18
  245. KeyF19
  246. KeyF20
  247. )
  248. // Mappings for control keys and other special keys to friendly consts.
  249. var keyNames = map[KeyType]string{
  250. // Control keys.
  251. keyNUL: "ctrl+@", // also ctrl+` (that's ctrl+backtick)
  252. keySOH: "ctrl+a",
  253. keySTX: "ctrl+b",
  254. keyETX: "ctrl+c",
  255. keyEOT: "ctrl+d",
  256. keyENQ: "ctrl+e",
  257. keyACK: "ctrl+f",
  258. keyBEL: "ctrl+g",
  259. keyBS: "ctrl+h",
  260. keyHT: "tab", // also ctrl+i
  261. keyLF: "ctrl+j",
  262. keyVT: "ctrl+k",
  263. keyFF: "ctrl+l",
  264. keyCR: "enter",
  265. keySO: "ctrl+n",
  266. keySI: "ctrl+o",
  267. keyDLE: "ctrl+p",
  268. keyDC1: "ctrl+q",
  269. keyDC2: "ctrl+r",
  270. keyDC3: "ctrl+s",
  271. keyDC4: "ctrl+t",
  272. keyNAK: "ctrl+u",
  273. keySYN: "ctrl+v",
  274. keyETB: "ctrl+w",
  275. keyCAN: "ctrl+x",
  276. keyEM: "ctrl+y",
  277. keySUB: "ctrl+z",
  278. keyESC: "esc",
  279. keyFS: "ctrl+\\",
  280. keyGS: "ctrl+]",
  281. keyRS: "ctrl+^",
  282. keyUS: "ctrl+_",
  283. keyDEL: "backspace",
  284. // Other keys.
  285. KeyRunes: "runes",
  286. KeyUp: "up",
  287. KeyDown: "down",
  288. KeyRight: "right",
  289. KeySpace: " ", // for backwards compatibility
  290. KeyLeft: "left",
  291. KeyShiftTab: "shift+tab",
  292. KeyHome: "home",
  293. KeyEnd: "end",
  294. KeyCtrlHome: "ctrl+home",
  295. KeyCtrlEnd: "ctrl+end",
  296. KeyShiftHome: "shift+home",
  297. KeyShiftEnd: "shift+end",
  298. KeyCtrlShiftHome: "ctrl+shift+home",
  299. KeyCtrlShiftEnd: "ctrl+shift+end",
  300. KeyPgUp: "pgup",
  301. KeyPgDown: "pgdown",
  302. KeyCtrlPgUp: "ctrl+pgup",
  303. KeyCtrlPgDown: "ctrl+pgdown",
  304. KeyDelete: "delete",
  305. KeyInsert: "insert",
  306. KeyCtrlUp: "ctrl+up",
  307. KeyCtrlDown: "ctrl+down",
  308. KeyCtrlRight: "ctrl+right",
  309. KeyCtrlLeft: "ctrl+left",
  310. KeyShiftUp: "shift+up",
  311. KeyShiftDown: "shift+down",
  312. KeyShiftRight: "shift+right",
  313. KeyShiftLeft: "shift+left",
  314. KeyCtrlShiftUp: "ctrl+shift+up",
  315. KeyCtrlShiftDown: "ctrl+shift+down",
  316. KeyCtrlShiftLeft: "ctrl+shift+left",
  317. KeyCtrlShiftRight: "ctrl+shift+right",
  318. KeyF1: "f1",
  319. KeyF2: "f2",
  320. KeyF3: "f3",
  321. KeyF4: "f4",
  322. KeyF5: "f5",
  323. KeyF6: "f6",
  324. KeyF7: "f7",
  325. KeyF8: "f8",
  326. KeyF9: "f9",
  327. KeyF10: "f10",
  328. KeyF11: "f11",
  329. KeyF12: "f12",
  330. KeyF13: "f13",
  331. KeyF14: "f14",
  332. KeyF15: "f15",
  333. KeyF16: "f16",
  334. KeyF17: "f17",
  335. KeyF18: "f18",
  336. KeyF19: "f19",
  337. KeyF20: "f20",
  338. }
  339. // Sequence mappings.
  340. var sequences = map[string]Key{
  341. // Arrow keys
  342. "\x1b[A": {Type: KeyUp},
  343. "\x1b[B": {Type: KeyDown},
  344. "\x1b[C": {Type: KeyRight},
  345. "\x1b[D": {Type: KeyLeft},
  346. "\x1b[1;2A": {Type: KeyShiftUp},
  347. "\x1b[1;2B": {Type: KeyShiftDown},
  348. "\x1b[1;2C": {Type: KeyShiftRight},
  349. "\x1b[1;2D": {Type: KeyShiftLeft},
  350. "\x1b[OA": {Type: KeyShiftUp}, // DECCKM
  351. "\x1b[OB": {Type: KeyShiftDown}, // DECCKM
  352. "\x1b[OC": {Type: KeyShiftRight}, // DECCKM
  353. "\x1b[OD": {Type: KeyShiftLeft}, // DECCKM
  354. "\x1b[a": {Type: KeyShiftUp}, // urxvt
  355. "\x1b[b": {Type: KeyShiftDown}, // urxvt
  356. "\x1b[c": {Type: KeyShiftRight}, // urxvt
  357. "\x1b[d": {Type: KeyShiftLeft}, // urxvt
  358. "\x1b[1;3A": {Type: KeyUp, Alt: true},
  359. "\x1b[1;3B": {Type: KeyDown, Alt: true},
  360. "\x1b[1;3C": {Type: KeyRight, Alt: true},
  361. "\x1b[1;3D": {Type: KeyLeft, Alt: true},
  362. "\x1b[1;4A": {Type: KeyShiftUp, Alt: true},
  363. "\x1b[1;4B": {Type: KeyShiftDown, Alt: true},
  364. "\x1b[1;4C": {Type: KeyShiftRight, Alt: true},
  365. "\x1b[1;4D": {Type: KeyShiftLeft, Alt: true},
  366. "\x1b[1;5A": {Type: KeyCtrlUp},
  367. "\x1b[1;5B": {Type: KeyCtrlDown},
  368. "\x1b[1;5C": {Type: KeyCtrlRight},
  369. "\x1b[1;5D": {Type: KeyCtrlLeft},
  370. "\x1b[Oa": {Type: KeyCtrlUp, Alt: true}, // urxvt
  371. "\x1b[Ob": {Type: KeyCtrlDown, Alt: true}, // urxvt
  372. "\x1b[Oc": {Type: KeyCtrlRight, Alt: true}, // urxvt
  373. "\x1b[Od": {Type: KeyCtrlLeft, Alt: true}, // urxvt
  374. "\x1b[1;6A": {Type: KeyCtrlShiftUp},
  375. "\x1b[1;6B": {Type: KeyCtrlShiftDown},
  376. "\x1b[1;6C": {Type: KeyCtrlShiftRight},
  377. "\x1b[1;6D": {Type: KeyCtrlShiftLeft},
  378. "\x1b[1;7A": {Type: KeyCtrlUp, Alt: true},
  379. "\x1b[1;7B": {Type: KeyCtrlDown, Alt: true},
  380. "\x1b[1;7C": {Type: KeyCtrlRight, Alt: true},
  381. "\x1b[1;7D": {Type: KeyCtrlLeft, Alt: true},
  382. "\x1b[1;8A": {Type: KeyCtrlShiftUp, Alt: true},
  383. "\x1b[1;8B": {Type: KeyCtrlShiftDown, Alt: true},
  384. "\x1b[1;8C": {Type: KeyCtrlShiftRight, Alt: true},
  385. "\x1b[1;8D": {Type: KeyCtrlShiftLeft, Alt: true},
  386. // Miscellaneous keys
  387. "\x1b[Z": {Type: KeyShiftTab},
  388. "\x1b[2~": {Type: KeyInsert},
  389. "\x1b[3;2~": {Type: KeyInsert, Alt: true},
  390. "\x1b[3~": {Type: KeyDelete},
  391. "\x1b[3;3~": {Type: KeyDelete, Alt: true},
  392. "\x1b[5~": {Type: KeyPgUp},
  393. "\x1b[5;3~": {Type: KeyPgUp, Alt: true},
  394. "\x1b[5;5~": {Type: KeyCtrlPgUp},
  395. "\x1b[5^": {Type: KeyCtrlPgUp}, // urxvt
  396. "\x1b[5;7~": {Type: KeyCtrlPgUp, Alt: true},
  397. "\x1b[6~": {Type: KeyPgDown},
  398. "\x1b[6;3~": {Type: KeyPgDown, Alt: true},
  399. "\x1b[6;5~": {Type: KeyCtrlPgDown},
  400. "\x1b[6^": {Type: KeyCtrlPgDown}, // urxvt
  401. "\x1b[6;7~": {Type: KeyCtrlPgDown, Alt: true},
  402. "\x1b[1~": {Type: KeyHome},
  403. "\x1b[H": {Type: KeyHome}, // xterm, lxterm
  404. "\x1b[1;3H": {Type: KeyHome, Alt: true}, // xterm, lxterm
  405. "\x1b[1;5H": {Type: KeyCtrlHome}, // xterm, lxterm
  406. "\x1b[1;7H": {Type: KeyCtrlHome, Alt: true}, // xterm, lxterm
  407. "\x1b[1;2H": {Type: KeyShiftHome}, // xterm, lxterm
  408. "\x1b[1;4H": {Type: KeyShiftHome, Alt: true}, // xterm, lxterm
  409. "\x1b[1;6H": {Type: KeyCtrlShiftHome}, // xterm, lxterm
  410. "\x1b[1;8H": {Type: KeyCtrlShiftHome, Alt: true}, // xterm, lxterm
  411. "\x1b[4~": {Type: KeyEnd},
  412. "\x1b[F": {Type: KeyEnd}, // xterm, lxterm
  413. "\x1b[1;3F": {Type: KeyEnd, Alt: true}, // xterm, lxterm
  414. "\x1b[1;5F": {Type: KeyCtrlEnd}, // xterm, lxterm
  415. "\x1b[1;7F": {Type: KeyCtrlEnd, Alt: true}, // xterm, lxterm
  416. "\x1b[1;2F": {Type: KeyShiftEnd}, // xterm, lxterm
  417. "\x1b[1;4F": {Type: KeyShiftEnd, Alt: true}, // xterm, lxterm
  418. "\x1b[1;6F": {Type: KeyCtrlShiftEnd}, // xterm, lxterm
  419. "\x1b[1;8F": {Type: KeyCtrlShiftEnd, Alt: true}, // xterm, lxterm
  420. "\x1b[7~": {Type: KeyHome}, // urxvt
  421. "\x1b[7^": {Type: KeyCtrlHome}, // urxvt
  422. "\x1b[7$": {Type: KeyShiftHome}, // urxvt
  423. "\x1b[7@": {Type: KeyCtrlShiftHome}, // urxvt
  424. "\x1b[8~": {Type: KeyEnd}, // urxvt
  425. "\x1b[8^": {Type: KeyCtrlEnd}, // urxvt
  426. "\x1b[8$": {Type: KeyShiftEnd}, // urxvt
  427. "\x1b[8@": {Type: KeyCtrlShiftEnd}, // urxvt
  428. // Function keys, Linux console
  429. "\x1b[[A": {Type: KeyF1}, // linux console
  430. "\x1b[[B": {Type: KeyF2}, // linux console
  431. "\x1b[[C": {Type: KeyF3}, // linux console
  432. "\x1b[[D": {Type: KeyF4}, // linux console
  433. "\x1b[[E": {Type: KeyF5}, // linux console
  434. // Function keys, X11
  435. "\x1bOP": {Type: KeyF1}, // vt100, xterm
  436. "\x1bOQ": {Type: KeyF2}, // vt100, xterm
  437. "\x1bOR": {Type: KeyF3}, // vt100, xterm
  438. "\x1bOS": {Type: KeyF4}, // vt100, xterm
  439. "\x1b[1;3P": {Type: KeyF1, Alt: true}, // vt100, xterm
  440. "\x1b[1;3Q": {Type: KeyF2, Alt: true}, // vt100, xterm
  441. "\x1b[1;3R": {Type: KeyF3, Alt: true}, // vt100, xterm
  442. "\x1b[1;3S": {Type: KeyF4, Alt: true}, // vt100, xterm
  443. "\x1b[11~": {Type: KeyF1}, // urxvt
  444. "\x1b[12~": {Type: KeyF2}, // urxvt
  445. "\x1b[13~": {Type: KeyF3}, // urxvt
  446. "\x1b[14~": {Type: KeyF4}, // urxvt
  447. "\x1b[15~": {Type: KeyF5}, // vt100, xterm, also urxvt
  448. "\x1b[15;3~": {Type: KeyF5, Alt: true}, // vt100, xterm, also urxvt
  449. "\x1b[17~": {Type: KeyF6}, // vt100, xterm, also urxvt
  450. "\x1b[18~": {Type: KeyF7}, // vt100, xterm, also urxvt
  451. "\x1b[19~": {Type: KeyF8}, // vt100, xterm, also urxvt
  452. "\x1b[20~": {Type: KeyF9}, // vt100, xterm, also urxvt
  453. "\x1b[21~": {Type: KeyF10}, // vt100, xterm, also urxvt
  454. "\x1b[17;3~": {Type: KeyF6, Alt: true}, // vt100, xterm
  455. "\x1b[18;3~": {Type: KeyF7, Alt: true}, // vt100, xterm
  456. "\x1b[19;3~": {Type: KeyF8, Alt: true}, // vt100, xterm
  457. "\x1b[20;3~": {Type: KeyF9, Alt: true}, // vt100, xterm
  458. "\x1b[21;3~": {Type: KeyF10, Alt: true}, // vt100, xterm
  459. "\x1b[23~": {Type: KeyF11}, // vt100, xterm, also urxvt
  460. "\x1b[24~": {Type: KeyF12}, // vt100, xterm, also urxvt
  461. "\x1b[23;3~": {Type: KeyF11, Alt: true}, // vt100, xterm
  462. "\x1b[24;3~": {Type: KeyF12, Alt: true}, // vt100, xterm
  463. "\x1b[1;2P": {Type: KeyF13},
  464. "\x1b[1;2Q": {Type: KeyF14},
  465. "\x1b[25~": {Type: KeyF13}, // vt100, xterm, also urxvt
  466. "\x1b[26~": {Type: KeyF14}, // vt100, xterm, also urxvt
  467. "\x1b[25;3~": {Type: KeyF13, Alt: true}, // vt100, xterm
  468. "\x1b[26;3~": {Type: KeyF14, Alt: true}, // vt100, xterm
  469. "\x1b[1;2R": {Type: KeyF15},
  470. "\x1b[1;2S": {Type: KeyF16},
  471. "\x1b[28~": {Type: KeyF15}, // vt100, xterm, also urxvt
  472. "\x1b[29~": {Type: KeyF16}, // vt100, xterm, also urxvt
  473. "\x1b[28;3~": {Type: KeyF15, Alt: true}, // vt100, xterm
  474. "\x1b[29;3~": {Type: KeyF16, Alt: true}, // vt100, xterm
  475. "\x1b[15;2~": {Type: KeyF17},
  476. "\x1b[17;2~": {Type: KeyF18},
  477. "\x1b[18;2~": {Type: KeyF19},
  478. "\x1b[19;2~": {Type: KeyF20},
  479. "\x1b[31~": {Type: KeyF17},
  480. "\x1b[32~": {Type: KeyF18},
  481. "\x1b[33~": {Type: KeyF19},
  482. "\x1b[34~": {Type: KeyF20},
  483. // Powershell sequences.
  484. "\x1bOA": {Type: KeyUp, Alt: false},
  485. "\x1bOB": {Type: KeyDown, Alt: false},
  486. "\x1bOC": {Type: KeyRight, Alt: false},
  487. "\x1bOD": {Type: KeyLeft, Alt: false},
  488. }
  489. // unknownInputByteMsg is reported by the input reader when an invalid
  490. // utf-8 byte is detected on the input. Currently, it is not handled
  491. // further by bubbletea. However, having this event makes it possible
  492. // to troubleshoot invalid inputs.
  493. type unknownInputByteMsg byte
  494. func (u unknownInputByteMsg) String() string {
  495. return fmt.Sprintf("?%#02x?", int(u))
  496. }
  497. // unknownCSISequenceMsg is reported by the input reader when an
  498. // unrecognized CSI sequence is detected on the input. Currently, it
  499. // is not handled further by bubbletea. However, having this event
  500. // makes it possible to troubleshoot invalid inputs.
  501. type unknownCSISequenceMsg []byte
  502. func (u unknownCSISequenceMsg) String() string {
  503. return fmt.Sprintf("?CSI%+v?", []byte(u)[2:])
  504. }
  505. var spaceRunes = []rune{' '}
  506. // readAnsiInputs reads keypress and mouse inputs from a TTY and produces messages
  507. // containing information about the key or mouse events accordingly.
  508. func readAnsiInputs(ctx context.Context, msgs chan<- Msg, input io.Reader) error {
  509. var buf [256]byte
  510. var leftOverFromPrevIteration []byte
  511. loop:
  512. for {
  513. // Read and block.
  514. numBytes, err := input.Read(buf[:])
  515. if err != nil {
  516. return fmt.Errorf("error reading input: %w", err)
  517. }
  518. b := buf[:numBytes]
  519. if leftOverFromPrevIteration != nil {
  520. b = append(leftOverFromPrevIteration, b...)
  521. }
  522. // If we had a short read (numBytes < len(buf)), we're sure that
  523. // the end of this read is an event boundary, so there is no doubt
  524. // if we are encountering the end of the buffer while parsing a message.
  525. // However, if we've succeeded in filling up the buffer, there may
  526. // be more data in the OS buffer ready to be read in, to complete
  527. // the last message in the input. In that case, we will retry with
  528. // the left over data in the next iteration.
  529. canHaveMoreData := numBytes == len(buf)
  530. var i, w int
  531. for i, w = 0, 0; i < len(b); i += w {
  532. var msg Msg
  533. w, msg = detectOneMsg(b[i:], canHaveMoreData)
  534. if w == 0 {
  535. // Expecting more bytes beyond the current buffer. Try waiting
  536. // for more input.
  537. leftOverFromPrevIteration = make([]byte, 0, len(b[i:])+len(buf))
  538. leftOverFromPrevIteration = append(leftOverFromPrevIteration, b[i:]...)
  539. continue loop
  540. }
  541. select {
  542. case msgs <- msg:
  543. case <-ctx.Done():
  544. err := ctx.Err()
  545. if err != nil {
  546. err = fmt.Errorf("found context error while reading input: %w", err)
  547. }
  548. return err
  549. }
  550. }
  551. leftOverFromPrevIteration = nil
  552. }
  553. }
  554. var (
  555. unknownCSIRe = regexp.MustCompile(`^\x1b\[[\x30-\x3f]*[\x20-\x2f]*[\x40-\x7e]`)
  556. mouseSGRRegex = regexp.MustCompile(`(\d+);(\d+);(\d+)([Mm])`)
  557. )
  558. func detectOneMsg(b []byte, canHaveMoreData bool) (w int, msg Msg) {
  559. // Detect mouse events.
  560. // X10 mouse events have a length of 6 bytes
  561. const mouseEventX10Len = 6
  562. if len(b) >= mouseEventX10Len && b[0] == '\x1b' && b[1] == '[' {
  563. switch b[2] {
  564. case 'M':
  565. return mouseEventX10Len, MouseMsg(parseX10MouseEvent(b))
  566. case '<':
  567. if matchIndices := mouseSGRRegex.FindSubmatchIndex(b[3:]); matchIndices != nil {
  568. // SGR mouse events length is the length of the match plus the length of the escape sequence
  569. mouseEventSGRLen := matchIndices[1] + 3 //nolint:gomnd
  570. return mouseEventSGRLen, MouseMsg(parseSGRMouseEvent(b))
  571. }
  572. }
  573. }
  574. // Detect bracketed paste.
  575. var foundbp bool
  576. foundbp, w, msg = detectBracketedPaste(b)
  577. if foundbp {
  578. return w, msg
  579. }
  580. // Detect escape sequence and control characters other than NUL,
  581. // possibly with an escape character in front to mark the Alt
  582. // modifier.
  583. var foundSeq bool
  584. foundSeq, w, msg = detectSequence(b)
  585. if foundSeq {
  586. return w, msg
  587. }
  588. // No non-NUL control character or escape sequence.
  589. // If we are seeing at least an escape character, remember it for later below.
  590. alt := false
  591. i := 0
  592. if b[0] == '\x1b' {
  593. alt = true
  594. i++
  595. }
  596. // Are we seeing a standalone NUL? This is not handled by detectSequence().
  597. if i < len(b) && b[i] == 0 {
  598. return i + 1, KeyMsg{Type: keyNUL, Alt: alt}
  599. }
  600. // Find the longest sequence of runes that are not control
  601. // characters from this point.
  602. var runes []rune
  603. for rw := 0; i < len(b); i += rw {
  604. var r rune
  605. r, rw = utf8.DecodeRune(b[i:])
  606. if r == utf8.RuneError || r <= rune(keyUS) || r == rune(keyDEL) || r == ' ' {
  607. // Rune errors are handled below; control characters and spaces will
  608. // be handled by detectSequence in the next call to detectOneMsg.
  609. break
  610. }
  611. runes = append(runes, r)
  612. if alt {
  613. // We only support a single rune after an escape alt modifier.
  614. i += rw
  615. break
  616. }
  617. }
  618. if i >= len(b) && canHaveMoreData {
  619. // We have encountered the end of the input buffer. Alas, we can't
  620. // be sure whether the data in the remainder of the buffer is
  621. // complete (maybe there was a short read). Instead of sending anything
  622. // dumb to the message channel, do a short read. The outer loop will
  623. // handle this case by extending the buffer as necessary.
  624. return 0, nil
  625. }
  626. // If we found at least one rune, we report the bunch of them as
  627. // a single KeyRunes or KeySpace event.
  628. if len(runes) > 0 {
  629. k := Key{Type: KeyRunes, Runes: runes, Alt: alt}
  630. if len(runes) == 1 && runes[0] == ' ' {
  631. k.Type = KeySpace
  632. }
  633. return i, KeyMsg(k)
  634. }
  635. // We didn't find an escape sequence, nor a valid rune. Was this a
  636. // lone escape character at the end of the input?
  637. if alt && len(b) == 1 {
  638. return 1, KeyMsg(Key{Type: KeyEscape})
  639. }
  640. // The character at the current position is neither an escape
  641. // sequence, a valid rune start or a sole escape character. Report
  642. // it as an invalid byte.
  643. return 1, unknownInputByteMsg(b[0])
  644. }