          scroll-y (.-scrollTop scroller) 
 
          ;; format the text
-         opts {:cursor-line (.-line cursor)
-               :cursor-x (.-ch cursor)
-               :cursor-dx (compute-cursor-dx cursor change)}
+         cursor-data {:cursor-line (.-line cursor)
+                      :cursor-x (.-ch cursor)
+                      :cursor-dx (compute-cursor-dx cursor change)}
 
          key- (cm-key cm)
          mode (or (get-in @state [key- :mode]) :infer)
-         format-fn (case mode
-                    :infer infer/format-text
-                    :prep prep/format-text
-                    nil)
-         new-text (format-fn opts current-text)]
+
+         prev-state (get-prev-state cm)
+
+         new-text
+         (case mode
+           :infer
+           (let [state (if (and @prev-state change)
+                         (cm-process-text-change cm change (merge @prev-state cursor-data))
+                         (infer/process-text cursor-data current-text))]
+
+             ;; uncomment this to try fast infer
+             ;; (when state
+             ;;   (reset! prev-state state))
+             (if state
+               (join "\n" (:lines state))
+               current-text))
+
+           :prep
+           (prep/format-text cursor-data current-text)
+
+           nil)]
 
      ;; update the text
      (swap! state assoc-in [key- :text] new-text)

           wrapper (.getWrapperElement cm)
           watcher (js/scrollMonitor.create wrapper)
           initial-state (assoc empty-editor-state
                                :mode (:parinfer-mode opts))]


       (set! (.-id wrapper) (str "cm-" element-id))

                      (+ len-last-line (.. change -from -ch)))]
          (- end-x start-x))))))

(defn cm-process-text-change
  [cm change prev-state]
  (let [start-line (.. change -from -line)
        end-line (inc (.. change -to -line))
        num-new-lines (alength (.-text change))
        lines (for [i (range start-line (+ start-line num-new-lines))]
                (.getLine cm i))]
    (infer/process-text-change
      prev-state
      {:line-no [start-line end-line]
       :new-lines lines})))
 
(defn fix-text!
  "Correctly format the text from the given editor."
