diff options
Diffstat (limited to 'uvim/src/testdir/keycode_check.vim')
| -rw-r--r-- | uvim/src/testdir/keycode_check.vim | 471 |
1 files changed, 0 insertions, 471 deletions
diff --git a/uvim/src/testdir/keycode_check.vim b/uvim/src/testdir/keycode_check.vim deleted file mode 100644 index 33eb6ceeb7..0000000000 --- a/uvim/src/testdir/keycode_check.vim +++ /dev/null @@ -1,471 +0,0 @@ -vim9script - -# Script to get various codes that keys send, depending on the protocol used. -# -# Usage: vim -u NONE -S keycode_check.vim -# -# Author: Bram Moolenaar -# Last Update: 2022 Nov 15 -# -# The codes are stored in the file "keycode_check.json", so that you can -# compare the results of various terminals. -# -# You can select what protocol to enable: -# - None -# - modifyOtherKeys level 2 -# - kitty keyboard protocol - -# Change directory to where this script is, so that the json file is found -# there. -exe 'cd ' .. expand('<sfile>:h') -echo 'working in directory: ' .. getcwd() - -const filename = 'keycode_check.json' - -# Dictionary of dictionaries with the results in the form: -# {'xterm': {protocol: 'none', 'Tab': '09', 'S-Tab': '09'}, -# 'xterm2': {protocol: 'mok2', 'Tab': '09', 'S-Tab': '09'}, -# 'kitty': {protocol: 'kitty', 'Tab': '09', 'S-Tab': '09'}, -# } -# The values are in hex form. -var keycodes = {} - -if filereadable(filename) - keycodes = readfile(filename)->join()->json_decode() -else - # Use some dummy entries to try out with - keycodes = { - 'xterm': {protocol: 'none', 'Tab': '09', 'S-Tab': '09'}, - 'kitty': {protocol: 'kitty', 'Tab': '09', 'S-Tab': '1b5b393b3275'}, - } -endif -var orig_keycodes = deepcopy(keycodes) # used to detect something changed - -# Write the "keycodes" variable in JSON form to "filename". -def WriteKeycodes() - # If the file already exists move it to become the backup file. - if filereadable(filename) - if rename(filename, filename .. '~') - echoerr $'Renaming {filename} to {filename}~ failed!' - return - endif - endif - - if writefile([json_encode(keycodes)], filename) != 0 - echoerr $'Writing {filename} failed!' - endif -enddef - -# The key entries that we want to list, in this order. -# The first item is displayed in the prompt, the second is the key in -# the keycodes dictionary. -var key_entries = [ - ['Tab', 'Tab'], - ['Shift-Tab', 'S-Tab'], - ['Ctrl-Tab', 'C-Tab'], - ['Alt-Tab', 'A-Tab'], - ['Ctrl-I', 'C-I'], - ['Shift-Ctrl-I', 'S-C-I'], - ['Esc', 'Esc'], - ['Shift-Esc', 'S-Esc'], - ['Ctrl-Esc', 'C-Esc'], - ['Alt-Esc', 'A-Esc'], - ['Space', 'Space'], - ['Shift-Space', 'S-Space'], - ['Ctrl-Space', 'C-Space'], - ['Alt-Space', 'A-Space'], - ['F3', 'F3'], - ] - -# Given a terminal name and a item name, return the text to display. -def GetItemDisplay(term: string, item: string): string - var val = get(keycodes[term], item, '') - - # see if we can pretty-print this one - var pretty = val - if val[0 : 1] == '1b' - pretty = 'ESC' - var idx = 2 - - if val[0 : 3] == '1b5b' - pretty = 'CSI' - idx = 4 - endif - - var digits = false - while idx < len(val) - var cc = val[idx : idx + 1] - var nr = str2nr('0x' .. cc, 16) - idx += 2 - if nr >= char2nr('0') && nr <= char2nr('9') - if !digits - pretty ..= ' ' - endif - digits = true - pretty ..= cc[1] - else - if nr == char2nr(';') && digits - # don't use space between semicolon and digits to keep it short - pretty ..= ';' - else - digits = false - if nr >= char2nr(' ') && nr <= char2nr('~') - # printable character - pretty ..= ' ' .. printf('%c', nr) - else - # non-printable, use hex code - pretty = val - break - endif - endif - endif - endwhile - endif - - return pretty -enddef - - -# Action: list the information in "keycodes" in a more or less nice way. -def ActionList() - var terms = keys(keycodes) - if len(terms) == 0 - echo 'No terminal results yet' - return - endif - sort(terms) - - var items = ['protocol', 'version', 'kitty', 'modkeys'] - + key_entries->copy()->map((_, v) => v[1]) - - # For each terminal compute the needed width, add two. - # You may need to increase the terminal width to avoid wrapping. - var widths = [] - for [idx, term] in items(terms) - widths[idx] = len(term) + 2 - endfor - - for item in items - for [idx, term] in items(terms) - var l = len(GetItemDisplay(term, item)) - if widths[idx] < l + 2 - widths[idx] = l + 2 - endif - endfor - endfor - - # Use one column of width 10 for the item name. - echo "\n" - echon ' ' - for [idx, term] in items(terms) - echon printf('%-' .. widths[idx] .. 's', term) - endfor - echo "\n" - - for item in items - echon printf('%8s ', item) - for [idx, term] in items(terms) - echon printf('%-' .. widths[idx] .. 's', GetItemDisplay(term, item)) - endfor - echo '' - endfor - echo "\n" -enddef - -# Convert the literal string after "raw key input" into hex form. -def Literal2hex(code: string): string - var hex = '' - for i in range(len(code)) - hex ..= printf('%02x', char2nr(code[i])) - endfor - return hex -enddef - -def GetTermName(): string - var name = input('Enter the name of the terminal: ') - return name -enddef - -# Gather key codes for terminal "name". -def DoTerm(name: string) - var proto = inputlist([$'What protocol to enable for {name}:', - '1. None', - '2. modifyOtherKeys level 2', - '3. kitty', - ]) - echo "\n" - &t_TE = "\<Esc>[>4;m" - var proto_name = 'unknown' - if proto == 1 - # Request the XTQMODKEYS value and request the kitty keyboard protocol status. - &t_TI = "\<Esc>[?4m" .. "\<Esc>[?u" - proto_name = 'none' - elseif proto == 2 - # Enable modifyOtherKeys level 2 and request the XTQMODKEYS value. - &t_TI = "\<Esc>[>4;2m" .. "\<Esc>[?4m" - proto_name = 'mok2' - elseif proto == 3 - # Enable Kitty keyboard protocol and request the status. - &t_TI = "\<Esc>[>1u" .. "\<Esc>[?u" - proto_name = 'kitty' - else - echoerr 'invalid protocol choice' - return - endif - - # Append the request for the version response, this is used to check we have - # the results. - &t_TI ..= "\<Esc>[>c" - - # Pattern that matches the line with the version response. - const version_pattern = "\<Esc>\\[>\\d\\+;\\d\\+;\\d*c" - - # Pattern that matches the XTQMODKEYS response: - # CSI > 4;Pv m - # where Pv indicates the modifyOtherKeys level - const modkeys_pattern = "\<Esc>\\[>4;\\dm" - - # Pattern that matches the line with the status. Currently what terminals - # return for the Kitty keyboard protocol. - const kitty_status_pattern = "\<Esc>\\[?\\d\\+u" - - ch_logfile('keylog', 'w') - - # executing a dummy shell command will output t_TI - !echo >/dev/null - - # Wait until the log file has the version response. - var startTime = reltime() - var seenVersion = false - while !seenVersion - var log = readfile('keylog') - if len(log) > 2 - for line in log - if line =~ 'raw key input' - var code = substitute(line, '.*raw key input: "\([^"]*\).*', '\1', '') - if code =~ version_pattern - seenVersion = true - echo 'Found the version response' - break - endif - endif - endfor - endif - if reltime(startTime)->reltimefloat() > 3 - # break out after three seconds - break - endif - endwhile - - echo 'seenVersion: ' seenVersion - - # Prepare the terminal entry, set protocol and clear status and version. - if !has_key(keycodes, name) - keycodes[name] = {} - endif - keycodes[name]['protocol'] = proto_name - keycodes[name]['version'] = '' - keycodes[name]['kitty'] = '' - keycodes[name]['modkeys'] = '' - - # Check the log file for a status and the version response - ch_logfile('', '') - var log = readfile('keylog') - delete('keylog') - - for line in log - if line =~ 'raw key input' - var code = substitute(line, '.*raw key input: "\([^"]*\).*', '\1', '') - - # Check for the XTQMODKEYS response. - if code =~ modkeys_pattern - var modkeys = substitute(code, '.*\(' .. modkeys_pattern .. '\).*', '\1', '') - # We could get the level out of the response, but showing the response - # itself provides more information. - # modkeys = substitute(modkeys, '.*4;\(\d\)m', '\1', '') - - if keycodes[name]['modkeys'] != '' - echomsg 'Another modkeys found after ' .. keycodes[name]['modkeys'] - endif - keycodes[name]['modkeys'] = modkeys - endif - - # Check for kitty keyboard protocol status - if code =~ kitty_status_pattern - var status = substitute(code, '.*\(' .. kitty_status_pattern .. '\).*', '\1', '') - # use the response itself as the status - status = Literal2hex(status) - - if keycodes[name]['kitty'] != '' - echomsg 'Another status found after ' .. keycodes[name]['kitty'] - endif - keycodes[name]['kitty'] = status - endif - - if code =~ version_pattern - var version = substitute(code, '.*\(' .. version_pattern .. '\).*', '\1', '') - keycodes[name]['version'] = Literal2hex(version) - break - endif - endif - endfor - - echo "For Alt to work you may need to press the Windows/Super key as well" - echo "When a key press doesn't get to Vim (e.g. when using Alt) press x" - - # The log of ignored typeahead is left around for debugging, start with an - # empty file here. - delete('keylog-ignore') - - for entry in key_entries - # Consume any typeahead. Wait a bit for any responses to arrive. - ch_logfile('keylog-ignore', 'a') - while 1 - sleep 100m - if getchar(1) == 0 - break - endif - while getchar(1) != 0 - getchar() - endwhile - endwhile - ch_logfile('', '') - - ch_logfile('keylog', 'w') - echo $'Press the {entry[0]} key (q to quit):' - var r = getcharstr() - ch_logfile('', '') - if r == 'q' - break - endif - - log = readfile('keylog') - delete('keylog') - if len(log) < 2 - echoerr 'failed to read result' - return - endif - var done = false - for line in log - if line =~ 'raw key input' - var code = substitute(line, '.*raw key input: "\([^"]*\).*', '\1', '') - - # Remove any version termresponse - code = substitute(code, version_pattern, '', 'g') - - # Remove any XTGETTCAP replies. - const cappat = "\<Esc>P[01]+\\k\\+=\\x*\<Esc>\\\\" - code = substitute(code, cappat, '', 'g') - - # Remove any kitty status reply - code = substitute(code, kitty_status_pattern, '', 'g') - if code == '' - continue - endif - - # Convert the literal bytes into hex. If 'x' was pressed then clear - # the entry. - var hex = '' - if code != 'x' - hex = Literal2hex(code) - endif - - keycodes[name][entry[1]] = hex - done = true - break - endif - endfor - if !done - echo 'Code not found in log' - endif - endfor -enddef - -# Action: Add key codes for a new terminal. -def ActionAdd() - var name = input('Enter name of the terminal: ') - echo "\n" - if index(keys(keycodes), name) >= 0 - echoerr $'Terminal {name} already exists' - return - endif - - DoTerm(name) -enddef - -# Action: Replace key codes for an already known terminal. -def ActionReplace() - var terms = keys(keycodes) - if len(terms) == 0 - echo 'No terminal results yet' - return - endif - - var choice = inputlist(['Select:'] + terms->copy()->map((idx, arg) => (idx + 1) .. ': ' .. arg)) - echo "\n" - if choice > 0 && choice <= len(terms) - DoTerm(terms[choice - 1]) - else - echo 'invalid index' - endif -enddef - -# Action: Clear key codes for an already known terminal. -def ActionClear() - var terms = keys(keycodes) - if len(terms) == 0 - echo 'No terminal results yet' - return - endif - - var choice = inputlist(['Select:'] + terms->copy()->map((idx, arg) => (idx + 1) .. ': ' .. arg)) - echo "\n" - if choice > 0 && choice <= len(terms) - remove(keycodes, terms[choice - 1]) - else - echo 'invalid index' - endif -enddef - -# Action: Quit, possibly after saving the results first. -def ActionQuit() - # If nothing was changed just quit - if keycodes == orig_keycodes - quit - endif - - while true - var res = input("Save the changed key codes (y/n)? ") - if res == 'n' - quit - endif - if res == 'y' - WriteKeycodes() - quit - endif - echo 'invalid reply' - endwhile -enddef - -# The main loop -while true - var action = inputlist(['Select operation:', - '1. List results', - '2. Add results for a new terminal', - '3. Replace results', - '4. Clear results', - '5. Quit', - ]) - echo "\n" - if action == 1 - ActionList() - elseif action == 2 - ActionAdd() - elseif action == 3 - ActionReplace() - elseif action == 4 - ActionClear() - elseif action == 5 || action == 0 - ActionQuit() - endif -endwhile |
