Metadata-Version: 2.4
Name: moyu-reader
Version: 0.3.0
Summary: A discreet terminal-only plain-text novel reader
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# 墨鱼 Moyu

墨鱼是一个只在命令行中运行的纯文本小说阅读器。它先用真实、只读的命令输出生成终端记录，再在底部原地显示少量正文；退出时只擦除正文，保留上面的正常输出。

## 快速开始

需要 Python 3.9 或更新版本，无第三方运行依赖。

```bash
./xx path/to/a.txt
./xx a.txt -s 1080
```

在项目目录中安装为全局命令：

```bash
pipx install .
moyu path/to/a.txt
```

发布到 PyPI 后，推荐使用 uv 安装独立命令行工具：

```bash
uv tool install moyu-reader
xx help
```

`moyu` 和 `xx` 完全等价。

忘记命令或按键时，可以随时查看内置帮助：

```bash
xx help
```

## 隐蔽别名

把真实文件注册为一个不显眼的别名：

```bash
xx add ~/Downloads/novel/a.txt --name build
xx build
xx recent
```

之后 Shell 历史中只出现 `xx build`。进度文件使用小说内容指纹作为键，不保存明文路径；进度和别名文件权限均为 `0600`。别名文件中的位置经过编码，目的是避免随手查看时直接暴露，不等同于加密。

同一文件改名或移动后，直接用新路径打开仍会根据内容指纹恢复进度。原别名指向旧位置时，重新执行一次 `xx add 新路径 --name build` 即可更新。

## 命令选项

```text
xx a.txt                     打开小说并继续上次进度
xx a.txt -s 1080             从原文第 1080 行开始
xx a.txt -n 5                显示 5 行正文
xx a.txt -e gb18030          手动指定编码
xx a.txt --show-encoding     只显示检测到的编码
xx a.txt --no-cover          不生成伪装输出
xx a.txt --cover git         使用 Git 风格伪装输出
xx a.txt --cover-lines 120   生成最多 120 行伪装输出
xx a.txt --auto-hide 10      闲置 10 秒自动隐藏
xx a.txt --no-hide-on-blur   失去焦点时保持正文可见
xx a.txt --no-title          不修改终端标题
xx a.txt --stats             为本次阅读记录统计
xx a.txt --left-click exit       临时把鼠标左键设为退出
xx a.txt --right-click next_page 临时把鼠标右键设为下一页
xx a.txt --middle-click next_page 临时把鼠标中键设为下一页
```

伪装场景包括 `system`、`git`、`build` 和 `network`。前半段来自真实的只读命令；最后一段是带时间戳、级别、中文模块名、批次号、进度和耗时的合成运维日志。日志采用长度不一的中文长句连续堆叠，让紧随其后的小说正文不再突然改变视觉纹理。合成日志不会读取私人系统日志，也不会暴露进程参数或小说路径。

## 阅读按键

| 按键 | 动作 |
| --- | --- |
| `↑` / `K` | 向上 1 行 |
| `↓` / `J` | 向下 1 行 |
| `←` / `H` | 向前 1 页 |
| `→` / `L` / 空格 / `Tab` | 向后 1 页 |
| 鼠标滚轮 | 前后翻页；1 秒内最多响应一次 |
| 鼠标左键 | 默认向后翻 1 页；可配置 |
| 鼠标右键 | 默认向前翻 1 页；可配置 |
| 鼠标中键 | 默认保存、擦除正文并退出；可配置 |
| `Ctrl-L` | 老板键：隐藏或恢复正文 |
| `[` / `]` | 上一章 / 下一章 |
| `20[` / `100]` | 向前 20 章 / 向后 100 章 |
| `100C` | 直接跳到第 100 个识别章节 |
| `C` | 打开章节序号输入框并按回车（备用） |
| `M` | 保存当前位置书签 |
| `'` | 返回最近保存的书签 |
| `/` | 搜索；支持中文输入法 |
| `N` / `Shift-N` | 下一个 / 上一个搜索结果 |
| `G` | 输入行号、`+100` 或 `-50` 跳转 |
| `I` | 显示行号、百分比和当前章节 1 秒 |
| `Q` / `~` / `～` | 保存、擦除正文并退出 |
| `Esc` / `Ctrl-C` | 保存、擦除正文并退出 |

