mirror of
https://github.com/vale981/emacs-ipython-notebook
synced 2025-03-05 09:01:40 -05:00
When I C-c C-c also C-c C-r if necessary
If user wants to execute cell, and the connection is down, automatically reconnect, then execute the cell.
This commit is contained in:
parent
f4aac8c951
commit
84fa177a1e
11 changed files with 150 additions and 116 deletions
|
@ -34,6 +34,19 @@ Scenario: kernel reconnect succeeds
|
|||
And I should not see "[error]"
|
||||
And I should see "ein:kernel-retrieve-session--complete"
|
||||
And I switch to buffer like "Untitled"
|
||||
And I kill processes like "websocket"
|
||||
And I switch to log expr "ein:log-all-buffer-name"
|
||||
Then I should see "WS closed unexpectedly"
|
||||
And I switch to buffer like "Untitled"
|
||||
And header says "Kernel requires reconnect C-c C-r"
|
||||
And I clear log expr "ein:log-all-buffer-name"
|
||||
And I wait for cell to execute
|
||||
And header does not say "Kernel requires reconnect C-c C-r"
|
||||
And I switch to log expr "ein:log-all-buffer-name"
|
||||
Then I should not see "[warn]"
|
||||
And I should not see "[error]"
|
||||
And I should see "ein:kernel-retrieve-session--complete"
|
||||
And I switch to buffer like "Untitled"
|
||||
And I clear log expr "ein:log-all-buffer-name"
|
||||
And I restart kernel
|
||||
And I switch to log expr "ein:log-all-buffer-name"
|
||||
|
@ -45,6 +58,3 @@ Scenario: kernel reconnect succeeds
|
|||
And header says "Kernel requires reconnect C-c C-r"
|
||||
And I clear log expr "ein:log-all-buffer-name"
|
||||
And my reconnect is questioned
|
||||
|
||||
|
||||
|
|
@ -15,8 +15,10 @@
|
|||
|
||||
(When "^my reconnect is questioned"
|
||||
(lambda ()
|
||||
(ein:notebook-reconnect-session-command (lambda (notebook session-p)
|
||||
(assert (not session-p))))))
|
||||
(cl-letf (((symbol-function 'y-or-n-p) (lambda (&rest ignore) t)))
|
||||
(ein:kernel-reconnect-session (ein:$notebook-kernel ein:%notebook%)
|
||||
(lambda (kernel session-p)
|
||||
(assert (not session-p)))))))
|
||||
|
||||
(When "I restart kernel$"
|
||||
(lambda ()
|
||||
|
@ -190,8 +192,16 @@
|
|||
|
||||
(When "^I wait for cell to execute$"
|
||||
(lambda ()
|
||||
(let ((cell (call-interactively #'ein:worksheet-execute-cell)))
|
||||
(ein:testing-wait-until (lambda () (not (slot-value cell 'running)))))))
|
||||
(let* ((cell (ein:worksheet-get-current-cell :cell-p #'ein:codecell-p))
|
||||
(orig (if (slot-boundp cell 'input-prompt-number)
|
||||
(slot-value cell 'input-prompt-number))))
|
||||
(call-interactively #'ein:worksheet-execute-cell)
|
||||
(ein:testing-wait-until
|
||||
(lambda ()
|
||||
(ein:aand (and (slot-boundp cell 'input-prompt-number)
|
||||
(slot-value cell 'input-prompt-number))
|
||||
(and (numberp it)
|
||||
(not (equal orig it)))))))))
|
||||
|
||||
(When "^I undo again$"
|
||||
(lambda ()
|
||||
|
|
|
@ -232,6 +232,8 @@
|
|||
|
||||
"
|
||||
url-or-port
|
||||
path
|
||||
kernelspec
|
||||
events
|
||||
api-version
|
||||
session-id
|
||||
|
|
|
@ -52,8 +52,8 @@ When prefix argument is given, it asks URL or port to use."
|
|||
(interactive (let* ((name (ein:junk-notebook-name))
|
||||
(url-or-port (or (ein:get-url-or-port)
|
||||
(ein:default-url-or-port)))
|
||||
(kernelspec (completing-read
|
||||
"Select kernel [default]: "
|
||||
(kernelspec (ido-completing-read
|
||||
"Select kernel: "
|
||||
(ein:list-available-kernels url-or-port) nil t nil nil "default" nil)))
|
||||
(setq name (read-string "Open notebook as: " name))
|
||||
(when current-prefix-arg
|
||||
|
|
|
@ -65,9 +65,11 @@
|
|||
|
||||
;;; Initialization and connection.
|
||||
|
||||
(defun ein:kernel-new (url-or-port base-url events &optional api-version)
|
||||
(defun ein:kernel-new (url-or-port path kernelspec base-url events &optional api-version)
|
||||
(make-ein:$kernel
|
||||
:url-or-port url-or-port
|
||||
:path path
|
||||
:kernelspec kernelspec
|
||||
:events events
|
||||
:api-version (or api-version 5)
|
||||
:session-id (ein:utils-uuid)
|
||||
|
@ -98,8 +100,8 @@
|
|||
:content content
|
||||
:parent_header (make-hash-table)))
|
||||
|
||||
(defun* ein:kernel-session-p (notebook callback &optional iteration &aux (kernel (ein:$notebook-kernel notebook)))
|
||||
"Don't make any changes on the server side. CALLBACK with arity 1, a boolean whether session exists on server."
|
||||
(defun* ein:kernel-session-p (kernel callback &optional iteration)
|
||||
"Don't make any changes on the server side. CALLBACK with arity 2, kernel and a boolean whether session exists on server."
|
||||
(unless iteration
|
||||
(setq iteration 0))
|
||||
(let ((session-id (ein:$kernel-session-id kernel)))
|
||||
|
@ -110,56 +112,48 @@
|
|||
:sync ein:force-sync
|
||||
:parser #'ein:json-read
|
||||
:complete (apply-partially #'ein:kernel-session-p--complete session-id)
|
||||
:success (apply-partially #'ein:kernel-session-p--success session-id callback)
|
||||
:error (apply-partially #'ein:kernel-session-p--error notebook callback iteration))))
|
||||
:success (apply-partially #'ein:kernel-session-p--success kernel session-id callback)
|
||||
:error (apply-partially #'ein:kernel-session-p--error kernel callback iteration))))
|
||||
|
||||
(defun* ein:kernel-session-p--complete (session-id &key data response
|
||||
&allow-other-keys
|
||||
&aux (resp-string (format "STATUS: %s DATA: %s" (request-response-status-code response) data)))
|
||||
(ein:log 'debug "ein:kernel-session-p--complete %s" resp-string))
|
||||
|
||||
(defun* ein:kernel-session-p--error (notebook callback iteration &key error-thrown symbol-status data &allow-other-keys)
|
||||
(defun* ein:kernel-session-p--error (kernel callback iteration &key error-thrown symbol-status data &allow-other-keys)
|
||||
(if (ein:aand (plist-get data :message) (search "not found" it))
|
||||
(when callback (funcall callback nil))
|
||||
(when callback (funcall callback kernel nil))
|
||||
(let* ((max-tries 3)
|
||||
(tries-left (1- (- max-tries iteration))))
|
||||
(ein:log 'verbose "ein:kernel-session-p--error [%s], %s tries left"
|
||||
(car error-thrown) tries-left)
|
||||
(if (> tries-left 0)
|
||||
(ein:kernel-session-p notebook callback (1+ iteration))))))
|
||||
(ein:kernel-session-p kernel callback (1+ iteration))))))
|
||||
|
||||
(defun* ein:kernel-session-p--success (session-id callback &key data &allow-other-keys)
|
||||
(defun* ein:kernel-session-p--success (kernel session-id callback &key data &allow-other-keys)
|
||||
(let ((session-p (equal (plist-get data :id) session-id)))
|
||||
(ein:log 'verbose "ein:kernel-session-p--success: session-id=%s session-p=%s"
|
||||
session-id session-p)
|
||||
(when callback (funcall callback session-p))))
|
||||
(when callback (funcall callback kernel session-p))))
|
||||
|
||||
(defun* ein:kernel-restart-session (notebook
|
||||
&aux (kernel (ein:$notebook-kernel notebook)))
|
||||
"Server side delete of NOTEBOOK session and subsequent restart with all new state"
|
||||
(ein:kernel-delete-session kernel
|
||||
(apply-partially
|
||||
(lambda (notebook*)
|
||||
(ein:events-trigger (ein:$kernel-events kernel)
|
||||
'status_restarting.Kernel)
|
||||
(ein:kernel-retrieve-session notebook* 0
|
||||
(apply-partially
|
||||
(lambda (nb)
|
||||
(with-current-buffer (ein:notebook-buffer nb)
|
||||
(ein:notification-status-set
|
||||
(slot-value ein:%notification% 'kernel)
|
||||
'status_restarted.Kernel)))
|
||||
notebook*)))
|
||||
notebook)))
|
||||
(defun* ein:kernel-restart-session (kernel)
|
||||
"Server side delete of KERNEL session and subsequent restart with all new state"
|
||||
(ein:kernel-delete-session
|
||||
kernel
|
||||
(lambda (kernel)
|
||||
(ein:events-trigger (ein:$kernel-events kernel) 'status_restarting.Kernel)
|
||||
(ein:kernel-retrieve-session kernel 0
|
||||
(lambda (kernel)
|
||||
(ein:events-trigger (ein:$kernel-events kernel)
|
||||
'status_restarted.Kernel))))))
|
||||
|
||||
(defun* ein:kernel-retrieve-session (notebook &optional iteration callback
|
||||
&aux (kernel (ein:$notebook-kernel notebook)))
|
||||
(defun* ein:kernel-retrieve-session (kernel &optional iteration callback)
|
||||
"Formerly ein:kernel-start, but that was misnomer because 1. the server really starts a session (and an accompanying kernel), and 2. it may not even start a session if one exists for the same path.
|
||||
|
||||
The server logic is here (could not find other documentation)
|
||||
https://github.com/jupyter/notebook/blob/04a686dbaf9dfe553324a03cb9e6f778cf1e3da1/notebook/services/sessions/handlers.py#L56-L81
|
||||
|
||||
CALLBACK of arity 0 (e.g., print a message kernel started)
|
||||
CALLBACK of arity 1, the kernel.
|
||||
|
||||
This no longer works in iPython-2.0. Protocol is to create a session for a
|
||||
notebook, which will automatically create and associate a kernel with the notebook.
|
||||
|
@ -168,8 +162,9 @@ notebook, which will automatically create and associate a kernel with the notebo
|
|||
(setq iteration 0))
|
||||
(if (<= (ein:$kernel-api-version kernel) 2)
|
||||
(error "Api %s unsupported" (ein:$kernel-api-version kernel))
|
||||
(let ((kernelspec (ein:$notebook-kernelspec notebook))
|
||||
(kernel-id (ein:$kernel-kernel-id kernel)))
|
||||
(let ((kernel-id (ein:$kernel-kernel-id kernel))
|
||||
(kernelspec (ein:$kernel-kernelspec kernel))
|
||||
(path (ein:$kernel-path kernel)))
|
||||
(ein:query-singleton-ajax
|
||||
(list 'kernel-retrieve-session kernel-id)
|
||||
(ein:url (ein:$kernel-url-or-port kernel) "api/sessions")
|
||||
|
@ -177,11 +172,11 @@ notebook, which will automatically create and associate a kernel with the notebo
|
|||
:data (json-encode
|
||||
(cond ((<= (ein:$kernel-api-version kernel) 4)
|
||||
`(("notebook" .
|
||||
(("path" . ,(ein:$notebook-notebook-path notebook))))
|
||||
(("path" . ,path)))
|
||||
,@(if kernelspec
|
||||
`(("kernel" .
|
||||
(("name" . ,(ein:$kernelspec-name kernelspec))))))))
|
||||
(t `(("path" . ,(ein:$notebook-notebook-path notebook))
|
||||
(t `(("path" . ,path)
|
||||
("type" . "notebook")
|
||||
,@(if kernelspec
|
||||
`(("kernel" .
|
||||
|
@ -192,21 +187,21 @@ notebook, which will automatically create and associate a kernel with the notebo
|
|||
:parser #'ein:json-read
|
||||
:complete (apply-partially #'ein:kernel-retrieve-session--complete kernel callback)
|
||||
:success (apply-partially #'ein:kernel-retrieve-session--success kernel callback)
|
||||
:error (apply-partially #'ein:kernel-retrieve-session--error notebook iteration callback)))))
|
||||
:error (apply-partially #'ein:kernel-retrieve-session--error kernel iteration callback)))))
|
||||
|
||||
(defun* ein:kernel-retrieve-session--complete (kernel callback &key data response
|
||||
&allow-other-keys
|
||||
&aux (resp-string (format "STATUS: %s DATA: %s" (request-response-status-code response) data)))
|
||||
(ein:log 'debug "ein:kernel-retrieve-session--complete %s" resp-string))
|
||||
|
||||
(defun* ein:kernel-retrieve-session--error (notebook iteration callback &key error-thrown symbol-status &allow-other-keys)
|
||||
(defun* ein:kernel-retrieve-session--error (kernel iteration callback &key error-thrown symbol-status &allow-other-keys)
|
||||
(let* ((max-tries 3)
|
||||
(tries-left (1- (- max-tries iteration))))
|
||||
(ein:log 'verbose "ein:kernel-retrieve-session--error [%s], %s tries left"
|
||||
(car error-thrown) tries-left)
|
||||
(sleep-for 0 (* (1+ iteration) 500))
|
||||
(if (> tries-left 0)
|
||||
(ein:kernel-retrieve-session notebook (1+ iteration) callback))))
|
||||
(ein:kernel-retrieve-session kernel (1+ iteration) callback))))
|
||||
|
||||
(defun* ein:kernel-retrieve-session--success (kernel callback &key data &allow-other-keys)
|
||||
(let ((session-id (plist-get data :id)))
|
||||
|
@ -220,8 +215,29 @@ notebook, which will automatically create and associate a kernel with the notebo
|
|||
(setf (ein:$kernel-ws-url kernel) (ein:kernel--ws-url (ein:$kernel-url-or-port kernel)))
|
||||
(setf (ein:$kernel-kernel-url kernel)
|
||||
(concat (file-name-as-directory (ein:$kernel-base-url kernel)) id)))
|
||||
(ein:kernel-start-websocket kernel)
|
||||
(when callback (funcall callback))))
|
||||
(ein:kernel-start-websocket kernel callback)))
|
||||
|
||||
(defun ein:kernel-reconnect-session (kernel &optional callback)
|
||||
"Check if session still exists. If it does, retrieve it. If it doesn't, ask the user to create a new session (ein:kernel-retrieve-session both retrieves and creates).
|
||||
|
||||
CALLBACK with arity 0 (e.g., execute cell now that we're reconnected)"
|
||||
(ein:kernel-disconnect kernel)
|
||||
(ein:events-trigger (ein:$kernel-events kernel) 'status_reconnecting.Kernel)
|
||||
(ein:kernel-session-p
|
||||
kernel
|
||||
(apply-partially
|
||||
(lambda (callback* kernel session-p)
|
||||
(if (or session-p
|
||||
(and (not noninteractive) (y-or-n-p "Session not found. Restart?")))
|
||||
(ein:kernel-retrieve-session
|
||||
kernel 0
|
||||
(apply-partially
|
||||
(lambda (callback** kernel)
|
||||
(ein:events-trigger (ein:$kernel-events kernel)
|
||||
'status_reconnected.Kernel)
|
||||
(when callback** (funcall callback** kernel)))
|
||||
callback*))))
|
||||
callback)))
|
||||
|
||||
(defun ein:kernel--ws-url (url-or-port &optional securep)
|
||||
"Use `ein:$kernel-url-or-port' if BASE_URL is an empty string.
|
||||
|
@ -266,7 +282,8 @@ See: https://github.com/ipython/ipython/pull/3307"
|
|||
(ein:kernel--handle-stdin-reply kernel packet))
|
||||
(t (ein:log 'warn "Received reply from unforeseen channel %s" channel)))))
|
||||
|
||||
(defun ein:start-single-websocket (kernel)
|
||||
(defun ein:start-single-websocket (kernel open-callback)
|
||||
"OPEN-CALLBACK (kernel) (e.g., execute cell)"
|
||||
(let ((ws-url (concat (ein:$kernel-ws-url kernel)
|
||||
(ein:$kernel-kernel-url kernel)
|
||||
"/channels?session_id="
|
||||
|
@ -279,19 +296,23 @@ See: https://github.com/ipython/ipython/pull/3307"
|
|||
(let* ((websocket (websocket-client-data ws))
|
||||
(kernel (ein:$websocket-kernel websocket)))
|
||||
(unless (ein:$websocket-closed-by-client websocket)
|
||||
(ein:log 'warn "WS closed unexpectedly: %s" (websocket-url ws))
|
||||
(ein:log 'verbose "WS closed unexpectedly: %s" (websocket-url ws))
|
||||
(ein:kernel-disconnect kernel))))
|
||||
(lambda (ws)
|
||||
(let* ((websocket (websocket-client-data ws))
|
||||
(kernel (ein:$websocket-kernel websocket)))
|
||||
(when (ein:kernel-live-p kernel)
|
||||
(ein:kernel-run-after-start-hook kernel))
|
||||
(ein:log 'verbose "WS opened: %s" (websocket-url ws))))))))
|
||||
(apply-partially
|
||||
(lambda (cb ws)
|
||||
(let* ((websocket (websocket-client-data ws))
|
||||
(kernel (ein:$websocket-kernel websocket)))
|
||||
(when (ein:kernel-live-p kernel)
|
||||
(ein:kernel-run-after-start-hook kernel)
|
||||
(when cb
|
||||
(funcall cb kernel)))
|
||||
(ein:log 'verbose "WS opened: %s" (websocket-url ws))))
|
||||
open-callback)))))
|
||||
|
||||
(defun ein:kernel-start-websocket (kernel)
|
||||
(defun ein:kernel-start-websocket (kernel callback)
|
||||
(cond ((<= (ein:$kernel-api-version kernel) 2)
|
||||
(error "Api version %s unsupported" (ein:$kernel-api-version kernel)))
|
||||
(t (ein:start-single-websocket kernel))))
|
||||
(t (ein:start-single-websocket kernel callback))))
|
||||
|
||||
(defun ein:kernel-on-connect (kernel content -metadata-not-used-)
|
||||
(ein:log 'info "Kernel connect_request_reply received."))
|
||||
|
@ -313,13 +334,12 @@ delete the kernel on the server side"
|
|||
(and (ein:$kernel-p kernel)
|
||||
(ein:aand (ein:$kernel-websocket kernel) (ein:websocket-open-p it))))
|
||||
|
||||
(defmacro ein:kernel-if-ready (kernel &rest body)
|
||||
"Execute BODY if KERNEL is ready. Warn user otherwise."
|
||||
(declare (indent 1))
|
||||
`(if (ein:kernel-live-p ,kernel)
|
||||
(progn ,@body)
|
||||
(message "Kernel unready or closed")
|
||||
(ein:log 'verbose "Kernel %s unavailable" (ein:$kernel-kernel-id ,kernel))))
|
||||
(defun ein:kernel-when-ready (kernel callback)
|
||||
"Execute CALLBACK of arity 0 (executing cell) when KERNEL is ready. Warn user otherwise."
|
||||
(if (ein:kernel-live-p kernel)
|
||||
(funcall callback kernel)
|
||||
(ein:log 'verbose "Kernel %s unavailable" (ein:$kernel-kernel-id kernel))
|
||||
(ein:kernel-reconnect-session kernel callback)))
|
||||
|
||||
|
||||
;;; Main public methods
|
||||
|
@ -606,7 +626,7 @@ Example::
|
|||
(ein:log 'info "Sent interruption command.")))))
|
||||
|
||||
(defun ein:kernel-delete-session (kernel &optional callback)
|
||||
"Regardless of success or error, we clear all state variables of kernel and funcall CALLBACK of arity 0 (e.g., kernel restart)"
|
||||
"Regardless of success or error, we clear all state variables of kernel and funcall CALLBACK of arity 1, the kernel"
|
||||
(ein:and-let* ((session-id (ein:$kernel-session-id kernel)))
|
||||
(ein:query-singleton-ajax
|
||||
(list 'kernel-delete-session session-id)
|
||||
|
@ -631,7 +651,7 @@ Example::
|
|||
&aux (resp-string (format "STATUS: %s DATA: %s" (request-response-status-code response) data)))
|
||||
(ein:log 'debug "ein:kernel-delete-session--complete %s" resp-string)
|
||||
(ein:kernel-disconnect kernel)
|
||||
(when callback (funcall callback)))
|
||||
(when callback (funcall callback kernel)))
|
||||
|
||||
|
||||
;; Reply handlers.
|
||||
|
|
|
@ -347,13 +347,13 @@ notebook buffer. Let's warn for now to see who is doing this.
|
|||
(ein:notebook-new url-or-port path kernelspec)))
|
||||
(callback0 (ein:notebook-open--decorate-callback notebook existing pending-clear
|
||||
callback)))
|
||||
(if pending-p
|
||||
(ein:log 'warn "Notebook %s is pending open!" pending-key)
|
||||
(if existing
|
||||
(progn
|
||||
(ein:log 'warn "Notebook %s is already open"
|
||||
(ein:$notebook-notebook-name notebook))
|
||||
(funcall callback0))
|
||||
(if existing
|
||||
(progn
|
||||
(ein:log 'info "Notebook %s is already open"
|
||||
(ein:$notebook-notebook-name notebook))
|
||||
(funcall callback0))
|
||||
(when (or (not pending-p)
|
||||
(y-or-n-p (format "Notebook %s pending open! Retry? " path)))
|
||||
(setf (gethash pending-key *ein:notebook--pending-query*) t)
|
||||
(ein:content-query-contents url-or-port path
|
||||
(apply-partially #'ein:notebook-open--callback
|
||||
|
@ -536,7 +536,7 @@ notebook buffer then the user will be prompted to select an opened notebook."
|
|||
(setf (ein:$notebook-kernelspec notebook) (ein:get-kernelspec (ein:$notebook-url-or-port notebook)
|
||||
kernel-name))
|
||||
(ein:log 'info "Restarting notebook %s with new kernel %s." (ein:$notebook-notebook-name notebook) kernel-name)
|
||||
(ein:kernel-restart-session notebook))
|
||||
(ein:kernel-restart-session (ein:$notebook-kernel notebook)))
|
||||
|
||||
(defun ein:notebook-retrieve-session (notebook)
|
||||
"Formerly ein:notebook-start-kernel.
|
||||
|
@ -545,42 +545,27 @@ If 'picking up from where we last off', that is, we restart emacs and reconnect
|
|||
(let* ((base-url (concat ein:base-kernel-url "kernels"))
|
||||
(kernelspec (ein:$notebook-kernelspec notebook))
|
||||
(kernel (ein:kernel-new (ein:$notebook-url-or-port notebook)
|
||||
(ein:$notebook-notebook-path notebook)
|
||||
kernelspec
|
||||
base-url
|
||||
(ein:$notebook-events notebook)
|
||||
(ein:$notebook-api-version notebook))))
|
||||
(setf (ein:$notebook-kernel notebook) kernel)
|
||||
(when (eq (ein:get-mode-for-kernel (ein:$notebook-kernelspec notebook)) 'python)
|
||||
(ein:pytools-setup-hooks kernel notebook))
|
||||
(ein:kernel-retrieve-session notebook)))
|
||||
(ein:kernel-retrieve-session (ein:$notebook-kernel notebook))))
|
||||
|
||||
(defun ein:notebook-reconnect-session-command (&optional callback)
|
||||
"It seems convenient but undisciplined to blithely create a new session if the original one no longer exists. CALLBACK takes notebook and session-p."
|
||||
(defun ein:notebook-reconnect-session-command ()
|
||||
"It seems convenient but undisciplined to blithely create a new session if the original one no longer exists."
|
||||
(interactive)
|
||||
(unless callback
|
||||
(setq callback
|
||||
(lambda (notebook session-p)
|
||||
(if (or session-p (y-or-n-p "Session not found. Restart?"))
|
||||
(ein:kernel-retrieve-session notebook 0
|
||||
(apply-partially (lambda (nb)
|
||||
(with-current-buffer (ein:notebook-buffer nb)
|
||||
(ein:notification-status-set
|
||||
(slot-value ein:%notification% 'kernel)
|
||||
'status_reconnected.Kernel)))
|
||||
notebook))))))
|
||||
(ein:aif ein:%notebook%
|
||||
(progn
|
||||
(ein:kernel-disconnect (ein:$notebook-kernel it))
|
||||
(ein:events-trigger (ein:$kernel-events (ein:$notebook-kernel it))
|
||||
'status_reconnecting.Kernel)
|
||||
(ein:kernel-session-p
|
||||
it (apply-partially callback it)))))
|
||||
(ein:kernel-reconnect-session (ein:$notebook-kernel ein:%notebook%)))
|
||||
|
||||
(defun ein:notebook-restart-session-command ()
|
||||
"Delete session on server side. Start new session."
|
||||
(interactive)
|
||||
(ein:aif ein:%notebook%
|
||||
(if (y-or-n-p "Are you sure? ")
|
||||
(ein:kernel-restart-session it))
|
||||
(ein:kernel-restart-session (ein:$notebook-kernel it)))
|
||||
(message "Not in notebook buffer!")))
|
||||
|
||||
(define-obsolete-function-alias
|
||||
|
|
|
@ -300,10 +300,10 @@ Generated by `ein:header-line-define-mouse-commands'" slot)
|
|||
(defun ein:header-line-switch-kernel (key-event)
|
||||
(interactive "e")
|
||||
(let* ((notebook (or (ein:get-notebook)
|
||||
(completing-read
|
||||
"Select notebook [URL-OR-PORT/NAME]: "
|
||||
(ido-completing-read
|
||||
"Select notebook: "
|
||||
(ein:notebook-opened-buffer-names))))
|
||||
(kernel-name (completing-read
|
||||
(kernel-name (ido-completing-read
|
||||
"Select kernel: "
|
||||
(ein:list-available-kernels (ein:$notebook-url-or-port notebook)))))
|
||||
(ein:notebook-switch-kernel notebook kernel-name)))
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
;; is needed. This module buffer containing one special cell for that
|
||||
;; purpose.
|
||||
|
||||
;; TODO - Undo accounting is almost certainly broken by this module
|
||||
|
||||
;;; Code:
|
||||
|
||||
(eval-when-compile (require 'cl))
|
||||
|
|
|
@ -1011,20 +1011,19 @@ Do not clear input prompts when the prefix argument is given."
|
|||
(cl-typep x 'ein:codecell))
|
||||
(ein:worksheet-get-cells ws))))
|
||||
|
||||
(defun ein:undo-execute-cell (ws cell old-cell)
|
||||
(ein:worksheet-insert-cell-below ws old-cell cell)
|
||||
(ein:worksheet-delete-cell ws cell))
|
||||
|
||||
(defun ein:worksheet-execute-cell (ws cell)
|
||||
"Execute code type CELL."
|
||||
(interactive (list (ein:worksheet--get-ws-or-error)
|
||||
(ein:worksheet-get-current-cell
|
||||
:cell-p #'ein:codecell-p)))
|
||||
(let ((buffer-undo-list t))
|
||||
(ein:kernel-if-ready (slot-value ws 'kernel)
|
||||
(ein:cell-execute cell)
|
||||
(oset ws :dirty t)))
|
||||
(ein:worksheet--unshift-undo-list cell)
|
||||
(ein:kernel-when-ready (slot-value ws 'kernel)
|
||||
(apply-partially
|
||||
(lambda (ws* cell* kernel)
|
||||
(let ((buffer-undo-list t))
|
||||
(ein:cell-execute cell*)
|
||||
(oset ws* :dirty t))
|
||||
(ein:worksheet--unshift-undo-list cell*))
|
||||
ws cell))
|
||||
cell)
|
||||
|
||||
(defun ein:worksheet-execute-cell-and-goto-next (ws cell &optional insert)
|
||||
|
@ -1206,10 +1205,16 @@ buffer, so you don't need to set current buffer to call this
|
|||
function."
|
||||
(interactive (list (ein:worksheet--get-ws-or-error)))
|
||||
(ein:with-live-buffer (ein:worksheet-buffer ws)
|
||||
(ein:kernel-if-ready (slot-value ws 'kernel)
|
||||
(mapc #'ein:cell-execute
|
||||
(ein:filter #'ein:cell-autoexec-p
|
||||
(ein:worksheet-get-cells ws))))))
|
||||
(ein:kernel-when-ready
|
||||
(slot-value ws 'kernel)
|
||||
|
||||
(apply-partially
|
||||
(lambda (ws kernel)
|
||||
(let ((buffer-undo-list t))
|
||||
(mapc #'ein:cell-execute
|
||||
(ein:filter #'ein:cell-autoexec-p
|
||||
(ein:worksheet-get-cells ws)))))
|
||||
ws))))
|
||||
|
||||
|
||||
;;; Imenu
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
(ein:notebook-enable-autosaves (notebook)))
|
||||
(let ((notebook (ein:notebook-new ein:testing-notebook-dummy-url path kernelspec)))
|
||||
(setf (ein:$notebook-kernel notebook)
|
||||
(ein:kernel-new 8888 "/kernels" (ein:$notebook-events notebook) (ein:need-notebook-version (ein:$notebook-url-or-port notebook))))
|
||||
(ein:kernel-new 8888 "" nil "/kernels" (ein:$notebook-events notebook) (ein:need-notebook-version (ein:$notebook-url-or-port notebook))))
|
||||
(setf (ein:$kernel-events (ein:$notebook-kernel notebook))
|
||||
(ein:events-new))
|
||||
; matryoshka: new-content makes a ein:$content using CONTENT as template
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
(require 'ein-testing-notebook)
|
||||
|
||||
(defun eintest:kernel-new (port)
|
||||
(ein:kernel-new port "/api/kernels"
|
||||
(ein:kernel-new port "" nil "/api/kernels"
|
||||
(get-buffer-create "*eintest: dummy for kernel test*")))
|
||||
|
||||
(ert-deftest ein:kernel-restart-check-url ()
|
||||
|
@ -26,7 +26,7 @@
|
|||
((symbol-function 'ein:get-notebook-or-error) (lambda () (ein:get-notebook))))
|
||||
(ein:kernel-retrieve-session--success
|
||||
kernel nil :data (list :ws_url "ws://127.0.0.1:8888" :id kernel-id))
|
||||
(ein:kernel-restart-session notebook)
|
||||
(ein:kernel-restart-session (ein:$notebook-kernel notebook))
|
||||
(should (equal got-url desired-url)))))
|
||||
|
||||
(ert-deftest ein:kernel-interrupt-check-url ()
|
||||
|
|
Loading…
Add table
Reference in a new issue