如何高效提取Clojure/ClojureScript中的各类名称以支持重命名重构?
解决方案:提取Clojure/CLJS项目中的命名供产品审核
一、用Clojure原生方式精准提取
既然Clojure天生擅长符号解析,直接写段代码在REPL里执行,能比git grep更精准地提取所有定义(完全避免匹配到注释或字符串里的假定义):
步骤1:准备依赖
如果项目没引入clojure.tools.reader,可以临时在REPL里加载:
(require '[clojure.tools.reader :as reader]) (require '[clojure.java.io :as io]) (require '[clojure.string :as str])
步骤2:编写提取脚本
这段代码会遍历项目src目录下的.clj/.cljs文件,解析AST后按命名空间分组提取所有变量、公私有函数:
(defn extract-defs [file-path] (try (with-open [r (io/reader file-path)] (let [forms (reader/read-all r) ns-form (first (filter #(and (list? %) (= 'ns (first %))) forms)) ns-name (second ns-form) defs (filter (fn [form] (and (list? form) (#{'def 'defn 'defn-} (first form)))) forms)] {:ns ns-name :file file-path :defs (map (fn [form] {:type (first form) :name (second form)}) defs)})) (catch Exception e (println "跳过无效文件:" file-path)))) (defn scan-project [root-dir] (->> (file-seq (io/file root-dir)) (filter #(or (str/ends-with? (.getName %) ".clj") (str/ends-with? (.getName %) ".cljs"))) (map extract-defs) (remove nil?))) ;; 执行并输出格式化结果(直接复制给产品经理即可) (doseq [ns-info (scan-project "src")] (println (str "\n=== 命名空间: " (:ns ns-info) " ===")) (doseq [def (:defs ns-info)] (println (str "[" (:type def) "] " (:name def)))))
二、Emacs/CIDER快捷操作技巧
如果你习惯在Emacs里处理,这些技巧能快速梳理项目命名:
1. 交互式浏览命名空间
- 打开任意Clojure文件,执行
M-x cider-browse-ns:可以交互式浏览所有命名空间,每个命名空间下的公私有函数、变量会分类列出,还能直接跳转定义。 - 执行
M-x cider-apropos:输入关键词就能搜索项目中所有匹配的符号,适合快速定位特定领域相关命名。
2. 项目级搜索汇总
- 用Projectile(CIDER默认集成)执行
M-x projectile-grep,输入正则^\(ns \|defn- \|def \|defn \),能精准匹配文件开头的定义,比git grep更适合在Emacs内操作。 - 执行
M-x occur,输入同样的正则,会在当前缓冲区列出所有匹配项,通过C-c C-o可导出为单独缓冲区,方便复制整理。
3. 单文件命名快速梳理
打开单个Clojure/CLJS文件,执行M-x imenu,会列出当前文件所有命名空间、函数、变量,按层级分类,适合快速核对单个文件的命名。
内容的提问来源于stack exchange,提问作者Pedro Delfino
相关产品推荐
相关产品推荐

