本地存储、标签分类、全文搜索——50 行 Python 代码实现一个轻量级代码片段管理工具,再也不用在文件夹里翻来翻去。
你是不是也有这种经历?
写了一段很棒的正则表达式,三个月后想复用,死活找不到在哪。或者同事分享了一个优雅的排序算法,你随手贴进备忘录,结果再也没打开过。
我就是这样。后来决定自己写一个代码片段管理器。
不用数据库,不用前端框架。Python + SQLite,50 多行代码搞定。
项目背景
程序员每天产生大量代码片段:一段 SQL 查询、一个 CSS 技巧、一个 API 调用模板。它们散落在笔记软件、浏览器书签、甚至聊天窗口里。
需要一个工具,能同时满足这几个条件:
- 本地存储,不依赖网络
- 全文搜索,输入关键词就能找到对应代码
- 标签分类,按语言或用途分组
- 零配置,打开就用
市面上有 SnippetBox、GistHub 之类的工具,但要么太重,要么要注册账号。我自己写的这个,跑在本机上,数据完全掌控在自己手里。
技术选型
|| 组件 | 选择 | 理由 |
|——|——|——|
| 存储 | SQLite3 | Python 内置,零安装 |
| 搜索 | Python in 操作符 | 简单直接,够用 |
| 格式化 | Pygments | 语法高亮,可选 |
| 交互 | argparse + input() | 命令行工具,轻量 |
SQLite 是最佳选择。它不是一个独立的数据库服务,就是一个文件。你的代码片段存在一个 .db 文件里,拷贝走就行。
实现步骤
第一步:初始化数据库
# snippet_manager.py
import sqlite3
import os
from datetime import datetime
DB_PATH = os.path.expanduser("~/.code_snippets.db")
def init_db():
"""初始化数据库表"""
conn = sqlite3.connect(DB_PATH)
cursor = conn.cursor()
cursor.execute("""
CREATE TABLE IF NOT EXISTS snippets (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
content TEXT NOT NULL,
language TEXT DEFAULT 'text',
tags TEXT DEFAULT '',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
""")
cursor.execute("""
CREATE INDEX IF NOT EXISTS idx_title ON snippets(title);
CREATE INDEX IF NOT EXISTS idx_tags ON snippets(tags);
CREATE INDEX IF NOT EXISTS idx_content ON snippets(content);
""")
conn.commit()
return conn
建了三张索引。标题、标签、内容都建立索引,这样搜索的时候不会太慢。
第二步:添加和保存片段
def add_snippet(conn, title, content, language="text", tags=""):
"""添加一个新的代码片段"""
cursor = conn.cursor()
cursor.execute(
"""INSERT INTO snippets (title, content, language, tags)
VALUES (?, ?, ?, ?)""",
(title, content, language, tags)
)
conn.commit()
print(f"✅ 已保存: {title} (ID: {cursor.lastrowid})")
return cursor.lastrowid
def update_snippet(conn, snippet_id, **kwargs):
"""更新已有片段"""
fields = []
values = []
for key, value in kwargs.items():
fields.append(f"{key} = ?")
values.append(value)
fields.append("updated_at = CURRENT_TIMESTAMP")
values.append(snippet_id)
query = f"UPDATE snippets SET {', '.join(fields)} WHERE id = ?"
conn.execute(query, values)
conn.commit()
print(f"✅ 已更新: ID {snippet_id}")
保存片段只需要传标题、内容和语言类型。标签用逗号分隔的字符串存就行,简单粗暴但有效。
第三步:搜索和列出片段
def search_snippets(conn, keyword, limit=20):
"""全文搜索代码片段"""
cursor = conn.cursor()
# 在标题、内容、标签三个字段中搜索
query = """
SELECT id, title, language, tags, created_at,
substr(content, 1, 200) as preview
FROM snippets
WHERE title LIKE ? OR content LIKE ? OR tags LIKE ?
ORDER BY updated_at DESC
LIMIT ?
"""
pattern = f"%{keyword}%"
cursor.execute(query, (pattern, pattern, pattern, limit))
return cursor.fetchall()
def list_snippets(conn, language=None, tag=None, limit=50):
"""列出所有片段,支持按语言/标签过滤"""
query = "SELECT id, title, language, tags, created_at FROM snippets WHERE 1=1"
params = []
if language:
query += " AND language = ?"
params.append(language)
if tag:
query += " AND tags LIKE ?"
params.append(f"%{tag}%")
query += " ORDER BY updated_at DESC LIMIT ?"
params.append(limit)
return conn.execute(query, params).fetchall()
def get_snippet(conn, snippet_id):
"""获取单个片段的完整内容"""
row = conn.execute(
"SELECT * FROM snippets WHERE id = ?", (snippet_id,)
).fetchone()
if row:
print(f"\n标题: {row[1]}")
print(f"语言: {row[3] or 'text'}")
print(f"标签: {row[4] or '(无)'}")
print(f"创建: {row[5]}")
print("-" * 50)
print(row[2]) # 完整内容
print("-" * 50)
else:
print(f"❌ 未找到 ID 为 {snippet_id} 的片段")
搜索逻辑很简单:用 LIKE %keyword% 在标题、内容和标签里做模糊匹配。三个字段一起搜,命中率更高。
第四步:命令行交互界面
def main():
import sys
conn = init_db()
if len(sys.argv) < 2:
print("用法:")
print(" python snippet_manager.py add \"标题\" \"内容\" [语言] [标签]")
print(" python snippet_manager.py search \"关键词\"")
print(" python snippet_manager.py list [--lang python]")
print(" python snippet_manager.py show <ID>")
print(" python snippet_manager.py delete <ID>")
return
cmd = sys.argv[1]
if cmd == "add":
if len(sys.argv) < 4:
print("❌ 请提供标题和内容")
return
title = sys.argv[2]
# 剩余参数合并为内容(支持多行)
content = " ".join(sys.argv[3:-2]) if len(sys.argv) > 4 else sys.argv[3]
language = sys.argv[-2] if len(sys.argv) > 4 and not sys.argv[-2].startswith('"') else "text"
tags = sys.argv[-1] if len(sys.argv) > 5 else ""
add_snippet(conn, title, content, language, tags)
elif cmd == "search":
if len(sys.argv) < 3:
print("❌ 请提供搜索关键词")
return
results = search_snippets(conn, sys.argv[2])
if not results:
print("🔍 未找到匹配结果")
return
print(f"\n找到 {len(results)} 条结果:\n")
for row in results:
print(f" [{row[0]}] {row[1]} ({row[2] or 'text'}) — {row[4]}")
print(f" {row[5]}...")
print()
elif cmd == "list":
lang_filter = None
tag_filter = None
args = sys.argv[2:]
i = 0
while i < len(args):
if args[i] == "--lang" and i + 1 < len(args):
lang_filter = args[i + 1]
i += 2
elif args[i] == "--tag" and i + 1 < len(args):
tag_filter = args[i + 1]
i += 2
else:
i += 1
results = list_snippets(conn, lang_filter, tag_filter)
print(f"\n共 {len(results)} 个片段:\n")
for row in results:
print(f" [{row[0]}] {row[1]} | {row[2] or 'text'} | {row[3] or '-'}")
elif cmd == "show":
if len(sys.argv) < 3:
print("❌ 请提供片段 ID")
return
get_snippet(conn, int(sys.argv[2]))
elif cmd == "delete":
if len(sys.argv) < 3:
print("❌ 请提供片段 ID")
return
conn.execute("DELETE FROM snippets WHERE id = ?", (int(sys.argv[2]),))
conn.commit()
print(f"✅ 已删除 ID {sys.argv[2]}")
conn.close()
if __name__ == "__main__":
main()
第五步:使用示例
# 添加一个 Python 片段
python snippet_manager.py add "列表推导式过滤" \
"[x for x in data if x > 0]" python "python,基础"
# 添加一个 SQL 片段
python snippet_manager.py add "分页查询模板" \
"SELECT * FROM users LIMIT 20 OFFSET 0;" sql "sql,数据库"
# 搜索包含 "filter" 的代码
python snippet_manager.py search filter
# 按语言列出所有 Python 片段
python snippet_manager.py list --lang python
# 查看完整内容
python snippet_manager.py show 1
# 删除一个片段
python snippet_manager.py delete 1
输出效果:
找到 2 条结果:
[1] 列表推导式过滤 (python) — 2026-07-15 14:30:00
[x for x in data if x > 0]...
[3] 正则提取邮箱 (python) — 2026-07-14 09:15:00
re.findall(r'\b[\w.-]+@[\w.-]+\.\w+\b', text)...
运行效果
装好之后,命令行里直接跑。数据存在 ~/.code_snippets.db 里,一个文件搞定。
你可以把这段代码加到你的 .bashrc 里做个别名:
alias sm='python /path/to/snippet_manager.py'
然后 sm search "正则" 就能快速查找。
优化方向
- JSON 导出:把片段导出成 JSON 格式,方便备份和迁移到其他平台
- Markdown 预览:支持在片段里写 Markdown 说明文档
- Web 界面:用 Flask 加个简单的 Web UI,手机也能查
- 同步功能:配合 git 或 syncthing 在多设备间同步数据库文件
- 语法高亮:集成 Pygments,在终端里显示彩色代码
- 版本历史:记录每次修改,支持回滚到旧版本
代码片段就像积木。攒得多了,写新东西的时候直接拿来拼,速度翻倍。
你的代码库里,现在最缺的是哪一类片段?去翻翻旧项目,说不定就能补上一块。
这篇文章对你有帮助吗?