Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 1 | vim9script |
| 2 | |
| 3 | # Script to get various codes that keys send, depending on the protocol used. |
| 4 | # |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 5 | # Usage: vim -u NONE -S keycode_check.vim |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 6 | # |
| 7 | # Author: Bram Moolenaar |
| 8 | # Last Update: 2022 Nov 15 |
| 9 | # |
| 10 | # The codes are stored in the file "keycode_check.json", so that you can |
| 11 | # compare the results of various terminals. |
| 12 | # |
| 13 | # You can select what protocol to enable: |
| 14 | # - None |
| 15 | # - modifyOtherKeys level 2 |
| 16 | # - kitty keyboard protocol |
| 17 | |
| 18 | # Change directory to where this script is, so that the json file is found |
| 19 | # there. |
| 20 | exe 'cd ' .. expand('<sfile>:h') |
| 21 | echo 'working in directory: ' .. getcwd() |
| 22 | |
| 23 | const filename = 'keycode_check.json' |
| 24 | |
| 25 | # Dictionary of dictionaries with the results in the form: |
| 26 | # {'xterm': {protocol: 'none', 'Tab': '09', 'S-Tab': '09'}, |
| 27 | # 'xterm2': {protocol: 'mok2', 'Tab': '09', 'S-Tab': '09'}, |
| 28 | # 'kitty': {protocol: 'kitty', 'Tab': '09', 'S-Tab': '09'}, |
| 29 | # } |
| 30 | # The values are in hex form. |
| 31 | var keycodes = {} |
| 32 | |
| 33 | if filereadable(filename) |
| 34 | keycodes = readfile(filename)->join()->json_decode() |
| 35 | else |
| 36 | # Use some dummy entries to try out with |
| 37 | keycodes = { |
| 38 | 'xterm': {protocol: 'none', 'Tab': '09', 'S-Tab': '09'}, |
| 39 | 'kitty': {protocol: 'kitty', 'Tab': '09', 'S-Tab': '1b5b393b3275'}, |
| 40 | } |
| 41 | endif |
| 42 | var orig_keycodes = deepcopy(keycodes) # used to detect something changed |
| 43 | |
| 44 | # Write the "keycodes" variable in JSON form to "filename". |
| 45 | def WriteKeycodes() |
| 46 | # If the file already exists move it to become the backup file. |
| 47 | if filereadable(filename) |
| 48 | if rename(filename, filename .. '~') |
| 49 | echoerr $'Renaming {filename} to {filename}~ failed!' |
| 50 | return |
| 51 | endif |
| 52 | endif |
| 53 | |
| 54 | if writefile([json_encode(keycodes)], filename) != 0 |
| 55 | echoerr $'Writing {filename} failed!' |
| 56 | endif |
| 57 | enddef |
| 58 | |
| 59 | # The key entries that we want to list, in this order. |
| 60 | # The first item is displayed in the prompt, the second is the key in |
| 61 | # the keycodes dictionary. |
| 62 | var key_entries = [ |
| 63 | ['Tab', 'Tab'], |
| 64 | ['Shift-Tab', 'S-Tab'], |
| 65 | ['Ctrl-Tab', 'C-Tab'], |
| 66 | ['Alt-Tab', 'A-Tab'], |
| 67 | ['Ctrl-I', 'C-I'], |
| 68 | ['Shift-Ctrl-I', 'S-C-I'], |
| 69 | ['Esc', 'Esc'], |
| 70 | ['Shift-Esc', 'S-Esc'], |
| 71 | ['Ctrl-Esc', 'C-Esc'], |
| 72 | ['Alt-Esc', 'A-Esc'], |
| 73 | ['Space', 'Space'], |
| 74 | ['Shift-Space', 'S-Space'], |
| 75 | ['Ctrl-Space', 'C-Space'], |
| 76 | ['Alt-Space', 'A-Space'], |
| 77 | ] |
| 78 | |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 79 | # Given a terminal name and a item name, return the text to display. |
| 80 | def GetItemDisplay(term: string, item: string): string |
| 81 | var val = get(keycodes[term], item, '') |
| 82 | |
| 83 | # see if we can pretty-print this one |
| 84 | var pretty = val |
| 85 | if val[0 : 1] == '1b' |
| 86 | pretty = 'ESC' |
| 87 | var idx = 2 |
| 88 | |
| 89 | if val[0 : 3] == '1b5b' |
| 90 | pretty = 'CSI' |
| 91 | idx = 4 |
| 92 | endif |
| 93 | |
| 94 | var digits = false |
| 95 | while idx < len(val) |
| 96 | var cc = val[idx : idx + 1] |
| 97 | var nr = str2nr('0x' .. cc, 16) |
| 98 | idx += 2 |
| 99 | if nr >= char2nr('0') && nr <= char2nr('9') |
| 100 | if !digits |
| 101 | pretty ..= ' ' |
| 102 | endif |
| 103 | digits = true |
| 104 | pretty ..= cc[1] |
| 105 | else |
| 106 | if nr == char2nr(';') && digits |
| 107 | # don't use space between semicolon and digits to keep it short |
| 108 | pretty ..= ';' |
| 109 | else |
| 110 | digits = false |
| 111 | if nr >= char2nr(' ') && nr <= char2nr('~') |
| 112 | # printable character |
| 113 | pretty ..= ' ' .. printf('%c', nr) |
| 114 | else |
| 115 | # non-printable, use hex code |
| 116 | pretty = val |
| 117 | break |
| 118 | endif |
| 119 | endif |
| 120 | endif |
| 121 | endwhile |
| 122 | endif |
| 123 | |
| 124 | return pretty |
| 125 | enddef |
| 126 | |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 127 | |
| 128 | # Action: list the information in "keycodes" in a more or less nice way. |
| 129 | def ActionList() |
| 130 | var terms = keys(keycodes) |
| 131 | if len(terms) == 0 |
| 132 | echo 'No terminal results yet' |
| 133 | return |
| 134 | endif |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 135 | sort(terms) |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 136 | |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 137 | var items = ['protocol', 'version', 'status', 'resource'] |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 138 | + key_entries->copy()->map((_, v) => v[1]) |
| 139 | |
| 140 | # For each terminal compute the needed width, add two. |
| 141 | # You may need to increase the terminal width to avoid wrapping. |
| 142 | var widths = [] |
| 143 | for [idx, term] in items(terms) |
| 144 | widths[idx] = len(term) + 2 |
| 145 | endfor |
| 146 | |
| 147 | for item in items |
| 148 | for [idx, term] in items(terms) |
| 149 | var l = len(GetItemDisplay(term, item)) |
| 150 | if widths[idx] < l + 2 |
| 151 | widths[idx] = l + 2 |
| 152 | endif |
| 153 | endfor |
| 154 | endfor |
| 155 | |
| 156 | # Use one column of width 10 for the item name. |
| 157 | echo "\n" |
| 158 | echon ' ' |
| 159 | for [idx, term] in items(terms) |
| 160 | echon printf('%-' .. widths[idx] .. 's', term) |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 161 | endfor |
| 162 | echo "\n" |
| 163 | |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 164 | for item in items |
| 165 | echon printf('%8s ', item) |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 166 | for [idx, term] in items(terms) |
| 167 | echon printf('%-' .. widths[idx] .. 's', GetItemDisplay(term, item)) |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 168 | endfor |
| 169 | echo '' |
| 170 | endfor |
| 171 | echo "\n" |
| 172 | enddef |
| 173 | |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 174 | # Convert the literal string after "raw key input" into hex form. |
| 175 | def Literal2hex(code: string): string |
| 176 | var hex = '' |
| 177 | for i in range(len(code)) |
| 178 | hex ..= printf('%02x', char2nr(code[i])) |
| 179 | endfor |
| 180 | return hex |
| 181 | enddef |
| 182 | |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 183 | def GetTermName(): string |
| 184 | var name = input('Enter the name of the terminal: ') |
| 185 | return name |
| 186 | enddef |
| 187 | |
| 188 | # Gather key codes for terminal "name". |
| 189 | def DoTerm(name: string) |
| 190 | var proto = inputlist([$'What protocol to enable for {name}:', |
| 191 | '1. None', |
| 192 | '2. modifyOtherKeys level 2', |
| 193 | '3. kitty', |
| 194 | ]) |
| 195 | echo "\n" |
| 196 | &t_TE = "\<Esc>[>4;m" |
| 197 | var proto_name = 'none' |
| 198 | if proto == 1 |
| 199 | &t_TI = "" |
| 200 | elseif proto == 2 |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 201 | # Enable modifyOtherKeys level 2 |
| 202 | # Request the resource value: DCS + Q modifyOtherKeys ST |
| 203 | &t_TI = "\<Esc>[>4;2m" .. "\<Esc>P+Q6d6f646966794f746865724b657973\<Esc>\\" |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 204 | proto_name = 'mok2' |
| 205 | elseif proto == 3 |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 206 | # Enable Kitty keyboard protocol and request the status |
| 207 | &t_TI = "\<Esc>[>1u" .. "\<Esc>[?u" |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 208 | proto_name = 'kitty' |
| 209 | else |
| 210 | echoerr 'invalid protocol choice' |
| 211 | return |
| 212 | endif |
| 213 | |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 214 | # Append the request for the version response, this is used to check we have |
| 215 | # the results. |
| 216 | &t_TI ..= "\<Esc>[>c" |
| 217 | |
| 218 | # Pattern that matches the line with the version response. |
| 219 | const version_pattern = "\<Esc>\\[>\\d\\+;\\d\\+;\\d*c" |
| 220 | |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 221 | # Pattern that matches the resource value response: |
| 222 | # DCS 1 + R Pt ST valid |
| 223 | # DCS 0 + R Pt ST invalid |
| 224 | const resource_pattern = "\<Esc>P[01]+R.*\<Esc>\\\\" |
| 225 | |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 226 | # Pattern that matches the line with the status. Currently what terminals |
| 227 | # return for the Kitty keyboard protocol. |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 228 | const kitty_status_pattern = "\<Esc>\\[?\\d\\+u" |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 229 | |
| 230 | ch_logfile('keylog', 'w') |
| 231 | |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 232 | # executing a dummy shell command will output t_TI |
| 233 | !echo >/dev/null |
| 234 | |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 235 | # Wait until the log file has the version response. |
| 236 | var startTime = reltime() |
| 237 | var seenVersion = false |
| 238 | while !seenVersion |
| 239 | var log = readfile('keylog') |
| 240 | if len(log) > 2 |
| 241 | for line in log |
| 242 | if line =~ 'raw key input' |
| 243 | var code = substitute(line, '.*raw key input: "\([^"]*\).*', '\1', '') |
| 244 | if code =~ version_pattern |
| 245 | seenVersion = true |
| 246 | echo 'Found the version response' |
| 247 | break |
| 248 | endif |
| 249 | endif |
| 250 | endfor |
| 251 | endif |
| 252 | if reltime(startTime)->reltimefloat() > 3 |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 253 | # break out after three seconds |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 254 | break |
| 255 | endif |
| 256 | endwhile |
| 257 | |
| 258 | echo 'seenVersion: ' seenVersion |
| 259 | |
| 260 | # Prepare the terminal entry, set protocol and clear status and version. |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 261 | if !has_key(keycodes, name) |
| 262 | keycodes[name] = {} |
| 263 | endif |
| 264 | keycodes[name]['protocol'] = proto_name |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 265 | keycodes[name]['version'] = '' |
| 266 | keycodes[name]['status'] = '' |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 267 | keycodes[name]['resource'] = '' |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 268 | |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 269 | # Check the log file for a status and the version response |
| 270 | ch_logfile('', '') |
| 271 | var log = readfile('keylog') |
| 272 | delete('keylog') |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 273 | |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 274 | for line in log |
| 275 | if line =~ 'raw key input' |
| 276 | var code = substitute(line, '.*raw key input: "\([^"]*\).*', '\1', '') |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 277 | |
| 278 | # Check for resource value response |
| 279 | if code =~ resource_pattern |
| 280 | var resource = substitute(code, '.*\(' .. resource_pattern .. '\).*', '\1', '') |
| 281 | # use the value as the resource, "=30" means zero |
| 282 | resource = substitute(resource, '.*\(=\p\+\).*', '\1', '') |
| 283 | |
| 284 | if keycodes[name]['resource'] != '' |
| 285 | echomsg 'Another resource found after ' .. keycodes[name]['resource'] |
| 286 | endif |
| 287 | keycodes[name]['resource'] = resource |
| 288 | endif |
| 289 | |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 290 | # Check for kitty keyboard protocol status |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 291 | if code =~ kitty_status_pattern |
| 292 | var status = substitute(code, '.*\(' .. kitty_status_pattern .. '\).*', '\1', '') |
| 293 | # use the response itself as the status |
| 294 | status = Literal2hex(status) |
| 295 | |
| 296 | if keycodes[name]['status'] != '' |
| 297 | echomsg 'Another status found after ' .. keycodes[name]['status'] |
| 298 | endif |
| 299 | keycodes[name]['status'] = status |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 300 | endif |
| 301 | |
| 302 | if code =~ version_pattern |
| 303 | var version = substitute(code, '.*\(' .. version_pattern .. '\).*', '\1', '') |
| 304 | keycodes[name]['version'] = Literal2hex(version) |
| 305 | break |
| 306 | endif |
| 307 | endif |
| 308 | endfor |
| 309 | |
| 310 | echo "For Alt to work you may need to press the Windows/Super key as well" |
| 311 | echo "When a key press doesn't get to Vim (e.g. when using Alt) press x" |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 312 | |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 313 | # The log of ignored typeahead is left around for debugging, start with an |
| 314 | # empty file here. |
| 315 | delete('keylog-ignore') |
| 316 | |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 317 | for entry in key_entries |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 318 | # Consume any typeahead. Wait a bit for any responses to arrive. |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 319 | ch_logfile('keylog-ignore', 'a') |
| 320 | while 1 |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 321 | sleep 100m |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 322 | if !getchar(1) |
| 323 | break |
| 324 | endif |
| 325 | while getchar(1) |
| 326 | getchar() |
| 327 | endwhile |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 328 | endwhile |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 329 | ch_logfile('', '') |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 330 | |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 331 | ch_logfile('keylog', 'w') |
| 332 | echo $'Press the {entry[0]} key (q to quit):' |
| 333 | var r = getcharstr() |
| 334 | ch_logfile('', '') |
| 335 | if r == 'q' |
| 336 | break |
| 337 | endif |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 338 | |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 339 | log = readfile('keylog') |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 340 | delete('keylog') |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 341 | if len(log) < 2 |
| 342 | echoerr 'failed to read result' |
| 343 | return |
| 344 | endif |
| 345 | var done = false |
| 346 | for line in log |
| 347 | if line =~ 'raw key input' |
| 348 | var code = substitute(line, '.*raw key input: "\([^"]*\).*', '\1', '') |
| 349 | |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 350 | # Remove any version termresponse |
| 351 | code = substitute(code, version_pattern, '', 'g') |
| 352 | |
| 353 | # Remove any XTGETTCAP replies. |
| 354 | const cappat = "\<Esc>P[01]+\\k\\+=\\x*\<Esc>\\\\" |
| 355 | code = substitute(code, cappat, '', 'g') |
| 356 | |
| 357 | # Remove any kitty status reply |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 358 | code = substitute(code, kitty_status_pattern, '', 'g') |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 359 | if code == '' |
| 360 | continue |
| 361 | endif |
| 362 | |
| 363 | # Convert the literal bytes into hex. If 'x' was pressed then clear |
| 364 | # the entry. |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 365 | var hex = '' |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 366 | if code != 'x' |
| 367 | hex = Literal2hex(code) |
| 368 | endif |
| 369 | |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 370 | keycodes[name][entry[1]] = hex |
| 371 | done = true |
| 372 | break |
| 373 | endif |
| 374 | endfor |
| 375 | if !done |
| 376 | echo 'Code not found in log' |
| 377 | endif |
| 378 | endfor |
| 379 | enddef |
| 380 | |
| 381 | # Action: Add key codes for a new terminal. |
| 382 | def ActionAdd() |
| 383 | var name = input('Enter name of the terminal: ') |
| 384 | echo "\n" |
| 385 | if index(keys(keycodes), name) >= 0 |
| 386 | echoerr $'Terminal {name} already exists' |
| 387 | return |
| 388 | endif |
| 389 | |
| 390 | DoTerm(name) |
| 391 | enddef |
| 392 | |
| 393 | # Action: Replace key codes for an already known terminal. |
| 394 | def ActionReplace() |
| 395 | var terms = keys(keycodes) |
| 396 | if len(terms) == 0 |
| 397 | echo 'No terminal results yet' |
| 398 | return |
| 399 | endif |
| 400 | |
| 401 | var choice = inputlist(['Select:'] + terms->copy()->map((idx, arg) => (idx + 1) .. ': ' .. arg)) |
| 402 | echo "\n" |
| 403 | if choice > 0 && choice <= len(terms) |
| 404 | DoTerm(terms[choice - 1]) |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 405 | else |
| 406 | echo 'invalid index' |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 407 | endif |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 408 | enddef |
| 409 | |
| 410 | # Action: Clear key codes for an already known terminal. |
| 411 | def ActionClear() |
| 412 | var terms = keys(keycodes) |
| 413 | if len(terms) == 0 |
| 414 | echo 'No terminal results yet' |
| 415 | return |
| 416 | endif |
| 417 | |
| 418 | var choice = inputlist(['Select:'] + terms->copy()->map((idx, arg) => (idx + 1) .. ': ' .. arg)) |
| 419 | echo "\n" |
| 420 | if choice > 0 && choice <= len(terms) |
| 421 | remove(keycodes, terms[choice - 1]) |
| 422 | else |
| 423 | echo 'invalid index' |
| 424 | endif |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 425 | enddef |
| 426 | |
| 427 | # Action: Quit, possibly after saving the results first. |
| 428 | def ActionQuit() |
| 429 | # If nothing was changed just quit |
| 430 | if keycodes == orig_keycodes |
| 431 | quit |
| 432 | endif |
| 433 | |
| 434 | while true |
| 435 | var res = input("Save the changed key codes (y/n)? ") |
| 436 | if res == 'n' |
| 437 | quit |
| 438 | endif |
| 439 | if res == 'y' |
| 440 | WriteKeycodes() |
| 441 | quit |
| 442 | endif |
| 443 | echo 'invalid reply' |
| 444 | endwhile |
| 445 | enddef |
| 446 | |
| 447 | # The main loop |
| 448 | while true |
| 449 | var action = inputlist(['Select operation:', |
| 450 | '1. List results', |
| 451 | '2. Add results for a new terminal', |
| 452 | '3. Replace results', |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 453 | '4. Clear results', |
| 454 | '5. Quit', |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 455 | ]) |
| 456 | echo "\n" |
| 457 | if action == 1 |
| 458 | ActionList() |
| 459 | elseif action == 2 |
| 460 | ActionAdd() |
| 461 | elseif action == 3 |
| 462 | ActionReplace() |
| 463 | elseif action == 4 |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 464 | ActionClear() |
| 465 | elseif action == 5 |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 466 | ActionQuit() |
| 467 | endif |
| 468 | endwhile |