Patch 8.1.2248
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.
Files: src/terminal.c, src/proto/terminal.pro, src/mouse.c
*** ../vim-8.1.2247/src/terminal.c 2019-10-26 16:21:34.511468348 +0200
--- src/terminal.c 2019-11-03 20:58:13.371134721 +0100
***************
*** 1226,1236 ****
}
/*
! * Convert typed key "c" 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)
{
VTerm *vterm = term->tl_vterm;
VTermKey key = VTERM_KEY_NONE;
--- 1226,1237 ----
}
/*
! * 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, int modmask, char *buf)
{
VTerm *vterm = term->tl_vterm;
VTermKey key = VTERM_KEY_NONE;
***************
*** 1375,1385 ****
}
// add modifiers for the typed key
! if (mod_mask & MOD_MASK_SHIFT)
mod |= VTERM_MOD_SHIFT;
! if (mod_mask & MOD_MASK_CTRL)
mod |= VTERM_MOD_CTRL;
! if (mod_mask & (MOD_MASK_ALT | MOD_MASK_META))
mod |= VTERM_MOD_ALT;
/*
--- 1376,1386 ----
}
// add modifiers for the typed key
! if (modmask & MOD_MASK_SHIFT)
mod |= VTERM_MOD_SHIFT;
! if (modmask & MOD_MASK_CTRL)
mod |= VTERM_MOD_CTRL;
! if (modmask & (MOD_MASK_ALT | MOD_MASK_META))
mod |= VTERM_MOD_ALT;
/*
***************
*** 1933,1944 ****
static int mouse_was_outside = FALSE;
/*
! * Send keys 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)
{
char msg[KEY_BUF_LEN];
size_t len;
--- 1934,1945 ----
static int mouse_was_outside = FALSE;
/*
! * 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 modmask, int typed)
{
char msg[KEY_BUF_LEN];
size_t len;
***************
*** 2005,2014 ****
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);
if (len > 0)
! /* TODO: if FAIL is returned, stop? */
channel_send(term->tl_job->jv_channel, get_tty_part(term),
(char_u *)msg, (int)len, NULL);
--- 2006,2015 ----
if (typed)
mouse_was_outside = FALSE;
! // 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?
channel_send(term->tl_job->jv_channel, get_tty_part(term),
(char_u *)msg, (int)len, NULL);
***************
*** 2259,2264 ****
--- 2260,2293 ----
}
/*
+ * 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
* when there is no more typahead.
***************
*** 2312,2335 ****
update_cursor(curbuf->b_term, FALSE);
restore_cursor = TRUE;
! 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);
break;
}
! if (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;
#ifdef UNIX
/*
--- 2341,2358 ----
update_cursor(curbuf->b_term, FALSE);
restore_cursor = TRUE;
! 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 (raw_c != K_IGNORE)
! vungetc(raw_c);
break;
}
! if (raw_c == K_IGNORE)
continue;
! c = raw_c_to_ctrl(raw_c);
#ifdef UNIX
/*
***************
*** 2362,2373 ****
)
{
int prev_c = c;
#ifdef FEAT_CMDL_INFO
if (add_to_showcmd(c))
out_flush();
#endif
! c = term_vgetc();
#ifdef FEAT_CMDL_INFO
clear_showcmd();
#endif
--- 2385,2400 ----
)
{
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
! raw_c = term_vgetc();
! c = raw_c_to_ctrl(raw_c);
!
#ifdef FEAT_CMDL_INFO
clear_showcmd();
#endif
***************
*** 2385,2392 ****
ret = FAIL;
goto theend;
}
! /* Send both keys to the terminal. */
! send_keys_to_term(curbuf->b_term, prev_c, TRUE);
}
else if (c == Ctrl_C)
{
--- 2412,2421 ----
ret = FAIL;
goto theend;
}
! // 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,2408 ****
{
/* "CTRL-W .": send CTRL-W to the job */
/* "'termwinkey' .": send 'termwinkey' to the job */
! c = termwinkey == 0 ? Ctrl_W : termwinkey;
}
else if (c == Ctrl_BSL)
{
/* "CTRL-W CTRL-\": send CTRL-\ to the job */
! c = Ctrl_BSL;
}
else if (c == 'N')
{
--- 2426,2437 ----
{
/* "CTRL-W .": send CTRL-W to the job */
/* "'termwinkey' .": send 'termwinkey' to the job */
! raw_c = ctrl_to_raw_c(termwinkey == 0 ? Ctrl_W : termwinkey);
}
else if (c == Ctrl_BSL)
{
/* "CTRL-W CTRL-\": send CTRL-\ to the job */
! raw_c = ctrl_to_raw_c(Ctrl_BSL);
}
else if (c == 'N')
{
***************
*** 2430,2449 ****
}
}
# ifdef MSWIN
! if (!enc_utf8 && has_mbyte && c >= 0x80)
{
WCHAR wc;
char_u mb[3];
! mb[0] = (unsigned)c >> 8;
! mb[1] = c;
if (MultiByteToWideChar(GetACP(), 0, (char*)mb, 2, &wc, 1) > 0)
! c = wc;
}
# endif
! if (send_keys_to_term(curbuf->b_term, raw_c, TRUE) != OK)
{
! if (c == K_MOUSEMOVE)
/* We are sure to come back here, don't reset the cursor color
* and shape to avoid flickering. */
restore_cursor = FALSE;
--- 2459,2478 ----
}
}
# ifdef MSWIN
! if (!enc_utf8 && has_mbyte && raw_c >= 0x80)
{
WCHAR wc;
char_u mb[3];
! mb[0] = (unsigned)raw_c >> 8;
! mb[1] = raw_c;
if (MultiByteToWideChar(GetACP(), 0, (char*)mb, 2, &wc, 1) > 0)
! raw_c = wc;
}
# endif
! if (send_keys_to_term(curbuf->b_term, raw_c, mod_mask, TRUE) != OK)
{
! 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,5551 ****
c = PTR2CHAR(msg);
msg += MB_CPTR2LEN(msg);
}
! send_keys_to_term(term, c, FALSE);
}
}
--- 5574,5580 ----
c = PTR2CHAR(msg);
msg += MB_CPTR2LEN(msg);
}
! send_keys_to_term(term, c, 0, FALSE);
}
}
***************
*** 5811,5817 ****
typedef int SIZE_T;
typedef int PSIZE_T;
typedef int PVOID;
! typedef int WINAPI;
#endif
HRESULT (WINAPI *pCreatePseudoConsole)(COORD, HANDLE, HANDLE, DWORD, HPCON*);
--- 5840,5847 ----
typedef int SIZE_T;
typedef int PSIZE_T;
typedef int PVOID;
! typedef int BOOL;
! # define WINAPI
#endif
HRESULT (WINAPI *pCreatePseudoConsole)(COORD, HANDLE, HANDLE, DWORD, HPCON*);
*** ../vim-8.1.2247/src/proto/terminal.pro 2019-09-26 23:08:10.501926883
+0200
--- src/proto/terminal.pro 2019-11-03 20:58:15.111125061 +0100
***************
*** 13,19 ****
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 terminal_is_active(void);
cursorentry_T *term_get_cursor_shape(guicolor_T *fg, guicolor_T *bg);
int term_use_loop(void);
--- 13,19 ----
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 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);
*** ../vim-8.1.2247/src/mouse.c 2019-10-17 22:58:59.066497012 +0200
--- src/mouse.c 2019-11-03 19:56:50.723673238 +0100
***************
*** 2012,2018 ****
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);
else
# endif
if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL))
--- 2012,2018 ----
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, mod_mask, FALSE);
else
# endif
if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL))
*** ../vim-8.1.2247/src/version.c 2019-11-03 18:38:44.492598820 +0100
--- src/version.c 2019-11-03 21:17:41.969127362 +0100
***************
*** 743,744 ****
--- 743,746 ----
{ /* Add new patch number below this line */
+ /**/
+ 2248,
/**/
--
How To Keep A Healthy Level Of Insanity:
13. Go to a poetry recital and ask why the poems don't rhyme.
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/vim_dev/201911032020.xA3KKLLJ020307%40masaka.moolenaar.net.