123456789module view1011#flag -I@VMODROOT/vendor/shim12#flag @VMODROOT/vendor/shim/koh_term.c13#include "koh_term.h"1415fn C.koh_term_raw(enable int) int1617fn C.koh_term_size(rows &int, cols &int) int1819fn C.koh_read_key(buf &char, cap int) int2021pub enum KeyKind {22 rune23 up24 down25 left26 right27 enter28 escape29 tab30 backspace31 delete32 home33 end34 page_up35 page_down36 interrupt37 eof38 unknown39}4041pub struct Key {42pub:43 kind KeyKind44 text string45}4647pub fn terminal_size() (int, int) {48 mut rows := 049 mut cols := 050 C.koh_term_size(&rows, &cols)51 return rows, cols52}5354pub fn raw_mode(enable bool) {55 if !enable {56 C.koh_term_raw(0)57 return58 }59 C.koh_term_raw(1)60}61626364pub fn read_key() Key {65 mut buf := []u8{len: 16}66 n := C.koh_read_key(unsafe { &char(buf.data) }, buf.len)67 if n <= 0 {68 return Key{69 kind: .eof70 }71 }72 return decode(buf[..n])73}7475fn decode(bytes []u8) Key {76 if bytes.len == 1 {77 b := bytes[0]78 match b {79 0x03 {80 return Key{81 kind: .interrupt82 }83 }84 0x04 {85 return Key{86 kind: .eof87 }88 }89 0x09 {90 return Key{91 kind: .tab92 }93 }94 0x0d, 0x0a {95 return Key{96 kind: .enter97 }98 }99 0x7f, 0x08 {100 return Key{101 kind: .backspace102 }103 }104 0x1b {105 return Key{106 kind: .escape107 }108 }109 else {110 if b >= 0x20 {111 return Key{112 kind: .rune113 text: bytes.bytestr()114 }115 }116 return Key{117 kind: .unknown118 }119 }120 }121 }122 if bytes[0] == 0x1b {123 sequence := bytes[1..].bytestr()124 return match sequence {125 '[A', 'OA' {126 Key{127 kind: .up128 }129 }130 '[B', 'OB' {131 Key{132 kind: .down133 }134 }135 '[C', 'OC' {136 Key{137 kind: .right138 }139 }140 '[D', 'OD' {141 Key{142 kind: .left143 }144 }145 '[H', 'OH', '[1~' {146 Key{147 kind: .home148 }149 }150 '[F', 'OF', '[4~' {151 Key{152 kind: .end153 }154 }155 '[3~' {156 Key{157 kind: .delete158 }159 }160 '[5~' {161 Key{162 kind: .page_up163 }164 }165 '[6~' {166 Key{167 kind: .page_down168 }169 }170 else {171 Key{172 kind: .escape173 }174 }175 }176 }177 178 179 return Key{180 kind: .rune181 text: bytes.bytestr()182 }183}