viminfo 是 Vim 自定义的类文本日志格式,需用状态机逐行解析:跳过注释与空行,按首字符(!、:、=、>、~)分类处理;~后为无填充 base64 寄存器内容,须补足 = 后解码;命令/搜索历史需转义解析;路径含~需跨平台展开,编码需检测 BOM 并适配 UTF-8/UTF-16。

viminfo 文件不是标准格式,直接用 C++ 解析需手动处理
viminfo 不是 JSON、INI 或 YAML,它没有统一 schema,而是 Vim 自定义的类文本日志格式:混合了注释(# 开头)、键值对(! 或 : 开头)、列表块(> 开头)、二进制 blob(~ 行后接 base64)以及版本/时间戳元信息。C++ 标准库不提供原生解析器,必须自己按行扫描 + 状态机驱动。
常见错误是试图用 std::getline + std::string::find('=') 粗暴切分——这会漏掉多行寄存器、跳过注释逻辑、把 base64 数据误判为普通值。
- 先跳过所有以
#开头的注释行和空行 - 识别行首标记:
!(全局设置)、:(命令历史)、=(寄存器)、>(搜索历史)、~(寄存器内容起始) - 遇到
~行后,下一行才是 base64 编码的寄存器内容,需调用 base64 解码(注意 Vim 使用的变种:末尾可能缺=,换行符已被移除)
读取寄存器内容时,base64 解码必须兼容 Vim 的编码规则
Vim 的 viminfo 寄存器字段(如 =*、=+)后面跟一个 ~ 行,再下一行才是 base64 字符串。但 Vim 的 base64 实现省略了填充符(=),且允许任意长度换行(实际写入时通常不换行,但规范允许)。标准 base64 库(如 Boost.Base64 或 OpenSSL)默认要求填充,直接解码会失败。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 读到
~行后,用std::getline读取下一行,去掉首尾空白 - 手动补足 base64 填充:计算字符串长度 mod 4,缺 1 位补
==,缺 2 位补=,缺 3 位不合法(Vim 不会产生) - 使用无依赖的轻量 base64 解码函数(几十行即可),避免引入 Boost 或 OpenSSL;推荐用 RFC 4648 兼容实现,禁用 URL-safe 变体
- 解码后得到的是原始字节流,可能是 UTF-8 文本,也可能是二进制(如含
