buffer-undo-list can become a dotted list in certain situations.

Unsure what those situations are, but when it happens it breakes ein's undo
facility. Calling `length' on a dotted list will generate wrong-argument-type
errors. To help soften the consequences of those situations we call `safe-length'
instead of `length'.
This commit is contained in:
John Miller 2019-12-06 21:22:06 -06:00
parent aefa088010
commit f36ae22b48
2 changed files with 19 additions and 5 deletions

View file

@ -1,3 +1,4 @@
@undo
Scenario: Undo turned off
Given I disable "ein:worksheet-enable-undo"
@ -353,3 +354,16 @@ Scenario: Split and merge don't break undo
And I undo again
And I undo again
Then the cursor should be at point "93"
@undo, @issue-630
Scenario: Regression case for issue #630.
Given I enable "ein:worksheet-enable-undo"
Given new python notebook
And I type "while True:"
And I press "RET"
and I type "print(1)"
And I press "M-RET"
And I wait 2 seconds
And I switch to buffer like "*Messages*"
And I wait 2 seconds
Then I should not see "ein: [info] WS action"

View file

@ -166,14 +166,14 @@ Normalize `buffer-undo-list' by removing extraneous details, and update the ein:
result))
(defun ein:worksheet--jigger-undo-list (&optional change-cell-id)
(if (/= (length buffer-undo-list) (length ein:%which-cell%))
(if (/= (safe-length buffer-undo-list) (length ein:%which-cell%))
(ein:log 'debug "jig %s to %s: %S %S" (length ein:%which-cell%) (length buffer-undo-list) buffer-undo-list ein:%which-cell%))
(ein:and-let* ((old-cell-id (car change-cell-id))
(new-cell-id (cdr change-cell-id))
(changed-p (not (eq old-cell-id new-cell-id))))
(when changed-p
(setq ein:%which-cell% (-replace old-cell-id new-cell-id ein:%which-cell%))))
(let ((fill (- (length buffer-undo-list) (length ein:%which-cell%))))
(let ((fill (- (safe-length buffer-undo-list) (length ein:%which-cell%))))
(if (> (abs fill) 1)
(progn
(let ((msg (format "Undo failure diagnostic %s %s | %s"
@ -193,16 +193,16 @@ Normalize `buffer-undo-list' by removing extraneous details, and update the ein:
(setq ein:%which-cell%
(nconc (make-list fill (car ein:%which-cell%))
ein:%which-cell%))))))
(cl-assert (= (length buffer-undo-list) (length ein:%which-cell%))
(cl-assert (= (safe-length buffer-undo-list) (length ein:%which-cell%))
t
"ein:worksheet--jigger-undo-list %d != %d"
(length buffer-undo-list) (length ein:%which-cell%)))
(safe-length buffer-undo-list) (length ein:%which-cell%)))
(defun ein:worksheet--unshift-undo-list (cell &optional exogenous-input old-cell)
"Adjust `buffer-undo-list' for adding CELL. Unshift in list parlance means prepending to list."
(unless old-cell
(setq old-cell cell))
(when (and (listp buffer-undo-list) buffer-local-enable-undo)
(when buffer-local-enable-undo
(ein:with-live-buffer (ein:cell-buffer cell)
(let* ((opl (ein:worksheet--prompt-length old-cell t))
(ool (ein:worksheet--output-length old-cell t))