support: move guide copy into text module

This commit is contained in:
m1ngsama 2026-05-23 19:55:44 +08:00
parent 0cf8ac6759
commit 81c3f45864
7 changed files with 173 additions and 97 deletions

1
.gitignore vendored
View file

@ -15,3 +15,4 @@ tests/unit/test_history_view
tests/unit/test_i18n
tests/unit/test_system_message
tests/unit/test_help_text
tests/unit/test_support_text

View file

@ -31,6 +31,8 @@
module, keeping large bilingual help copy out of TUI and command flow code.
- Session language, unknown-command, suggestion, and continuation prompts now
use the shared i18n table instead of inline command-flow conditionals.
- Interactive and exec support guide copy now lives in a dedicated
`support_text` module, with focused language-selection unit coverage.
### Changed
- NORMAL mode now opens at the latest visible messages instead of the oldest

9
include/support_text.h Normal file
View file

@ -0,0 +1,9 @@
#ifndef SUPPORT_TEXT_H
#define SUPPORT_TEXT_H
#include "common.h"
const char *support_text_interactive(help_lang_t lang);
const char *support_text_exec(help_lang_t lang);
#endif /* SUPPORT_TEXT_H */

View file

@ -1,109 +1,17 @@
#include "support.h"
#include "support_text.h"
void support_append_interactive_panel(char *buffer, size_t buf_size,
size_t *pos, help_lang_t lang) {
if (!buffer || !pos) return;
if (lang == LANG_ZH) {
buffer_appendf(buffer, buf_size, pos,
"\033[1;36m支持 · support\033[0m\n"
"\n"
"\033[1;37m第一次进来\033[0m\n"
" INSERT 输入消息Enter 发送ESC 进入 NORMAL\n"
" NORMAL 浏览消息G 回到最新i 继续输入\n"
" COMMAND 按 : 输入命令q/ESC 关闭当前面板\n"
"\n"
"\033[1;37m我想...\033[0m\n"
" 看谁在线 :users\n"
" 看最近历史 :last 20\n"
" 搜索聊天记录 :search <keyword>\n"
" 回到最新消息 G 或 End\n"
" 私聊某个人 :msg <user> <text>\n"
" 查看私聊收件箱 :inbox\n"
" 静音进出提示 :mute-joins\n"
"\n"
"\033[1;37m遇到问题\033[0m\n"
" 看不到新消息: 在 NORMAL 按 G 或 End 回到最新\n"
" 粘贴多行文本: 直接粘贴TNT 会等 Enter 后一次发送\n"
" 输入太长: 状态行接近限制时会提示,超出会响铃\n"
" 命令不记得: 输入 :help 看列表,输入 :support 回到这里\n"
" 连接断开: 可能是空闲超时、连接数限制或网络重连\n"
"\n"
"\033[2;37m更多: ? 打开完整按键帮助,:help 查看命令列表\033[0m\n");
return;
}
buffer_appendf(buffer, buf_size, pos,
"\033[1;36mSupport\033[0m\n"
"\n"
"\033[1;37mFirst minute\033[0m\n"
" INSERT Type messages, Enter sends, ESC enters NORMAL\n"
" NORMAL Browse history, G jumps latest, i continues typing\n"
" COMMAND Press : for commands, q/ESC closes this panel\n"
"\n"
"\033[1;37mI want to...\033[0m\n"
" See who is online :users\n"
" See recent history :last 20\n"
" Search history :search <keyword>\n"
" Return to latest G or End\n"
" Whisper someone :msg <user> <text>\n"
" Read whispers :inbox\n"
" Mute join notices :mute-joins\n"
"\n"
"\033[1;37mTroubleshooting\033[0m\n"
" Missing new messages: press G or End in NORMAL\n"
" Pasting many lines: paste normally, then Enter sends once\n"
" Message too long: the status line warns near the limit\n"
" Forgot a command: type :help or return here with :support\n"
" Disconnected: check idle timeout, limits, or reconnect\n"
"\n"
"\033[2;37mMore: ? opens full key help, :help lists commands\033[0m\n");
buffer_appendf(buffer, buf_size, pos, "%s",
support_text_interactive(lang));
}
void support_append_exec_panel(char *buffer, size_t buf_size, size_t *pos,
help_lang_t lang) {
if (!buffer || !pos) return;
if (lang == LANG_ZH) {
buffer_appendf(buffer, buf_size, pos,
"TNT 支持\n"
"\n"
"交互使用:\n"
" ssh -p 2222 HOST\n"
" INSERT: 输入消息并按 Enter 发送\n"
" NORMAL: G 回到最新k/PageUp 查看更早消息\n"
" COMMAND: 按 : 后可运行 users, last, search, msg, inbox\n"
"\n"
"非交互检查:\n"
" ssh -p 2222 HOST health\n"
" ssh -p 2222 HOST stats --json\n"
" ssh -p 2222 HOST users --json\n"
" ssh -p 2222 HOST 'tail -n 20'\n"
" ssh -p 2222 USER@HOST post 'message'\n"
"\n"
"排查:\n"
" 连接过早关闭: 检查限流、空闲超时、连接容量、\n"
" 单 IP 限制和防火墙规则。\n");
return;
}
buffer_appendf(buffer, buf_size, pos,
"TNT support\n"
"\n"
"Interactive use:\n"
" ssh -p 2222 HOST\n"
" INSERT: type and press Enter to send\n"
" NORMAL: press G for latest, k/PageUp for older messages\n"
" COMMAND: press : then run users, last, search, msg, inbox\n"
"\n"
"Non-interactive checks:\n"
" ssh -p 2222 HOST health\n"
" ssh -p 2222 HOST stats --json\n"
" ssh -p 2222 HOST users --json\n"
" ssh -p 2222 HOST 'tail -n 20'\n"
" ssh -p 2222 USER@HOST post 'message'\n"
"\n"
"Troubleshooting:\n"
" Connection closes early: check rate limits, idle timeout,\n"
" global connection capacity, per-IP limits, and firewall rules.\n");
buffer_appendf(buffer, buf_size, pos, "%s", support_text_exec(lang));
}

