Skip to content

Commit 5c013a1

Browse files
committed
Don't attempt to handle messages if the Org buffer disappears
This is a partial solution to #531 which would still make the code more robust to the fact that the buffer can indeed be killed while an asynchronous block is running. A more complete solution would be to stop processing messages from kernels whose Org buffers have been deleted or, in the case of a deletion it may still be useful to partially process the output, e.g. redirect stream messages to an external buffer and display results in other ways outside of the Org buffer. * jupyter-org-client.el (jupyter-org-with-point-at): New macro. Same as `org-with-point-at`, but does nothing if the request's marker points nowhere. (jupyter-org--goto-error-string) (jupyter-handle-error) (jupyter-handle-execute-reply, jupyter-org-result) (jupyter-org--clear-async-indicator) (jupyter-org-inserted-result): Replace calls to `org-with-point-at` to `jupyter-org-with-point-at`.
1 parent 0b960b2 commit 5c013a1

File tree

1 file changed

+19
-12
lines changed

1 file changed

+19
-12
lines changed

jupyter-org-client.el

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,16 @@ e.g. `org-babel-get-src-block-info'."
166166
(and (member (alist-get :async params) '("yes" nil))
167167
(not org-babel-jupyter-resolving-reference-p)))
168168

169+
(defmacro jupyter-org-with-point-at (req &rest body)
170+
"Move to the associated marker of REQ while evaluating BODY.
171+
If the marker points nowhere don't evaluate BODY, just do
172+
nothing and return nil."
173+
(declare (indent 1))
174+
`(pcase-let (((cl-struct jupyter-org-request marker) ,req))
175+
(when (and (marker-buffer marker) (marker-position marker))
176+
(org-with-point-at marker
177+
,@body))))
178+
169179
;;; `jupyter-kernel-client' interface
170180

171181
;;;; `jupyter-request' interface
@@ -303,7 +313,7 @@ line number could not be found."
303313

304314
(defun jupyter-org--goto-error-string (req)
305315
(let* ((buffer (current-buffer))
306-
(loc (org-with-point-at (jupyter-org-request-marker req)
316+
(loc (jupyter-org-with-point-at req
307317
(forward-line (or (with-current-buffer buffer
308318
(save-excursion
309319
(goto-char (point-min))
@@ -336,16 +346,14 @@ to."
336346
(jupyter-with-message-content msg (traceback)
337347
(setq traceback (org-element-normalize-string
338348
(mapconcat #'identity traceback "\n")))
339-
(pcase-let (((cl-struct jupyter-org-request
340-
marker inline-block-p silent-p)
341-
req))
349+
(pcase-let (((cl-struct jupyter-org-request inline-block-p silent-p) req))
342350
(cond
343351
((or inline-block-p silent-p)
344352
;; Remove old inline results when an error happens since, if this was not
345353
;; done, it would look like the code which caused the error produced the
346354
;; old result.
347355
(when inline-block-p
348-
(org-with-point-at marker
356+
(jupyter-org-with-point-at req
349357
(org-babel-remove-inline-result)))
350358
(jupyter-with-display-buffer "traceback" 'reset
351359
(jupyter-insert-ansi-coded-text traceback)
@@ -417,15 +425,15 @@ to."
417425
(cl-defmethod jupyter-handle-execute-reply ((_client jupyter-org-client) (req jupyter-org-request) msg)
418426
(jupyter-with-message-content msg (status payload)
419427
(when payload
420-
(org-with-point-at (jupyter-org-request-marker req)
428+
(jupyter-org-with-point-at req
421429
(jupyter-handle-payload payload)))
422430
(jupyter-org--remove-overlay req)
423431
(if (equal status "ok")
424432
(message "Code block evaluation complete.")
425433
(message "An error occurred when evaluating code block."))
426434
(when (jupyter-org-request-async-p req)
427435
(jupyter-org--clear-async-indicator req)
428-
(org-with-point-at (jupyter-org-request-marker req)
436+
(jupyter-org-with-point-at req
429437
(run-hooks 'org-babel-after-execute-hook)))))
430438

431439
;;; Queueing requests
@@ -1190,8 +1198,7 @@ those mime types instead."
11901198
;; we don't want `org-babel-insert-result' to handle it.
11911199
(when (jupyter-org-request-file req)
11921200
(push (cons :file (jupyter-org-request-file req)) params))
1193-
(or (org-with-point-at
1194-
(jupyter-org-request-marker req)
1201+
(or (jupyter-org-with-point-at req
11951202
(jupyter-map-mime-bundle mime-types
11961203
(jupyter-normalize-data plist metadata)
11971204
(lambda (mime content)
@@ -1300,7 +1307,7 @@ new \"scalar\" result with the result of calling
13001307
(defun jupyter-org--clear-async-indicator (req)
13011308
"Clear any async indicators of REQ in the buffer."
13021309
(unless (jupyter-org-request-id-cleared-p req)
1303-
(org-with-point-at (jupyter-org-request-marker req)
1310+
(jupyter-org-with-point-at req
13041311
(if (jupyter-org-request-inline-block-p req)
13051312
(when-let* ((pos (org-babel-where-is-src-block-result)))
13061313
(goto-char pos)
@@ -1703,10 +1710,10 @@ If INDENTATION is nil, it defaults to `current-indentation'."
17031710
"Return a monadic value that inserts DATA and METADATA as an Org element."
17041711
(jupyter-mlet* ((req (jupyter-get-state)))
17051712
(pcase-let (((cl-struct jupyter-org-request
1706-
marker inline-block-p block-params client)
1713+
inline-block-p block-params client)
17071714
req))
17081715
(let ((result (jupyter-org-result req data metadata)))
1709-
(org-with-point-at marker
1716+
(jupyter-org-with-point-at req
17101717
(if inline-block-p
17111718
(org-babel-insert-result
17121719
(if (stringp result) result

0 commit comments

Comments
 (0)