feat: add Vim-style page scrolling keybindings

Add page-level scroll controls in NORMAL mode:
- Ctrl+D: half page down
- Ctrl+U: half page up
- Ctrl+F: full page down
- Ctrl+B: full page up

These complement the existing j/k single-line scrolling and g/G
jump-to-top/bottom, matching standard Vim navigation conventions.
Updated bilingual help text to document all new keybindings.
This commit is contained in:
m1ngsama 2026-04-19 16:43:01 +08:00
parent 0de13a6314
commit 4836f57f9e
2 changed files with 48 additions and 4 deletions

View file

@ -1281,6 +1281,42 @@ static bool handle_key(client_t *client, unsigned char key, char *input) {
client->scroll_pos = max_scroll; client->scroll_pos = max_scroll;
tui_render_screen(client); tui_render_screen(client);
return true; /* Key consumed */ return true; /* Key consumed */
} else if (key == 4) { /* Ctrl+D: half page down */
int msg_height = client->height - 3;
if (msg_height < 1) msg_height = 1;
int half = msg_height / 2;
if (half < 1) half = 1;
int max_scroll = room_get_message_count(g_room) - msg_height;
if (max_scroll < 0) max_scroll = 0;
client->scroll_pos += half;
if (client->scroll_pos > max_scroll) client->scroll_pos = max_scroll;
tui_render_screen(client);
return true;
} else if (key == 21) { /* Ctrl+U: half page up */
int msg_height = client->height - 3;
if (msg_height < 1) msg_height = 1;
int half = msg_height / 2;
if (half < 1) half = 1;
client->scroll_pos -= half;
if (client->scroll_pos < 0) client->scroll_pos = 0;
tui_render_screen(client);
return true;
} else if (key == 6) { /* Ctrl+F: full page down */
int msg_height = client->height - 3;
if (msg_height < 1) msg_height = 1;
int max_scroll = room_get_message_count(g_room) - msg_height;
if (max_scroll < 0) max_scroll = 0;
client->scroll_pos += msg_height;
if (client->scroll_pos > max_scroll) client->scroll_pos = max_scroll;
tui_render_screen(client);
return true;
} else if (key == 2) { /* Ctrl+B: full page up */
int msg_height = client->height - 3;
if (msg_height < 1) msg_height = 1;
client->scroll_pos -= msg_height;
if (client->scroll_pos < 0) client->scroll_pos = 0;
tui_render_screen(client);
return true;
} else if (key == '?') { } else if (key == '?') {
client->show_help = true; client->show_help = true;
client->help_scroll_pos = 0; client->help_scroll_pos = 0;

View file

@ -285,8 +285,12 @@ const char* tui_get_help_text(help_lang_t lang) {
"NORMAL MODE KEYS:\n" "NORMAL MODE KEYS:\n"
" i - Return to INSERT mode\n" " i - Return to INSERT mode\n"
" : - Enter COMMAND mode\n" " : - Enter COMMAND mode\n"
" j - Scroll down (older messages)\n" " j / Down - Scroll down one line\n"
" k - Scroll up (newer messages)\n" " k / Up - Scroll up one line\n"
" Ctrl+D - Half page down\n"
" Ctrl+U - Half page up\n"
" Ctrl+F - Full page down\n"
" Ctrl+B - Full page up\n"
" g - Jump to top (oldest)\n" " g - Jump to top (oldest)\n"
" G - Jump to bottom (newest)\n" " G - Jump to bottom (newest)\n"
" ? - Show this help\n" " ? - Show this help\n"
@ -331,8 +335,12 @@ const char* tui_get_help_text(help_lang_t lang) {
"NORMAL 模式按键:\n" "NORMAL 模式按键:\n"
" i - 返回 INSERT 模式\n" " i - 返回 INSERT 模式\n"
" : - 进入 COMMAND 模式\n" " : - 进入 COMMAND 模式\n"
" j - 向下滚动(更早的消息)\n" " j / 下箭头 - 向下滚动一行\n"
" k - 向上滚动(更新的消息)\n" " k / 上箭头 - 向上滚动一行\n"
" Ctrl+D - 半页下翻\n"
" Ctrl+U - 半页上翻\n"
" Ctrl+F - 整页下翻\n"
" Ctrl+B - 整页上翻\n"
" g - 跳到顶部(最早)\n" " g - 跳到顶部(最早)\n"
" G - 跳到底部(最新)\n" " G - 跳到底部(最新)\n"
" ? - 显示此帮助\n" " ? - 显示此帮助\n"