                  :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

              (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))

                                    (into [parent       ] children)))]
    (if (nil? tree) [parent (vnew)] (insta/transform {parent f} tree))))

(defn- nml-gets [tree gets no-prefix]
  (doseq [[nml key] gets]
    (let [val (nml-get tree nml key)]
      (println (if no-prefix val (str nml ":" key "=" val))))))

(defn- nml-name [x]
  (nml-str (second x)))

(defn- nml-sets [tree sets]
  (loop [t tree s sets]
    (if (empty? s)
      t
      (let [[nml key val] (first s)]
        (recur (nml-set t nml key val) (rest s))))))

(defn- nml-str [x]
  (let [k         (first x)
        v         (rest  x)
        cjoin    #(string/join "," %)
