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);