Skip to content

Commit 236dffa

Browse files
committed
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.
1 parent 696d0a8 commit 236dffa

File tree

3 files changed

+64
-22
lines changed

3 files changed

+64
-22
lines changed

src/term.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5244,6 +5244,9 @@ handle_osc(char_u *tp, char_u *argp, int len, char_u *key_name, int *slen)
52445244
* {flag} can be '0' or '1'
52455245
* {tail} can be Esc>\ or STERM
52465246
*
5247+
* Check for resource response from xterm (and drop it):
5248+
* {lead}{flag}+R<hex bytes>=<value>{tail}
5249+
*
52475250
* Check for cursor shape response from xterm:
52485251
* {lead}1$r<digit> q{tail}
52495252
*
@@ -5260,7 +5263,8 @@ handle_dcs(char_u *tp, char_u *argp, int len, char_u *key_name, int *slen)
52605263
j = 1 + (tp[0] == ESC);
52615264
if (len < j + 3)
52625265
i = len; // need more chars
5263-
else if ((argp[1] != '+' && argp[1] != '$') || argp[2] != 'r')
5266+
else if ((argp[1] != '+' && argp[1] != '$')
5267+
|| (argp[2] != 'r' && argp[2] != 'R'))
52645268
i = 0; // no match
52655269
else if (argp[1] == '+')
52665270
// key code response
@@ -5269,7 +5273,8 @@ handle_dcs(char_u *tp, char_u *argp, int len, char_u *key_name, int *slen)
52695273
if ((tp[i] == ESC && i + 1 < len && tp[i + 1] == '\\')
52705274
|| tp[i] == STERM)
52715275
{
5272-
if (i - j >= 3)
5276+
// handle a key code response, drop a resource response
5277+
if (i - j >= 3 && argp[2] == 'r')
52735278
got_code_from_term(tp + j, i);
52745279
key_name[0] = (int)KS_EXTRA;
52755280
key_name[1] = (int)KE_IGNORE;
@@ -5674,9 +5679,10 @@ check_termcode(
56745679

56755680
// Check for key code response from xterm,
56765681
// starting with <Esc>P or DCS
5677-
else if ((check_for_codes || rcs_status.tr_progress == STATUS_SENT)
5678-
&& ((tp[0] == ESC && len >= 2 && tp[1] == 'P')
5679-
|| tp[0] == DCS))
5682+
// It would only be needed with this condition:
5683+
// (check_for_codes || rcs_status.tr_progress == STATUS_SENT)
5684+
// Now this is always done so that DCS codes don't mess up things.
5685+
else if ((tp[0] == ESC && len >= 2 && tp[1] == 'P') || tp[0] == DCS)
56805686
{
56815687
if (handle_dcs(tp, argp, len, key_name, &slen) == FAIL)
56825688
return -1;

src/testdir/keycode_check.vim

Lines changed: 51 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ def ActionList()
134134
endif
135135
sort(terms)
136136

137-
var items = ['protocol', 'version', 'status']
137+
var items = ['protocol', 'version', 'status', 'resource']
138138
+ key_entries->copy()->map((_, v) => v[1])
139139

140140
# For each terminal compute the needed width, add two.
@@ -198,8 +198,9 @@ def DoTerm(name: string)
198198
if proto == 1
199199
&t_TI = ""
200200
elseif proto == 2
201-
# Enable modifyOtherKeys level 2 - no status is reported
202-
&t_TI = "\<Esc>[>4;2m"
201+
# Enable modifyOtherKeys level 2
202+
# Request the resource value: DCS + Q modifyOtherKeys ST
203+
&t_TI = "\<Esc>[>4;2m" .. "\<Esc>P+Q6d6f646966794f746865724b657973\<Esc>\\"
203204
proto_name = 'mok2'
204205
elseif proto == 3
205206
# Enable Kitty keyboard protocol and request the status
@@ -217,9 +218,14 @@ def DoTerm(name: string)
217218
# Pattern that matches the line with the version response.
218219
const version_pattern = "\<Esc>\\[>\\d\\+;\\d\\+;\\d*c"
219220

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+
220226
# Pattern that matches the line with the status. Currently what terminals
221227
# return for the Kitty keyboard protocol.
222-
const status_pattern = "\<Esc>\\[?\\d\\+u"
228+
const kitty_status_pattern = "\<Esc>\\[?\\d\\+u"
223229

224230
ch_logfile('keylog', 'w')
225231

@@ -244,6 +250,7 @@ def DoTerm(name: string)
244250
endfor
245251
endif
246252
if reltime(startTime)->reltimefloat() > 3
253+
# break out after three seconds
247254
break
248255
endif
249256
endwhile
@@ -257,18 +264,39 @@ def DoTerm(name: string)
257264
keycodes[name]['protocol'] = proto_name
258265
keycodes[name]['version'] = ''
259266
keycodes[name]['status'] = ''
267+
keycodes[name]['resource'] = ''
260268

261269
# Check the log file for a status and the version response
262270
ch_logfile('', '')
263271
var log = readfile('keylog')
264272
delete('keylog')
273+
265274
for line in log
266275
if line =~ 'raw key input'
267276
var code = substitute(line, '.*raw key input: "\([^"]*\).*', '\1', '')
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+
268290
# Check for kitty keyboard protocol status
269-
if code =~ status_pattern
270-
var status = substitute(code, '.*\(' .. status_pattern .. '\).*', '\1', '')
271-
keycodes[name]['status'] = Literal2hex(status)
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
272300
endif
273301

274302
if code =~ version_pattern
@@ -282,13 +310,23 @@ def DoTerm(name: string)
282310
echo "For Alt to work you may need to press the Windows/Super key as well"
283311
echo "When a key press doesn't get to Vim (e.g. when using Alt) press x"
284312

313+
# The log of ignored typeahead is left around for debugging, start with an
314+
# empty file here.
315+
delete('keylog-ignore')
316+
285317
for entry in key_entries
286318
# Consume any typeahead. Wait a bit for any responses to arrive.
287-
sleep 100m
288-
while getchar(1)
289-
getchar()
319+
ch_logfile('keylog-ignore', 'a')
320+
while 1
290321
sleep 100m
322+
if !getchar(1)
323+
break
324+
endif
325+
while getchar(1)
326+
getchar()
327+
endwhile
291328
endwhile
329+
ch_logfile('', '')
292330

293331
ch_logfile('keylog', 'w')
294332
echo $'Press the {entry[0]} key (q to quit):'
@@ -297,13 +335,9 @@ def DoTerm(name: string)
297335
if r == 'q'
298336
break
299337
endif
338+
300339
log = readfile('keylog')
301-
if entry[1] == 'Tab'
302-
# keep a copy
303-
rename('keylog', 'keylog-tab')
304-
else
305-
delete('keylog')
306-
endif
340+
delete('keylog')
307341
if len(log) < 2
308342
echoerr 'failed to read result'
309343
return
@@ -321,7 +355,7 @@ rename('keylog', 'keylog-tab')
321355
code = substitute(code, cappat, '', 'g')
322356

323357
# Remove any kitty status reply
324-
code = substitute(code, status_pattern, '', 'g')
358+
code = substitute(code, kitty_status_pattern, '', 'g')
325359
if code == ''
326360
continue
327361
endif

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,8 @@ static char *(features[]) =
695695

696696
static int included_patches[] =
697697
{ /* Add new patch number below this line */
698+
/**/
699+
903,
698700
/**/
699701
902,
700702
/**/

0 commit comments

Comments
 (0)