Promote the execution-state to be a slot of jupyter-kernel-client

* jupyter-client.el (jupyter-kernel-client): Do it.
(jupyter-run-hook-with-args-until-success): Pass client as first argument to
hooks.
(jupyter-execution-state): New convenience function.
(jupyter--set-execution-state): New helper function. Add as global IOPUB
message hook to set the execution-state slot.

* jupyter-repl.el (jupyter-repl-client): Remove execution-state slot.
(jupyter-handle-status): Don't set the execution-state slot.
(jupyter-repl-ret, jupyter-repl-interaction-mode-line): Use
jupyter-execution-state.
(jupyter-repl-initialize-hooks): Take into account changes to message hooks.

* jupyter-kernel-manager (jupyter-start-new-kernel): Update callback.
This commit is contained in:
Nathaniel Nicandro 2018-11-11 13:42:43 -06:00
parent 9f2c88d252
commit af32a3352f
3 changed files with 31 additions and 13 deletions

View file

@ -88,6 +88,11 @@ requests like the above example.")
:documentation "A ring of pending `jupyter-request's.
A request is pending if it has not been sent to the kernel via the
client's ioloop slot.")
(execution-state
:type string
:initform "idle"
:documentation "The current state of the kernel. Can be
either \"idle\", \"busy\", or \"starting\".")
(requests
:type hash-table
:initform (make-hash-table :test 'equal)
@ -319,11 +324,13 @@ this is called."
(add-hook hook function append t)))
(defun jupyter-run-hook-with-args-until-success (client hook &rest args)
"Run CLIENT's value for HOOK with the arguments ARGS."
"Run CLIENT's value for HOOK with the arguments ARGS.
CLIENT is passed as the first argument and then ARGS."
(jupyter-with-client-buffer client
(when jupyter--debug
(message "RUN-HOOK: %s" hook))
(apply #'run-hook-with-args-until-success hook args)))
(with-demoted-errors "Error in Jupyter message hook: %S"
(apply #'run-hook-with-args-until-success hook client args))))
(defun jupyter-remove-hook (client hook function)
"Remove from CLIENT's value of HOOK the function FUNCTION."
@ -1238,6 +1245,24 @@ If RESTART is non-nil, request a restart instead of a complete shutdown."
(declare (indent 1))
nil)
(defun jupyter-execution-state (client)
"Return the execution state of CLIENT's kernel."
(cl-check-type client jupyter-kernel-client)
(oref client execution-state))
(defun jupyter--set-execution-state (client msg)
"Set the execution-state slot of CLIENT.
If MSG is a status message, set the execution-state slot of
CLIENT to its execution state slot."
(prog1 nil ; Allow the handlers to run.
(and (eq (jupyter-message-type msg) :status)
(oset client execution-state
(jupyter-message-get msg :execution_state)))))
;; Added as a hook as opposed to a :before method due to
;; `jupyter-inhibit-handlers'.
(add-hook 'jupyter-iopub-message-hook #'jupyter--set-execution-state)
(cl-defgeneric jupyter-handle-status ((_client jupyter-kernel-client)
_req
_execution-state)

View file

@ -364,7 +364,7 @@ instance, see `jupyter-make-client'."
;; NOTE: Startup messages have no parent header, hence the need for
;; `jupyter-include-other-output'.
(let* ((jupyter-include-other-output t)
(cb (lambda (msg)
(cb (lambda (_ msg)
(setq started
(jupyter-message-status-starting-p msg)))))
(jupyter-add-hook client 'jupyter-iopub-message-hook cb)

View file

@ -135,11 +135,6 @@ timeout, the built-in is-complete handler is used."
:documentation "Whether or not we should wait to clear the
current output of the cell. Set when the kernel sends a
`:clear-output' message.")
(execution-state
:type string
:initform "idle"
:documentation "The current state of the kernel. Can be
either \"idle\", \"busy\", or \"starting\".")
(execution-count
:type integer
:initform 1
@ -926,7 +921,6 @@ lines, truncate it to something less than
(jupyter-repl-clear-last-cell-output client)))))
(cl-defmethod jupyter-handle-status ((client jupyter-repl-client) req execution-state)
(oset client execution-state execution-state)
(when (equal execution-state "idle")
(jupyter-with-repl-buffer client
(save-excursion
@ -1116,7 +1110,7 @@ execute the current cell."
;; sending a request when the kernel is busy because of the
;; is-complete request. Some kernels don't respond to this request
;; when the kernel is busy.
(unless (member (oref jupyter-current-client execution-state)
(unless (member (jupyter-execution-state jupyter-current-client)
'("starting" "idle"))
(jupyter-repl-sync-execution-state)
(error "Kernel busy"))
@ -2140,8 +2134,7 @@ When the kernel restarts, insert a new prompt."
;; NOTE: This hook will only run if `jupyter-include-other-output' is non-nil
;; during the restart.
(jupyter-add-hook jupyter-current-client 'jupyter-iopub-message-hook
(apply-partially
#'jupyter-repl-on-kernel-restart jupyter-current-client)))
#'jupyter-repl-on-kernel-restart))
(defun jupyter-repl-propertize-output (beg end)
"Remove string syntax from quote characters between BEG and END."
@ -2350,7 +2343,7 @@ the REPL is connected, 'x' means the REPL is disconnected
from the kernel."
(and (jupyter-repl-client-p jupyter-current-client)
(concat " JuPy["
(if (equal (oref jupyter-current-client execution-state) "busy")
(if (equal (jupyter-execution-state jupyter-current-client) "busy")
"*"
(if (jupyter-hb-beating-p jupyter-current-client)
"-"