# HG changeset patch # User Bram Moolenaar # Date 1668807004 -3600 # Node ID 548241980a274bd111697662b5a646fb7c9085a4 # Parent 9423dacd1538fe1e639048891f0f61afa09cfadc patch 9.0.0903: key code checker doesn't check modifyOtherKeys resource Commit: https://github.com/vim/vim/commit/236dffab43f919bdbc565e6edc38eb27e7a5b657 Author: Bram Moolenaar Date: Fri Nov 18 21:20:25 2022 +0000 patch 9.0.0903: key code checker doesn't check modifyOtherKeys resource Problem: Key code checker doesn't check modifyOtherKeys resource. Solution: Request the modifyOtherKeys resource value. Drop resource DCS responses. diff --git a/src/term.c b/src/term.c --- a/src/term.c +++ b/src/term.c @@ -5244,6 +5244,9 @@ handle_osc(char_u *tp, char_u *argp, int * {flag} can be '0' or '1' * {tail} can be Esc>\ or STERM * + * Check for resource response from xterm (and drop it): + * {lead}{flag}+R={tail} + * * Check for cursor shape response from xterm: * {lead}1$r q{tail} * @@ -5260,7 +5263,8 @@ handle_dcs(char_u *tp, char_u *argp, int j = 1 + (tp[0] == ESC); if (len < j + 3) i = len; // need more chars - else if ((argp[1] != '+' && argp[1] != '$') || argp[2] != 'r') + else if ((argp[1] != '+' && argp[1] != '$') + || (argp[2] != 'r' && argp[2] != 'R')) i = 0; // no match else if (argp[1] == '+') // key code response @@ -5269,7 +5273,8 @@ handle_dcs(char_u *tp, char_u *argp, int if ((tp[i] == ESC && i + 1 < len && tp[i + 1] == '\\') || tp[i] == STERM) { - if (i - j >= 3) + // handle a key code response, drop a resource response + if (i - j >= 3 && argp[2] == 'r') got_code_from_term(tp + j, i); key_name[0] = (int)KS_EXTRA; key_name[1] = (int)KE_IGNORE; @@ -5674,9 +5679,10 @@ check_termcode( // Check for key code response from xterm, // starting with P or DCS - else if ((check_for_codes || rcs_status.tr_progress == STATUS_SENT) - && ((tp[0] == ESC && len >= 2 && tp[1] == 'P') - || tp[0] == DCS)) + // It would only be needed with this condition: + // (check_for_codes || rcs_status.tr_progress == STATUS_SENT) + // Now this is always done so that DCS codes don't mess up things. + else if ((tp[0] == ESC && len >= 2 && tp[1] == 'P') || tp[0] == DCS) { if (handle_dcs(tp, argp, len, key_name, &slen) == FAIL) return -1; diff --git a/src/testdir/keycode_check.vim b/src/testdir/keycode_check.vim --- a/src/testdir/keycode_check.vim +++ b/src/testdir/keycode_check.vim @@ -134,7 +134,7 @@ def ActionList() endif sort(terms) - var items = ['protocol', 'version', 'status'] + var items = ['protocol', 'version', 'status', 'resource'] + key_entries->copy()->map((_, v) => v[1]) # For each terminal compute the needed width, add two. @@ -198,8 +198,9 @@ def DoTerm(name: string) if proto == 1 &t_TI = "" elseif proto == 2 - # Enable modifyOtherKeys level 2 - no status is reported - &t_TI = "\[>4;2m" + # Enable modifyOtherKeys level 2 + # Request the resource value: DCS + Q modifyOtherKeys ST + &t_TI = "\[>4;2m" .. "\P+Q6d6f646966794f746865724b657973\\\" proto_name = 'mok2' elseif proto == 3 # Enable Kitty keyboard protocol and request the status @@ -217,9 +218,14 @@ def DoTerm(name: string) # Pattern that matches the line with the version response. const version_pattern = "\\\[>\\d\\+;\\d\\+;\\d*c" + # Pattern that matches the resource value response: + # DCS 1 + R Pt ST valid + # DCS 0 + R Pt ST invalid + const resource_pattern = "\P[01]+R.*\\\\\" + # Pattern that matches the line with the status. Currently what terminals # return for the Kitty keyboard protocol. - const status_pattern = "\\\[?\\d\\+u" + const kitty_status_pattern = "\\\[?\\d\\+u" ch_logfile('keylog', 'w') @@ -244,6 +250,7 @@ def DoTerm(name: string) endfor endif if reltime(startTime)->reltimefloat() > 3 + # break out after three seconds break endif endwhile @@ -257,18 +264,39 @@ def DoTerm(name: string) keycodes[name]['protocol'] = proto_name keycodes[name]['version'] = '' keycodes[name]['status'] = '' + keycodes[name]['resource'] = '' # 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 resource value response + if code =~ resource_pattern + var resource = substitute(code, '.*\(' .. resource_pattern .. '\).*', '\1', '') + # use the value as the resource, "=30" means zero + resource = substitute(resource, '.*\(=\p\+\).*', '\1', '') + + if keycodes[name]['resource'] != '' + echomsg 'Another resource found after ' .. keycodes[name]['resource'] + endif + keycodes[name]['resource'] = resource + endif + # Check for kitty keyboard protocol status - if code =~ status_pattern - var status = substitute(code, '.*\(' .. status_pattern .. '\).*', '\1', '') - keycodes[name]['status'] = Literal2hex(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]['status'] != '' + echomsg 'Another status found after ' .. keycodes[name]['status'] + endif + keycodes[name]['status'] = status endif if code =~ version_pattern @@ -282,13 +310,23 @@ def DoTerm(name: string) 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. - sleep 100m - while getchar(1) - getchar() + ch_logfile('keylog-ignore', 'a') + while 1 sleep 100m + if !getchar(1) + break + endif + while getchar(1) + getchar() + endwhile endwhile + ch_logfile('', '') ch_logfile('keylog', 'w') echo $'Press the {entry[0]} key (q to quit):' @@ -297,13 +335,9 @@ def DoTerm(name: string) if r == 'q' break endif + log = readfile('keylog') - if entry[1] == 'Tab' -# keep a copy -rename('keylog', 'keylog-tab') - else - delete('keylog') - endif + delete('keylog') if len(log) < 2 echoerr 'failed to read result' return @@ -321,7 +355,7 @@ rename('keylog', 'keylog-tab') code = substitute(code, cappat, '', 'g') # Remove any kitty status reply - code = substitute(code, status_pattern, '', 'g') + code = substitute(code, kitty_status_pattern, '', 'g') if code == '' continue endif diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -696,6 +696,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 903, +/**/ 902, /**/ 901,