       (if (and (:in-place options) (not file)) (warn (msgs 0)))
       (if debug (println tree))
       (cond gets  (nml-gets tree gets (:no-prefix options))
-            sets  (println (string/trim (nml-str (nml-sets tree sets))))
+            sets  (let [out (string/trim (nml-str (nml-sets tree sets)))]
+                    (if (and file (:in-place options))
+                      (try (spit file out)
+                           (catch Exception e
+                             (fail (str "Could not write to file '" file "'."))))
+                      (println out)))
             :else (println (string/trim (nml-str tree)))))))

;; utility defns

(defn fail [& lines]
  (doseq [line lines]
    (println line))
  (System/exit 1))

(defn warn [& lines]
  (binding [*out* *err*]

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

(defn nml-tree [file]
  (let [child  :nvseq
        f      (fn [& v] (into [child] (nml-uniq v)))
        result (try (parse (slurp file))
                    (catch Exception e
                      (fail (str "Could not read from file '" file "'."))))]
    (if (insta/failure? result)
      (let [{t :text l :line c :column} result]
        (fail (str "Error parsing '" file "' at line " l " column " c ":")
              t
              (str (apply str (repeat (- c 1) " ")) "^")))
      (insta/transform {child f} result))))
