久しぶりの更新。treeコマンドを作った。
はじまり
何だか最近は更新も滞って何も書いていませんでした。
たまたま、clojureでtreeコマンドを実装しているのをみて作ってみました。
treeコマンドをsequenceだけを使って実装できそうな気がしたのです。
例えば、1,2,3…という数列を作る時には、iterateにincと数字を渡せば良いのと同じように、
上手い具合に、何かの関数とルートになるディレクトリのパスだけ渡して綺麗に書けないかなーと。
(iterate inc 1) ;; (1 2 3 4 .... (iterate f "<root-directory>") ;; (<root-directory> ...
コード
reverseが必要だったり、empty?で調べているところが気にくわないのですが完成しました。
30行くらいです。まー、まずまずといったところです。
(ns tool.tree (:import java.io.File)) (defn- check-cons [x y] (if (empty? x) y (cons x y))) (defn- dir-files [dir] (-> (if (string? dir) (File. dir) dir) .listFiles sort)) (defn files-extend [seqs] (let [[[x & xs] & rest] seqs] (cond (and x (.isDirectory x)) (check-cons (dir-files x) (cons xs rest)) (not x) rest :else (check-cons xs rest)))) (defn- prn-tree-left-side [xs] (doseq [x (reverse xs)] (print (if (empty? x) " " "│ ")))) (defn tree [dir] (println dir) (let [origin (dir-files dir)] (doseq [[xs & seqs] (take-while identity (iterate files-extend [origin]))] (when-let [[x & xr] xs] (prn-tree-left-side seqs) (let [prefix (if (empty? xr) "└── " "├── ")] (println prefix (.getName x))))))) (->> *command-line-args* (map tree) dorun)