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 | # |
Bram Moolenaar | 94722c5 | 2023-01-28 19:19:03 +0000 | [diff] [blame] | 7 | # Author: Bram Moolenaar |
| 8 | # Last Update: 2022 Nov 15 |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 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 | cc09071 | 2022-11-27 11:31:23 +0000 | [diff] [blame] | 137 | var items = ['protocol', 'version', 'kitty', 'modkeys'] |
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" |
Bram Moolenaar | cc09071 | 2022-11-27 11:31:23 +0000 | [diff] [blame] | 197 | var proto_name = 'unknown' |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 198 | if proto == 1 |
Bram Moolenaar | cc09071 | 2022-11-27 11:31:23 +0000 | [diff] [blame] | 199 | # Request the XTQMODKEYS value and request the kitty keyboard protocol status. |
| 200 | &t_TI = "\<Esc>[?4m" .. "\<Esc>[?u" |
| 201 | proto_name = 'none' |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 202 | elseif proto == 2 |
Bram Moolenaar | cc09071 | 2022-11-27 11:31:23 +0000 | [diff] [blame] | 203 | # Enable modifyOtherKeys level 2 and request the XTQMODKEYS value. |
Bram Moolenaar | c255b78 | 2022-11-26 19:16:48 +0000 | [diff] [blame] | 204 | &t_TI = "\<Esc>[>4;2m" .. "\<Esc>[?4m" |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 205 | proto_name = 'mok2' |
| 206 | elseif proto == 3 |
Bram Moolenaar | cc09071 | 2022-11-27 11:31:23 +0000 | [diff] [blame] | 207 | # Enable Kitty keyboard protocol and request the status. |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 208 | &t_TI = "\<Esc>[>1u" .. "\<Esc>[?u" |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 209 | proto_name = 'kitty' |
| 210 | else |
| 211 | echoerr 'invalid protocol choice' |
| 212 | return |
| 213 | endif |
| 214 | |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 215 | # Append the request for the version response, this is used to check we have |
| 216 | # the results. |
| 217 | &t_TI ..= "\<Esc>[>c" |
| 218 | |
| 219 | # Pattern that matches the line with the version response. |
| 220 | const version_pattern = "\<Esc>\\[>\\d\\+;\\d\\+;\\d*c" |
| 221 | |
Bram Moolenaar | c255b78 | 2022-11-26 19:16:48 +0000 | [diff] [blame] | 222 | # Pattern that matches the XTQMODKEYS response: |
| 223 | # CSI > 4;Pv m |
| 224 | # where Pv indicates the modifyOtherKeys level |
| 225 | const modkeys_pattern = "\<Esc>\\[>4;\\dm" |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 226 | |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 227 | # Pattern that matches the line with the status. Currently what terminals |
| 228 | # return for the Kitty keyboard protocol. |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 229 | const kitty_status_pattern = "\<Esc>\\[?\\d\\+u" |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 230 | |
| 231 | ch_logfile('keylog', 'w') |
| 232 | |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 233 | # executing a dummy shell command will output t_TI |
| 234 | !echo >/dev/null |
| 235 | |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 236 | # Wait until the log file has the version response. |
| 237 | var startTime = reltime() |
| 238 | var seenVersion = false |
| 239 | while !seenVersion |
| 240 | var log = readfile('keylog') |
| 241 | if len(log) > 2 |
| 242 | for line in log |
| 243 | if line =~ 'raw key input' |
| 244 | var code = substitute(line, '.*raw key input: "\([^"]*\).*', '\1', '') |
| 245 | if code =~ version_pattern |
| 246 | seenVersion = true |
| 247 | echo 'Found the version response' |
| 248 | break |
| 249 | endif |
| 250 | endif |
| 251 | endfor |
| 252 | endif |
| 253 | if reltime(startTime)->reltimefloat() > 3 |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 254 | # break out after three seconds |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 255 | break |
| 256 | endif |
| 257 | endwhile |
| 258 | |
| 259 | echo 'seenVersion: ' seenVersion |
| 260 | |
| 261 | # Prepare the terminal entry, set protocol and clear status and version. |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 262 | if !has_key(keycodes, name) |
| 263 | keycodes[name] = {} |
| 264 | endif |
| 265 | keycodes[name]['protocol'] = proto_name |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 266 | keycodes[name]['version'] = '' |
Bram Moolenaar | cc09071 | 2022-11-27 11:31:23 +0000 | [diff] [blame] | 267 | keycodes[name]['kitty'] = '' |
Bram Moolenaar | c255b78 | 2022-11-26 19:16:48 +0000 | [diff] [blame] | 268 | keycodes[name]['modkeys'] = '' |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 269 | |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 270 | # Check the log file for a status and the version response |
| 271 | ch_logfile('', '') |
| 272 | var log = readfile('keylog') |
| 273 | delete('keylog') |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 274 | |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 275 | for line in log |
| 276 | if line =~ 'raw key input' |
| 277 | var code = substitute(line, '.*raw key input: "\([^"]*\).*', '\1', '') |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 278 | |
Bram Moolenaar | c255b78 | 2022-11-26 19:16:48 +0000 | [diff] [blame] | 279 | # Check for the XTQMODKEYS response. |
| 280 | if code =~ modkeys_pattern |
| 281 | var modkeys = substitute(code, '.*\(' .. modkeys_pattern .. '\).*', '\1', '') |
Bram Moolenaar | cc09071 | 2022-11-27 11:31:23 +0000 | [diff] [blame] | 282 | # We could get the level out of the response, but showing the response |
| 283 | # itself provides more information. |
| 284 | # modkeys = substitute(modkeys, '.*4;\(\d\)m', '\1', '') |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 285 | |
Bram Moolenaar | c255b78 | 2022-11-26 19:16:48 +0000 | [diff] [blame] | 286 | if keycodes[name]['modkeys'] != '' |
| 287 | echomsg 'Another modkeys found after ' .. keycodes[name]['modkeys'] |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 288 | endif |
Bram Moolenaar | c255b78 | 2022-11-26 19:16:48 +0000 | [diff] [blame] | 289 | keycodes[name]['modkeys'] = modkeys |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 290 | endif |
| 291 | |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 292 | # Check for kitty keyboard protocol status |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 293 | if code =~ kitty_status_pattern |
| 294 | var status = substitute(code, '.*\(' .. kitty_status_pattern .. '\).*', '\1', '') |
| 295 | # use the response itself as the status |
| 296 | status = Literal2hex(status) |
| 297 | |
Bram Moolenaar | cc09071 | 2022-11-27 11:31:23 +0000 | [diff] [blame] | 298 | if keycodes[name]['kitty'] != '' |
| 299 | echomsg 'Another status found after ' .. keycodes[name]['kitty'] |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 300 | endif |
Bram Moolenaar | cc09071 | 2022-11-27 11:31:23 +0000 | [diff] [blame] | 301 | keycodes[name]['kitty'] = status |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 302 | endif |
| 303 | |
| 304 | if code =~ version_pattern |
| 305 | var version = substitute(code, '.*\(' .. version_pattern .. '\).*', '\1', '') |
| 306 | keycodes[name]['version'] = Literal2hex(version) |
| 307 | break |
| 308 | endif |
| 309 | endif |
| 310 | endfor |
| 311 | |
| 312 | echo "For Alt to work you may need to press the Windows/Super key as well" |
| 313 | 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] | 314 | |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 315 | # The log of ignored typeahead is left around for debugging, start with an |
| 316 | # empty file here. |
| 317 | delete('keylog-ignore') |
| 318 | |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 319 | for entry in key_entries |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 320 | # Consume any typeahead. Wait a bit for any responses to arrive. |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 321 | ch_logfile('keylog-ignore', 'a') |
| 322 | while 1 |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 323 | sleep 100m |
Bram Moolenaar | c896adb | 2022-11-19 19:02:40 +0000 | [diff] [blame] | 324 | if getchar(1) == 0 |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 325 | break |
| 326 | endif |
Bram Moolenaar | c896adb | 2022-11-19 19:02:40 +0000 | [diff] [blame] | 327 | while getchar(1) != 0 |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 328 | getchar() |
| 329 | endwhile |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 330 | endwhile |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 331 | ch_logfile('', '') |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 332 | |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 333 | ch_logfile('keylog', 'w') |
| 334 | echo $'Press the {entry[0]} key (q to quit):' |
| 335 | var r = getcharstr() |
| 336 | ch_logfile('', '') |
| 337 | if r == 'q' |
| 338 | break |
| 339 | endif |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 340 | |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 341 | log = readfile('keylog') |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 342 | delete('keylog') |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 343 | if len(log) < 2 |
| 344 | echoerr 'failed to read result' |
| 345 | return |
| 346 | endif |
| 347 | var done = false |
| 348 | for line in log |
| 349 | if line =~ 'raw key input' |
| 350 | var code = substitute(line, '.*raw key input: "\([^"]*\).*', '\1', '') |
| 351 | |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 352 | # Remove any version termresponse |
| 353 | code = substitute(code, version_pattern, '', 'g') |
| 354 | |
| 355 | # Remove any XTGETTCAP replies. |
| 356 | const cappat = "\<Esc>P[01]+\\k\\+=\\x*\<Esc>\\\\" |
| 357 | code = substitute(code, cappat, '', 'g') |
| 358 | |
| 359 | # Remove any kitty status reply |
Bram Moolenaar | 236dffa | 2022-11-18 21:20:25 +0000 | [diff] [blame] | 360 | code = substitute(code, kitty_status_pattern, '', 'g') |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 361 | if code == '' |
| 362 | continue |
| 363 | endif |
| 364 | |
| 365 | # Convert the literal bytes into hex. If 'x' was pressed then clear |
| 366 | # the entry. |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 367 | var hex = '' |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 368 | if code != 'x' |
| 369 | hex = Literal2hex(code) |
| 370 | endif |
| 371 | |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 372 | keycodes[name][entry[1]] = hex |
| 373 | done = true |
| 374 | break |
| 375 | endif |
| 376 | endfor |
| 377 | if !done |
| 378 | echo 'Code not found in log' |
| 379 | endif |
| 380 | endfor |
| 381 | enddef |
| 382 | |
| 383 | # Action: Add key codes for a new terminal. |
| 384 | def ActionAdd() |
| 385 | var name = input('Enter name of the terminal: ') |
| 386 | echo "\n" |
| 387 | if index(keys(keycodes), name) >= 0 |
| 388 | echoerr $'Terminal {name} already exists' |
| 389 | return |
| 390 | endif |
| 391 | |
| 392 | DoTerm(name) |
| 393 | enddef |
| 394 | |
| 395 | # Action: Replace key codes for an already known terminal. |
| 396 | def ActionReplace() |
| 397 | var terms = keys(keycodes) |
| 398 | if len(terms) == 0 |
| 399 | echo 'No terminal results yet' |
| 400 | return |
| 401 | endif |
| 402 | |
| 403 | var choice = inputlist(['Select:'] + terms->copy()->map((idx, arg) => (idx + 1) .. ': ' .. arg)) |
| 404 | echo "\n" |
| 405 | if choice > 0 && choice <= len(terms) |
| 406 | DoTerm(terms[choice - 1]) |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 407 | else |
| 408 | echo 'invalid index' |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 409 | endif |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 410 | enddef |
| 411 | |
| 412 | # Action: Clear key codes for an already known terminal. |
| 413 | def ActionClear() |
| 414 | var terms = keys(keycodes) |
| 415 | if len(terms) == 0 |
| 416 | echo 'No terminal results yet' |
| 417 | return |
| 418 | endif |
| 419 | |
| 420 | var choice = inputlist(['Select:'] + terms->copy()->map((idx, arg) => (idx + 1) .. ': ' .. arg)) |
| 421 | echo "\n" |
| 422 | if choice > 0 && choice <= len(terms) |
| 423 | remove(keycodes, terms[choice - 1]) |
| 424 | else |
| 425 | echo 'invalid index' |
| 426 | endif |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 427 | enddef |
| 428 | |
| 429 | # Action: Quit, possibly after saving the results first. |
| 430 | def ActionQuit() |
| 431 | # If nothing was changed just quit |
| 432 | if keycodes == orig_keycodes |
| 433 | quit |
| 434 | endif |
| 435 | |
| 436 | while true |
| 437 | var res = input("Save the changed key codes (y/n)? ") |
| 438 | if res == 'n' |
| 439 | quit |
| 440 | endif |
| 441 | if res == 'y' |
| 442 | WriteKeycodes() |
| 443 | quit |
| 444 | endif |
| 445 | echo 'invalid reply' |
| 446 | endwhile |
| 447 | enddef |
| 448 | |
| 449 | # The main loop |
| 450 | while true |
| 451 | var action = inputlist(['Select operation:', |
Bram Moolenaar | 94722c5 | 2023-01-28 19:19:03 +0000 | [diff] [blame] | 452 | '1. List results', |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 453 | '2. Add results for a new terminal', |
| 454 | '3. Replace results', |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 455 | '4. Clear results', |
| 456 | '5. Quit', |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 457 | ]) |
| 458 | echo "\n" |
| 459 | if action == 1 |
| 460 | ActionList() |
| 461 | elseif action == 2 |
| 462 | ActionAdd() |
| 463 | elseif action == 3 |
| 464 | ActionReplace() |
| 465 | elseif action == 4 |
Bram Moolenaar | 8303035 | 2022-11-16 16:08:30 +0000 | [diff] [blame] | 466 | ActionClear() |
| 467 | elseif action == 5 |
Bram Moolenaar | a44c781 | 2022-11-15 22:59:07 +0000 | [diff] [blame] | 468 | ActionQuit() |
| 469 | endif |
| 470 | endwhile |