   (with-current-buffer (if (bufferp buffer)
                            (buffer-name buffer)
                          buffer)
-    (if (boundp 'emdocs-is-network-insert)
-        (unless emdocs-is-network-insert
-          (cond ((= prev-length 0)
-                 (emdocs-emit-keypress-json
-                  buffer "insert" beg (buffer-substring beg end)))
-                ((= beg end)
-                 (emdocs-emit-keypress-json
-                  buffer "delete" beg prev-length)))))))
+    (when (= prev-length 0)
+      (setq-local emdocs-undo-list
+                  (cons `(:type ,"insert" :point ,beg
+                          :content ,(buffer-substring-no-properties beg end)
+                          :local ,(not emdocs-is-network-insert))
+                        emdocs-undo-list)))
+    (when (and (boundp 'emdocs-is-network-insert)
+               emdocs-is-network-insert)
+        (cond ((= prev-length 0)
+               (emdocs-emit-keypress-json
+                buffer "insert" beg
+                (buffer-substring-no-properties beg end)))
+              ((= beg end)
+               (emdocs-emit-keypress-json
+                buffer "delete" beg prev-length))))))
+
+(defun emdocs-before-change-function (buffer beg end)
+  "docstring"
+  (with-current-buffer buffer
+    (when (/= beg end)
+      (setq-local emdocs-undo-list
+                  (cons `(:type ,"delete" :point ,beg
+                          :content ,(buffer-substring-no-properties beg end)
+                          :local ,(not emdocs-is-network-insert))
+                        emdocs-undo-list)))))
 
 (defun emdocs-attach-to-buffer (buffer ip)
   "docstring"

                              (with-current-buffer buffer
                                (emdocs-after-change-function
                                 buffer beg end prev-length))))
                (setq-local after-change-functions
                            (cons emdocs-after-change-lambda
                                  after-change-functions))
                (add-hook 'kill-buffer-hook
                          (lambda ()
                            (when (string-equal

  "docstring")

(defvar-local emdocs-after-change-lambda nil
  "docstring")

(defvar-local emdocs-before-change-lambda nil
  "docstring")

(defvar-local emdocs-undo-list nil
  "docstring")

;;; classes
