     (setq-local emdocs-buffer-id (uuid-string)))
   (add-hook 'after-change-functions #'emdocs--after-change-function)
   (add-hook 'before-change-functions #'emdocs--before-change-function))
+
+(defun emdocs--unset-change-hooks ()
+  (remove-hook 'after-change-functions #'emdocs--after-change-function)
+  (remove-hook 'before-change-functions #'emdocs--before-change-function))
 
  

   :stderr (get-buffer-create emdocs--error-buffer-name)))

(defun emdocs--after-change-function (beg end prev-length)
  (let ((source (emdocs--create-buffer-id emdocs-buffer-id))
        (point (emdocs--create-point beg)))
    (->> (cond ((zerop prev-length)
                (->> (buffer-substring-no-properties beg end)
                     (emdocs--create-insert point)))
               ((= beg end)
                (emdocs--create-delete point prev-length))
               (t (error "should never get here")))
         (emdocs--create-edit source)
         (emdocs--write-stdin))))

(defun emdocs--before-change-function (beg end)
  ;; TODO: set up undo list, etc

        (unless (process-live-p (get-process emdocs--process-name))
          (emdocs--make-process))
        t)
    (emdocs--unset-change-hooks)
    nil))

(provide 'emdocs)
