                       (update-thread-text! thread-id text)))
 
         update-text! (fn [f]
-                       (swap! state update :text f)
-                       (update-thread-text! thread-id (@state :text)))
+                       (let [{:keys [text pos]} @state
+                             updated-text (f (.slice text 0 pos))
+                             new-text (str updated-text (.slice text pos))]
+                         (swap! state assoc :text new-text)
+                         (update-thread-text! thread-id (@state :text))))
 
         choose-result!
         (fn [result]

        state (r/atom {:text thread-text
                       :force-close? false
                       :highlighted-result-index 0
                       :results nil})

        reset-state! (fn []
                       (swap! state assoc

       (fn [c]
         (let [config (r/props c)]
           (go (loop []
                 (let [[data ch] (alts! [throttled-autocomplete-chan kill-chan])]
                   (when (= ch throttled-autocomplete-chan)
                     (let [{:keys [text pos]} data
                           text (.slice text 0 pos)]
                       (when-not (inside-code-block? text)
                         (set-results!
                           (seq (mapcat (fn [e] (e text)) @autocomplete-engines)))
                         (highlight-first!)))
                     (recur)))))
           (go (loop []
                 (let [[v ch] (alts! [throttled-thread-text-chan
