Mercurial > vim
comparison src/terminal.c @ 18508:3cd689e9eb7f v8.1.2248
patch 8.1.2248: CTRL-W dot does not work when modifyOtherKeys is enabled
Commit: https://github.com/vim/vim/commit/1e814bc017907209a66af82f8fb76c6d1fc324aa
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Nov 3 21:19:41 2019 +0100
patch 8.1.2248: CTRL-W dot does not work when modifyOtherKeys is enabled
Problem: CTRL-W dot does not work in a terminal when modifyOtherKeys is
enabled.
Solution: Use the modifier when needed. Pass the modifier along with the
key to avoid mistakes.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 03 Nov 2019 21:30:04 +0100 |
parents | 507348b211b4 |
children | 39b0c28fe495 |
comparison
equal
deleted
inserted
replaced
18507:5cab7eef0829 | 18508:3cd689e9eb7f |
---|---|
1224 } | 1224 } |
1225 return TRUE; | 1225 return TRUE; |
1226 } | 1226 } |
1227 | 1227 |
1228 /* | 1228 /* |
1229 * Convert typed key "c" into bytes to send to the job. | 1229 * Convert typed key "c" with modifiers "modmask" into bytes to send to the |
1230 * job. | |
1230 * Return the number of bytes in "buf". | 1231 * Return the number of bytes in "buf". |
1231 */ | 1232 */ |
1232 static int | 1233 static int |
1233 term_convert_key(term_T *term, int c, char *buf) | 1234 term_convert_key(term_T *term, int c, int modmask, char *buf) |
1234 { | 1235 { |
1235 VTerm *vterm = term->tl_vterm; | 1236 VTerm *vterm = term->tl_vterm; |
1236 VTermKey key = VTERM_KEY_NONE; | 1237 VTermKey key = VTERM_KEY_NONE; |
1237 VTermModifier mod = VTERM_MOD_NONE; | 1238 VTermModifier mod = VTERM_MOD_NONE; |
1238 int other = FALSE; | 1239 int other = FALSE; |
1373 other = TRUE; | 1374 other = TRUE; |
1374 break; | 1375 break; |
1375 } | 1376 } |
1376 | 1377 |
1377 // add modifiers for the typed key | 1378 // add modifiers for the typed key |
1378 if (mod_mask & MOD_MASK_SHIFT) | 1379 if (modmask & MOD_MASK_SHIFT) |
1379 mod |= VTERM_MOD_SHIFT; | 1380 mod |= VTERM_MOD_SHIFT; |
1380 if (mod_mask & MOD_MASK_CTRL) | 1381 if (modmask & MOD_MASK_CTRL) |
1381 mod |= VTERM_MOD_CTRL; | 1382 mod |= VTERM_MOD_CTRL; |
1382 if (mod_mask & (MOD_MASK_ALT | MOD_MASK_META)) | 1383 if (modmask & (MOD_MASK_ALT | MOD_MASK_META)) |
1383 mod |= VTERM_MOD_ALT; | 1384 mod |= VTERM_MOD_ALT; |
1384 | 1385 |
1385 /* | 1386 /* |
1386 * Convert special keys to vterm keys: | 1387 * Convert special keys to vterm keys: |
1387 * - Write keys to vterm: vterm_keyboard_key() | 1388 * - Write keys to vterm: vterm_keyboard_key() |
1931 } | 1932 } |
1932 | 1933 |
1933 static int mouse_was_outside = FALSE; | 1934 static int mouse_was_outside = FALSE; |
1934 | 1935 |
1935 /* | 1936 /* |
1936 * Send keys to terminal. | 1937 * Send key "c" with modifiers "modmask" to terminal. |
1937 * Return FAIL when the key needs to be handled in Normal mode. | 1938 * Return FAIL when the key needs to be handled in Normal mode. |
1938 * Return OK when the key was dropped or sent to the terminal. | 1939 * Return OK when the key was dropped or sent to the terminal. |
1939 */ | 1940 */ |
1940 int | 1941 int |
1941 send_keys_to_term(term_T *term, int c, int typed) | 1942 send_keys_to_term(term_T *term, int c, int modmask, int typed) |
1942 { | 1943 { |
1943 char msg[KEY_BUF_LEN]; | 1944 char msg[KEY_BUF_LEN]; |
1944 size_t len; | 1945 size_t len; |
1945 int dragging_outside = FALSE; | 1946 int dragging_outside = FALSE; |
1946 | 1947 |
2003 } | 2004 } |
2004 } | 2005 } |
2005 if (typed) | 2006 if (typed) |
2006 mouse_was_outside = FALSE; | 2007 mouse_was_outside = FALSE; |
2007 | 2008 |
2008 /* Convert the typed key to a sequence of bytes for the job. */ | 2009 // Convert the typed key to a sequence of bytes for the job. |
2009 len = term_convert_key(term, c, msg); | 2010 len = term_convert_key(term, c, modmask, msg); |
2010 if (len > 0) | 2011 if (len > 0) |
2011 /* TODO: if FAIL is returned, stop? */ | 2012 // TODO: if FAIL is returned, stop? |
2012 channel_send(term->tl_job->jv_channel, get_tty_part(term), | 2013 channel_send(term->tl_job->jv_channel, get_tty_part(term), |
2013 (char_u *)msg, (int)len, NULL); | 2014 (char_u *)msg, (int)len, NULL); |
2014 | 2015 |
2015 return OK; | 2016 return OK; |
2016 } | 2017 } |
2257 enter_mouse_row = mouse_row; | 2258 enter_mouse_row = mouse_row; |
2258 } | 2259 } |
2259 } | 2260 } |
2260 | 2261 |
2261 /* | 2262 /* |
2263 * vgetc() may not include CTRL in the key when modify_other_keys is set. | |
2264 * Return the Ctrl-key value in that case. | |
2265 */ | |
2266 static int | |
2267 raw_c_to_ctrl(int c) | |
2268 { | |
2269 if ((mod_mask & MOD_MASK_CTRL) | |
2270 && ((c >= '`' && c <= 0x7f) || (c >= '@' && c <= '_'))) | |
2271 return c & 0x1f; | |
2272 return c; | |
2273 } | |
2274 | |
2275 /* | |
2276 * When modify_other_keys is set then do the reverse of raw_c_to_ctrl(). | |
2277 * May set "mod_mask". | |
2278 */ | |
2279 static int | |
2280 ctrl_to_raw_c(int c) | |
2281 { | |
2282 if (c < 0x20 && vterm_is_modify_other_keys(curbuf->b_term->tl_vterm)) | |
2283 { | |
2284 mod_mask |= MOD_MASK_CTRL; | |
2285 return c + '@'; | |
2286 } | |
2287 return c; | |
2288 } | |
2289 | |
2290 /* | |
2262 * Wait for input and send it to the job. | 2291 * Wait for input and send it to the job. |
2263 * When "blocking" is TRUE wait for a character to be typed. Otherwise return | 2292 * When "blocking" is TRUE wait for a character to be typed. Otherwise return |
2264 * when there is no more typahead. | 2293 * when there is no more typahead. |
2265 * Return when the start of a CTRL-W command is typed or anything else that | 2294 * Return when the start of a CTRL-W command is typed or anything else that |
2266 * should be handled as a Normal mode command. | 2295 * should be handled as a Normal mode command. |
2310 break; | 2339 break; |
2311 | 2340 |
2312 update_cursor(curbuf->b_term, FALSE); | 2341 update_cursor(curbuf->b_term, FALSE); |
2313 restore_cursor = TRUE; | 2342 restore_cursor = TRUE; |
2314 | 2343 |
2315 c = term_vgetc(); | 2344 raw_c = term_vgetc(); |
2316 if (!term_use_loop_check(TRUE) || in_terminal_loop != curbuf->b_term) | 2345 if (!term_use_loop_check(TRUE) || in_terminal_loop != curbuf->b_term) |
2317 { | 2346 { |
2318 /* Job finished while waiting for a character. Push back the | 2347 /* Job finished while waiting for a character. Push back the |
2319 * received character. */ | 2348 * received character. */ |
2320 if (c != K_IGNORE) | 2349 if (raw_c != K_IGNORE) |
2321 vungetc(c); | 2350 vungetc(raw_c); |
2322 break; | 2351 break; |
2323 } | 2352 } |
2324 if (c == K_IGNORE) | 2353 if (raw_c == K_IGNORE) |
2325 continue; | 2354 continue; |
2326 | 2355 c = raw_c_to_ctrl(raw_c); |
2327 // vgetc may not include CTRL in the key when modify_other_keys is set. | |
2328 raw_c = c; | |
2329 if ((mod_mask & MOD_MASK_CTRL) | |
2330 && ((c >= '`' && c <= 0x7f) | |
2331 || (c >= '@' && c <= '_'))) | |
2332 c &= 0x1f; | |
2333 | 2356 |
2334 #ifdef UNIX | 2357 #ifdef UNIX |
2335 /* | 2358 /* |
2336 * The shell or another program may change the tty settings. Getting | 2359 * The shell or another program may change the tty settings. Getting |
2337 * them for every typed character is a bit of overhead, but it's needed | 2360 * them for every typed character is a bit of overhead, but it's needed |
2360 && !curbuf->b_term->tl_system | 2383 && !curbuf->b_term->tl_system |
2361 #endif | 2384 #endif |
2362 ) | 2385 ) |
2363 { | 2386 { |
2364 int prev_c = c; | 2387 int prev_c = c; |
2388 int prev_raw_c = raw_c; | |
2389 int prev_mod_mask = mod_mask; | |
2365 | 2390 |
2366 #ifdef FEAT_CMDL_INFO | 2391 #ifdef FEAT_CMDL_INFO |
2367 if (add_to_showcmd(c)) | 2392 if (add_to_showcmd(c)) |
2368 out_flush(); | 2393 out_flush(); |
2369 #endif | 2394 #endif |
2370 c = term_vgetc(); | 2395 raw_c = term_vgetc(); |
2396 c = raw_c_to_ctrl(raw_c); | |
2397 | |
2371 #ifdef FEAT_CMDL_INFO | 2398 #ifdef FEAT_CMDL_INFO |
2372 clear_showcmd(); | 2399 clear_showcmd(); |
2373 #endif | 2400 #endif |
2374 if (!term_use_loop_check(TRUE) | 2401 if (!term_use_loop_check(TRUE) |
2375 || in_terminal_loop != curbuf->b_term) | 2402 || in_terminal_loop != curbuf->b_term) |
2383 /* CTRL-\ CTRL-N : go to Terminal-Normal mode. */ | 2410 /* CTRL-\ CTRL-N : go to Terminal-Normal mode. */ |
2384 term_enter_normal_mode(); | 2411 term_enter_normal_mode(); |
2385 ret = FAIL; | 2412 ret = FAIL; |
2386 goto theend; | 2413 goto theend; |
2387 } | 2414 } |
2388 /* Send both keys to the terminal. */ | 2415 // Send both keys to the terminal, first one here, second one |
2389 send_keys_to_term(curbuf->b_term, prev_c, TRUE); | 2416 // below. |
2417 send_keys_to_term(curbuf->b_term, prev_raw_c, prev_mod_mask, | |
2418 TRUE); | |
2390 } | 2419 } |
2391 else if (c == Ctrl_C) | 2420 else if (c == Ctrl_C) |
2392 { | 2421 { |
2393 /* "CTRL-W CTRL-C" or 'termwinkey' CTRL-C: end the job */ | 2422 /* "CTRL-W CTRL-C" or 'termwinkey' CTRL-C: end the job */ |
2394 mch_signal_job(curbuf->b_term->tl_job, (char_u *)"kill"); | 2423 mch_signal_job(curbuf->b_term->tl_job, (char_u *)"kill"); |
2395 } | 2424 } |
2396 else if (c == '.') | 2425 else if (c == '.') |
2397 { | 2426 { |
2398 /* "CTRL-W .": send CTRL-W to the job */ | 2427 /* "CTRL-W .": send CTRL-W to the job */ |
2399 /* "'termwinkey' .": send 'termwinkey' to the job */ | 2428 /* "'termwinkey' .": send 'termwinkey' to the job */ |
2400 c = termwinkey == 0 ? Ctrl_W : termwinkey; | 2429 raw_c = ctrl_to_raw_c(termwinkey == 0 ? Ctrl_W : termwinkey); |
2401 } | 2430 } |
2402 else if (c == Ctrl_BSL) | 2431 else if (c == Ctrl_BSL) |
2403 { | 2432 { |
2404 /* "CTRL-W CTRL-\": send CTRL-\ to the job */ | 2433 /* "CTRL-W CTRL-\": send CTRL-\ to the job */ |
2405 c = Ctrl_BSL; | 2434 raw_c = ctrl_to_raw_c(Ctrl_BSL); |
2406 } | 2435 } |
2407 else if (c == 'N') | 2436 else if (c == 'N') |
2408 { | 2437 { |
2409 /* CTRL-W N : go to Terminal-Normal mode. */ | 2438 /* CTRL-W N : go to Terminal-Normal mode. */ |
2410 term_enter_normal_mode(); | 2439 term_enter_normal_mode(); |
2428 ret = OK; | 2457 ret = OK; |
2429 goto theend; | 2458 goto theend; |
2430 } | 2459 } |
2431 } | 2460 } |
2432 # ifdef MSWIN | 2461 # ifdef MSWIN |
2433 if (!enc_utf8 && has_mbyte && c >= 0x80) | 2462 if (!enc_utf8 && has_mbyte && raw_c >= 0x80) |
2434 { | 2463 { |
2435 WCHAR wc; | 2464 WCHAR wc; |
2436 char_u mb[3]; | 2465 char_u mb[3]; |
2437 | 2466 |
2438 mb[0] = (unsigned)c >> 8; | 2467 mb[0] = (unsigned)raw_c >> 8; |
2439 mb[1] = c; | 2468 mb[1] = raw_c; |
2440 if (MultiByteToWideChar(GetACP(), 0, (char*)mb, 2, &wc, 1) > 0) | 2469 if (MultiByteToWideChar(GetACP(), 0, (char*)mb, 2, &wc, 1) > 0) |
2441 c = wc; | 2470 raw_c = wc; |
2442 } | 2471 } |
2443 # endif | 2472 # endif |
2444 if (send_keys_to_term(curbuf->b_term, raw_c, TRUE) != OK) | 2473 if (send_keys_to_term(curbuf->b_term, raw_c, mod_mask, TRUE) != OK) |
2445 { | 2474 { |
2446 if (c == K_MOUSEMOVE) | 2475 if (raw_c == K_MOUSEMOVE) |
2447 /* We are sure to come back here, don't reset the cursor color | 2476 /* We are sure to come back here, don't reset the cursor color |
2448 * and shape to avoid flickering. */ | 2477 * and shape to avoid flickering. */ |
2449 restore_cursor = FALSE; | 2478 restore_cursor = FALSE; |
2450 | 2479 |
2451 ret = OK; | 2480 ret = OK; |
5543 else | 5572 else |
5544 { | 5573 { |
5545 c = PTR2CHAR(msg); | 5574 c = PTR2CHAR(msg); |
5546 msg += MB_CPTR2LEN(msg); | 5575 msg += MB_CPTR2LEN(msg); |
5547 } | 5576 } |
5548 send_keys_to_term(term, c, FALSE); | 5577 send_keys_to_term(term, c, 0, FALSE); |
5549 } | 5578 } |
5550 } | 5579 } |
5551 | 5580 |
5552 #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) || defined(PROTO) | 5581 #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) || defined(PROTO) |
5553 /* | 5582 /* |
5809 typedef int HRESULT; | 5838 typedef int HRESULT; |
5810 typedef int LPPROC_THREAD_ATTRIBUTE_LIST; | 5839 typedef int LPPROC_THREAD_ATTRIBUTE_LIST; |
5811 typedef int SIZE_T; | 5840 typedef int SIZE_T; |
5812 typedef int PSIZE_T; | 5841 typedef int PSIZE_T; |
5813 typedef int PVOID; | 5842 typedef int PVOID; |
5814 typedef int WINAPI; | 5843 typedef int BOOL; |
5844 # define WINAPI | |
5815 #endif | 5845 #endif |
5816 | 5846 |
5817 HRESULT (WINAPI *pCreatePseudoConsole)(COORD, HANDLE, HANDLE, DWORD, HPCON*); | 5847 HRESULT (WINAPI *pCreatePseudoConsole)(COORD, HANDLE, HANDLE, DWORD, HPCON*); |
5818 HRESULT (WINAPI *pResizePseudoConsole)(HPCON, COORD); | 5848 HRESULT (WINAPI *pResizePseudoConsole)(HPCON, COORD); |
5819 HRESULT (WINAPI *pClosePseudoConsole)(HPCON); | 5849 HRESULT (WINAPI *pClosePseudoConsole)(HPCON); |