1
0
forked from aniani/vim

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.
This commit is contained in:
Bram Moolenaar 2019-11-03 21:19:41 +01:00
parent e890b9f5dd
commit 1e814bc017
4 changed files with 68 additions and 36 deletions

View File

@ -2012,7 +2012,7 @@ nv_mousescroll(cmdarg_T *cap)
if (term_use_loop())
// This window is a terminal window, send the mouse event there.
// Set "typed" to FALSE to avoid an endless loop.
send_keys_to_term(curbuf->b_term, cap->cmdchar, FALSE);
send_keys_to_term(curbuf->b_term, cap->cmdchar, mod_mask, FALSE);
else
# endif
if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL))

View File

@ -13,7 +13,7 @@ int term_try_stop_job(buf_T *buf);
int term_check_timers(int next_due_arg, proftime_T *now);
int term_in_normal_mode(void);
void term_enter_job_mode(void);
int send_keys_to_term(term_T *term, int c, int typed);
int send_keys_to_term(term_T *term, int c, int modmask, int typed);
int terminal_is_active(void);
cursorentry_T *term_get_cursor_shape(guicolor_T *fg, guicolor_T *bg);
int term_use_loop(void);

View File

@ -1226,11 +1226,12 @@ term_mouse_click(VTerm *vterm, int key)
}
/*
* Convert typed key "c" into bytes to send to the job.
* Convert typed key "c" with modifiers "modmask" into bytes to send to the
* job.
* Return the number of bytes in "buf".
*/
static int
term_convert_key(term_T *term, int c, char *buf)
term_convert_key(term_T *term, int c, int modmask, char *buf)
{
VTerm *vterm = term->tl_vterm;
VTermKey key = VTERM_KEY_NONE;
@ -1375,11 +1376,11 @@ term_convert_key(term_T *term, int c, char *buf)
}
// add modifiers for the typed key
if (mod_mask & MOD_MASK_SHIFT)
if (modmask & MOD_MASK_SHIFT)
mod |= VTERM_MOD_SHIFT;
if (mod_mask & MOD_MASK_CTRL)
if (modmask & MOD_MASK_CTRL)
mod |= VTERM_MOD_CTRL;
if (mod_mask & (MOD_MASK_ALT | MOD_MASK_META))
if (modmask & (MOD_MASK_ALT | MOD_MASK_META))
mod |= VTERM_MOD_ALT;
/*
@ -1933,12 +1934,12 @@ term_vgetc()
static int mouse_was_outside = FALSE;
/*
* Send keys to terminal.
* Send key "c" with modifiers "modmask" to terminal.
* Return FAIL when the key needs to be handled in Normal mode.
* Return OK when the key was dropped or sent to the terminal.
*/
int
send_keys_to_term(term_T *term, int c, int typed)
send_keys_to_term(term_T *term, int c, int modmask, int typed)
{
char msg[KEY_BUF_LEN];
size_t len;
@ -2005,10 +2006,10 @@ send_keys_to_term(term_T *term, int c, int typed)
if (typed)
mouse_was_outside = FALSE;
/* Convert the typed key to a sequence of bytes for the job. */
len = term_convert_key(term, c, msg);
// Convert the typed key to a sequence of bytes for the job.
len = term_convert_key(term, c, modmask, msg);
if (len > 0)
/* TODO: if FAIL is returned, stop? */
// TODO: if FAIL is returned, stop?
channel_send(term->tl_job->jv_channel, get_tty_part(term),
(char_u *)msg, (int)len, NULL);
@ -2258,6 +2259,34 @@ term_win_entered()
}
}
/*
* vgetc() may not include CTRL in the key when modify_other_keys is set.
* Return the Ctrl-key value in that case.
*/
static int
raw_c_to_ctrl(int c)
{
if ((mod_mask & MOD_MASK_CTRL)
&& ((c >= '`' && c <= 0x7f) || (c >= '@' && c <= '_')))
return c & 0x1f;
return c;
}
/*
* When modify_other_keys is set then do the reverse of raw_c_to_ctrl().
* May set "mod_mask".
*/
static int
ctrl_to_raw_c(int c)
{
if (c < 0x20 && vterm_is_modify_other_keys(curbuf->b_term->tl_vterm))
{
mod_mask |= MOD_MASK_CTRL;
return c + '@';
}
return c;
}
/*
* Wait for input and send it to the job.
* When "blocking" is TRUE wait for a character to be typed. Otherwise return
@ -2312,24 +2341,18 @@ terminal_loop(int blocking)
update_cursor(curbuf->b_term, FALSE);
restore_cursor = TRUE;
c = term_vgetc();
raw_c = term_vgetc();
if (!term_use_loop_check(TRUE) || in_terminal_loop != curbuf->b_term)
{
/* Job finished while waiting for a character. Push back the
* received character. */
if (c != K_IGNORE)
vungetc(c);
if (raw_c != K_IGNORE)
vungetc(raw_c);
break;
}
if (c == K_IGNORE)
if (raw_c == K_IGNORE)
continue;
// vgetc may not include CTRL in the key when modify_other_keys is set.
raw_c = c;
if ((mod_mask & MOD_MASK_CTRL)
&& ((c >= '`' && c <= 0x7f)
|| (c >= '@' && c <= '_')))
c &= 0x1f;
c = raw_c_to_ctrl(raw_c);
#ifdef UNIX
/*
@ -2362,12 +2385,16 @@ terminal_loop(int blocking)
)
{
int prev_c = c;
int prev_raw_c = raw_c;
int prev_mod_mask = mod_mask;
#ifdef FEAT_CMDL_INFO
if (add_to_showcmd(c))
out_flush();
#endif
c = term_vgetc();
raw_c = term_vgetc();
c = raw_c_to_ctrl(raw_c);
#ifdef FEAT_CMDL_INFO
clear_showcmd();
#endif
@ -2385,8 +2412,10 @@ terminal_loop(int blocking)
ret = FAIL;
goto theend;
}
/* Send both keys to the terminal. */
send_keys_to_term(curbuf->b_term, prev_c, TRUE);
// Send both keys to the terminal, first one here, second one
// below.
send_keys_to_term(curbuf->b_term, prev_raw_c, prev_mod_mask,
TRUE);
}
else if (c == Ctrl_C)
{
@ -2397,12 +2426,12 @@ terminal_loop(int blocking)
{
/* "CTRL-W .": send CTRL-W to the job */
/* "'termwinkey' .": send 'termwinkey' to the job */
c = termwinkey == 0 ? Ctrl_W : termwinkey;
raw_c = ctrl_to_raw_c(termwinkey == 0 ? Ctrl_W : termwinkey);
}
else if (c == Ctrl_BSL)
{
/* "CTRL-W CTRL-\": send CTRL-\ to the job */
c = Ctrl_BSL;
raw_c = ctrl_to_raw_c(Ctrl_BSL);
}
else if (c == 'N')
{
@ -2430,20 +2459,20 @@ terminal_loop(int blocking)
}
}
# ifdef MSWIN
if (!enc_utf8 && has_mbyte && c >= 0x80)
if (!enc_utf8 && has_mbyte && raw_c >= 0x80)
{
WCHAR wc;
char_u mb[3];
mb[0] = (unsigned)c >> 8;
mb[1] = c;
mb[0] = (unsigned)raw_c >> 8;
mb[1] = raw_c;
if (MultiByteToWideChar(GetACP(), 0, (char*)mb, 2, &wc, 1) > 0)
c = wc;
raw_c = wc;
}
# endif
if (send_keys_to_term(curbuf->b_term, raw_c, TRUE) != OK)
if (send_keys_to_term(curbuf->b_term, raw_c, mod_mask, TRUE) != OK)
{
if (c == K_MOUSEMOVE)
if (raw_c == K_MOUSEMOVE)
/* We are sure to come back here, don't reset the cursor color
* and shape to avoid flickering. */
restore_cursor = FALSE;
@ -5545,7 +5574,7 @@ f_term_sendkeys(typval_T *argvars, typval_T *rettv)
c = PTR2CHAR(msg);
msg += MB_CPTR2LEN(msg);
}
send_keys_to_term(term, c, FALSE);
send_keys_to_term(term, c, 0, FALSE);
}
}
@ -5811,7 +5840,8 @@ typedef int LPPROC_THREAD_ATTRIBUTE_LIST;
typedef int SIZE_T;
typedef int PSIZE_T;
typedef int PVOID;
typedef int WINAPI;
typedef int BOOL;
# define WINAPI
#endif
HRESULT (WINAPI *pCreatePseudoConsole)(COORD, HANDLE, HANDLE, DWORD, HPCON*);

View File

@ -741,6 +741,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
2248,
/**/
2247,
/**/