97
src/support_text.c Normal file
View file

@ -0,0 +1,97 @@
#include "support_text.h"
const char *support_text_interactive(help_lang_t lang) {
if (lang == LANG_ZH) {
return "\033[1;36m支持 · support\033[0m\n"
"\n"
"\033[1;37m第一次进来\033[0m\n"
" INSERT 输入消息Enter 发送ESC 进入 NORMAL\n"
" NORMAL 浏览消息G 回到最新i 继续输入\n"
" COMMAND 按 : 输入命令q/ESC 关闭当前面板\n"
"\n"
"\033[1;37m我想...\033[0m\n"
" 看谁在线 :users\n"
" 看最近历史 :last 20\n"
" 搜索聊天记录 :search <keyword>\n"
" 回到最新消息 G 或 End\n"
" 私聊某个人 :msg <user> <text>\n"
" 查看私聊收件箱 :inbox\n"
" 静音进出提示 :mute-joins\n"
"\n"
"\033[1;37m遇到问题\033[0m\n"
" 看不到新消息: 在 NORMAL 按 G 或 End 回到最新\n"
" 粘贴多行文本: 直接粘贴TNT 会等 Enter 后一次发送\n"
" 输入太长: 状态行接近限制时会提示,超出会响铃\n"
" 命令不记得: 输入 :help 看列表,输入 :support 回到这里\n"
" 连接断开: 可能是空闲超时、连接数限制或网络重连\n"
"\n"
"\033[2;37m更多: ? 打开完整按键帮助,:help 查看命令列表\033[0m\n";
}
return "\033[1;36mSupport\033[0m\n"
"\n"
"\033[1;37mFirst minute\033[0m\n"
" INSERT Type messages, Enter sends, ESC enters NORMAL\n"
" NORMAL Browse history, G jumps latest, i continues typing\n"
" COMMAND Press : for commands, q/ESC closes this panel\n"
"\n"
"\033[1;37mI want to...\033[0m\n"
" See who is online :users\n"
" See recent history :last 20\n"
" Search history :search <keyword>\n"
" Return to latest G or End\n"
" Whisper someone :msg <user> <text>\n"
" Read whispers :inbox\n"
" Mute join notices :mute-joins\n"
"\n"
"\033[1;37mTroubleshooting\033[0m\n"
" Missing new messages: press G or End in NORMAL\n"
" Pasting many lines: paste normally, then Enter sends once\n"
" Message too long: the status line warns near the limit\n"
" Forgot a command: type :help or return here with :support\n"
" Disconnected: check idle timeout, limits, or reconnect\n"
"\n"
"\033[2;37mMore: ? opens full key help, :help lists commands\033[0m\n";
}
const char *support_text_exec(help_lang_t lang) {
if (lang == LANG_ZH) {
return "TNT 支持\n"
"\n"
"交互使用:\n"
" ssh -p 2222 HOST\n"
" INSERT: 输入消息并按 Enter 发送\n"
" NORMAL: G 回到最新k/PageUp 查看更早消息\n"
" COMMAND: 按 : 后可运行 users, last, search, msg, inbox\n"
"\n"
"非交互检查:\n"
" ssh -p 2222 HOST health\n"
" ssh -p 2222 HOST stats --json\n"
" ssh -p 2222 HOST users --json\n"
" ssh -p 2222 HOST 'tail -n 20'\n"
" ssh -p 2222 USER@HOST post 'message'\n"
"\n"
"排查:\n"
" 连接过早关闭: 检查限流、空闲超时、连接容量、\n"
" 单 IP 限制和防火墙规则。\n";
}
return "TNT support\n"
"\n"
"Interactive use:\n"
" ssh -p 2222 HOST\n"
" INSERT: type and press Enter to send\n"
" NORMAL: press G for latest, k/PageUp for older messages\n"
" COMMAND: press : then run users, last, search, msg, inbox\n"
"\n"
"Non-interactive checks:\n"
" ssh -p 2222 HOST health\n"
" ssh -p 2222 HOST stats --json\n"
" ssh -p 2222 HOST users --json\n"
" ssh -p 2222 HOST 'tail -n 20'\n"
" ssh -p 2222 USER@HOST post 'message'\n"
"\n"
"Troubleshooting:\n"
" Connection closes early: check rate limits, idle timeout,\n"
" global connection capacity, per-IP limits, and firewall rules.\n";
}

