From 9484735c0651a412ad6e2a4d6628c740feda1419 Mon Sep 17 00:00:00 2001 From: Nathaniel Nicandro Date: Thu, 21 Feb 2019 22:54:30 -0600 Subject: [PATCH] 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. --- jupyter-repl.el | 16 +++++++++++----- test/jupyter-test.el | 14 ++++++++++++++ 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/jupyter-repl.el b/jupyter-repl.el index 927a664..9678b2c 100644 --- a/jupyter-repl.el +++ b/jupyter-repl.el @@ -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))) diff --git a/test/jupyter-test.el b/test/jupyter-test.el index 9be3abd..a082e4b 100644 --- a/test/jupyter-test.el +++ b/test/jupyter-test.el @@ -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)