 (defn fs-cursor []
   (om/ref-cursor (get-in (om/root-cursor state/app-state) [:characters :nix :fs])))
 
-(declare files)
+(defn commands [dir]
+  (let [files (seq (:files dir))]
+    (apply concat 
+           ;; Flattened list of lists of command structures
+           (map #(cond
+                   (= :dir (:type (second %))) (commands (second %))
+                   (and (= :file (:type (second %))) (contains? (:mod (second %)) :x)) [(assoc (second %) :name (first %))]
+                   :default [])
+                files))))
+
+(defn command-trie []
+  (let [c (map :name (commands (:root @(fs-cursor))))]
+    (trie/build c)))
+    
+(defn command-map []
+  (reduce #(assoc %1 (:name %2) %2) {} (commands (:root @(fs-cursor)))))
 
 (defn ls []
   (let [fs @(fs-cursor)
         dir (get-in (:root fs) (interleave (repeat :files) (:cwd fs)))]
     (str/join "\t" (keys (:files dir)))))
 
-(defn cd [dir]
-  (if (= [".."] dir)
+(defn cd [param]
+  (if (= [".."] param)
     (om/transact! (fs-cursor) #(assoc % :cwd (drop-last (:cwd %))))
-    (let [path (str/split dir "/")
+    (let [path (str/split param "/")
           cwd (:cwd @(fs-cursor))
           new-cwd (concat cwd path)]
       (om/transact! (fs-cursor) #(assoc % :cwd new-cwd))))

                          :files {"ls" {:mod #{:x}
                                        :type :file
                                        :fn ls
                                        :args []}
                                  "cd" {:mod #{:x}
                                        :type :file
                                        :fn cd
                                        :args [:file]}
                                  "clear" {:mod #{:x}
                                           :type :file
                                           :fn clear
                                           :args []}}}
                   "usr" {:mod #{:r}
                          :type :dir
                          :files {}}}}

      (assoc-in c [:active] (mode/initial-line-state {:mode :nix}))))
  nil)

(defn help [param]
  (let [cmd (get (command-map) param)]
    (print (str ">" param "<"))
    (cond
      (and cmd (:help cmd))
      (:help cmd)
      cmd
      (str (:args cmd))
      :default
      (str param " is not a command"))))        

(defn init []
  (om/update!
   (fs-cursor)