View file

@ -18,8 +18,9 @@ HISTORY_VIEW_SRC = ../../src/history_view.c
I18N_SRC = ../../src/i18n.c
SYSTEM_MESSAGE_SRC = ../../src/system_message.c
HELP_TEXT_SRC = ../../src/help_text.c
SUPPORT_TEXT_SRC = ../../src/support_text.c
TESTS = test_utf8 test_message test_chat_room test_history_view test_i18n test_system_message test_help_text
TESTS = test_utf8 test_message test_chat_room test_history_view test_i18n test_system_message test_help_text test_support_text
.PHONY: all clean run
@ -46,6 +47,9 @@ test_system_message: test_system_message.c $(SYSTEM_MESSAGE_SRC) $(I18N_SRC)
test_help_text: test_help_text.c $(HELP_TEXT_SRC) $(COMMON_SRC)
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
test_support_text: test_support_text.c $(SUPPORT_TEXT_SRC)
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
run: all
@echo "=== Running UTF-8 Tests ==="
./test_utf8
@ -67,6 +71,9 @@ run: all
@echo ""
@echo "=== Running Help Text Tests ==="
./test_help_text
@echo ""
@echo "=== Running Support Text Tests ==="
./test_support_text
clean:
rm -f $(TESTS) *.o test_messages.log

View file

@ -0,0 +1,52 @@
/* Unit tests for support text language selection */
#include "../../include/support_text.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
#define TEST(name) static void test_##name()
#define RUN_TEST(name) do { \
printf("Running %s... ", #name); \
test_##name(); \
printf("\n"); \
tests_passed++; \
} while(0)
static int tests_passed = 0;
TEST(interactive_support_matches_language) {
const char *en = support_text_interactive(LANG_EN);
const char *zh = support_text_interactive(LANG_ZH);
assert(strstr(en, "Support") != NULL);
assert(strstr(en, "First minute") != NULL);
assert(strstr(en, ":mute-joins") != NULL);
assert(strstr(zh, "支持") != NULL);
assert(strstr(zh, "第一次进来") != NULL);
assert(strstr(zh, ":mute-joins") != NULL);
}
TEST(exec_support_matches_language) {
const char *en = support_text_exec(LANG_EN);
const char *zh = support_text_exec(LANG_ZH);
assert(strstr(en, "TNT support") != NULL);
assert(strstr(en, "Non-interactive checks") != NULL);
assert(strstr(en, "stats --json") != NULL);
assert(strstr(zh, "TNT 支持") != NULL);
assert(strstr(zh, "非交互检查") != NULL);
assert(strstr(zh, "stats --json") != NULL);
}
int main(void) {
printf("Running support text unit tests...\n\n");
RUN_TEST(interactive_support_matches_language);
RUN_TEST(exec_support_matches_language);
printf("\n✓ All %d tests passed!\n", tests_passed);
return 0;
}