Fix undo in the REPL

When inserting continuation prompts, extra text deletion entries where being
added in `buffer-undo-list` which caused yanked text to not be undone fully
since it would add in those entries before undoing the yank.
This commit is contained in:
Nathaniel Nicandro 2019-02-21 22:54:30 -06:00
parent e357166371
commit 9484735c06
No known key found for this signature in database
GPG key ID: C34814B309DD06B8
2 changed files with 25 additions and 5 deletions

View file

@ -359,7 +359,8 @@ interpreted as `in'."
;; The insertion of a new prompt starts a new cell, don't consider the
;; buffer modified anymore. This is also an indicator for when undo's
;; can be made in the buffer.
(set-buffer-modified-p nil))
(set-buffer-modified-p nil)
(setq buffer-undo-list '((t . 0))))
((eq type 'out)
;; Output is normally inserted by first going to the end of the output
;; for the request. The end of the ouput for a request is at the
@ -1099,10 +1100,15 @@ Return the new BOUND since inserting continuation prompts may add
more characters than were initially in the buffer."
(setq bound (set-marker (make-marker) bound))
(set-marker-insertion-type bound t)
(while (and (< (point) bound)
(search-forward "\n" bound 'noerror))
(delete-char -1)
(jupyter-repl-insert-prompt 'continuation))
;; Don't record these changes as it adds unnecessary undo information which
;; interferes with undo.
(let ((buffer-undo-list t))
(while (and (< (point) bound)
(search-forward "\n" bound 'noerror))
;; Delete the newline that is re-added by prompt insertion
;; FIXME: Why not just overlay the newline?
(delete-char -1)
(jupyter-repl-insert-prompt 'continuation)))
(prog1 (marker-position bound)
(set-marker bound nil)))

View file

@ -1115,6 +1115,20 @@ last element being the newest element added to the history."
(jupyter-repl-syntax-propertize-function #'ignore (point-min) (point-max))
(jupyter-test-text-has-property 'syntax-table '(1 . ?.) '(5 9))))))
(ert-deftest jupyter-repl-undo ()
:tags '(repl yank undo)
(jupyter-test-with-python-repl client
(jupyter-ert-info ("Undo after yank undoes all the yanked text")
(kill-new "import IPython\ndef foo(x)\n\treturn x")
(undo-boundary)
(yank)
(should (equal (jupyter-repl-cell-code) "import IPython\ndef foo(x)\n\treturn x"))
(let ((beg (jupyter-repl-cell-beginning-position)))
(undo)
(should (get-text-property beg 'jupyter-cell))
(goto-char (point-max))
(should (equal (jupyter-repl-cell-code) ""))))))
;;; `org-mode'
(defvar org-babel-jupyter-resource-directory nil)