               (str (apply str (repeat (- c 1) " ")) "^")))
       (insta/transform {child f} result))))
 
-(defn nml-uniq [values]
-  (loop [head (first values) tail (rest values) tree []]
-    (if (nil? head)
-      tree
-      (let [name #(nml-name (second %))
-            copy  (some #(= (name head) (name %)) tail)]
-        (recur (first tail) (rest tail) (into tree (if copy [] [head])))))))
-
-;; cli
-
-(defn assoc-get [m k v]
-  (let [gets (:get m [])]
-    (assoc m :get (into gets [v]))))
-
-(defn assoc-set [m k v]
-  (let [sets (:set m [])]
-    (assoc m :set (into sets [v]))))
-
-(defn parse-get [x]
-  (string/split x #":" 2))
-
-(defn parse-set [x]
-  (let [[nml+key val] (string/split x #"=" 2)
-        [nml key] (parse-get nml+key)]
-    [nml key val]))
-
-(def cliopts
-  [["-g" "--get n:k"   "Get value of key 'k' in namelist 'n'"         :assoc-fn assoc-get :parse-fn parse-get]
-   ["-h" "--help"      "Show usage information"                                                              ]
-   ["-i" "--in-place"  "Edit namelist file in place"                                                         ]
-   ["-n" "--no-prefix" "Report values without 'namelist:key=' prefix"                                        ]
-   ["-s" "--set n:k=v" "Set value of key 'k' in namelist 'n' to 'v'"  :assoc-fn assoc-set :parse-fn parse-set]
-   ["-v" "--version"   "Show version information"                                                            ]])
-  
 ;; main
-
-(defn usage [summary]
-  (doseq [x [""
-             "Usage: nml [options] file"
-             ""
-             "Options:"
-             ""
-             summary
-             ""]]
-    (println x))
-  (System/exit 0))
 
 (defn -main [& args]
   (alter-var-root #'*read-eval* (constantly false))


(def version "0.1")


;; utility defns

(defn fail [& lines]
  (binding [*out* *err*]
    (doseq [line lines]
      (println line))
    (System/exit 1)))

(defn warn [& lines]
  (binding [*out* *err*]
    (doseq [line lines]
      (println (str "WARNING: " line)))))

;; nml defns

(defn nml-add [tree parent child match proxy]
  (let [missing  (fn [children] (not-any? #(= (nml-name %) match) children))
        vnew    #(parse proxy :start child)
        f        (fn [& children] (if (missing children)

                 :ws       ""
                 :wsopt    ""))))

(defn- nml-uniq [values]
  (loop [head (first values) tail (rest values) tree []]
    (if (nil? head)
      tree
      (let [name #(nml-name (second %))
            copy  (some #(= (name head) (name %)) tail)]
        (recur (first tail) (rest tail) (into tree (if copy [] [head])))))))

;; cli

(defn- assoc-get [m k v]
  (let [gets (:get m [])]
    (assoc m :get (into gets [v]))))

(defn- assoc-set [m k v]
  (let [sets (:set m [])]
    (assoc m :set (into sets [v]))))

(defn- parse-get [x]
  (string/split x #":" 2))

(defn- parse-set [x]
  (let [[nml+key val] (string/split x #"=" 2)
        [nml key] (parse-get nml+key)]
    [nml key val]))

(def cliopts
  [["-g" "--get n:k"   "Get value of key 'k' in namelist 'n'"         :assoc-fn assoc-get :parse-fn parse-get]
   ["-h" "--help"      "Show usage information"                                                              ]
   ["-i" "--in-place"  "Edit namelist file in place"                                                         ]
   ["-n" "--no-prefix" "Report values without 'namelist:key=' prefix"                                        ]
   ["-s" "--set n:k=v" "Set value of key 'k' in namelist 'n' to 'v'"  :assoc-fn assoc-set :parse-fn parse-set]
   ["-v" "--version"   "Show version information"                                                            ]])
  
;; nml public defns

(defn nml-get [tree nml key]
  (let [stmt     (last (filter #(= (nml-name %) (string/lower-case nml)) (rest tree)))
        nvsubseq (last (filter #(= (nml-name %) (string/lower-case key)) (rest (last stmt))))
        values   (last nvsubseq)]
    (if (nil? values) "" (nml-str values))))

(defn nml-set [tree nml key val & sub]
  (let [child  (if sub :nvsubseq :stmt)
        match  (if sub (string/lower-case key) (string/lower-case nml))
        parent (if sub :nvseq :s)
        proxy  (if sub (str match "=0") (str "&" match " /"))
        vnew   (if sub (fn [tree] (parse val :start :values)) #(nml-set % nml key val true))
        f      (fn
                 ([k v] (if (= (nml-str k) match) [child k (vnew v  )] [child k v]))
                 ([k  ] (if (= (nml-str k) match) [child k (vnew nil)] [child k  ])))]
    (insta/transform {child f} (nml-add tree parent child match proxy))))

(defn nml-tree [s]
  (let [result (parse s)
        child  :nvseq
