cljfmt、clojure-lsp与depot如何依赖rewrite-clj:构建你自己的Clojure代码工具实战手册
cljfmt、clojure-lsp与depot如何依赖rewrite-clj:构建你自己的Clojure代码工具实战手册
【免费下载链接】rewrite-cljRewrite Clojure code and edn项目地址: https://gitcode.com/gh_mirrors/re/rewrite-clj
rewrite-clj是一个让 Clojure、ClojureScript 和 EDN 源码"可读写、可变形"的开源库:它能在完整保留空白和注释的前提下,把源码解析成节点树,再精准修改后写回。今天流行的三款工具——代码格式化器cljfmt、语言服务器clojure-lsp、依赖升级检查工具depot——背后都站着它。读完这篇指南,你也能动手构建自己的 Clojure 代码工具 🚀
为什么 rewrite-clj 是 Clojure 工具生态的"地基"?
普通解析器(read)读入(* a 3)后只留下( * a 3 )这层含义——缩进、换行、注释全部丢失。但做格式化工具、LSP 重构、deps.edn 批量升级时,你恰恰需要:
- 保留空白与注释:格式化的本质就是"重新安排空白,别动代码语义"
- 知道每个元素的位置:每个节点都携带
:row、:col、:end-row、:end-col行号列号,方便定位和替换 - 结构化遍历与修改:内置一套基于
clojure.zip的 zip API,down / up / left / right / edit走树、改树一气呵成
一句话:parse → 修改节点树 → 写回字符串,三步就是所有 Clojure 代码工具的核心套路。官方完整讲解见 doc/01-user-guide.adoc。
三大明星工具是怎么依赖 rewrite-clj 的?
| 工具 | 用途 | 用到的 rewrite-clj 能力 |
|---|---|---|
| 🎨cljfmt | Clojure 代码格式化 | zip API 遍历节点树,重写空白节点实现缩进规范 |
| 🧠clojure-lsp | Clojure 语言服务器 | 解析/编辑源码支撑重命名、抽取函数等重构 |
| 📦depot | 检查 deps.edn 中的依赖新版本 | 读取并修改deps.edn,保留原有排版与注释 |
这三者均在 rewrite-clj 的 README.adoc 官方"Used In..."清单中标记为 🐥canary tested——即经过 rewrite-clj 官方库测试套件回归验证,兼容性最有保障。
- cljfmt的工作流程:
of-string把文件读进 zipper,用walk/map类函数按风格规则调整空白,root-string导出新源码。因为空白本来就是"一等节点",格式化器只需替换 whitespace 节点即可。 - clojure-lsp处理 LSP 请求(如重命名符号)时,用
find系列函数定位目标节点,edit修改后写回,全程不破坏用户手写注释与排版。 - depot把
deps.edn当作 EDN 数据读入,定位依赖 map 中的版本值,替换为新版号——注释原样保留,git diff 干净漂亮。
实战手册:四步构建你自己的 Clojure 代码工具
第 1 步:获取 rewrite-clj 源码
git clone https://gitcode.com/gh_mirrors/re/rewrite-clj克隆后可以先跑bb unit-test感受它的测试体系,项目脚本入口在 bb.edn 和 script/ 目录。
第 2 步:把 rewrite-clj 加进你的项目
在你的deps.edn中加入一行依赖(当前版本1.2.55,与 deps.edn 中 neil 项目属性一致):
rewrite-clj/rewrite-clj {:mvn/version "1.2.55"}第 3 步:用 zip API 解析和修改代码
以"给所有 defn 改名"这类小工具为例,核心就几行(完整示例见 doc/01-user-guide.adoc):
(require '[rewrite-clj.zip :as z]) (-> "(defn my-function [a] (* a 3))" z/of-string ;; 源码 → zipper z/down ;; 进入 defn 列表 z/right ;; 定位到函数名节点 (z/edit (comp symbol str) "2") ;; 改名为 my-function2 z/root-string) ;; 写回字符串 ;; => "(defn my-function2 [a] (* a 3))"zip API 的完整函数清单(of-string、find、edit、insert、remove、walk 等)定义在 src/rewrite_clj/zip.cljc。
第 4 步:导出结果并封装成命令
把z/root-string的结果写回文件,再套一层 CLI 参数解析,一个"代码批量改写工具"就完工了——这正是 cljfmt、depot 们的骨架。
新手避坑指南:3 个高频注意点
- 空白和注释默认被跳过:导航时 zipper 会自动跳过 whitespace/comment 节点;若需精细操作空白(格式化器就要!),用
of-string*系列或z/whitespace?等判断函数。 - zipper 是不可变的:
z/down、z/edit都返回新的zipper,原zloc不会被改动;函数名看起来像"修改",实际是"返回修改后的副本"。 - 区分 v0 与 v1:
cljfmt、clojure-lsp、depot用的都是重写合并后的v1(Clojure + ClojureScript 双端统一 API)。从 v0 迁移注意 namespaced element 相关行为差异,详见 doc/03-faq.adoc 与 CHANGELOG.adoc。
小结
rewrite-clj 用"保留空白的节点树 + 强大的 zip API"这一套组合拳,支撑起了 cljfmt 的代码格式化、clojure-lsp 的智能重构和 depot 的依赖体检。掌握of-string → 导航 → edit → root-string这条主线,配合 doc/02-developer-guide.adoc 深入阅读,你就能像它们一样,构建出排版整洁、注释无损的 Clojure 代码工具 🔧
【免费下载链接】rewrite-cljRewrite Clojure code and edn项目地址: https://gitcode.com/gh_mirrors/re/rewrite-clj
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
