mirror of
https://oauth2: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@github.com/m1ngsama/TNT.git
synced 2026-06-26 05:34:39 +08:00
i18n: add session language command
This commit is contained in:
parent
0c27976763
commit
2e69283e5c
9 changed files with 68 additions and 5 deletions
|
|
@ -96,6 +96,7 @@ Ctrl+C - Exit chat
|
|||
:search <keyword> - Search full message history (case-insensitive)
|
||||
:mute-joins - Toggle join/leave system notifications
|
||||
:support - Show quick support guide
|
||||
:lang <en|zh> - Switch UI language for this session
|
||||
:help - Show available commands
|
||||
:clear - Clear command output
|
||||
:q, :quit, :exit - Disconnect
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
- Added a first i18n boundary: `TNT_LANG` / locale detection now chooses the
|
||||
default interactive UI language (`en` or `zh`) for username prompts, status
|
||||
hints, help language, and `:support`.
|
||||
- Added `:lang <en|zh>` so users can switch the interactive UI language for
|
||||
their current session.
|
||||
|
||||
### Changed
|
||||
- NORMAL mode now opens at the latest visible messages instead of the oldest
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ typedef enum {
|
|||
I18N_NORMAL_NEW_MESSAGES
|
||||
} i18n_text_id_t;
|
||||
|
||||
bool i18n_try_parse_lang(const char *value, help_lang_t *lang);
|
||||
help_lang_t i18n_parse_lang(const char *value, help_lang_t fallback);
|
||||
help_lang_t i18n_default_lang(void);
|
||||
const char *i18n_lang_code(help_lang_t lang);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "chat_room.h"
|
||||
#include "client.h"
|
||||
#include "common.h"
|
||||
#include "i18n.h"
|
||||
#include "message.h"
|
||||
#include "support.h"
|
||||
#include "tui.h"
|
||||
|
|
@ -82,7 +83,8 @@ static const char *suggest_command(const char *cmd) {
|
|||
static const char *commands[] = {
|
||||
"list", "users", "who", "nick", "name", "msg", "w", "inbox",
|
||||
"last", "search", "mute-joins", "mute", "support", "guide",
|
||||
"help", "commands", "clear", "cls", "q", "quit", "exit"
|
||||
"lang", "language", "help", "commands", "clear", "cls",
|
||||
"q", "quit", "exit"
|
||||
};
|
||||
const char *best = NULL;
|
||||
int best_distance = 99;
|
||||
|
|
@ -177,6 +179,7 @@ void commands_dispatch(client_t *client) {
|
|||
"search <keyword> - Search message history\n"
|
||||
"mute-joins - Toggle join/leave notices\n"
|
||||
"support - Show quick support guide\n"
|
||||
"lang [en|zh] - Show or switch UI language\n"
|
||||
"help, commands - Show this help\n"
|
||||
"clear, cls - Clear command output\n"
|
||||
"q, quit, exit - Disconnect\n"
|
||||
|
|
@ -191,6 +194,34 @@ void commands_dispatch(client_t *client) {
|
|||
support_append_interactive_panel(output, sizeof(output), &pos,
|
||||
client->help_lang);
|
||||
|
||||
} else if (strcmp(cmd, "lang") == 0 || strcmp(cmd, "language") == 0 ||
|
||||
strncmp(cmd, "lang ", 5) == 0 ||
|
||||
strncmp(cmd, "language ", 9) == 0) {
|
||||
char *arg = NULL;
|
||||
help_lang_t next_lang;
|
||||
|
||||
if (strncmp(cmd, "lang ", 5) == 0) {
|
||||
arg = cmd + 5;
|
||||
} else if (strncmp(cmd, "language ", 9) == 0) {
|
||||
arg = cmd + 9;
|
||||
}
|
||||
|
||||
if (!arg || arg[0] == '\0') {
|
||||
buffer_appendf(output, sizeof(output), &pos,
|
||||
"Current language: %s\n"
|
||||
"Usage: lang <en|zh>\n",
|
||||
i18n_lang_code(client->help_lang));
|
||||
} else if (i18n_try_parse_lang(arg, &next_lang)) {
|
||||
client->help_lang = next_lang;
|
||||
buffer_appendf(output, sizeof(output), &pos,
|
||||
"Language set to: %s\n",
|
||||
i18n_lang_code(client->help_lang));
|
||||
} else {
|
||||
buffer_appendf(output, sizeof(output), &pos,
|
||||
"Unsupported language: %s\n"
|
||||
"Usage: lang <en|zh>\n", arg);
|
||||
}
|
||||
|
||||
} else if (strncmp(cmd, "msg ", 4) == 0 || strncmp(cmd, "w ", 2) == 0) {
|
||||
char *rest = (cmd[0] == 'w') ? cmd + 2 : cmd + 4;
|
||||
while (*rest == ' ') rest++;
|
||||
|
|
|
|||
18
src/i18n.c
18
src/i18n.c
|
|
@ -17,23 +17,33 @@ static bool starts_with_lang(const char *value, const char *prefix) {
|
|||
return *value == '\0' || *value == '_' || *value == '-' || *value == '.';
|
||||
}
|
||||
|
||||
help_lang_t i18n_parse_lang(const char *value, help_lang_t fallback) {
|
||||
bool i18n_try_parse_lang(const char *value, help_lang_t *lang) {
|
||||
if (!value || value[0] == '\0') {
|
||||
return fallback;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (starts_with_lang(value, "zh") ||
|
||||
starts_with_lang(value, "cn") ||
|
||||
starts_with_lang(value, "chinese")) {
|
||||
return LANG_ZH;
|
||||
if (lang) *lang = LANG_ZH;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (starts_with_lang(value, "en") ||
|
||||
starts_with_lang(value, "c") ||
|
||||
starts_with_lang(value, "posix")) {
|
||||
return LANG_EN;
|
||||
if (lang) *lang = LANG_EN;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
help_lang_t i18n_parse_lang(const char *value, help_lang_t fallback) {
|
||||
help_lang_t lang;
|
||||
if (i18n_try_parse_lang(value, &lang)) {
|
||||
return lang;
|
||||
}
|
||||
return fallback;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -784,6 +784,7 @@ const char* tui_get_help_text(help_lang_t lang) {
|
|||
" :search <keyword> - Search message history\n"
|
||||
" :mute-joins - Toggle join/leave notices\n"
|
||||
" :support - Show quick support guide\n"
|
||||
" :lang <en|zh> - Switch UI language\n"
|
||||
" :help - Show available commands\n"
|
||||
" :clear - Clear command output\n"
|
||||
" :q, :quit, :exit - Disconnect\n"
|
||||
|
|
@ -838,6 +839,7 @@ const char* tui_get_help_text(help_lang_t lang) {
|
|||
" :search <关键词> - 搜索消息历史\n"
|
||||
" :mute-joins - 切换加入/离开提示\n"
|
||||
" :support - 显示快速支持指南\n"
|
||||
" :lang <en|zh> - 切换界面语言\n"
|
||||
" :help - 显示可用命令\n"
|
||||
" :clear - 清空命令输出\n"
|
||||
" :q, :quit, :exit - 断开连接\n"
|
||||
|
|
|
|||
|
|
@ -148,6 +148,13 @@ send -- "support\r"
|
|||
expect "支持"
|
||||
expect "Press any key"
|
||||
send -- "q"
|
||||
expect "NORMAL"
|
||||
send -- ":"
|
||||
expect ":"
|
||||
send -- "lang en\r"
|
||||
expect "Language set to: en"
|
||||
expect "Press any key"
|
||||
send -- "q"
|
||||
sleep 0.2
|
||||
send -- "\003"
|
||||
sleep 0.2
|
||||
|
|
|
|||
|
|
@ -17,11 +17,19 @@
|
|||
static int tests_passed = 0;
|
||||
|
||||
TEST(parse_explicit_languages) {
|
||||
help_lang_t lang;
|
||||
|
||||
assert(i18n_parse_lang("zh", LANG_EN) == LANG_ZH);
|
||||
assert(i18n_parse_lang("zh_CN.UTF-8", LANG_EN) == LANG_ZH);
|
||||
assert(i18n_parse_lang("cn", LANG_EN) == LANG_ZH);
|
||||
assert(i18n_parse_lang("en", LANG_ZH) == LANG_EN);
|
||||
assert(i18n_parse_lang("en_US.UTF-8", LANG_ZH) == LANG_EN);
|
||||
|
||||
assert(i18n_try_parse_lang("zh", &lang) == true);
|
||||
assert(lang == LANG_ZH);
|
||||
assert(i18n_try_parse_lang("en", &lang) == true);
|
||||
assert(lang == LANG_EN);
|
||||
assert(i18n_try_parse_lang("fr", &lang) == false);
|
||||
}
|
||||
|
||||
TEST(parse_unknown_uses_fallback) {
|
||||
|
|
|
|||
1
tnt.1
1
tnt.1
|
|
@ -121,6 +121,7 @@ l l.
|
|||
:search \fIkeyword\fR Case\-insensitive search across full message history
|
||||
:mute\-joins Toggle join/leave system notifications on/off
|
||||
:support Show quick support guide
|
||||
:lang \fIen|zh\fR Switch UI language for this session
|
||||
:help Show available commands
|
||||
:clear Clear command output
|
||||
:q, :quit, :exit Disconnect
|
||||
|
|
|
|||
Loading…
Reference in a new issue