尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

告别复杂工具,用Vim、Markdown和Git搭建个人知识库与任务追踪方案

告别复杂工具,用Vim、Markdown和Git搭建个人知识库与任务追踪方案 我从年初的一次翻车说起。那时候我手机里躺着三个笔记应用电脑桌面上还有几十个四处散落的 Word 文档和 Markdown 片段云盘里也备份了一份但每次要找资料都像在垃圾堆里淘金。更离谱的是某天某款笔记软件突然通知我要升级会员才能继续多端同步而它导出给我的 HTML 文件里图片路径全是乱的几乎等于宣布我的历史资料被锁死了。痛定思痛之后我把这套东西整个推翻用最“原始”的方式重新搭了一套个人知识库和任务追踪方案。我给它起了个代号叫caveman意思是“穴居人思维”——不是拒绝现代技术而是把工具降到只有几个确定性的、我能完全掌控的部件。这套方案的核心就是 Vim 加 Markdown 加 Shell 脚本再加一个 Git 仓库做同步和备份。这篇文章我就完整复盘一下它的设计思路、具体实现、踩过的坑以及后来做的一些进阶扩展。如果你和我一样已经受够了被各种“生产力工具”绑架每次换软件都要为迁移数据头疼或者你只是想要一套学习成本低、十年后还能打开、文件永远属于你自己的记录系统那么这套 caveman 方案应该能给你不少启发。我会尽量把每一步的原理和操作细节都写清楚方便你直接照着搭。1. 复杂工具吃掉了太多时间Caveman 方案的出发点1.1 从一次资料迁移事故说起我一直有个习惯把所有读过的书、看过的文章、突然冒出来的想法都记下来。时间久了笔记量到了几千条。表面上看笔记应用帮我管理了这一切但实际上这些数据是以一种非常脆弱的姿态存在的数据库格式不公开导出功能不完整图片附件分散在各种目录里。当我试图把笔记应用 A 的数据迁移到笔记应用 B 时才发现自己收藏多年的网页剪藏内容全都变成了无法打开的乱码。这件事让我非常清醒地认识到一个事实所谓“云笔记”本质上是一个黑盒。我每个月付费享有的却是数据的临时保管权而不是所有权。真正的所有权意味着我可以随时拿走我的所有内容用任何工具打开不依赖任何一家公司的服务器和商业决策。纯文本恰好满足了这一点。Markdown 格式的纯文本文件放到任何系统上哪怕用最古老的记事本打开内容依然是完整可读的。这就好比粮票时代人们存粮食而我现在选择“存粮食而不是存粮票”。1.2 工具选择过载才是效率的真正敌人市面上那些宣称“提升生产力”的工具很多时候反而在损耗生产力。今天这个应用推出了“双向链接”明天那个工具搞出了“AI 自动标签”后天又有新的数据库型笔记软件宣称要“重塑你的第二大脑”。我早期确实沉迷过这套东西花大量时间折腾模板、配色、插件弄完之后发现真正用来读书思考的时间反而变少了。更重要的是复杂工具带来了隐性的维护成本。插件升级后不兼容一堆配置需要重新调整同步服务偶尔抽风多端数据不一致界面迭代后按钮位置变了肌肉记忆全部作废。我越来越觉得工具的复杂度本身就是一种税。而 caveman 方案的核心逻辑就是把复杂度砍掉只留下三个不可替代的环节写下来、存得住、找得到。其他所有花里胡哨的功能能不要就不要。1.3 “穴居人”的三条判断标准在决定搭建这套方案前我给自己定了几条硬性规则每条都可以被当成一道筛选工具的标准。第一数据必须完全由我掌控。任何格式不公开、无法批量导出、导出后信息不全的工具全部排除。第二操作必须可预期。我不会因为软件版本升级一夜之间发现所有快捷键都变了也不希望某个按钮点了之后不知道数据去了哪里。第三十年后必须还能打开。我用 ASCII 字符、Markdown 语法、纯文本文件和简单脚本就是确保哪怕十年后哪怕我忘光了现在的所有操作细节只要找一个终端就能把这套系统重新跑起来。想清楚了这三条后面的事情就变得很简单选编辑器选存储格式选同步方式选检索手段。每一样东西都不需要“最好”只需要“最确定”。2. 工具选型留什么、砍什么用最笨的东西解决最核心的问题2.1 编辑器为什么是 Vim 而不是全功能 IDE先说明一下我本身并不是 Vim 的狂热爱好者日常写代码也会用 VS Code。但在这套纯文本工作流里Vim 几乎是唯一理性的选择。原因很简单。Vim 在任何一台 Linux 服务器、Mac 或者 Windows 机器上都几乎必然存在SSH 到远程机器上也可以直接使用完全不需要图形界面。它的启动速度极快哪怕是十几年前的旧电脑敲入vim命令到光标开始闪烁用时不到一秒。全功能 IDE 为了加载工程索引、语言服务器、插件市场启动动辄需要几秒钟在一个“纯文本随手记”的场景里这完全是浪费。另外Vim 的编辑模式非常适合处理短文本。输入一句话、改一个词、删除一整行在普通模式下只要两三个按键就能完成手不用离开键盘。我把笔记编辑器切换到 Vim 之后记录的阻力明显变小了“随时写几笔”的频率高了很多。如果你不熟悉 Vim用 Nano 或者系统自带的文本编辑器也完全可以原理是一样的只是 Vim 在长远来看更值得投入时间去熟悉。2.2 存储格式为什么必须用 Markdown 纯文本这一步我几乎没有纠结。Markdown 语法简单到可以用几句话讲完井号是标题星号是强调短横线是列表链接和图片的中括号小括号组合也不难记。这些语法在任何编辑器里都能被正确渲染而文件本身就是一个.md后缀的纯文本文件。纯文本还有一个巨大的隐藏优势——可 diff。文件内容的任何改动都可以被 Git 精确追踪我可以随时查看某一条笔记在三个月前的版本长什么样也可以把误删的文字找回来。这是任何数据库型笔记应用都做不到的就算它们有“历史版本”功能也是封闭在自家系统里看不到底层的变化过程。顺带说一句我的笔记里也包含表格。Markdown 的表格语法虽然写起来略显繁琐但胜在稳定。用管道符号和短横线画出的表格即便脱离了渲染器肉眼也完全能看懂原始结构。这一点对我这种喜欢做各种方案对比记录的人来说非常重要。2.3 自动化与同步Shell 脚本加 Git工欲善其事必先利其器。既然已经有了编辑器和存储格式剩下要解决的就是“新建”“查找”“同步备份”这三件日常操作。我选择用 Shell 脚本处理前两件事用 Git 处理第三件。为什么不直接装个更“现代化”的笔记软件因为脚本的每一步都是透明的。我可以打开脚本文件逐行阅读它逻辑知道它在哪个目录创建什么文件知道它搜索哪个路径。我不用担心某个“同步功能”在后台偷偷把数据传到某个我无法控制的地方也不需要为了加一个统计功能去安装一个几十 MB 的应用程序。Git 作为版本控制工具每年被全球无数开发者使用牢靠程度是经过数十年检验的。下面是我最终确定的工具清单做完选型之后整套系统的全貌非常清晰维度传统笔记方案Caveman 方案写入速度取决于应用启动速度和网络同步状态Vim 秒开离线可用数据所有权数据在服务商服务器导出格式不完整所有数据为本地纯文本随时可迁移检索能力依赖应用内搜索算法直接交给 ripgrep 和 fzf速度快且可控同步成本依赖服务商的多端同步功能一个 Git 仓库手动或定时 push学习曲线界面和功能不断变化只有 Vim、Markdown、Shell 三个知识点3. 核心实现一套可以直接抄走的 Caveman 工作流3.1 目录结构设计与命名规则一套好的纯文本管理系统目录规划比想象中更重要。如果文件到处都是再强大的搜索工具也无法帮你整理思绪。我的目录结构非常简单只有三层任何人看一眼就明白。~/caveman/ ├── README.md ├── inbox/ # 临时想法快速捕捉 ├── notes/ # 常青笔记按主题存放 │ ├── tech/ │ ├── reading/ │ └── life/ ├── tasks/ # 任务追踪与项目进度 │ ├── active/ │ └── archive/ └── archive/ # 已完成笔记的归档区顶层是一个名为caveman的文件夹里面按用途分成了四个核心区域。inbox存放一切未经整理的碎片想法比如路上想到的一个点子、临时看到的一段话。每天晚上或者每周整理一次把有长期价值的内容移到notes中对应的主题目录下。tasks放任务相关的内容某项任务结束之后把它挪到archive保持目录清爽。文件的命名规则我统一采用“日期 描述性标题”格式。比如一篇关于 Vim 技巧的笔记就叫20250104-vim-register-tips.md。这样做有两个好处第一按文件名排序时时间顺序一目了然第二不需要搜索内容只看文件名就能大概猜出这篇笔记讲什么。任何命名规则都行关键是整个系统里必须一致不一致的命名会让后续脚本处理变得非常麻烦。3.2 新建笔记脚本降低记录的阻力“写笔记”最大的阻力往往不是打字而是打开正确的文件夹、新建文件、填上模板这一堆前置动作。为此我写了一个简单的脚本存放在用户目录下随时可以用。#!/usr/bin/env bash # 用法: new.sh 标题关键词 TITLE$* if [ -z $TITLE ]; then echo 请输入标题关键词 exit 1 fi DATE$(date %Y%m%d) FILENAME$HOME/caveman/inbox/${DATE}-${TITLE}.md if [ -f $FILENAME ]; then echo 文件已存在: $FILENAME exit 1 fi cat $FILENAME EOF # ${TITLE} 日期: $(date %Y-%m-%d) ## 想法 EOF vim $FILENAME把这段代码保存为new.sh加上执行权限之后我只要在终端敲一句./new.sh Vim寄存器技巧就会自动在 inbox 目录里生成一个带当天日期和标题的 Markdown 文件并且直接用 Vim 打开光标停在“想法”标题下面等待输入。整个流程压缩成了两步输入标题开始写字。需要注意的是脚本里对文件名做了处理但我没有处理空格转义。因为我的习惯是标题关键词之间用短横线连接或者只用一个短语尽量避免空格。如果一定要用空格脚本在循环处理参数时用$*会导致文件名里出现空格后续脚本检索时容易出问题这个我们在踩坑部分专门细说。3.3 快速搜索脚本让“找到”变得毫不费力很多笔记应用宣传自己的“智能搜索”但对我来说最可靠的搜索就是直接对纯文本内容做正则匹配。现代命令行里有两个工具能让这个体验变得极好ripgrep负责内容匹配fzf负责模糊选择。我常用的搜索命令是长这样的rg -l $1 ~/caveman/ | fzf --preview bat --coloralways {}一条命令解释起来很简单先用rg在 caveman 目录下递归查找所有包含关键词的文件列出文件名接着用fzf做交互式选择按上下键浏览回车打开在浏览的时候bat在下方预览窗口里渲染这个文件的彩色内容。后来我觉得每次敲这一长串命令太累就又封装了一个find.sh#!/usr/bin/env bash # 用法: find.sh 搜索关键词 KEYWORD$1 if [ -z $KEYWORD ]; then echo 请输入搜索关键词 exit 1 fi rg -l $KEYWORD $HOME/caveman | fzf --preview bat --coloralways {}按下回车之后选中的文件会直接用 Vim 打开。整个检索过程基本在一秒钟内完成比任何图形化笔记软件的搜索都快。我试过在几千个 Markdown 文件里搜一个冷门名词ripgrep几乎不需要等待。3.4 同步与备份Git 仓库的搭法备份这件事纯文本下的 Git 方案可以说是最优雅的解决方案。我直接把~/caveman目录初始化成一个 Git 仓库在~/.gitignore里排除掉临时文件和编辑器产生的垃圾文件。由于内容全是文本仓库的体积常年保持在几 MB 以内push 和 pull 都很快。*.tmp .DS_Store .obsidian/ .vscode/我配置了一个私有 Git 远端地址每天工作结束执行一次git add -A git commit -m daily git push就完成了一整天的同步和备份。这样做有三个额外的收益。第一误删恢复变得非常简单。万一某天我rm错了一个文件用git checkout commit -- path就能秒回。第二我可以回顾自己的记录节奏。用git log --stat看一眼提交历史就能知道自己哪几天写得多、哪几天断了更这种数据透明度是其他笔记软件给不了的。第三如果需要换电脑只需要git clone一次整个知识库就完整地搬家了不需要任何“导出导入”操作。如果你担心远端 Git 服务出问题还可以加一层保险用一个外接硬盘或者其他存储介质做一份离线裸仓库备份。裸仓库的创建很简单一条命令就能完成。git clone --bare ~/caveman ~/backup/caveman.git之后定期执行git push --mirror ~/backup/caveman.git就能把整个历史完整地镜像过去。我对这种“本地主仓库 远端仓库 离线裸仓库”的三重备份结构非常有信心哪怕硬盘坏了两块数据依然不会丢。4. 我在实际使用中踩过的坑4.1 Vim 中文乱码问题编码设置的第一课刚把工作流搭好时我在 Vim 里打开自己写的中文 Markdown 文件发现光标后面有一串乱码。排查下来原因很简单Vim 的默认编码检测顺序没配置好而我的笔记文件都是 UTF-8 编码。解决方案是在~/.vimrc里加上两行配置set encodingutf-8 set fileencodingsucs-bom,utf-8,gbk,gb18030这里fileencodings的顺序很关键。它告诉 Vim 在打开文件时按照这个顺序去猜测编码UTF-8 被放在前面之后绝大多数现代文本文件都能被正确识别。万一碰到老的 GBK 编码文件后面还有 GB18030 兜底。这个问题我一开始觉得稀奇后来发现是很多从 Windows 转过来的同事最容易遇到的 Vim 配置问题所以专门写出来提一下。还有一个隐藏的小坑终端本身的编码设置。如果终端模拟器被设置成非 UTF-8 模式Vim 内部设置得再好也无济于事。我用的终端都是默认 UTF-8如果你发现同样的文件在不同终端里显示不一致可以优先检查终端的字符编码设置。4.2 文件名里的空格和特殊字符搜索脚本的灾难有一次我在写某篇读书笔记时手滑生成的标题里带了一个空格20250104-《人类简史》读书笔记 .md。当时没在意直到运行搜索脚本时发现这个文件无论如何都搜不到而且在 fzf 的预览窗口里文件名也显示得怪怪的。根因在脚本处理参数的方式上。Shell 默认以空格作为参数分隔符如果文件路径里带着空格rg -l $KEYWORD ~/caveman这样的命令本身没问题问题出在我没有给路径加引号的其他手工命令里。比如有时候我想直接对目标文件执行vim打开偷懒不引号整条命令就会把空格后的片段当成另一个参数看待。这个问题的彻底解法还是回到命名习惯。我给自己定了一条铁律所有文件名一律不能用空格用短横线代替。中文标题之间没有空格问题但英文关键词之间一定用-。这样一来脚本、Shell 循环、批处理都能少掉一多半的引号陷阱。如果你实在改不了空格的癖好那么所有脚本里涉及文件路径的地方必须老老实实用$VAR把变量包起来。4.3 一次 Git 提交大文件导致的仓库膨胀事故某一天我尝试在笔记里嵌入一个 PDF 截图作为参考资料直接拖进了 caveman 目录顺手就git add -A提交了。结果那个 PDF 有几十 MBGit 仓库瞬间膨胀到让人觉得不安的地步。更麻烦的是这个文件已经被记录进了历史提交后面即使我把它删掉仓库体积也不会自动缩小。解决这个问题的办法分两步。第一以后所有二进制文件比如图片、PDF、音频统一放在一个专门的附件目录里并且用.gitignore忽略掉不纳入 Git 管理。其实对纯文本笔记系统来说真正的持久化图片需求没有那么强烈。我的笔记里如果需要引用某个外部资料我更倾向于写清楚来源链接和阅读体会而不是把整个 PDF 塞进仓库。第二如果已经误提交了可以用 Git 的 filter 相关操作清理历史但这操作比较折腾普通用户最省心的办法是把仓库推倒重建一次也就是把当前所有文本文件复制到新目录重新初始化。这个经历让我彻底意识到文本系统就是文本系统它不应该承担文件存储库的职责。4.4 图片与附件的处理最反“穴居人”的东西纯文本什么都好唯独图片是个麻烦。Markdown 里的图片语法是![](path)但如果你在本地写笔记时引用的是某个云盘链接那么链接一断图就没了如果你引用的是本地路径换一台电脑路径就会失效。我目前采用的折中方案是只有真正需要长期保存的图片才动手处理一般的网页截图看一眼就删不存。对于少数值得保留的图片我统一放进~/caveman/assets目录文件名按日期命名然后在 Markdown 里引用相对路径。这样整个 caveman 文件夹依然可以被 Git 完整追踪图片虽然不会像文本那样精确 diff但至少有了版本管理换电脑也不怕丢。不要试图让这套系统把所有东西都管起来保持它“以文字为中心”的纯粹性才走得远。5. 从“够用”到“好用”Caveman 方案的进阶扩展5.1 模糊搜索体验升级rg 加 fzf 的黄金组合基础版的搜索脚本只能根据关键词匹配整词实际使用时我发现很多时候我只记得某句话里的一两个片段甚至只记得大概的字母顺序。这时候fzf的模糊匹配能力就派上了大用场。我调整了搜索脚本让它分两层工作。先在 caveman 目录下把所有文件名喂给 fzf让用户按文件名模糊选择如果没有选到再进入内容全文搜索模式。通常 90% 的情况在文件名一层就解决了因为我的命名规范已经把核心信息塞进文件名了。剩下的 10%用 ripgrep 全文搜也能快速定位到段落。这一步做完之后整个检索体验基本达到了“现代软件”的水平但底层的工具却是最古老的命令行组件。这种感觉很奇妙像是给皮实耐造的拖拉机加上了助力转向结构没变体验却完全不一样了。5.2 一键导成网页或 PDF 分享给非技术朋友纯文本的另一个问题是不方便直接给不熟悉的人看。我给老婆分享一篇自己写的菜谱笔记时总不能让她打开 Vim。于是我在脚本库里加了一个export.sh核心逻辑是调用 pandoc 把指定 Markdown 文件转成带样式的 HTML 文件然后在浏览器里打开。pandoc $1 -s -o /tmp/export.html --metadata titlecaveman 导出 open /tmp/export.html我的主力写作环境是 Vim但平时草稿阶段的灵感记录会先用手机上的文本编辑器快速写几笔同步到服务器之后再回到 Vim 整理。手机上编辑纯文本也很简单任何一款支持 Markdown 的编辑器都能打开仓库里的文件。不要在手机上硬套整套命令行的东西保持“读取用手机深度编辑用电脑”的思路才是契合穴居人理念的使用姿势。这不等于放弃移动端而是把移动端定位成“快速输入”和“随时查阅”把完整的沉淀过程留给桌面端。6. 对我来说穴居人式工具真正的价值是什么6.1 工具应该提供确定性而不是惊喜整套系统用下来半年多我最深的感受其实不是“快”或者“轻”而是“放心”。现在的笔记软件市场每隔几个月就会冒出新概念每个公司都在想尽办法提高你的使用频次让你留在它的生态里。而 caveman 这套方案几乎不给惊喜也几乎没有不可预料的状况。Vim 二十年没怎么大变Markdown 语法二十年没变Shell 脚本的基本逻辑更是四十年稳定。它们的“无聊”恰恰是最大的优点。6.2 搜索的尽头是命名规范如果你只从这篇文章里带走一条经验我希望是想让自己写的东西将来能被找到与其依赖搜索工具的智能程度不如先把文件名规范好。在我这套系统里80% 的检索靠文件名就能完成剩余的才需要内容搜索。命名规范简单直接效果胜过任何花哨的标签系统。6.3 一个可能被忽略的扩展方向这套系统目前只服务我自己一个人的知识管理。但我已经开始设想如果把它推广到一个小团队里做项目文档共享会怎么样思路很简单开一个内部的 Git 仓库团队成员各自往里面提交纯文本格式的文档和任务清单所有人都能通过 pull 获取最新内容历史版本天然可追溯。比起在一个商用协作平台上建立一座信息孤岛这种“每个人都拥有一份完整备份”的文档协作方式也许才是最符合穴居人精神的做法。如果你正在被各种复杂的协作平台困扰不妨从这个方向试一试。
返回列表