按键不区分文档中的大小写说明：实际使用 `m` 保存书签、`n` 查找下一处、`N` 查找上一处、`g` 跳转、`i` 查看状态。

终端窗口改变宽度时会自动重新折行并保持当前位置。中文标点会尽量避免单独出现在新行开头。

默认阅读单位仍是 3 行原文，但终端中会预留 `3 + 2 = 5` 行空间。长行折成两行时使用额外空间，不会挤掉本页后续的原文；没有折行时，多出的两行保持空白。使用 `-n N` 时同样会预留 `N+2` 行。

空行以及只包含空格、Tab 或全角空格的行会自动跳过，不占用三行阅读区域。跳转和进度仍使用原文件行号；如果目标位置是空行，会显示后面的第一行正文。

## 自动隐藏

默认闲置 15 秒自动擦除正文。滚轮或按键会恢复正文；恢复动作本身不会翻页。支持焦点事件的终端在切换窗口或标签页时也会立即隐藏，返回时恢复。

`Ctrl-L` 可以随时隐藏而不退出，再次按下或进行其他操作即可恢复。鼠标右键当前默认用于上一页；如果希望用鼠标隐藏，可将任意鼠标键配置为 `toggle_hide`。

## 章节、搜索和书签

章节识别支持 `第一章`、`第108节`、`第十二卷`、`Chapter 12` 等常见标题。输入 `100]` 可向后跳 100 个章节，`20[` 可向前跳 20 个章节，`100c` 可直接跳到识别列表中的第 100 章。数字在按下动作键时结束，因此不存在 `c10` 和 `c100` 的输入歧义。单独按 `c` 仍会打开输入框，可输入章节序号并按回车。搜索和跳转输入时会暂时恢复终端的正常输入模式，因此中文输入法可以正常提交关键词。

中文输入法直接产生的 `【】`、`［］`、`「」`、`〔〕` 会自动映射为上一章和下一章，不需要切换到英文输入法。

书签和阅读位置保存在：

```text
~/.local/state/moyu/progress.json
```

## 配置文件

生成默认配置：

```bash
xx init-config
```

路径为 `~/.config/moyu/config.toml`：

```toml
lines = 3
cover = "system"
cover_lines = 0
wheel_cooldown = 1.0
auto_hide_seconds = 15.0
hide_on_blur = true
left_click = "next_page"
right_click = "previous_page"
middle_click = "exit"
disguise_title = "system monitor — zsh"
statistics = false
```

`cover_lines = 0` 表示根据终端高度自动生成 40–100 行。命令行参数优先于配置文件。

`left_click`、`right_click`、`middle_click` 均可设为 `next_page`、`previous_page`、`exit` 或 `toggle_hide`。当前默认布局是左键下一页、右键上一页、中键退出；也可用对应的 `--left-click`、`--right-click`、`--middle-click` 参数临时覆盖。

## 阅读统计

统计默认关闭。配置 `statistics = true` 或启动时传入 `--stats` 后，会记录阅读时长、翻阅行数和会话次数，不保存正文内容。

```bash
xx stats
xx stats build
```

## 编码与性能

支持 UTF-8、带或不带 BOM 的 UTF-16、GB18030/GBK、Big5、Shift-JIS 和 EUC-KR。UTF-8 与 BOM 编码会确定性识别，无标记的传统编码通过文本特征选择，也可用 `-e` 覆盖。

布局只在打开及终端宽度变化时计算，翻页不重复处理整本小说。当前版本仍会将解码后的文本载入内存：普通小说和几十 MB 文本适用；数百 MB 文件尚不是严格的流式读取。

## 测试

```bash
uv sync
uv run python -m unittest discover -s tests -v
uv build --no-sources
```

也可以直接使用系统 Python：

```bash
PYTHONPATH=src python3 -m unittest discover -s tests -v
```
