        :text-area text-area
        :close-fn! (fn [])
        :italicize-fn #(.isDirty text-area)
-       :should-remove-fn #(not (.exists (io/file path)))})))
+       :should-remove-fn #(not (.exists (io/file path)))
+       :edit-history edit-history})))
 
 (def ^:dynamic *types* [:text :logcat :git])
 

(ns nightcode.editors
  (:require [clojure.java.io :as io]
            [clojure.string :refer [join split]]
            [flatland.ordered.map :as flatland]
            [nightcode.completions :as completions]
            [nightcode.dialogs :as dialogs]

        index (+ (count s) (inc col))]
    index))

(defn custom-split-lines
  [s]
  (let [s (if-not (= \newline (last s))
            (str s "\n ")
            (str s " "))
        lines (split-lines s)
        last-line (last lines)
        last-line-len (max 0 (dec (count last-line)))]
    (conj (vec (butlast lines))
          (subs last-line 0 last-line-len))))

(defn count-lines-changed
  [new-lines old-lines]
  (->> (diff new-lines old-lines) first (remove nil?) count))

(defn update-edit-history!
  [edit-history state]
  (let [{:keys [current-state states]} @edit-history
        old-state (get states current-state)
        old-lines (:lines old-state)
        new-lines (:lines state)
        old-lines-changed (:lines-changed old-state)
        new-lines-changed (count-lines-changed new-lines old-lines)
        state (assoc state :lines-changed new-lines-changed)]
    ; if the last two edits only affected one line, replace the last edit instead of adding a new edit
    (when (not= old-lines-changed new-lines-changed 1)
      (swap! edit-history update-in [:current-state] inc))
    (swap! edit-history update-in [:states] subvec 0 (:current-state @edit-history))
    (swap! edit-history update-in [:states] conj state)))

(defn get-state
  [^TextEditorPane text-area paren-mode?]
  (let [old-pos (.getCaretPosition text-area)
        old-x (.getCaretOffsetFromLineStart text-area)
