mirror of
https://oauth2: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@github.com/m1ngsama/TNT.git
synced 2026-06-26 05:34:39 +08:00
input: Up/Down in INSERT mode walks sent-message history (UX-2)
ESC in INSERT mode used to switch straight to NORMAL. Now it follows the same arrow-key probe COMMAND mode already does: if the next two bytes are "[A" or "[B", treat as Up / Down and walk through the last 16 messages this client has sent. A plain ESC still falls through to NORMAL — the 50 ms probe timeout keeps that path responsive. Storage: new client_t fields char insert_history[16][MAX_MESSAGE_LEN]; int insert_history_count; int insert_history_pos; Recording: every Enter that broadcasts a message pushes the input buffer onto the ring (with FIFO eviction at 16) and resets pos. Down at the bottom of the ring returns to an empty input. This is the standard chat-client recall that vim users (and anyone who's ever used a shell) expect.
This commit is contained in:
parent
94f3d28562
commit
f3217de36b
2 changed files with 56 additions and 2 deletions
|
|
@ -24,6 +24,11 @@ typedef struct client {
|
|||
char command_history[16][256];
|
||||
int command_history_count;
|
||||
int command_history_pos;
|
||||
/* INSERT mode chat-message history. Last 16 messages this client
|
||||
* sent, oldest first. Up/Down in INSERT mode walks through it. */
|
||||
char insert_history[16][MAX_MESSAGE_LEN];
|
||||
int insert_history_count;
|
||||
int insert_history_pos;
|
||||
char command_output[2048];
|
||||
bool show_motd; /* command_output holds MOTD text */
|
||||
char exec_command[MAX_EXEC_COMMAND_LEN];
|
||||
|
|
|
|||
53
src/input.c
53
src/input.c
|
|
@ -206,13 +206,62 @@ static bool handle_key(client_t *client, unsigned char key, char *input) {
|
|||
/* Mode-specific handling */
|
||||
switch (client->mode) {
|
||||
case MODE_INSERT:
|
||||
if (key == 27) { /* ESC */
|
||||
if (key == 27) { /* ESC — may also be the start of an arrow seq */
|
||||
char seq[2];
|
||||
int n = ssh_channel_read_timeout(client->channel, seq, 1, 0, 50);
|
||||
if (n == 1 && seq[0] == '[') {
|
||||
n = ssh_channel_read_timeout(client->channel, &seq[1], 1, 0, 50);
|
||||
if (n == 1) {
|
||||
if (seq[1] == 'A') { /* Up — walk back through sent history */
|
||||
if (client->insert_history_count > 0 &&
|
||||
client->insert_history_pos > 0) {
|
||||
client->insert_history_pos--;
|
||||
strncpy(input,
|
||||
client->insert_history[client->insert_history_pos],
|
||||
MAX_MESSAGE_LEN - 1);
|
||||
input[MAX_MESSAGE_LEN - 1] = '\0';
|
||||
tui_render_input(client, input);
|
||||
}
|
||||
return true;
|
||||
} else if (seq[1] == 'B') { /* Down — walk forward */
|
||||
if (client->insert_history_pos <
|
||||
client->insert_history_count - 1) {
|
||||
client->insert_history_pos++;
|
||||
strncpy(input,
|
||||
client->insert_history[client->insert_history_pos],
|
||||
MAX_MESSAGE_LEN - 1);
|
||||
input[MAX_MESSAGE_LEN - 1] = '\0';
|
||||
} else {
|
||||
client->insert_history_pos =
|
||||
client->insert_history_count;
|
||||
input[0] = '\0';
|
||||
}
|
||||
tui_render_input(client, input);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Plain ESC — fall through to NORMAL mode */
|
||||
client->mode = MODE_NORMAL;
|
||||
client->scroll_pos = 0;
|
||||
tui_render_screen(client);
|
||||
return true; /* Key consumed */
|
||||
return true;
|
||||
} else if (key == '\r' || key == '\n') { /* Enter */
|
||||
if (input[0] != '\0') {
|
||||
/* Record into the per-client INSERT history ring */
|
||||
int max_hist = (int)(sizeof(client->insert_history) /
|
||||
sizeof(client->insert_history[0]));
|
||||
if (client->insert_history_count >= max_hist) {
|
||||
memmove(&client->insert_history[0],
|
||||
&client->insert_history[1],
|
||||
(max_hist - 1) * sizeof(client->insert_history[0]));
|
||||
client->insert_history_count = max_hist - 1;
|
||||
}
|
||||
snprintf(client->insert_history[client->insert_history_count],
|
||||
sizeof(client->insert_history[0]), "%s", input);
|
||||
client->insert_history_count++;
|
||||
client->insert_history_pos = client->insert_history_count;
|
||||
|
||||
message_t msg = {
|
||||
.timestamp = time(NULL),
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue