     om/IRenderState
     (render-state [_ state]
       (let [words (str/split (str/join (reverse (:letters cursor))) " ")
-            space (contains? #{:typing-space :mashing-space} (first (:state cursor)))
-            cur (dom/span #js {:style #js {:color "#900"}} "\u2588")
+            spacing (contains? #{:typing-space :mashing-space} (first (:state cursor)))
+            commanding (contains? valid-commands (first words))
+            cursor-char (dom/span #js {:style #js {:color "#900"}} "\u2588")
             rendered-words (interpose
                             (dom/span nil " ")
                             (map #(if (contains? valid-words %)

(defn recognize? [letters]
  (let [last-word (str/join (reverse (take-while #(not= " " %) letters)))]
    (contains? valid-words last-word)))

(defn handle-keydown [owner e]
  (let [key (.-key e)]

        (apply dom/div #js {:style #js {:fontSize "30px"
                                        :lineHeight "40px"
                                        :padding "15px 15px 0 15px"}}
               (as-> rendered-words r
                 (if (and (:focus state) spacing) (concat r [(dom/span nil " ") cursor-char]) r)
                 (if (and (:focus state) (not spacing)) (concat r [cursor-char]) r)
                 (if commanding (cons (dom/span #js {:style #js {:color "#33f"}} (first words))
                                      (rest r)) r)))))))

(defn app-view [cursor owner]
  (reify
