           (remove-if #'emdocs-client-dead-p
                      *emdocs-incoming-clients*))
     (setq-local after-change-functions
-                (remove emdocs-after-change-lambda after-change-functions))
-    (setq-local emdocs-after-change-lambda nil)
-    (setq-local emdocs-undo-list nil)
+                (remove #'emdocs-after-change-function
+                        after-change-functions))
     (setq-local before-change-functions
-                (remove emdocs-before-change-lambda before-change-functions))
-    (setq-local emdocs-before-change-lambda nil)))
+                (remove #'emdocs-before-change-function
+                        before-change-functions))
+    (setq-local emdocs-undo-list nil)))
 
 (defun emdocs-kill-server ()
   "docstring"

                       (emdocs-disconnect))
              (with-current-buffer buffer
                (setq-local emdocs-is-network-insert nil)
                (setq-local emdocs-after-change-lambda
                            (lambda (beg end prev-length)
                              (with-current-buffer buffer
                                (emdocs-after-change-function
                                 buffer beg end prev-length))))
                (setq-local emdocs-before-change-lambda
                            (lambda (beg end)
                              (with-current-buffer buffer
                                (emdocs-before-change-function
                                 buffer beg end))))
                (setq-local after-change-functions
                            (cons emdocs-after-change-lambda
                                  after-change-functions))
                (setq-local before-change-functions
                            (cons emdocs-before-change-lambda
                                  before-change-functions))
                (setq-local emdocs-undo-list nil)
                ;; TODO: add removable lambda as with after-change-functions

           :content content))
    "\n")))

(defun emdocs-after-change-function (beg end prev-length)
  "docstring"
  (when (and (boundp 'emdocs-is-network-insert)
             (not emdocs-is-network-insert))
    (cond ((= prev-length 0)
           (emdocs-emit-keypress-json
            (buffer-name) "insert" beg
            (buffer-substring-no-properties beg end))
           (setq-local
            emdocs-undo-list
            (cons (list :type "insert" :point beg :end end
                        :content (buffer-substring-no-properties beg end)
                        :local (not emdocs-is-network-insert))
                  emdocs-undo-list)))
          ((= beg end)
           (emdocs-emit-keypress-json
            (buffer-name) "delete" beg prev-length))))
  (unless emdocs-is-network-insert
    (setq-local emdocs-undo-posn emdocs-undo-list)))

(defun emdocs-before-change-function (beg end)
  "docstring"
  (when (and (boundp 'emdocs-is-network-insert)
             (not emdocs-is-network-insert)
             (/= beg end))
    (setq-local
     emdocs-undo-list
     (cons (list :type "delete" :point beg :end end
                 :content (buffer-substring-no-properties beg end)
                 :local (not emdocs-is-network-insert))
           emdocs-undo-list))))

(defun emdocs-undo ()
  "docstring"
  (interactive)
  ())

(defun emdocs-attach-to-buffer (buffer ip)
  "docstring"
