@@ -91,6 +91,20 @@ after the failed one are not executed."
9191 :group 'ob-jupyter
9292 :type 'boolean )
9393
94+ (defcustom jupyter-org-display-execution-time nil
95+ " Whether or not to display the execution time of a source block.
96+ If this variable is nil, the execution times are not displayed.
97+ When it is t, display the execution times regardless of how long
98+ it took to execute. When it is a number, display the execution
99+ time when it is longer than that many seconds.
100+
101+ To clear the execution time information from the source block
102+ simply edit it or call `jupyter-org-clear-execution-time' ."
103+ :group 'ob-jupyter
104+ :type '(choice (const :tag " Never display" nil )
105+ (const :tag " Always display" t )
106+ (number :tag " Display when above this threshold (in seconds)" )))
107+
94108(defcustom jupyter-org-resource-directory " ./.ob-jupyter/"
95109 " Directory used to store automatically generated image files.
96110See `jupyter-org-image-file-name' ."
@@ -216,6 +230,7 @@ nothing and return nil."
216230 ; ; started due to sending a completion request.
217231 (save-excursion
218232 (goto-char org-babel-current-src-block-location)
233+ (jupyter-org-clear-execution-time)
219234 (let* ((context (org-element-context ))
220235 (block-params org-babel-jupyter-current-src-block-params)
221236 (result-params (alist-get :result-params block-params))
@@ -422,7 +437,51 @@ to."
422437 (forward-line )
423438 (insert (org-element-normalize-string (plist-get pl :text ))))))
424439
440+ (defun jupyter-org--display-execution-time (req )
441+ " In the Org buffer of REQ, show the REQ's execution time."
442+ (pcase jupyter-org-display-execution-time
443+ ((and (or (and `t
444+ (let time (jupyter-execution-time req)))
445+ (and (pred numberp) secs
446+ (let time (jupyter-execution-time req))
447+ (guard (> time secs))))
448+ (let (cl-struct jupyter-org-request inline-block-p) req)
449+ (guard (not inline-block-p)))
450+ (jupyter-org-with-point-at req
451+ (let* ((src-block (org-element-at-point ))
452+ (ov (make-overlay
453+ (org-element-property :begin src-block)
454+ ; ; Exclude the newline to make it look like
455+ ; ;
456+ ; ; #+end_src Execution time ...
457+ (1- (jupyter-org-element-end-before-blanks src-block)))))
458+ (let ((delete
459+ (list (lambda (&rest _ )
460+ (delete-overlay ov)))))
461+ (overlay-put ov 'evaporate t )
462+ (overlay-put ov 'jupyter-execution-time time)
463+ (overlay-put ov 'modification-hooks delete)
464+ (overlay-put ov 'insert-in-front-hooks delete)
465+ (overlay-put ov 'insert-behind-hooks delete))
466+ (overlay-put
467+ ov 'after-string
468+ (concat " " (propertize
469+ (format " Execution time: %s "
470+ (jupyter-format-time time))
471+ 'face 'bold-italic ))))))))
472+
473+ (defun jupyter-org-clear-execution-time ()
474+ " Clear the execution time overlay for the source block at point."
475+ (interactive )
476+ (let ((el (org-element-at-point )))
477+ (pcase (org-element-type el)
478+ ((or `src-block `babel-call)
479+ (dolist (ov (overlays-at (org-element-property :begin el)))
480+ (when (overlay-get ov 'jupyter-execution-time )
481+ (delete-overlay ov)))))))
482+
425483(cl-defmethod jupyter-handle-execute-reply ((_client jupyter-org-client) (req jupyter-org-request) msg)
484+ (jupyter-org--display-execution-time req)
426485 (jupyter-with-message-content msg (status payload)
427486 (when payload
428487 (jupyter-org-with-point-at req
0 commit comments