Modified the key input redirection so that it captures and

handles Control-u in the same way that tkcon does, so that when
typing via redirection into the console, Control-u will delete
the entire command back to the prompt. (See github issue #456.)
This commit is contained in:
R. Timothy Edwards 2025-10-10 10:39:40 -04:00
parent 27c423c2ed
commit c42db8e71b
4 changed files with 87 additions and 53 deletions

View File

@ -1 +1 @@
8.3.560 8.3.561

View File

@ -546,7 +546,7 @@ XEvent *xevent;
break; break;
case KeyPress: case KeyPress:
{ {
int keywstate, keymod, idx, idxmax; int keywstate, keymod, modifier, idx, idxmax;
char inChar[10]; char inChar[10];
Tcl_Channel outChannel = Tcl_GetStdChannel(TCL_STDOUT); Tcl_Channel outChannel = Tcl_GetStdChannel(TCL_STDOUT);
@ -569,6 +569,7 @@ keys_and_buttons:
#else #else
keymod |= (Mod1Mask & KeyPressedEvent->state); keymod |= (Mod1Mask & KeyPressedEvent->state);
#endif #endif
modifier = keymod;
if (nbytes == 0) /* No ASCII equivalent */ if (nbytes == 0) /* No ASCII equivalent */
{ {
@ -691,9 +692,19 @@ keys_and_buttons:
Tcl_EvalEx(consoleinterp, outstr, 26, 0); Tcl_EvalEx(consoleinterp, outstr, 26, 0);
outstr[24] = '\"'; outstr[24] = '\"';
outstr[25] = '\0'; outstr[25] = '\0';
/* fall through */
default: default:
/* Handle Ctrl-u: Delete entire command */
if ((keysym == XK_u) && (modifier == ControlMask))
{
Tcl_EvalEx(consoleinterp, ".text delete limit end",
22, 0);
}
else
{
outstr[23] = inChar[idx]; outstr[23] = inChar[idx];
Tcl_EvalEx(consoleinterp, outstr, 25, 0); Tcl_EvalEx(consoleinterp, outstr, 25, 0);
}
break; break;
} }
} }

View File

@ -550,7 +550,7 @@ TOGLEventProc(clientData, xevent)
break; break;
case KeyPress: case KeyPress:
{ {
int keywstate, keymod, idx, idxmax; int keywstate, keymod, modifier, idx, idxmax;
char inChar[10]; char inChar[10];
Tcl_Channel outChannel = Tcl_GetStdChannel(TCL_STDOUT); Tcl_Channel outChannel = Tcl_GetStdChannel(TCL_STDOUT);
@ -573,6 +573,7 @@ keys_and_buttons:
#else #else
keymod |= (Mod1Mask & KeyPressedEvent->state); keymod |= (Mod1Mask & KeyPressedEvent->state);
#endif #endif
modifier = keymod;
if (nbytes == 0) /* No ASCII equivalent */ if (nbytes == 0) /* No ASCII equivalent */
{ {
@ -588,6 +589,7 @@ keys_and_buttons:
} }
else /* ASCII-valued character */ else /* ASCII-valued character */
{ {
/* Remove single modifier (Control or Shift) */
if (!(keymod & (LockMask | Mod1Mask))) { if (!(keymod & (LockMask | Mod1Mask))) {
if (!(keymod & ControlMask)) if (!(keymod & ControlMask))
keymod &= ~ShiftMask; keymod &= ~ShiftMask;
@ -627,7 +629,7 @@ keys_and_buttons:
case XK_Pointer_Button3: case XK_Pointer_Button3:
case XK_Pointer_Button4: case XK_Pointer_Button4:
case XK_Pointer_Button5: case XK_Pointer_Button5:
LocRedirect = TX_INPUT_NORMAL;; LocRedirect = TX_INPUT_NORMAL;
break; break;
} }
} }
@ -695,9 +697,19 @@ keys_and_buttons:
Tcl_EvalEx(consoleinterp, outstr, 26, 0); Tcl_EvalEx(consoleinterp, outstr, 26, 0);
outstr[24] = '\"'; outstr[24] = '\"';
outstr[25] = '\0'; outstr[25] = '\0';
/* fall through */
default: default:
/* Handle Ctrl-u like tkcon: Delete entire command */
if ((keysym == XK_u) && (modifier == ControlMask))
{
Tcl_EvalEx(consoleinterp, ".text delete limit end",
22, 0);
}
else
{
outstr[23] = inChar[idx]; outstr[23] = inChar[idx];
Tcl_EvalEx(consoleinterp, outstr, 25, 0); Tcl_EvalEx(consoleinterp, outstr, 25, 0);
}
break; break;
} }
} }

View File

@ -793,7 +793,7 @@ MagicEventProc(clientData, xevent)
break; break;
case KeyPress: case KeyPress:
{ {
int keywstate, keymod, idx, idxmax; int keywstate, keymod, modifier, idx, idxmax;
char inChar[10]; char inChar[10];
Tcl_Channel outChannel = Tcl_GetStdChannel(TCL_STDOUT); Tcl_Channel outChannel = Tcl_GetStdChannel(TCL_STDOUT);
@ -820,6 +820,7 @@ keys_and_buttons:
#else #else
keymod |= (Mod1Mask & KeyPressedEvent->state); keymod |= (Mod1Mask & KeyPressedEvent->state);
#endif #endif
modifier = keymod;
if (nbytes == 0) if (nbytes == 0)
{ {
@ -951,9 +952,19 @@ keys_and_buttons:
Tcl_EvalEx(consoleinterp, outstr, 26, 0); Tcl_EvalEx(consoleinterp, outstr, 26, 0);
outstr[24] = '\"'; outstr[24] = '\"';
outstr[25] = '\0'; outstr[25] = '\0';
/* fall through */
default: default:
/* Handle Ctrl-u: Delete entire command */
if ((keysym == XK_u) && (modifier == ControlMask))
{
Tcl_EvalEx(consoleinterp, ".text delete limit end",
22, 0);
}
else
{
outstr[23] = inChar[idx]; outstr[23] = inChar[idx];
Tcl_EvalEx(consoleinterp, outstr, 25, 0); Tcl_EvalEx(consoleinterp, outstr, 25, 0);
}
break; break;
} }
} }