mirror of
https://oauth2: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@github.com/m1ngsama/TNT.git
synced 2026-06-26 05:34:39 +08:00
ux: collapse help surface around manual
This commit is contained in:
parent
15aac7134f
commit
a693d281f8
27 changed files with 236 additions and 368 deletions
12
README.md
12
README.md
|
|
@ -82,7 +82,7 @@ Ctrl+F/B - Scroll full page down/up
|
|||
PgDn/PgUp - Scroll full page down/up
|
||||
End/Home - Jump to bottom/top
|
||||
g/G - Jump to top/bottom
|
||||
? - Show help
|
||||
? - Show full key reference
|
||||
Ctrl+C - Exit chat
|
||||
```
|
||||
|
||||
|
|
@ -92,12 +92,12 @@ Ctrl+C - Exit chat
|
|||
:nick <name> - Change nickname
|
||||
:msg <user> <text> - Whisper to user
|
||||
:w <user> <text> - Short alias for :msg
|
||||
:inbox - Show whispers
|
||||
:last [N] - Show last N messages from history (max 50, default 10)
|
||||
: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
|
||||
:help - Show concise manual
|
||||
:clear - Clear command output
|
||||
:q, :quit, :exit - Disconnect
|
||||
Up/Down - Browse command history
|
||||
|
|
@ -176,7 +176,6 @@ TNT also exposes a small non-interactive SSH surface for scripts:
|
|||
ssh -p 2222 chat.m1ng.space health
|
||||
ssh -p 2222 chat.m1ng.space stats --json
|
||||
ssh -p 2222 chat.m1ng.space users
|
||||
ssh -p 2222 chat.m1ng.space support
|
||||
ssh -p 2222 chat.m1ng.space "tail -n 20"
|
||||
ssh -p 2222 operator@chat.m1ng.space post "service notice"
|
||||
ssh -p 2222 chat.m1ng.space post "/me deploys v2.0"
|
||||
|
|
@ -256,8 +255,9 @@ TNT/
|
|||
│ ├── chat_room.c # chat room logic
|
||||
│ ├── message.c # message persistence
|
||||
│ ├── history_view.c # message viewport and scroll state
|
||||
│ ├── help_text.c # full-screen and command help content
|
||||
│ ├── support_text.c # quick support guide content
|
||||
│ ├── help_text.c # full-screen key reference content
|
||||
│ ├── manual.c # concise manual panel rendering
|
||||
│ ├── manual_text.c # concise manual content
|
||||
│ ├── i18n.c # language selection and shared UI text
|
||||
│ ├── ratelimit.c # connection limits and rate limiting
|
||||
│ ├── tui.c # terminal UI rendering
|
||||
|
|
|
|||
|
|
@ -1,5 +1,16 @@
|
|||
# Changelog
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Changed
|
||||
- Collapsed the interactive help surface around a concise Unix-style `:help`
|
||||
manual and the `?` full key reference; `:support` is no longer a user-facing
|
||||
command.
|
||||
- First-use hints and unknown-command guidance now point users to `:help`
|
||||
instead of the removed support entry.
|
||||
- The concise manual module is now named `manual_text`, and the redundant
|
||||
interactive `:commands` entrypoint was removed.
|
||||
|
||||
## 1.0.1 - 2026-05-24 - Release candidate hardening
|
||||
|
||||
### Added
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ Deployments are operator-driven:
|
|||
3. Install the new binary.
|
||||
4. Restart the service.
|
||||
5. Run black-box checks (`health`, `stats --json`, `users --json`,
|
||||
`support`, and a post/tail smoke test).
|
||||
and a post/tail smoke test).
|
||||
|
||||
The installer can still be used manually on a server:
|
||||
curl -sSL https://raw.githubusercontent.com/m1ngsama/TNT/main/install.sh | sh
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ Place a `motd.txt` file in the state directory. TNT displays it to each user on
|
|||
# Systemd deployment (state dir is /var/lib/tnt)
|
||||
sudo tee /var/lib/tnt/motd.txt <<'EOF'
|
||||
Welcome! Be respectful. No spam.
|
||||
Type :help for available commands.
|
||||
Type :help for a concise manual, or ? for the full key reference.
|
||||
EOF
|
||||
sudo chown tnt:tnt /var/lib/tnt/motd.txt
|
||||
|
||||
|
|
|
|||
|
|
@ -79,8 +79,9 @@ src/
|
|||
├── tui.c - Terminal UI rendering (ANSI escape codes)
|
||||
├── tui_status.c - Mode/status/input-line rendering
|
||||
├── i18n.c - Language selection and shared UI text
|
||||
├── help_text.c - Full-screen and command help text
|
||||
├── support_text.c - Quick support guide text
|
||||
├── help_text.c - Full-screen key reference text
|
||||
├── manual.c - Concise manual panel rendering
|
||||
├── manual_text.c - Concise manual text
|
||||
├── system_message.c - Localized join/leave/nick system messages
|
||||
├── ratelimit.c - Per-IP and global connection limits
|
||||
└── utf8.c - UTF-8 character handling
|
||||
|
|
@ -98,8 +99,9 @@ include/
|
|||
├── history_view.h - Scroll-state helpers
|
||||
├── tui.h - TUI rendering functions
|
||||
├── i18n.h - Language and shared text IDs
|
||||
├── help_text.h - Help text interface
|
||||
├── support_text.h - Support guide text interface
|
||||
├── help_text.h - Key reference text interface
|
||||
├── manual.h - Concise manual panel interface
|
||||
├── manual_text.h - Concise manual text interface
|
||||
├── ratelimit.h - Connection limit interface
|
||||
└── utf8.h - UTF-8 utilities
|
||||
```
|
||||
|
|
@ -363,7 +365,7 @@ if (strcmp(cmd, "newcmd") == 0) {
|
|||
|
||||
3. **Move user-facing strings through `src/i18n.c` when they need localization or are reused.**
|
||||
|
||||
4. **Update help text in `src/help_text.c`:**
|
||||
4. **Update user help text in `src/manual_text.c` and `src/help_text.c`:**
|
||||
```c
|
||||
"AVAILABLE COMMANDS:\n"
|
||||
" newcmd - Description of new command\n"
|
||||
|
|
|
|||
|
|
@ -27,11 +27,12 @@ COMMANDS (COMMAND mode, prefix with :)
|
|||
nick <name> change nickname
|
||||
msg <user> <text> whisper to user
|
||||
w <user> <text> alias for msg
|
||||
inbox show whispers
|
||||
last [N] last N messages from log (default 10, max 50)
|
||||
search <keyword> search full history (case-insensitive, 15 results)
|
||||
mute-joins toggle join/leave notifications
|
||||
support quick support guide
|
||||
help show all commands
|
||||
help concise manual
|
||||
lang [en|zh] show or switch UI language
|
||||
clear clear output
|
||||
q / quit / exit disconnect
|
||||
|
||||
|
|
@ -52,8 +53,9 @@ STRUCTURE
|
|||
src/exec.c SSH exec command dispatch
|
||||
src/message.c persistence, search
|
||||
src/history_view.c message viewport / scroll state
|
||||
src/help_text.c full-screen and command help text
|
||||
src/support_text.c quick support guide content
|
||||
src/help_text.c full-screen key reference text
|
||||
src/manual.c concise manual panel rendering
|
||||
src/manual_text.c concise manual content
|
||||
src/i18n.c language selection and shared text
|
||||
src/ratelimit.c connection limits and rate limiting
|
||||
src/tui.c rendering
|
||||
|
|
|
|||
|
|
@ -4,7 +4,5 @@
|
|||
#include "common.h"
|
||||
|
||||
const char *help_text_full(help_lang_t lang);
|
||||
void help_text_append_commands(char *output, size_t buf_size, size_t *pos,
|
||||
help_lang_t lang);
|
||||
|
||||
#endif /* HELP_TEXT_H */
|
||||
|
|
|
|||
9
include/manual.h
Normal file
9
include/manual.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef MANUAL_H
|
||||
#define MANUAL_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
void manual_append_interactive_panel(char *buffer, size_t buf_size,
|
||||
size_t *pos, help_lang_t lang);
|
||||
|
||||
#endif /* MANUAL_H */
|
||||
8
include/manual_text.h
Normal file
8
include/manual_text.h
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef MANUAL_TEXT_H
|
||||
#define MANUAL_TEXT_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
const char *manual_text_interactive(help_lang_t lang);
|
||||
|
||||
#endif /* MANUAL_TEXT_H */
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
#ifndef SUPPORT_H
|
||||
#define SUPPORT_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
void support_append_interactive_panel(char *buffer, size_t buf_size,
|
||||
size_t *pos, help_lang_t lang);
|
||||
void support_append_exec_panel(char *buffer, size_t buf_size, size_t *pos,
|
||||
help_lang_t lang);
|
||||
|
||||
#endif /* SUPPORT_H */
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
#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 */
|
||||
|
|
@ -8,10 +8,9 @@
|
|||
#include "chat_room.h"
|
||||
#include "client.h"
|
||||
#include "common.h"
|
||||
#include "help_text.h"
|
||||
#include "i18n.h"
|
||||
#include "manual.h"
|
||||
#include "message.h"
|
||||
#include "support.h"
|
||||
#include "system_message.h"
|
||||
#include "tui.h"
|
||||
#include "utf8.h"
|
||||
|
|
@ -84,8 +83,8 @@ static int command_edit_distance(const char *a, const char *b) {
|
|||
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",
|
||||
"lang", "language", "help", "commands", "clear", "cls",
|
||||
"last", "search", "mute-joins", "mute", "lang", "language",
|
||||
"help", "clear", "cls",
|
||||
"q", "quit", "exit"
|
||||
};
|
||||
const char *best = NULL;
|
||||
|
|
@ -168,13 +167,9 @@ void commands_dispatch(client_t *client) {
|
|||
}
|
||||
pthread_rwlock_unlock(&g_room->lock);
|
||||
|
||||
} else if (strcmp(cmd, "help") == 0 || strcmp(cmd, "commands") == 0) {
|
||||
help_text_append_commands(output, sizeof(output), &pos,
|
||||
client->help_lang);
|
||||
|
||||
} else if (strcmp(cmd, "support") == 0 || strcmp(cmd, "guide") == 0) {
|
||||
support_append_interactive_panel(output, sizeof(output), &pos,
|
||||
client->help_lang);
|
||||
} else if (strcmp(cmd, "help") == 0) {
|
||||
manual_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 ||
|
||||
|
|
|
|||
12
src/exec.c
12
src/exec.c
|
|
@ -6,7 +6,6 @@
|
|||
#include "input.h"
|
||||
#include "message.h"
|
||||
#include "ratelimit.h"
|
||||
#include "support.h"
|
||||
#include "utf8.h"
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
|
|
@ -122,14 +121,6 @@ static int exec_command_help(client_t *client) {
|
|||
return client_send(client, help_text, strlen(help_text)) == 0 ? 0 : 1;
|
||||
}
|
||||
|
||||
static int exec_command_support(client_t *client) {
|
||||
char output[2048] = {0};
|
||||
size_t pos = 0;
|
||||
|
||||
support_append_exec_panel(output, sizeof(output), &pos, client->help_lang);
|
||||
return client_send(client, output, pos) == 0 ? 0 : 1;
|
||||
}
|
||||
|
||||
static int exec_command_health(client_t *client) {
|
||||
static const char ok[] = "ok\n";
|
||||
return client_send(client, ok, sizeof(ok) - 1) == 0 ? 0 : 1;
|
||||
|
|
@ -429,9 +420,6 @@ int exec_dispatch(client_t *client) {
|
|||
if (strcmp(cmd, "help") == 0 || strcmp(cmd, "--help") == 0) {
|
||||
return exec_command_help(client);
|
||||
}
|
||||
if (strcmp(cmd, "support") == 0 || strcmp(cmd, "guide") == 0) {
|
||||
return exec_command_support(client);
|
||||
}
|
||||
if (strcmp(cmd, "health") == 0) {
|
||||
return exec_command_health(client);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,60 +1,8 @@
|
|||
#include "help_text.h"
|
||||
|
||||
void help_text_append_commands(char *output, size_t buf_size, size_t *pos,
|
||||
help_lang_t lang) {
|
||||
if (lang == LANG_ZH) {
|
||||
buffer_appendf(output, buf_size, pos,
|
||||
"========================================\n"
|
||||
" 可用命令\n"
|
||||
"========================================\n"
|
||||
"list, users, who - 显示在线用户\n"
|
||||
"nick/name <name> - 修改昵称\n"
|
||||
"msg/w <user> <text> - 私聊用户\n"
|
||||
"inbox - 查看私聊历史\n"
|
||||
"last [N] - 查看最近 N 条消息\n"
|
||||
"search <keyword> - 搜索消息历史\n"
|
||||
"mute-joins - 切换加入/离开提示\n"
|
||||
"support - 显示快速支持指南\n"
|
||||
"lang [en|zh] - 查看或切换界面语言\n"
|
||||
"help, commands - 显示此帮助\n"
|
||||
"clear, cls - 清空命令输出\n"
|
||||
"q, quit, exit - 断开连接\n"
|
||||
"上/下方向键 - 命令历史\n"
|
||||
"========================================\n"
|
||||
"INSERT 模式:\n"
|
||||
" /me <action> - 发送动作消息\n"
|
||||
" @username - 提及用户并响铃提示\n"
|
||||
"========================================\n");
|
||||
return;
|
||||
}
|
||||
|
||||
buffer_appendf(output, buf_size, pos,
|
||||
"========================================\n"
|
||||
" Available Commands\n"
|
||||
"========================================\n"
|
||||
"list, users, who - Show online users\n"
|
||||
"nick/name <name> - Change nickname\n"
|
||||
"msg/w <user> <text> - Whisper to user (private)\n"
|
||||
"inbox - Show whisper history\n"
|
||||
"last [N] - Show last N messages\n"
|
||||
"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"
|
||||
"Up/Down arrows - Command history\n"
|
||||
"========================================\n"
|
||||
"In INSERT mode:\n"
|
||||
" /me <action> - Send action message\n"
|
||||
" @username - Mention (bell notify)\n"
|
||||
"========================================\n");
|
||||
}
|
||||
|
||||
const char *help_text_full(help_lang_t lang) {
|
||||
if (lang == LANG_EN) {
|
||||
return "TERMINAL CHAT ROOM - HELP\n"
|
||||
return "TNT KEY REFERENCE\n"
|
||||
"\n"
|
||||
"OPERATING MODES:\n"
|
||||
" INSERT - Type and send messages (default)\n"
|
||||
|
|
@ -80,7 +28,7 @@ const char *help_text_full(help_lang_t lang) {
|
|||
" PgDn/PgUp - Scroll full page down/up\n"
|
||||
" End/Home - Jump to bottom/top\n"
|
||||
" g/G - Jump to top/bottom\n"
|
||||
" ? - Show this help\n"
|
||||
" ? - Show full key reference\n"
|
||||
" Ctrl+C - Exit chat\n"
|
||||
"\n"
|
||||
"AVAILABLE COMMANDS:\n"
|
||||
|
|
@ -88,12 +36,12 @@ const char *help_text_full(help_lang_t lang) {
|
|||
" :nick <name> - Change nickname\n"
|
||||
" :msg <user> <text> - Whisper to user\n"
|
||||
" :w <user> <text> - Short alias for :msg\n"
|
||||
" :inbox - Show whispers\n"
|
||||
" :last [N] - Show last N messages (max 50)\n"
|
||||
" :search <keyword> - Search message history\n"
|
||||
" :mute-joins - Toggle join/leave notices\n"
|
||||
" :support - Show quick support guide\n"
|
||||
" :help - Show concise manual\n"
|
||||
" :lang <en|zh> - Switch UI language\n"
|
||||
" :help - Show available commands\n"
|
||||
" :clear - Clear command output\n"
|
||||
" :q, :quit, :exit - Disconnect\n"
|
||||
"\n"
|
||||
|
|
@ -110,7 +58,7 @@ const char *help_text_full(help_lang_t lang) {
|
|||
" e/z - Switch English/Chinese\n";
|
||||
}
|
||||
|
||||
return "终端聊天室 - 帮助\n"
|
||||
return "TNT 按键参考\n"
|
||||
"\n"
|
||||
"操作模式:\n"
|
||||
" INSERT - 输入和发送消息(默认)\n"
|
||||
|
|
@ -136,7 +84,7 @@ const char *help_text_full(help_lang_t lang) {
|
|||
" PgDn/PgUp - 向下/上滚动整页\n"
|
||||
" End/Home - 跳到底部/顶部\n"
|
||||
" g/G - 跳到顶部/底部\n"
|
||||
" ? - 显示此帮助\n"
|
||||
" ? - 显示完整按键参考\n"
|
||||
" Ctrl+C - 退出聊天\n"
|
||||
"\n"
|
||||
"可用命令:\n"
|
||||
|
|
@ -144,12 +92,12 @@ const char *help_text_full(help_lang_t lang) {
|
|||
" :nick <名字> - 更改昵称\n"
|
||||
" :msg <用户> <文本> - 私聊\n"
|
||||
" :w <用户> <文本> - :msg 的简写\n"
|
||||
" :inbox - 查看私聊\n"
|
||||
" :last [N] - 显示最后 N 条消息(最多50)\n"
|
||||
" :search <关键词> - 搜索消息历史\n"
|
||||
" :mute-joins - 切换加入/离开提示\n"
|
||||
" :support - 显示快速支持指南\n"
|
||||
" :help - 显示简明手册\n"
|
||||
" :lang <en|zh> - 切换界面语言\n"
|
||||
" :help - 显示可用命令\n"
|
||||
" :clear - 清空命令输出\n"
|
||||
" :q, :quit, :exit - 断开连接\n"
|
||||
"\n"
|
||||
|
|
|
|||
26
src/i18n.c
26
src/i18n.c
|
|
@ -104,17 +104,17 @@ const char *i18n_text(help_lang_t lang, i18n_text_id_t id) {
|
|||
case I18N_WELCOME_FALLBACK_FORMAT:
|
||||
return "TNT %s - SSH 匿名聊天室\r\n\r\n";
|
||||
case I18N_INSERT_HINT_WIDE:
|
||||
return "Enter 发送 · Esc 浏览 · :support";
|
||||
return "Enter 发送 · Esc 浏览 · :help";
|
||||
case I18N_INSERT_HINT_NARROW:
|
||||
return "Enter · Esc · :support";
|
||||
return "Enter · Esc · :help";
|
||||
case I18N_NORMAL_LATEST:
|
||||
return "G 最新";
|
||||
case I18N_NORMAL_NEW_MESSAGES:
|
||||
return "新消息";
|
||||
case I18N_HELP_TITLE:
|
||||
return " 帮助 ";
|
||||
return " 按键 ";
|
||||
case I18N_HELP_STATUS_FORMAT:
|
||||
return "-- 帮助 -- (%d/%d) j/k:滚动 g/G:首尾 e/z:语言 q:关闭";
|
||||
return "-- 按键参考 -- (%d/%d) j/k:滚动 g/G:首尾 e/z:语言 q:关闭";
|
||||
case I18N_COMMAND_OUTPUT_TITLE:
|
||||
return " 命令输出 ";
|
||||
case I18N_MOTD_TITLE:
|
||||
|
|
@ -126,7 +126,7 @@ const char *i18n_text(help_lang_t lang, i18n_text_id_t id) {
|
|||
case I18N_TITLE_MUTED:
|
||||
return "静音";
|
||||
case I18N_TITLE_HELP_HINT:
|
||||
return "? 帮助";
|
||||
return "? 按键";
|
||||
case I18N_IDLE_TIMEOUT_FORMAT:
|
||||
return "\r\n\033[33m已断开: 空闲超时 (%d 分钟)\033[0m\r\n";
|
||||
case I18N_SYSTEM_USERNAME:
|
||||
|
|
@ -189,7 +189,7 @@ const char *i18n_text(help_lang_t lang, i18n_text_id_t id) {
|
|||
case I18N_DID_YOU_MEAN_FORMAT:
|
||||
return "你是想输入 :%s 吗?\n";
|
||||
case I18N_UNKNOWN_GUIDANCE:
|
||||
return "输入 :support 查看引导,或 :help 查看命令\n";
|
||||
return "输入 :help 查看帮助\n";
|
||||
case I18N_EXEC_HELP:
|
||||
return "TNT exec 接口\n"
|
||||
"命令:\n"
|
||||
|
|
@ -201,7 +201,6 @@ const char *i18n_text(help_lang_t lang, i18n_text_id_t id) {
|
|||
" tail -n N 输出最近消息\n"
|
||||
" post MESSAGE 非交互发送消息\n"
|
||||
" post \"/me act\" 发送动作消息\n"
|
||||
" support 显示快速支持指南\n"
|
||||
" exit 成功退出\n";
|
||||
case I18N_EXEC_USERS_USAGE:
|
||||
return "users: 用法: users [--json]\n";
|
||||
|
|
@ -236,17 +235,17 @@ const char *i18n_text(help_lang_t lang, i18n_text_id_t id) {
|
|||
case I18N_WELCOME_FALLBACK_FORMAT:
|
||||
return "TNT %s - anonymous chat over SSH\r\n\r\n";
|
||||
case I18N_INSERT_HINT_WIDE:
|
||||
return "Enter send · Esc browse · :support";
|
||||
return "Enter send · Esc browse · :help";
|
||||
case I18N_INSERT_HINT_NARROW:
|
||||
return "Enter · Esc · :support";
|
||||
return "Enter · Esc · :help";
|
||||
case I18N_NORMAL_LATEST:
|
||||
return "G latest";
|
||||
case I18N_NORMAL_NEW_MESSAGES:
|
||||
return "new";
|
||||
case I18N_HELP_TITLE:
|
||||
return " HELP ";
|
||||
return " KEYS ";
|
||||
case I18N_HELP_STATUS_FORMAT:
|
||||
return "-- HELP -- (%d/%d) j/k:scroll g/G:top/bottom e/z:lang q:close";
|
||||
return "-- KEY REFERENCE -- (%d/%d) j/k:scroll g/G:top/bottom e/z:lang q:close";
|
||||
case I18N_COMMAND_OUTPUT_TITLE:
|
||||
return " COMMAND OUTPUT ";
|
||||
case I18N_MOTD_TITLE:
|
||||
|
|
@ -258,7 +257,7 @@ const char *i18n_text(help_lang_t lang, i18n_text_id_t id) {
|
|||
case I18N_TITLE_MUTED:
|
||||
return "muted";
|
||||
case I18N_TITLE_HELP_HINT:
|
||||
return "? help";
|
||||
return "? keys";
|
||||
case I18N_IDLE_TIMEOUT_FORMAT:
|
||||
return "\r\n\033[33mDisconnected: idle timeout (%d min)\033[0m\r\n";
|
||||
case I18N_SYSTEM_USERNAME:
|
||||
|
|
@ -321,7 +320,7 @@ const char *i18n_text(help_lang_t lang, i18n_text_id_t id) {
|
|||
case I18N_DID_YOU_MEAN_FORMAT:
|
||||
return "Did you mean :%s?\n";
|
||||
case I18N_UNKNOWN_GUIDANCE:
|
||||
return "Type :support for guidance or :help for commands\n";
|
||||
return "Type :help for help\n";
|
||||
case I18N_EXEC_HELP:
|
||||
return "TNT exec interface\n"
|
||||
"Commands:\n"
|
||||
|
|
@ -333,7 +332,6 @@ const char *i18n_text(help_lang_t lang, i18n_text_id_t id) {
|
|||
" tail -n N Print recent messages\n"
|
||||
" post MESSAGE Post a message non-interactively\n"
|
||||
" post \"/me act\" Post an action message\n"
|
||||
" support Show quick support guide\n"
|
||||
" exit Exit successfully\n";
|
||||
case I18N_EXEC_USERS_USAGE:
|
||||
return "users: usage: users [--json]\n";
|
||||
|
|
|
|||
10
src/manual.c
Normal file
10
src/manual.c
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#include "manual.h"
|
||||
#include "manual_text.h"
|
||||
|
||||
void manual_append_interactive_panel(char *buffer, size_t buf_size,
|
||||
size_t *pos, help_lang_t lang) {
|
||||
if (!buffer || !pos) return;
|
||||
|
||||
buffer_appendf(buffer, buf_size, pos, "%s",
|
||||
manual_text_interactive(lang));
|
||||
}
|
||||
63
src/manual_text.c
Normal file
63
src/manual_text.c
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#include "manual_text.h"
|
||||
|
||||
const char *manual_text_interactive(help_lang_t lang) {
|
||||
if (lang == LANG_ZH) {
|
||||
return "\033[1;36mTNT(1) 帮助\033[0m\n"
|
||||
"\n"
|
||||
"\033[1;37m名称\033[0m\n"
|
||||
" TNT - SSH 终端聊天室\n"
|
||||
"\n"
|
||||
"\033[1;37m快速开始\033[0m\n"
|
||||
" 直接输入消息,Enter 发送\n"
|
||||
" Esc 进入 NORMAL 浏览历史;G 回到最新;i 继续输入\n"
|
||||
" : 输入命令;q 或 Esc 关闭输出面板\n"
|
||||
"\n"
|
||||
"\033[1;37m命令\033[0m\n"
|
||||
" :users 在线用户\n"
|
||||
" :last [N] 最近消息,默认 10,最多 50\n"
|
||||
" :search <关键词> 搜索历史\n"
|
||||
" :msg <用户> <文本> 私聊\n"
|
||||
" :inbox 私聊收件箱\n"
|
||||
" :nick <名字> 修改昵称\n"
|
||||
" :mute-joins 静音/开启进出提示\n"
|
||||
" :clear 清空命令输出\n"
|
||||
" :q 断开连接\n"
|
||||
"\n"
|
||||
"\033[1;37m语言\033[0m\n"
|
||||
" :lang 显示当前语言\n"
|
||||
" :lang zh 切换中文\n"
|
||||
" :lang en 切换英文\n"
|
||||
"\n"
|
||||
"\033[1;37m参见\033[0m\n"
|
||||
" ? 完整按键参考\n";
|
||||
}
|
||||
|
||||
return "\033[1;36mTNT(1) help\033[0m\n"
|
||||
"\n"
|
||||
"\033[1;37mName\033[0m\n"
|
||||
" TNT - SSH terminal chat room\n"
|
||||
"\n"
|
||||
"\033[1;37mQuick start\033[0m\n"
|
||||
" Type a message and press Enter to send\n"
|
||||
" Esc enters NORMAL history browsing; G jumps latest; i types again\n"
|
||||
" : enters COMMAND mode; q or Esc closes output panels\n"
|
||||
"\n"
|
||||
"\033[1;37mCommands\033[0m\n"
|
||||
" :users show online users\n"
|
||||
" :last [N] show recent messages, default 10, max 50\n"
|
||||
" :search <keyword> search history\n"
|
||||
" :msg <user> <text> whisper privately\n"
|
||||
" :inbox show whispers\n"
|
||||
" :nick <name> change nickname\n"
|
||||
" :mute-joins toggle join/leave notices\n"
|
||||
" :clear clear command output\n"
|
||||
" :q disconnect\n"
|
||||
"\n"
|
||||
"\033[1;37mLanguage\033[0m\n"
|
||||
" :lang show current language\n"
|
||||
" :lang en switch to English\n"
|
||||
" :lang zh switch to Chinese\n"
|
||||
"\n"
|
||||
"\033[1;37mSee also\033[0m\n"
|
||||
" ? full key reference\n";
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
#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;
|
||||
|
||||
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;
|
||||
|
||||
buffer_appendf(buffer, buf_size, pos, "%s", support_text_exec(lang));
|
||||
}
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
#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";
|
||||
}
|
||||
|
|
@ -75,18 +75,6 @@ else
|
|||
FAIL=$((FAIL + 1))
|
||||
fi
|
||||
|
||||
SUPPORT_OUTPUT=$(ssh $SSH_OPTS localhost support 2>/dev/null || true)
|
||||
printf '%s\n' "$SUPPORT_OUTPUT" | grep -Eq '^TNT (support|支持)$' &&
|
||||
printf '%s\n' "$SUPPORT_OUTPUT" | grep -Eq '^(Troubleshooting|排查):'
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✓ support returns quick guide"
|
||||
PASS=$((PASS + 1))
|
||||
else
|
||||
echo "✗ support output unexpected"
|
||||
printf '%s\n' "$SUPPORT_OUTPUT"
|
||||
FAIL=$((FAIL + 1))
|
||||
fi
|
||||
|
||||
HELP_OUTPUT=$(ssh $SSH_OPTS localhost help 2>/dev/null || true)
|
||||
printf '%s\n' "$HELP_OUTPUT" | grep -q '^TNT exec 接口$' &&
|
||||
printf '%s\n' "$HELP_OUTPUT" | grep -q '^命令:$'
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ set timeout 10
|
|||
spawn ssh $SSH_OPTS anonymous@127.0.0.1
|
||||
sleep 1
|
||||
send -- "tester\r"
|
||||
expect ":support"
|
||||
expect ":help"
|
||||
send -- "\033\[200~"
|
||||
send -- "line1\nline2\nline3"
|
||||
send -- "\033\[201~"
|
||||
|
|
@ -133,19 +133,19 @@ else
|
|||
FAIL=$((FAIL + 1))
|
||||
fi
|
||||
|
||||
SUPPORT_SCRIPT="$STATE_DIR/support.expect"
|
||||
cat >"$SUPPORT_SCRIPT" <<EOF
|
||||
HELP_SCRIPT="$STATE_DIR/help.expect"
|
||||
cat >"$HELP_SCRIPT" <<EOF
|
||||
set timeout 10
|
||||
spawn ssh $SSH_OPTS anonymous@127.0.0.1
|
||||
sleep 1
|
||||
send -- "supporter\r"
|
||||
expect ":support"
|
||||
send -- "helper\r"
|
||||
expect ":help"
|
||||
send -- "\033"
|
||||
expect "NORMAL"
|
||||
send -- ":"
|
||||
expect ":"
|
||||
send -- "support\r"
|
||||
expect "支持"
|
||||
send -- "help\r"
|
||||
expect "TNT\\(1\\) 帮助"
|
||||
expect "按任意键"
|
||||
send -- "q"
|
||||
expect "NORMAL"
|
||||
|
|
@ -162,12 +162,12 @@ send -- "\003"
|
|||
expect eof
|
||||
EOF
|
||||
|
||||
if expect "$SUPPORT_SCRIPT" >"$STATE_DIR/support.log" 2>&1; then
|
||||
echo "✓ :support renders quick guide"
|
||||
if expect "$HELP_SCRIPT" >"$STATE_DIR/help.log" 2>&1; then
|
||||
echo "✓ :help renders concise manual"
|
||||
PASS=$((PASS + 1))
|
||||
else
|
||||
echo "x :support command failed"
|
||||
sed -n '1,160p' "$STATE_DIR/support.log"
|
||||
echo "x :help command failed"
|
||||
sed -n '1,160p' "$STATE_DIR/help.log"
|
||||
sed -n '1,120p' "$STATE_DIR/server.log"
|
||||
FAIL=$((FAIL + 1))
|
||||
fi
|
||||
|
|
@ -178,13 +178,13 @@ set timeout 10
|
|||
spawn ssh $SSH_OPTS anonymous@127.0.0.1
|
||||
sleep 1
|
||||
send -- "mistype\r"
|
||||
expect ":support"
|
||||
expect ":help"
|
||||
send -- "\033"
|
||||
expect "NORMAL"
|
||||
send -- ":"
|
||||
expect ":"
|
||||
send -- "suport\r"
|
||||
expect "你是想输入 :support 吗?"
|
||||
send -- "hlep\r"
|
||||
expect "你是想输入 :help 吗?"
|
||||
expect "按任意键"
|
||||
send -- "q"
|
||||
sleep 0.2
|
||||
|
|
@ -210,7 +210,7 @@ set timeout 10
|
|||
spawn ssh $SSH_OPTS anonymous@127.0.0.1
|
||||
sleep 1
|
||||
send -- "localized\r"
|
||||
expect ":support"
|
||||
expect ":help"
|
||||
send -- "\033"
|
||||
expect "NORMAL"
|
||||
send -- ":"
|
||||
|
|
@ -260,7 +260,7 @@ set timeout 10
|
|||
spawn ssh $SSH_OPTS anonymous@127.0.0.1
|
||||
sleep 1
|
||||
send -- "usageuser\r"
|
||||
expect ":support"
|
||||
expect ":help"
|
||||
send -- "\033"
|
||||
expect "NORMAL"
|
||||
send -- ":"
|
||||
|
|
@ -328,7 +328,7 @@ set timeout 10
|
|||
spawn ssh $SSH_OPTS anonymous@127.0.0.1
|
||||
sleep 1
|
||||
send -- "systemuser\r"
|
||||
expect ":support"
|
||||
expect ":help"
|
||||
send -- "\033"
|
||||
expect "NORMAL"
|
||||
send -- ":"
|
||||
|
|
|
|||
|
|
@ -19,10 +19,10 @@ 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
|
||||
MANUAL_TEXT_SRC = ../../src/manual_text.c
|
||||
RATELIMIT_SRC = ../../src/ratelimit.c
|
||||
|
||||
TESTS = test_utf8 test_message test_chat_room test_history_view test_i18n test_system_message test_help_text test_support_text test_cli_text test_ratelimit
|
||||
TESTS = test_utf8 test_message test_chat_room test_history_view test_i18n test_system_message test_help_text test_manual_text test_cli_text test_ratelimit
|
||||
|
||||
.PHONY: all clean run
|
||||
|
||||
|
|
@ -49,7 +49,7 @@ 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)
|
||||
test_manual_text: test_manual_text.c $(MANUAL_TEXT_SRC)
|
||||
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
test_cli_text: test_cli_text.c $(CLI_TEXT_SRC) $(COMMON_SRC)
|
||||
|
|
@ -80,8 +80,8 @@ run: all
|
|||
@echo "=== Running Help Text Tests ==="
|
||||
./test_help_text
|
||||
@echo ""
|
||||
@echo "=== Running Support Text Tests ==="
|
||||
./test_support_text
|
||||
@echo "=== Running Manual Text Tests ==="
|
||||
./test_manual_text
|
||||
@echo ""
|
||||
@echo "=== Running CLI Text Tests ==="
|
||||
./test_cli_text
|
||||
|
|
|
|||
|
|
@ -19,39 +19,25 @@ TEST(full_help_matches_language) {
|
|||
const char *en = help_text_full(LANG_EN);
|
||||
const char *zh = help_text_full(LANG_ZH);
|
||||
|
||||
assert(strstr(en, "TERMINAL CHAT ROOM - HELP") != NULL);
|
||||
assert(strstr(en, "TNT KEY REFERENCE") != NULL);
|
||||
assert(strstr(en, "AVAILABLE COMMANDS") != NULL);
|
||||
assert(strstr(en, ":inbox") != NULL);
|
||||
assert(strstr(en, ":support") == NULL);
|
||||
assert(strstr(en, ":commands") == NULL);
|
||||
assert(strstr(en, "Switch English/Chinese") != NULL);
|
||||
|
||||
assert(strstr(zh, "终端聊天室 - 帮助") != NULL);
|
||||
assert(strstr(zh, "TNT 按键参考") != NULL);
|
||||
assert(strstr(zh, "可用命令") != NULL);
|
||||
assert(strstr(zh, ":inbox") != NULL);
|
||||
assert(strstr(zh, ":support") == NULL);
|
||||
assert(strstr(zh, ":commands") == NULL);
|
||||
assert(strstr(zh, "切换英文/中文") != NULL);
|
||||
}
|
||||
|
||||
TEST(command_help_matches_language) {
|
||||
char out[2048];
|
||||
size_t pos;
|
||||
|
||||
out[0] = '\0';
|
||||
pos = 0;
|
||||
help_text_append_commands(out, sizeof(out), &pos, LANG_EN);
|
||||
assert(strstr(out, "Available Commands") != NULL);
|
||||
assert(strstr(out, "Show online users") != NULL);
|
||||
assert(pos == strlen(out));
|
||||
|
||||
out[0] = '\0';
|
||||
pos = 0;
|
||||
help_text_append_commands(out, sizeof(out), &pos, LANG_ZH);
|
||||
assert(strstr(out, "可用命令") != NULL);
|
||||
assert(strstr(out, "显示在线用户") != NULL);
|
||||
assert(pos == strlen(out));
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
printf("Running help text unit tests...\n\n");
|
||||
|
||||
RUN_TEST(full_help_matches_language);
|
||||
RUN_TEST(command_help_matches_language);
|
||||
|
||||
printf("\n✓ All %d tests passed!\n", tests_passed);
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -81,9 +81,9 @@ TEST(text_lookup_matches_language) {
|
|||
assert(strstr(i18n_text(LANG_ZH, I18N_WELCOME_SUBTITLE),
|
||||
"匿名聊天室") != NULL);
|
||||
assert(strstr(i18n_text(LANG_EN, I18N_HELP_STATUS_FORMAT),
|
||||
"HELP") != NULL);
|
||||
"KEY REFERENCE") != NULL);
|
||||
assert(strstr(i18n_text(LANG_ZH, I18N_HELP_STATUS_FORMAT),
|
||||
"帮助") != NULL);
|
||||
"按键参考") != NULL);
|
||||
assert(strstr(i18n_text(LANG_EN, I18N_COMMAND_OUTPUT_TITLE),
|
||||
"COMMAND") != NULL);
|
||||
assert(strstr(i18n_text(LANG_ZH, I18N_COMMAND_OUTPUT_TITLE),
|
||||
|
|
@ -118,8 +118,12 @@ TEST(text_lookup_matches_language) {
|
|||
"未知命令") != NULL);
|
||||
assert(strstr(i18n_text(LANG_EN, I18N_EXEC_HELP),
|
||||
"TNT exec interface") != NULL);
|
||||
assert(strstr(i18n_text(LANG_EN, I18N_EXEC_HELP),
|
||||
"support") == NULL);
|
||||
assert(strstr(i18n_text(LANG_ZH, I18N_EXEC_HELP),
|
||||
"TNT exec 接口") != NULL);
|
||||
assert(strstr(i18n_text(LANG_ZH, I18N_EXEC_HELP),
|
||||
"support") == NULL);
|
||||
assert(strstr(i18n_text(LANG_EN, I18N_EXEC_POST_EMPTY),
|
||||
"message cannot be empty") != NULL);
|
||||
assert(strstr(i18n_text(LANG_ZH, I18N_EXEC_POST_EMPTY),
|
||||
|
|
|
|||
44
tests/unit/test_manual_text.c
Normal file
44
tests/unit/test_manual_text.c
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/* Unit tests for concise manual text language selection */
|
||||
|
||||
#include "../../include/manual_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_manual_matches_language) {
|
||||
const char *en = manual_text_interactive(LANG_EN);
|
||||
const char *zh = manual_text_interactive(LANG_ZH);
|
||||
|
||||
assert(strstr(en, "TNT(1) help") != NULL);
|
||||
assert(strstr(en, "Quick start") != NULL);
|
||||
assert(strstr(en, "Commands") != NULL);
|
||||
assert(strstr(en, ":mute-joins") != NULL);
|
||||
assert(strstr(en, ":support") == NULL);
|
||||
assert(strstr(en, ":commands") == NULL);
|
||||
|
||||
assert(strstr(zh, "TNT(1) 帮助") != NULL);
|
||||
assert(strstr(zh, "快速开始") != NULL);
|
||||
assert(strstr(zh, "命令") != NULL);
|
||||
assert(strstr(zh, ":mute-joins") != NULL);
|
||||
assert(strstr(zh, ":support") == NULL);
|
||||
assert(strstr(zh, ":commands") == NULL);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
printf("Running manual text unit tests...\n\n");
|
||||
|
||||
RUN_TEST(interactive_manual_matches_language);
|
||||
|
||||
printf("\n✓ All %d tests passed!\n", tests_passed);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
/* 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;
|
||||
}
|
||||
16
tnt.1
16
tnt.1
|
|
@ -1,5 +1,5 @@
|
|||
.\" tnt(1) - Terminal Network Talk
|
||||
.TH TNT 1 "May 2026" "TNT 1.0.1" "User Commands"
|
||||
.TH TNT 1 "2026-05-24" "TNT 1.0.1" "User Commands"
|
||||
.SH NAME
|
||||
tnt \- anonymous SSH chat server with Vim\-style TUI
|
||||
.SH SYNOPSIS
|
||||
|
|
@ -15,7 +15,8 @@ tnt \- anonymous SSH chat server with Vim\-style TUI
|
|||
is a multi\-user anonymous chat server accessed over SSH.
|
||||
It provides a Vim\-style terminal user interface with INSERT, NORMAL, and
|
||||
COMMAND modes.
|
||||
Users connect with any standard SSH client; no account or registration is needed.
|
||||
Users connect with any standard SSH client; no account or registration is
|
||||
needed.
|
||||
.PP
|
||||
Messages are persisted to a log file and restored on server restart.
|
||||
The server supports CJK and emoji input, rate limiting, access tokens, and
|
||||
|
|
@ -44,7 +45,6 @@ Print version and exit.
|
|||
.BR \-h ", " \-\-help
|
||||
Print a short usage summary and exit.
|
||||
.SH CONNECTING
|
||||
.PP
|
||||
.nf
|
||||
ssh any\-username@hostname \-p 2222
|
||||
.fi
|
||||
|
|
@ -70,7 +70,7 @@ to return to INSERT,
|
|||
.B :
|
||||
to enter COMMAND mode,
|
||||
.B ?
|
||||
to open the help screen.
|
||||
to open the full key reference.
|
||||
.TP
|
||||
.B COMMAND
|
||||
Execute commands prefixed with
|
||||
|
|
@ -102,7 +102,7 @@ End/Home Jump to bottom/top
|
|||
g/G Jump to top/bottom
|
||||
i Switch to INSERT
|
||||
: Enter COMMAND mode
|
||||
? Open help screen
|
||||
? Open full key reference
|
||||
Ctrl+C Disconnect
|
||||
.TE
|
||||
.PP
|
||||
|
|
@ -117,12 +117,12 @@ l l.
|
|||
:name \fIname\fR Alias for :nick
|
||||
:msg \fIuser text\fR Send private whisper
|
||||
:w \fIuser text\fR Short alias for :msg
|
||||
:inbox Show private whispers
|
||||
:last [\fIN\fR] Show last N messages from history (1\-50, default 10)
|
||||
: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
|
||||
:help Show concise manual
|
||||
:clear Clear command output
|
||||
:q, :quit, :exit Disconnect
|
||||
Up/Down Browse command history
|
||||
|
|
@ -133,7 +133,6 @@ Commands can be run non\-interactively for scripting:
|
|||
.PP
|
||||
.nf
|
||||
ssh host \-p 2222 help
|
||||
ssh host \-p 2222 support
|
||||
ssh host \-p 2222 users \-\-json
|
||||
ssh host \-p 2222 stats \-\-json
|
||||
ssh host \-p 2222 tail 20
|
||||
|
|
@ -246,6 +245,7 @@ m1ngsama <contact@m1ng.space>
|
|||
.SH BUGS
|
||||
Report bugs at
|
||||
.UR https://github.com/m1ngsama/TNT/issues
|
||||
the project issue tracker
|
||||
.UE .
|
||||
.SH SEE ALSO
|
||||
.BR ssh (1),
|
||||
|
|
|
|||
Loading…
Reference in a new issue