mirror of
https://github.com/vale981/emacs-ipython-notebook
synced 2025-03-06 09:31:39 -05:00
Merge pull request #342 from dickmao/async-staging
Asynchronize all server communication
This commit is contained in:
commit
98ce6cc83e
26 changed files with 744 additions and 979 deletions
|
@ -38,4 +38,4 @@ before_script:
|
|||
- cask install
|
||||
|
||||
script:
|
||||
- make test || cat log/*.server
|
||||
- make test || ( for file in log/{testfunc,ecukes}.* ; do echo $file ; cat $file ; done )
|
||||
|
|
2
Cask
2
Cask
|
@ -3,7 +3,7 @@
|
|||
|
||||
(package "ein" "0.14.2" "Emacs IPython Notebook.")
|
||||
(package-file "lisp/ein.el")
|
||||
(files "lisp/*.el" :exclude ("lisp/zeroein.el"))
|
||||
(files "lisp/*.el" (:exclude "lisp/zeroein.el"))
|
||||
|
||||
(development
|
||||
(depends-on "websocket")
|
||||
|
|
6
Makefile
6
Makefile
|
@ -4,11 +4,13 @@ IPY_VERSION = 5.8.0
|
|||
SRC=$(shell cask files)
|
||||
ELCFILES = $(SRC:.el=.elc)
|
||||
|
||||
.PHONY: loaddefs
|
||||
loaddefs:
|
||||
sh tools/update-autoloads.sh
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
cask clean-elc
|
||||
-rm -f log/testein*
|
||||
-rm -f log/testfunc*
|
||||
|
||||
env-ipy.%:
|
||||
tools/makeenv.sh env/ipy.$* tools/requirement-ipy.$*.txt
|
||||
|
|
35
features/notebooklist.feature
Normal file
35
features/notebooklist.feature
Normal file
|
@ -0,0 +1,35 @@
|
|||
Scenario: No warnings
|
||||
Given I switch to log expr "ein:log-all-buffer-name"
|
||||
Then I should see "[info]"
|
||||
And I should not see "[warn]"
|
||||
And I should not see "[error]"
|
||||
|
||||
Scenario: Breadcrumbs
|
||||
Given I am in notebooklist buffer
|
||||
When I click on dir "step-definitions"
|
||||
Then I should see "ein-steps"
|
||||
And I click on "Home"
|
||||
Then I should see "support"
|
||||
|
||||
Scenario: New Notebook
|
||||
Given I am in notebooklist buffer
|
||||
When I clear log expr "ein:log-all-buffer-name"
|
||||
And I click on "New Notebook"
|
||||
And I switch to log expr "ein:log-all-buffer-name"
|
||||
Then I should see "Opened notebook Untitled"
|
||||
|
||||
Scenario: Resync
|
||||
Given I am in notebooklist buffer
|
||||
When I clear log expr "ein:log-all-buffer-name"
|
||||
And I click on "Resync"
|
||||
And I switch to log expr "ein:log-all-buffer-name"
|
||||
Then I should see "kernelspecs--complete"
|
||||
|
||||
@foo
|
||||
Scenario: Global notebooks
|
||||
Given I am in notebooklist buffer
|
||||
When I clear log expr "ein:log-all-buffer-name"
|
||||
And I call "ein:notebooklist-open-notebook-global"
|
||||
And I wait 0.9 seconds
|
||||
And I switch to log expr "ein:log-all-buffer-name"
|
||||
Then I should see "Opened notebook"
|
|
@ -1,3 +1,28 @@
|
|||
(When "^I clear log expr \"\\(.+\\)\"$"
|
||||
(lambda (log-expr)
|
||||
(with-current-buffer (symbol-value (intern log-expr))
|
||||
(let ((inhibit-read-only t))
|
||||
(erase-buffer)))))
|
||||
|
||||
(When "^I switch to log expr \"\\(.+\\)\"$"
|
||||
(lambda (log-expr)
|
||||
(switch-to-buffer (symbol-value (intern log-expr)))))
|
||||
|
||||
(When "^I am in notebooklist buffer$"
|
||||
(lambda ()
|
||||
(multiple-value-bind (url-or-port token) (ein:jupyter-server-conn-info)
|
||||
(switch-to-buffer (ein:notebooklist-get-buffer url-or-port))
|
||||
(sit-for 0.8)
|
||||
)))
|
||||
|
||||
(When "^I wait \\([.0-9]+\\) seconds$"
|
||||
(lambda (seconds)
|
||||
(sit-for (string-to-number seconds))))
|
||||
|
||||
(When "^I am in log buffer$"
|
||||
(lambda ()
|
||||
(switch-to-buffer ein:log-all-buffer-name)))
|
||||
|
||||
(When "^new \\(.+\\) notebook$"
|
||||
(lambda (kernel)
|
||||
(multiple-value-bind (url-or-port token) (ein:jupyter-server-conn-info)
|
||||
|
@ -14,6 +39,25 @@
|
|||
(switch-to-buffer buf-name)
|
||||
(Then "I should be in buffer \"%s\"" buf-name))))))
|
||||
|
||||
(When "^I click on \"\\(.+\\)\"$"
|
||||
(lambda (word)
|
||||
;; from espuds "go to word" without the '\\b's
|
||||
(goto-char (point-min))
|
||||
(let ((search (re-search-forward (format "\\[%s\\]" word) nil t))
|
||||
(message "Cannot go to link '%s' in buffer: %s"))
|
||||
(cl-assert search nil message word (buffer-string))
|
||||
(backward-char)
|
||||
(When "I press \"RET\"")
|
||||
(sit-for 0.8))))
|
||||
|
||||
(When "^I click on dir \"\\(.+\\)\"$"
|
||||
(lambda (dir)
|
||||
(When (format "I go to word \"%s\"" dir))
|
||||
(re-search-backward "Dir" nil t)
|
||||
(When "I press \"RET\"")
|
||||
(sit-for 0.8)
|
||||
))
|
||||
|
||||
(When "^old notebook \"\\(.+\\)\"$"
|
||||
(lambda (path)
|
||||
(multiple-value-bind (url-or-port token) (ein:jupyter-server-conn-info)
|
||||
|
|
|
@ -17,44 +17,13 @@
|
|||
(defvar ein:testing-jupyter-server-root (f-parent (f-dirname load-file-name)))
|
||||
(ein:deflocal ein:%testing-port% nil)
|
||||
|
||||
(defun ein:testing-wait-until (predicate &optional predargs ms)
|
||||
"Wait until PREDICATE function returns non-`nil'.
|
||||
PREDARGS is argument list for the PREDICATE function.
|
||||
MS is milliseconds to wait."
|
||||
(let* ((subms 300)
|
||||
(count (max 1 (if ms (truncate (/ ms subms)) 25))))
|
||||
(unless (loop repeat count
|
||||
when (apply predicate predargs)
|
||||
return t
|
||||
do (sleep-for 0 subms))
|
||||
(error "Timeout: %s" predicate))))
|
||||
|
||||
(Setup
|
||||
(setq ein:force-sync t)
|
||||
(ein:dev-start-debug)
|
||||
(setq ein:notebook-autosave-frequency 10000)
|
||||
(setq ein:testing-dump-file-log "./log/ecukes.log")
|
||||
(setq ein:testing-dump-file-messages "./log/ecukes.messages")
|
||||
(setq ein:testing-dump-server-log "./log/ecukes.server")
|
||||
|
||||
(setq ein:jupyter-server-args '("--no-browser" "--debug"))
|
||||
(deferred:sync! (ein:jupyter-server-start (executable-find "jupyter") ein:testing-jupyter-server-root))
|
||||
(assert (processp %ein:jupyter-server-session%) t "notebook server defunct")
|
||||
(setq ein:%testing-url% (car (ein:jupyter-server-conn-info))
|
||||
))
|
||||
|
||||
(After
|
||||
(defun ein:testing-after-scenario ()
|
||||
(with-current-buffer (ein:notebooklist-get-buffer ein:%testing-url%)
|
||||
(loop for buffer in (ein:notebook-opened-buffers)
|
||||
do (let ((kill-buffer-query-functions nil))
|
||||
(with-current-buffer buffer (not-modified))
|
||||
(kill-buffer buffer)))
|
||||
(let ((sessions #s(hash-table test equal data (:pending t)))
|
||||
(urlport (ein:$notebooklist-url-or-port ein:%notebooklist%)))
|
||||
(ein:content-query-sessions sessions urlport)
|
||||
(loop repeat 4
|
||||
until (null (gethash :pending sessions))
|
||||
do (sleep-for 0 50))
|
||||
(let ((urlport (ein:$notebooklist-url-or-port ein:%notebooklist%)))
|
||||
(loop for note in (ein:$notebooklist-data ein:%notebooklist%)
|
||||
for path = (plist-get note :path)
|
||||
for notebook = (ein:notebook-get-opened-notebook urlport path)
|
||||
|
@ -62,14 +31,31 @@
|
|||
do (ein:notebook-kill-kernel-then-close-command notebook t)
|
||||
(if (search "Untitled" path)
|
||||
(ein:notebooklist-delete-notebook path))
|
||||
end))))
|
||||
end)))
|
||||
)
|
||||
(Setup
|
||||
(ein:dev-start-debug)
|
||||
(setq ein:notebook-autosave-frequency 10000)
|
||||
(setq ein:testing-dump-file-log (concat default-directory "log/ecukes.log"))
|
||||
(setq ein:testing-dump-file-messages (concat default-directory "log/ecukes.messages"))
|
||||
(setq ein:testing-dump-file-server (concat default-directory "log/ecukes.server"))
|
||||
(setq ein:testing-dump-file-request (concat default-directory "log/ecukes.request"))
|
||||
(setq ein:jupyter-server-args '("--no-browser" "--debug"))
|
||||
(setq ein:%testing-url% nil)
|
||||
(deferred:sync! (ein:jupyter-server-start (executable-find "jupyter") ein:testing-jupyter-server-root))
|
||||
(assert (processp %ein:jupyter-server-session%) t "notebook server defunct")
|
||||
(setq ein:%testing-url% (car (ein:jupyter-server-conn-info))))
|
||||
|
||||
(After
|
||||
(ein:testing-after-scenario))
|
||||
|
||||
(Teardown
|
||||
(cl-letf (((symbol-function 'y-or-n-p) (lambda (prompt) t)))
|
||||
(ein:jupyter-server-stop t))
|
||||
(ein:testing-dump-logs)
|
||||
; (ein:testing-dump-logs) ; taken care of by ein-testing.el kill-emacs-hook?
|
||||
(assert (not (processp %ein:jupyter-server-session%)) t "notebook server orphaned"))
|
||||
|
||||
(Fail
|
||||
(if (not noninteractive)
|
||||
(keyboard-quit))) ;; useful to prevent emacs from quitting
|
||||
(if noninteractive
|
||||
(ein:testing-after-scenario)
|
||||
(keyboard-quit))) ;; useful to prevent emacs from quitting
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
@default
|
||||
Scenario: Undo by default turned off
|
||||
Given new default notebook
|
||||
When I type "import math"
|
||||
|
@ -5,6 +6,7 @@ Scenario: Undo by default turned off
|
|||
And I undo demoting errors
|
||||
Then I should see message "demoted: (user-error No undo information in this buffer)"
|
||||
|
||||
@yank
|
||||
Scenario: Kill yank doesn't break undo
|
||||
Given I enable undo
|
||||
Given new default notebook
|
||||
|
|
|
@ -258,9 +258,7 @@ a number will limit the number of lines in a cell output."
|
|||
(ein:oset-if-empty cell 'metadata (plist-get data :metadata))
|
||||
(ein:aif (plist-get (slot-value cell 'metadata) :slideshow)
|
||||
(let ((slide-type (nth 0 (cdr it))))
|
||||
(setf (slot-value cell 'slidetype) slide-type)
|
||||
(message "read slidetype %s" (slot-value cell 'slidetype))
|
||||
(message "reconstructed slideshow %s" (ein:get-slide-show cell)))))
|
||||
(setf (slot-value cell 'slidetype) slide-type))))
|
||||
cell))
|
||||
|
||||
(defmethod ein:cell-init ((cell ein:codecell) data)
|
||||
|
|
|
@ -180,7 +180,7 @@ notebooks."
|
|||
(ein:notebooklist-list-notebooks))))
|
||||
(ein:notebooklist-open-notebook-global
|
||||
nbpath
|
||||
(lambda (notebook -ignore- buffer no-reconnection)
|
||||
(lambda (notebook created buffer no-reconnection)
|
||||
(ein:connect-buffer-to-notebook notebook buffer no-reconnection))
|
||||
(list (or buffer (current-buffer)) no-reconnection)))
|
||||
|
||||
|
@ -189,9 +189,10 @@ notebooks."
|
|||
"Connect any buffer to opened notebook and its kernel."
|
||||
(interactive (list (completing-read "Notebook buffer to connect: "
|
||||
(ein:notebook-opened-buffer-names))))
|
||||
(let ((notebook
|
||||
(buffer-local-value 'ein:%notebook% (get-buffer buffer-or-name))))
|
||||
(ein:connect-buffer-to-notebook notebook)))
|
||||
(ein:aif (get-buffer-buffer-or-name)
|
||||
(let ((notebook (buffer-local-value 'ein:%notebook% it)))
|
||||
(ein:connect-buffer-to-notebook notebook))
|
||||
(error "No buffer %s" buffer-or-name)))
|
||||
|
||||
;;;###autoload
|
||||
(defun ein:connect-buffer-to-notebook (notebook &optional buffer
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
(provide 'ein-contents-api) ; must provide before requiring ein-notebook:
|
||||
(require 'ein-notebook) ; circular: depends on this file!
|
||||
|
||||
(defcustom ein:content-query-timeout (* 60 1000) ; 1 min
|
||||
(defcustom ein:content-query-timeout (* 60 1000) ;1 min
|
||||
"Query timeout for getting content from Jupyter/IPython notebook.
|
||||
If you cannot open large notebooks because of a timeout error try
|
||||
increasing this value. Setting this value to `nil' means to use
|
||||
|
@ -56,71 +56,61 @@ global setting. For global setting and more information, see
|
|||
:group 'ein)
|
||||
|
||||
(defun ein:content-url (content &rest params)
|
||||
(let ((url-or-port (ein:$content-url-or-port content))
|
||||
(path (ein:$content-path content)))
|
||||
(if params
|
||||
(url-encode-url (apply #'ein:url
|
||||
url-or-port
|
||||
"api/contents"
|
||||
path
|
||||
params))
|
||||
(url-encode-url (ein:url url-or-port "api/contents" path)))))
|
||||
(apply #'ein:content-url* (ein:$content-url-or-port content) (ein:$content-path content) params))
|
||||
|
||||
(defun ein:content-url-legacy (content &rest params)
|
||||
"Generate content url's for IPython Notebook version 2.x"
|
||||
(let ((url-or-port (ein:$content-url-or-port content))
|
||||
(path (ein:$content-path content)))
|
||||
(if params
|
||||
(url-encode-url (apply #'ein:url
|
||||
url-or-port
|
||||
"api/notebooks"
|
||||
path
|
||||
params))
|
||||
(url-encode-url (ein:url url-or-port "api/notebooks" path)))))
|
||||
(defun ein:content-url* (url-or-port path &rest params)
|
||||
(let* ((which (if (<= (ein:need-ipython-version url-or-port) 2)
|
||||
"notebooks" "contents"))
|
||||
(api-path (concat "api/" which)))
|
||||
(url-encode-url (apply #'ein:url
|
||||
url-or-port
|
||||
api-path
|
||||
path
|
||||
params))))
|
||||
|
||||
(defun ein:content-query-contents (path &optional url-or-port force-sync callback retry-p)
|
||||
"Return the contents of the object at the specified path from the Jupyter server."
|
||||
(condition-case err
|
||||
(let* ((url-or-port (or url-or-port (ein:default-url-or-port)))
|
||||
(new-content (make-ein:$content
|
||||
:url-or-port url-or-port
|
||||
:ipython-version (ein:query-ipython-version url-or-port)
|
||||
:path path))
|
||||
(url (ein:content-url new-content)))
|
||||
(if (= 2 (ein:$content-ipython-version new-content))
|
||||
(setq new-content (ein:content-query-contents-legacy path url-or-port ein:force-sync callback))
|
||||
(ein:query-singleton-ajax
|
||||
(list 'content-query-contents url-or-port path)
|
||||
url
|
||||
:type "GET"
|
||||
:timeout ein:content-query-timeout
|
||||
:parser #'ein:json-read
|
||||
:sync (or force-sync ein:force-sync)
|
||||
:success (apply-partially #'ein:new-content new-content callback)
|
||||
:error (apply-partially #'ein:content-query-contents-error url retry-p
|
||||
(list path url-or-port force-sync callback t))))
|
||||
new-content)
|
||||
(error (progn (message "Error %s on query contents, try calling `ein:notebooklist-login` first..." err)
|
||||
(if (>= ein:log-level (ein:log-level-name-to-int 'debug))
|
||||
(throw 'error err))))))
|
||||
(defun ein:content-query-contents (url-or-port path callback)
|
||||
"Register CALLBACK of arity 1 for the contents at PATH from the Jupyter URL-OR-PORT."
|
||||
(ein:query-singleton-ajax
|
||||
(list 'content-query-contents url-or-port path)
|
||||
(ein:content-url* url-or-port path)
|
||||
:type "GET"
|
||||
:timeout ein:content-query-timeout
|
||||
:parser #'ein:json-read
|
||||
:sync ein:force-sync
|
||||
:complete (apply-partially #'ein:content-query-contents--complete url-or-port path)
|
||||
:success (apply-partially #'ein:content-query-contents--success url-or-port path callback)
|
||||
:error (apply-partially #'ein:content-query-contents--error url-or-port path)
|
||||
))
|
||||
|
||||
(defun ein:content-query-contents-legacy (path &optional url-or-port force-sync callback)
|
||||
"Return contents of object at specified path for IPython Notebook versions 2.x"
|
||||
(let* ((url-or-port (or url-or-port (ein:default-url-or-port)))
|
||||
(new-content (make-ein:$content :url-or-port url-or-port
|
||||
:ipython-version (ein:query-ipython-version url-or-port)
|
||||
:path path))
|
||||
(url (ein:content-url-legacy new-content)))
|
||||
(ein:query-singleton-ajax
|
||||
(list 'content-query-contents-legacy url-or-port path)
|
||||
url
|
||||
:type "GET"
|
||||
:timeout ein:content-query-timeout
|
||||
:parser #'ein:json-read
|
||||
:sync ein:force-sync
|
||||
:success (apply-partially #'ein:query-contents-legacy-success path new-content callback)
|
||||
:error (apply-partially #'ein:content-query-contents-error url))
|
||||
new-content))
|
||||
(defun* ein:content-query-contents--complete (url-or-port path
|
||||
&key data symbol-status response
|
||||
&allow-other-keys
|
||||
&aux (resp-string (format "STATUS: %s DATA: %s" (request-response-status-code response) data)))
|
||||
(ein:log 'debug "ein:query-contents--complete %s" resp-string))
|
||||
|
||||
(defun* ein:content-query-contents--error (url-or-port path &key symbol-status response error-thrown &allow-other-keys)
|
||||
(ein:log 'error "ein:content-query-contents--error %s REQUEST-STATUS %s DATA %s" (concat (file-name-as-directory url-or-port) path) symbol-status (cdr error-thrown)))
|
||||
|
||||
|
||||
;; TODO: This is one place to check for redirects - update the url slot if so.
|
||||
;; Will need to pass the response object and check either request-response-history
|
||||
;; or request-response-url.
|
||||
(defun* ein:content-query-contents--success (url-or-port path callback
|
||||
&key data symbol-status response
|
||||
&allow-other-keys)
|
||||
(let (content)
|
||||
(if (<= (ein:need-ipython-version url-or-port) 2)
|
||||
(setq content (ein:new-content-legacy url-or-port path data))
|
||||
(setq content (ein:new-content url-or-port path data)))
|
||||
(ein:aif response
|
||||
(setf (ein:$content-url-or-port content) (ein:get-response-redirect it)))
|
||||
;; (if (length (request-response-history response))
|
||||
;; (let ((url (url-generic-parse-url (format "%s" (request-response-url response)))))
|
||||
;; (setf (ein:$content-url-or-port content) (format "%s://%s:%s"
|
||||
;; (url-type url)
|
||||
;; (url-host url)
|
||||
;; (url-port url)))))
|
||||
(when callback (funcall callback content))))
|
||||
|
||||
(defun ein:fix-legacy-content-data (data)
|
||||
(if (listp (car data))
|
||||
|
@ -131,49 +121,6 @@ global setting. For global setting and more information, see
|
|||
(plist-put data :path (plist-get data :name))
|
||||
(plist-put data :path (format "%s/%s" (plist-get data :path) (plist-get data :name))))))
|
||||
|
||||
(defun* ein:query-contents-legacy-success (path content callback &key data &allow-other-keys)
|
||||
(if (not (plist-get data :type))
|
||||
;; Content API in 2.x a bit inconsistent.
|
||||
(progn
|
||||
(setf (ein:$content-name content) (substring path (or (cl-position ?/ path) 0))
|
||||
(ein:$content-path content) path
|
||||
(ein:$content-type content) "directory"
|
||||
;;(ein:$content-created content) (plist-get data :created)
|
||||
;;(ein:$content-last-modified content) (plist-get data :last_modified)
|
||||
(ein:$content-format content) nil
|
||||
(ein:$content-writable content) nil
|
||||
(ein:$content-mimetype content) nil
|
||||
(ein:$content-raw-content content) (ein:fix-legacy-content-data data))
|
||||
(when callback
|
||||
(funcall callback content))
|
||||
content)
|
||||
(ein:new-content content callback :data data)))
|
||||
|
||||
;; TODO: This is one place to check for redirects - update the url slot if so.
|
||||
;; Will need to pass the response object and check either request-response-history
|
||||
;; or request-response-url.
|
||||
(defun* ein:new-content (content callback &key data response &allow-other-keys)
|
||||
(setf (ein:$content-name content) (plist-get data :name)
|
||||
(ein:$content-path content) (plist-get data :path)
|
||||
(ein:$content-type content) (plist-get data :type)
|
||||
(ein:$content-created content) (plist-get data :created)
|
||||
(ein:$content-last-modified content) (plist-get data :last_modified)
|
||||
(ein:$content-format content) (plist-get data :format)
|
||||
(ein:$content-writable content) (plist-get data :writable)
|
||||
(ein:$content-mimetype content) (plist-get data :mimetype)
|
||||
(ein:$content-raw-content content) (plist-get data :content))
|
||||
(ein:aif response
|
||||
(setf (ein:$content-url-or-port content) (ein:get-response-redirect it)))
|
||||
;; (if (length (request-response-history response))
|
||||
;; (let ((url (url-generic-parse-url (format "%s" (request-response-url response)))))
|
||||
;; (setf (ein:$content-url-or-port content) (format "%s://%s:%s"
|
||||
;; (url-type url)
|
||||
;; (url-host url)
|
||||
;; (url-port url)))))
|
||||
(when callback
|
||||
(funcall callback content))
|
||||
content)
|
||||
|
||||
(defun ein:content-to-json (content)
|
||||
(let ((path (if (>= (ein:$content-ipython-version content) 3)
|
||||
(ein:$content-path content)
|
||||
|
@ -196,63 +143,111 @@ global setting. For global setting and more information, see
|
|||
:ipython-version (ein:$notebook-api-version nb)
|
||||
:raw-content nb-content)))
|
||||
|
||||
|
||||
(defun* ein:content-query-contents-error (url retry-p packed &key symbol-status response &allow-other-keys)
|
||||
(ein:gc-complete-operation)
|
||||
(if (and (eql symbol-status 'parse-error)
|
||||
(not retry-p))
|
||||
(progn
|
||||
(message "Content list call failed, maybe because curl hasn't updated it's cookie jar yet? Let's try one more time....")
|
||||
(apply #'ein:content-query-contents packed))
|
||||
(progn
|
||||
(ein:log 'verbose
|
||||
"Error thrown: %S" (request-response-error-thrown response))
|
||||
(ein:log 'error
|
||||
"Content list call %s failed with status %s." url symbol-status))))
|
||||
|
||||
|
||||
;;; Managing/listing the content hierarchy
|
||||
|
||||
(defvar *ein:content-hierarchy* (make-hash-table :test #'equal))
|
||||
(defvar *ein:content-hierarchy* (make-hash-table :test #'equal)
|
||||
"Content tree keyed by URL-OR-PORT.")
|
||||
|
||||
(defun ein:get-content-hierarchy (url-or-port)
|
||||
(or (gethash url-or-port *ein:content-hierarchy*)
|
||||
(ein:refresh-content-hierarchy url-or-port)))
|
||||
(defun ein:content-need-hierarchy (url-or-port)
|
||||
"Callers assume ein:content-query-hierarchy succeeded. If not, nil."
|
||||
(ein:aif (gethash url-or-port *ein:content-hierarchy*) it
|
||||
(ein:log 'warn "No recorded content hierarchy for %s" url-or-port)
|
||||
nil))
|
||||
|
||||
(defun ein:make-content-hierarchy (path url-or-port)
|
||||
(let* ((node (ein:content-query-contents path url-or-port t))
|
||||
(active-sessions (make-hash-table :test 'equal))
|
||||
(items (ein:$content-raw-content node)))
|
||||
(ein:content-query-sessions active-sessions url-or-port t)
|
||||
(ein:flatten (loop for item in items
|
||||
for c = (make-ein:$content :url-or-port url-or-port)
|
||||
do (ein:new-content c nil :data item)
|
||||
(defun ein:new-content-legacy (url-or-port path data)
|
||||
"Content API in 2.x a bit inconsistent."
|
||||
(if (plist-get data :type)
|
||||
(ein:new-content url-or-port path data)
|
||||
(let ((content (make-ein:$content
|
||||
:url-or-port url-or-port
|
||||
:ipython-version (ein:need-ipython-version url-or-port)
|
||||
:path path)))
|
||||
(setf (ein:$content-name content) (substring path (or (cl-position ?/ path) 0))
|
||||
(ein:$content-path content) path
|
||||
(ein:$content-type content) "directory"
|
||||
;;(ein:$content-created content) (plist-get data :created)
|
||||
;;(ein:$content-last-modified content) (plist-get data :last_modified)
|
||||
(ein:$content-format content) nil
|
||||
(ein:$content-writable content) nil
|
||||
(ein:$content-mimetype content) nil
|
||||
(ein:$content-raw-content content) (ein:fix-legacy-content-data data))
|
||||
content)))
|
||||
|
||||
(defun ein:new-content (url-or-port path data)
|
||||
;; data is like (:size 72 :content nil :writable t :path Untitled7.ipynb :name Untitled7.ipynb :type notebook)
|
||||
(let ((content (make-ein:$content
|
||||
:url-or-port url-or-port
|
||||
:ipython-version (ein:need-ipython-version url-or-port)
|
||||
:path path)))
|
||||
(setf (ein:$content-name content) (plist-get data :name)
|
||||
(ein:$content-path content) (plist-get data :path)
|
||||
(ein:$content-type content) (plist-get data :type)
|
||||
(ein:$content-created content) (plist-get data :created)
|
||||
(ein:$content-last-modified content) (plist-get data :last_modified)
|
||||
(ein:$content-format content) (plist-get data :format)
|
||||
(ein:$content-writable content) (plist-get data :writable)
|
||||
(ein:$content-mimetype content) (plist-get data :mimetype)
|
||||
(ein:$content-raw-content content) (plist-get data :content))
|
||||
content))
|
||||
|
||||
(defun ein:content-query-hierarchy* (url-or-port path callback sessions content)
|
||||
"Returns list (tree) of content objects"
|
||||
(lexical-let* ((url-or-port url-or-port)
|
||||
(path path)
|
||||
(callback callback)
|
||||
(items (ein:$content-raw-content content))
|
||||
(directories (loop for item in items
|
||||
if (string= "directory" (plist-get item :type))
|
||||
collect (ein:new-content url-or-port path item)
|
||||
end))
|
||||
(others (loop for item in items
|
||||
with c0
|
||||
if (not (string= "directory" (plist-get item :type)))
|
||||
do (setf c0 (ein:new-content url-or-port path item))
|
||||
(setf (ein:$content-session-p c0)
|
||||
(gethash (ein:$content-path c0) sessions))
|
||||
and collect c0
|
||||
end)))
|
||||
(deferred:$
|
||||
(apply #'deferred:parallel
|
||||
(loop for c0 in directories
|
||||
collect
|
||||
(cond ((string= (ein:$content-type c) "directory")
|
||||
(cons c
|
||||
(ein:make-content-hierarchy (ein:$content-path c) url-or-port)))
|
||||
(t (progn
|
||||
(setf (ein:$content-session-p c)
|
||||
(gethash (ein:$content-path c) active-sessions))
|
||||
c)))))))
|
||||
(lexical-let ((c0 c0) (d0 (deferred:new #'identity)))
|
||||
(ein:content-query-contents
|
||||
url-or-port
|
||||
(ein:$content-path c0)
|
||||
(apply-partially #'ein:content-query-hierarchy* url-or-port (ein:$content-path c0) (lambda (tree) (deferred:callback-post d0 (cons c0 tree))) sessions))
|
||||
d0)))
|
||||
(deferred:nextc it
|
||||
(lambda (tree)
|
||||
(let ((result (append others tree)))
|
||||
(if (string= path "")
|
||||
(setf (gethash url-or-port *ein:content-hierarchy*) (-flatten result)))
|
||||
(funcall callback result)))))))
|
||||
|
||||
(defun ein:refresh-content-hierarchy (&optional url-or-port)
|
||||
(let ((url-or-port (or url-or-port (ein:default-url-or-port))))
|
||||
(setf (gethash url-or-port *ein:content-hierarchy*)
|
||||
(ein:make-content-hierarchy "" url-or-port))))
|
||||
(defun ein:content-query-hierarchy (url-or-port callback)
|
||||
"Send for content hierarchy of URL-OR-PORT with CALLBACK arity 1 for content hierarchy"
|
||||
(lexical-let ((url-or-port url-or-port)
|
||||
(callback callback))
|
||||
(ein:content-query-sessions
|
||||
url-or-port
|
||||
(lambda (sessions)
|
||||
(ein:content-query-contents url-or-port "" (apply-partially #'ein:content-query-hierarchy* url-or-port "" callback sessions))))))
|
||||
|
||||
|
||||
;;; Save Content
|
||||
|
||||
(defun ein:content-save-legacy (content &optional callback cbargs errcb errcbargs)
|
||||
(ein:query-singleton-ajax
|
||||
(list 'content-save (ein:$content-url-or-port content) (ein:$content-path content))
|
||||
(ein:content-url-legacy content)
|
||||
:type "PUT"
|
||||
:headers '(("Content-Type" . "application/json"))
|
||||
:timeout ein:content-query-timeout
|
||||
:data (ein:content-to-json content)
|
||||
:success (apply-partially #'ein:content-save-success callback cbargs)
|
||||
:error (apply-partially #'ein:content-save-error (ein:content-url-legacy content) errcb errcbargs)))
|
||||
(list 'content-save (ein:$content-url-or-port content) (ein:$content-path content))
|
||||
(ein:content-url content)
|
||||
:type "PUT"
|
||||
:headers '(("Content-Type" . "application/json"))
|
||||
:timeout ein:content-query-timeout
|
||||
:data (ein:content-to-json content)
|
||||
:success (apply-partially #'ein:content-save-success callback cbargs)
|
||||
:error (apply-partially #'ein:content-save-error (ein:content-url content) errcb errcbargs)))
|
||||
|
||||
(defun ein:content-save (content &optional callback cbargs errcb errcbargs)
|
||||
(if (>= (ein:$content-ipython-version content) 3)
|
||||
|
@ -283,12 +278,13 @@ global setting. For global setting and more information, see
|
|||
|
||||
;;; Rename Content
|
||||
|
||||
|
||||
(defun ein:content-legacy-rename (content new-path callback cbargs)
|
||||
(let ((path (substring new-path 0 (or (position ?/ new-path :from-end t) 0)))
|
||||
(name (substring new-path (or (position ?/ new-path :from-end t) 0))))
|
||||
(ein:query-singleton-ajax
|
||||
(list 'content-rename (ein:$content-url-or-port content) (ein:$content-path content))
|
||||
(ein:content-url-legacy content)
|
||||
(ein:content-url content)
|
||||
:type "PATCH"
|
||||
:data (json-encode `((name . ,name)
|
||||
(path . ,path)))
|
||||
|
@ -333,38 +329,44 @@ global setting. For global setting and more information, see
|
|||
|
||||
;;; Sessions
|
||||
|
||||
(defun ein:content-query-sessions (session-hash url-or-port &optional force-sync)
|
||||
(unless force-sync
|
||||
(setq force-sync ein:force-sync))
|
||||
(ein:query-singleton-ajax
|
||||
(list 'content-query-sessions)
|
||||
(ein:url url-or-port "api/sessions")
|
||||
:type "GET"
|
||||
:parser #'ein:json-read
|
||||
:success (apply-partially #'ein:content-query-sessions-success session-hash url-or-port)
|
||||
:error (apply-partially #'ein:content-query-sessions-error session-hash)
|
||||
:sync force-sync))
|
||||
|
||||
(defun* ein:content-query-sessions-success (session-hash url-or-port &key data &allow-other-keys)
|
||||
(defun ein:content-query-sessions (url-or-port callback)
|
||||
"Register CALLBACK of arity 1 to retrieve the sessions"
|
||||
(ein:query-singleton-ajax
|
||||
(list 'content-query-sessions url-or-port)
|
||||
(ein:url url-or-port "api/sessions")
|
||||
:type "GET"
|
||||
:parser #'ein:json-read
|
||||
:complete (apply-partially #'ein:content-query-sessions--complete url-or-port callback)
|
||||
:success (apply-partially #'ein:content-query-sessions--success url-or-port callback)
|
||||
:error (apply-partially #'ein:content-query-sessions--error url-or-port)
|
||||
:sync ein:force-sync))
|
||||
|
||||
(defun* ein:content-query-sessions--success (url-or-port callback &key data &allow-other-keys)
|
||||
(cl-flet ((read-name (nb-json)
|
||||
(if (= (ein:query-ipython-version url-or-port) 2)
|
||||
(if (= (ein:need-ipython-version url-or-port) 2)
|
||||
(if (string= (plist-get nb-json :path) "")
|
||||
(plist-get nb-json :name)
|
||||
(format "%s/%s" (plist-get nb-json :path) (plist-get nb-json :name)))
|
||||
(plist-get nb-json :path))))
|
||||
(clrhash session-hash)
|
||||
(dolist (s data)
|
||||
(setf (gethash (read-name (plist-get s :notebook)) session-hash)
|
||||
(cons (plist-get s :id) (plist-get s :kernel))))
|
||||
session-hash))
|
||||
(let ((session-hash (make-hash-table :test 'equal)))
|
||||
(dolist (s data (funcall callback session-hash))
|
||||
(setf (gethash (read-name (plist-get s :notebook)) session-hash)
|
||||
(cons (plist-get s :id) (plist-get s :kernel)))))))
|
||||
|
||||
(defun* ein:content-query-sessions-error (session-hash &key symbol-status response &allow-other-keys)
|
||||
(clrhash session-hash)
|
||||
(ein:log 'error "Session query failed with status %s (%s)." symbol-status response))
|
||||
(defun* ein:content-query-sessions--error (url-or-port &key error-thrown &allow-other-keys)
|
||||
(ein:log 'error "ein:content-query-sessions--error %s: ERROR %s DATA %s" url-or-port (car error-thrown) (cdr error-thrown)))
|
||||
|
||||
(defun* ein:content-query-sessions--complete (url-or-port 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:query-sessions--complete %s" resp-string))
|
||||
|
||||
|
||||
;;; Checkpoints
|
||||
|
||||
|
||||
(defun ein:content-query-checkpoints (content &optional callback cbargs)
|
||||
(let* ((url (ein:content-url content "checkpoints")))
|
||||
(ein:query-singleton-ajax
|
||||
|
@ -428,6 +430,7 @@ global setting. For global setting and more information, see
|
|||
|
||||
;;; Uploads
|
||||
|
||||
|
||||
(defun ein:get-local-file (path)
|
||||
"If path exists, get contents and try to guess type of file (one of file, notebook, or directory)
|
||||
and content format (one of json, text, or base64)."
|
||||
|
|
119
lisp/ein-core.el
119
lisp/ein-core.el
|
@ -127,50 +127,105 @@ the source is in git repository."
|
|||
(concat ein:version "." it)
|
||||
ein:version))
|
||||
|
||||
(defvar *running-ipython-version* (make-hash-table :test #'equal))
|
||||
|
||||
;;; Server attribute getters. Not sure if these should be here.
|
||||
|
||||
(defun ein:get-ipython-major-version (vstr)
|
||||
(defvar *ein:ipython-version* (make-hash-table :test #'equal)
|
||||
"url-or-port to major ipython version")
|
||||
|
||||
(defvar *ein:kernelspecs* (make-hash-table :test #'equal)
|
||||
"url-or-port to kernelspecs")
|
||||
|
||||
(defun ein:need-kernelspecs (url-or-port)
|
||||
"Callers assume ein:query-kernelspecs succeeded. If not, nil."
|
||||
(ein:aif (gethash url-or-port *ein:kernelspecs*) it
|
||||
(ein:log 'warn "No recorded kernelspecs for %s" url-or-port)
|
||||
nil))
|
||||
|
||||
(defun ein:query-kernelspecs (url-or-port callback)
|
||||
"Send for kernelspecs of URL-OR-PORT with CALLBACK arity 0 (just a semaphore)"
|
||||
(ein:query-singleton-ajax
|
||||
(list 'ein:query-kernelspecs url-or-port)
|
||||
(ein:url url-or-port "api/kernelspecs")
|
||||
:type "GET"
|
||||
:timeout ein:content-query-timeout
|
||||
:parser 'ein:json-read
|
||||
:sync ein:force-sync
|
||||
:complete (apply-partially #'ein:query-kernelspecs--complete url-or-port callback)
|
||||
:success (apply-partially #'ein:query-kernelspecs--success url-or-port)
|
||||
:error (apply-partially #'ein:query-kernelspecs--error url-or-port)))
|
||||
|
||||
(defun* ein:query-kernelspecs--success (url-or-port
|
||||
&key data symbol-status response
|
||||
&allow-other-keys)
|
||||
(let ((ks (list :default (plist-get data :default)))
|
||||
(specs (ein:plist-iter (plist-get data :kernelspecs))))
|
||||
(setf (gethash url-or-port *ein:kernelspecs*)
|
||||
(ein:flatten (dolist (spec specs ks)
|
||||
(let ((name (car spec))
|
||||
(info (cdr spec)))
|
||||
(push (list name (make-ein:$kernelspec :name (plist-get info :name)
|
||||
:display-name (plist-get (plist-get info :spec)
|
||||
:display_name)
|
||||
:resources (plist-get info :resources)
|
||||
:language (plist-get (plist-get info :spec)
|
||||
:language)
|
||||
:spec (plist-get info :spec)))
|
||||
ks)))))))
|
||||
|
||||
(defun* ein:query-kernelspecs--error (url-or-port &key error-thrown &allow-other-keys)
|
||||
(ein:log 'error
|
||||
"ein:query-kernelspecs-error %s: ERROR %s DATA %s" url-or-port (car error-thrown) (cdr error-thrown)))
|
||||
|
||||
(defun* ein:query-kernelspecs--complete (url-or-port 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:query-kernelspecs--complete %s" resp-string)
|
||||
(when callback (funcall callback)))
|
||||
|
||||
(defsubst ein:get-ipython-major-version (vstr)
|
||||
(if vstr
|
||||
(string-to-number (car (split-string vstr "\\.")))
|
||||
(if (>= ein:log-level (ein:log-level-name-to-int 'debug))
|
||||
(throw 'error "Null value passed to ein:get-ipython-major-version.")
|
||||
(ein:log 'warn "Null value passed to ein:get-ipython-major-version."))))
|
||||
|
||||
(defun ein:need-ipython-version (url-or-port)
|
||||
"Callers assume ein:query-ipython-version succeeded. If not, we hardcode a guess."
|
||||
(ein:aif (gethash url-or-port *ein:ipython-version*) it
|
||||
(ein:log 'warn "No recorded ipython version for %s" url-or-port)
|
||||
5))
|
||||
|
||||
;; TODO: Use symbols instead of numbers for ipython version ('jupyter and 'legacy)?
|
||||
(defun ein:query-ipython-version (&optional url-or-port force)
|
||||
(ein:aif (and (not force) (gethash (or url-or-port (ein:default-url-or-port)) *running-ipython-version*))
|
||||
it
|
||||
(let ((resp (request
|
||||
(ein:jupyterhub-correct-query-url-maybe (ein:url (or url-or-port
|
||||
(ein:default-url-or-port))
|
||||
"api"))
|
||||
:parser #'(lambda ()
|
||||
(ignore-errors
|
||||
(ein:json-read)))
|
||||
:timeout 5.0
|
||||
:sync t)))
|
||||
(if (eql 408 (request-response-status-code resp))
|
||||
(progn
|
||||
(ein:log 'blather "Version request timed out, could be the server is still warming up. Assuming we are working Jupyter 4.x, and will recheck later.")
|
||||
4)
|
||||
(if (eql 404 (request-response-status-code resp))
|
||||
(progn
|
||||
(ein:log 'blather "Version api not implemented, assuming we are working with IPython 2.x")
|
||||
(setf (gethash url-or-port *running-ipython-version*) 2))
|
||||
(condition-case nil
|
||||
(if (plist-get (request-response-data resp) :version)
|
||||
(setf (gethash url-or-port *running-ipython-version*)
|
||||
(ein:get-ipython-major-version (plist-get (request-response-data resp) :version)))
|
||||
(progn
|
||||
(sit-for 0.1)
|
||||
(ein:query-ipython-version url-or-port t)))
|
||||
(error (ein:force-ipython-version-check))))))))
|
||||
(defun ein:query-ipython-version (url-or-port callback)
|
||||
"Send for ipython version of URL-OR-PORT with CALLBACK arity 0 (just a semaphore)"
|
||||
(ein:query-singleton-ajax
|
||||
(list 'query-ipython-version url-or-port)
|
||||
(ein:jupyterhub-correct-query-url-maybe
|
||||
(ein:url url-or-port "api"))
|
||||
:parser #'ein:json-read
|
||||
:sync ein:force-sync
|
||||
:complete (apply-partially #'ein:query-ipython-version--complete url-or-port callback)))
|
||||
|
||||
(defun* ein:query-ipython-version--complete (url-or-port 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:query-ipython-version--complete %s" resp-string)
|
||||
(ein:aif (plist-get data :version)
|
||||
(setf (gethash url-or-port *ein:ipython-version*)
|
||||
(ein:get-ipython-major-version it))
|
||||
(case (request-response-status-code response)
|
||||
(404 (ein:log 'warn "ipython version api not implemented")
|
||||
(setf (gethash url-or-port *ein:ipython-version*) 2))
|
||||
(t (ein:log 'warn "ipython version currently unknowable"))))
|
||||
(when callback (funcall callback)))
|
||||
|
||||
(defun ein:force-ipython-version-check ()
|
||||
(interactive)
|
||||
(maphash #'(lambda (url-or-port --ignore--)
|
||||
(ein:query-ipython-version url-or-port t))
|
||||
*running-ipython-version*))
|
||||
(ein:query-ipython-version url-or-port nil))
|
||||
*ein:ipython-version*))
|
||||
|
||||
|
||||
;;; File name translation (tramp support)
|
||||
|
|
|
@ -119,6 +119,11 @@ When the prefix argument is given, debugging support for websocket
|
|||
callback (`websocket-callback-debug-on-error') is enabled."
|
||||
(interactive "P")
|
||||
(setq debug-on-error t)
|
||||
;; only use these with deferred:sync! they cause strange failures otherwise!
|
||||
;; (setq deferred:debug-on-signal t)
|
||||
;; (setq deferred:debug t)
|
||||
(setq request-log-level (quote debug))
|
||||
(setq request-message-level (quote verbose))
|
||||
(setq websocket-debug t)
|
||||
(when ws-callback
|
||||
(setq websocket-callback-debug-on-error t))
|
||||
|
@ -130,10 +135,14 @@ callback (`websocket-callback-debug-on-error') is enabled."
|
|||
|
||||
;;;###autoload
|
||||
(defun ein:dev-stop-debug ()
|
||||
"Disable debugging support enabled by `ein:dev-start-debug'."
|
||||
"Inverse of `ein:dev-start-debug'. Hard to maintain because it needs to match start"
|
||||
(interactive)
|
||||
(setq debug-on-error nil)
|
||||
(setq websocket-debug nil)
|
||||
(setq deferred:debug-on-signal nil)
|
||||
(setq deferred:debug nil)
|
||||
(setq request-log-level -1)
|
||||
(setq request-message-level 'warn)
|
||||
(setq websocket-callback-debug-on-error nil)
|
||||
(setq ein:debug nil)
|
||||
(ein:log-set-level 'verbose)
|
||||
|
|
|
@ -35,8 +35,7 @@
|
|||
path))
|
||||
|
||||
(defun ein:file-open (url-or-port path)
|
||||
(ein:content-query-contents path url-or-port nil
|
||||
#'ein:file-open-finish))
|
||||
(ein:content-query-contents url-or-port path #'ein:file-open-finish))
|
||||
|
||||
(defun ein:file-open-finish (content)
|
||||
(with-current-buffer (get-buffer-create (ein:file-buffer-name (ein:$content-url-or-port content)
|
||||
|
|
|
@ -174,11 +174,11 @@ the log of the running jupyter server."
|
|||
(setf *ein:last-jupyter-command* server-cmd-path
|
||||
*ein:last-jupyter-directory* notebook-directory)
|
||||
(if (buffer-live-p (get-buffer ein:jupyter-server-buffer-name))
|
||||
(message "Notebook session is already running, check the contents of %s"
|
||||
(ein:log 'info "Notebook session is already running, check the contents of %s"
|
||||
ein:jupyter-server-buffer-name))
|
||||
(add-hook 'kill-emacs-hook #'(lambda ()
|
||||
(ein:jupyter-server-stop t)))
|
||||
(message "Starting notebook server in directory: %s" notebook-directory)
|
||||
(ein:log 'info "Starting notebook server in directory: %s" notebook-directory)
|
||||
(lexical-let ((no-login-after-start-p no-login-after-start-p)
|
||||
(no-popup no-popup)
|
||||
(proc (ein:jupyter-server--run ein:jupyter-server-buffer-name
|
||||
|
@ -204,7 +204,6 @@ the log of the running jupyter server."
|
|||
(progn
|
||||
(warn "[EIN] Jupyter server failed to start, cancelling operation.")
|
||||
(ein:jupyter-server-stop t))
|
||||
(ein:force-ipython-version-check)
|
||||
(unless no-login-p
|
||||
(ein:jupyter-server-login-and-open no-popup))))))))
|
||||
|
||||
|
@ -245,8 +244,8 @@ there is no running server then no action will be taken.
|
|||
(let ((process (get-buffer-process (current-buffer))))
|
||||
(when process
|
||||
(let ((pid (process-id process)))
|
||||
(ein:log 'info "Signaled %s with pid %s" process pid)
|
||||
(message "Stopped Jupyter notebook server.")
|
||||
(ein:log 'verbose "Signaled %s with pid %s" process pid)
|
||||
(ein:log 'info "Stopped Jupyter notebook server.")
|
||||
(signal-process (process-id process) 15)))))
|
||||
(when log
|
||||
(with-current-buffer ein:jupyter-server-buffer-name
|
||||
|
|
|
@ -3,62 +3,19 @@
|
|||
;;; Code:
|
||||
|
||||
|
||||
;;;### (autoloads nil "ein-ac" "ein-ac.el" (0 0 0 0))
|
||||
;;; Generated autoloads from ein-ac.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-ac" '("ein:")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-cell" "ein-cell.el" (0 0 0 0))
|
||||
;;; Generated autoloads from ein-cell.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-cell" '("ein:")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-cell-edit" "ein-cell-edit.el" (0 0 0 0))
|
||||
;;; Generated autoloads from ein-cell-edit.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-cell-edit" '("ein:")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-cell-output" "ein-cell-output.el" (0 0
|
||||
;;;;;; 0 0))
|
||||
;;; Generated autoloads from ein-cell-output.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-cell-output" '("ein:")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-classes" "ein-classes.el" (0 0 0 0))
|
||||
;;; Generated autoloads from ein-classes.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-classes" '("ein:")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-company" "ein-company.el" (0 0 0 0))
|
||||
;;;### (autoloads nil "ein-company" "ein-company.el" (23475 34241
|
||||
;;;;;; 887134 78000))
|
||||
;;; Generated autoloads from ein-company.el
|
||||
|
||||
(autoload 'ein:company-backend "ein-company" "\
|
||||
|
||||
|
||||
\(fn COMMAND &optional ARG &rest IGNORE)" t nil)
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-company" '("ein:company-handle-doc-buffer")))
|
||||
\(fn COMMAND &optional ARG &rest _)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-completer" "ein-completer.el" (0 0 0 0))
|
||||
;;; Generated autoloads from ein-completer.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-completer" '("ein:complete")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-connect" "ein-connect.el" (0 0 0 0))
|
||||
;;;### (autoloads nil "ein-connect" "ein-connect.el" (23468 61365
|
||||
;;;;;; 135112 242000))
|
||||
;;; Generated autoloads from ein-connect.el
|
||||
|
||||
(autoload 'ein:connect-to-notebook-command "ein-connect" "\
|
||||
|
@ -92,11 +49,10 @@ notebook.
|
|||
|
||||
\(fn)" nil nil)
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-connect" '("ein:")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-console" "ein-console.el" (0 0 0 0))
|
||||
;;;### (autoloads nil "ein-console" "ein-console.el" (23468 61365
|
||||
;;;;;; 135112 242000))
|
||||
;;; Generated autoloads from ein-console.el
|
||||
|
||||
(autoload 'ein:console-open "ein-console" "\
|
||||
|
@ -113,26 +69,10 @@ It should be possible to support python-mode.el. Patches are welcome!
|
|||
|
||||
\(fn)" t nil)
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-console" '("ein:console-")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-contents-api" "ein-contents-api.el" (0
|
||||
;;;;;; 0 0 0))
|
||||
;;; Generated autoloads from ein-contents-api.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-contents-api" '("ein:" "update-content-path" "*ein:content-hierarchy*")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-core" "ein-core.el" (0 0 0 0))
|
||||
;;; Generated autoloads from ein-core.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-core" '("*running-ipython-version*" "ein:")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-dev" "ein-dev.el" (0 0 0 0))
|
||||
;;;### (autoloads nil "ein-dev" "ein-dev.el" (23477 31845 251244
|
||||
;;;;;; 240000))
|
||||
;;; Generated autoloads from ein-dev.el
|
||||
|
||||
(autoload 'ein:dev-insert-mode-map "ein-dev" "\
|
||||
|
@ -148,7 +88,7 @@ callback (`websocket-callback-debug-on-error') is enabled.
|
|||
\(fn &optional WS-CALLBACK)" t nil)
|
||||
|
||||
(autoload 'ein:dev-stop-debug "ein-dev" "\
|
||||
Disable debugging support enabled by `ein:dev-start-debug'.
|
||||
Inverse of `ein:dev-start-debug'. Hard to maintain. Not really used.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
|
@ -157,25 +97,10 @@ Open a buffer with bug report template.
|
|||
|
||||
\(fn)" t nil)
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-dev" '("ein:")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-events" "ein-events.el" (0 0 0 0))
|
||||
;;; Generated autoloads from ein-events.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-events" '("ein:events-")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-file" "ein-file.el" (0 0 0 0))
|
||||
;;; Generated autoloads from ein-file.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-file" '("ein:" "*ein:file-buffername-template*")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-helm" "ein-helm.el" (0 0 0 0))
|
||||
;;;### (autoloads nil "ein-helm" "ein-helm.el" (23064 59027 190301
|
||||
;;;;;; 971000))
|
||||
;;; Generated autoloads from ein-helm.el
|
||||
|
||||
(autoload 'anything-ein-kernel-history "ein-helm" "\
|
||||
|
@ -198,18 +123,10 @@ Choose opened notebook using helm interface.
|
|||
|
||||
\(fn)" t nil)
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-helm" '("ein:helm-")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-hy" "ein-hy.el" (0 0 0 0))
|
||||
;;; Generated autoloads from ein-hy.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-hy" '("ein:cell-")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-iexec" "ein-iexec.el" (0 0 0 0))
|
||||
;;;### (autoloads nil "ein-iexec" "ein-iexec.el" (23064 59027 190301
|
||||
;;;;;; 971000))
|
||||
;;; Generated autoloads from ein-iexec.el
|
||||
|
||||
(autoload 'ein:iexec-mode "ein-iexec" "\
|
||||
|
@ -219,11 +136,10 @@ change in its input area.
|
|||
|
||||
\(fn &optional ARG)" t nil)
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-iexec" '("ein:iexec-")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-inspector" "ein-inspector.el" (0 0 0 0))
|
||||
;;;### (autoloads nil "ein-inspector" "ein-inspector.el" (23475 34241
|
||||
;;;;;; 887134 78000))
|
||||
;;; Generated autoloads from ein-inspector.el
|
||||
|
||||
(autoload 'ein:inspect-object "ein-inspector" "\
|
||||
|
@ -231,19 +147,10 @@ change in its input area.
|
|||
|
||||
\(fn KERNEL OBJECT)" t nil)
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-inspector" '("ein:")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-ipdb" "ein-ipdb.el" (0 0 0 0))
|
||||
;;; Generated autoloads from ein-ipdb.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-ipdb" '("ein:" "*ein:ipdb-")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-ipynb-mode" "ein-ipynb-mode.el" (0 0 0
|
||||
;;;;;; 0))
|
||||
;;;### (autoloads nil "ein-ipynb-mode" "ein-ipynb-mode.el" (23064
|
||||
;;;;;; 59027 194301 980000))
|
||||
;;; Generated autoloads from ein-ipynb-mode.el
|
||||
|
||||
(autoload 'ein:ipynb-mode "ein-ipynb-mode" "\
|
||||
|
@ -253,11 +160,10 @@ A simple mode for ipynb file.
|
|||
|
||||
(add-to-list 'auto-mode-alist '(".*\\.ipynb\\'" . ein:ipynb-mode))
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-ipynb-mode" '("ein:ipynb-parent-mode")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-jedi" "ein-jedi.el" (0 0 0 0))
|
||||
;;;### (autoloads nil "ein-jedi" "ein-jedi.el" (23468 61365 139112
|
||||
;;;;;; 317000))
|
||||
;;; Generated autoloads from ein-jedi.el
|
||||
|
||||
(autoload 'ein:jedi-complete "ein-jedi" "\
|
||||
|
@ -282,33 +188,10 @@ To use EIN and Jedi together, add the following in your Emacs setup before loadi
|
|||
|
||||
\(fn)" nil nil)
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-jedi" '("ein:jedi-")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-junk" "ein-junk.el" (0 0 0 0))
|
||||
;;; Generated autoloads from ein-junk.el
|
||||
|
||||
(autoload 'ein:junk-new "ein-junk" "\
|
||||
Open a notebook to try random thing.
|
||||
Notebook name is determined based on
|
||||
`ein:junk-notebook-name-template'.
|
||||
|
||||
When prefix argument is given, it asks URL or port to use.
|
||||
|
||||
\(fn NAME KERNELSPEC URL-OR-PORT)" t nil)
|
||||
|
||||
(autoload 'ein:junk-rename "ein-junk" "\
|
||||
Rename the current notebook based on `ein:junk-notebook-name-template'
|
||||
and save it immediately.
|
||||
|
||||
\(fn NAME)" t nil)
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-junk" '("ein:junk-notebook-name")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-jupyter" "ein-jupyter.el" (0 0 0 0))
|
||||
;;;### (autoloads nil "ein-jupyter" "ein-jupyter.el" (23478 35725
|
||||
;;;;;; 832413 900000))
|
||||
;;; Generated autoloads from ein-jupyter.el
|
||||
|
||||
(autoload 'ein:jupyter-server-login-and-open "ein-jupyter" "\
|
||||
|
@ -349,14 +232,12 @@ Stop a running jupyter notebook server.
|
|||
Use this command to stop a running jupyter notebook server. If
|
||||
there is no running server then no action will be taken.
|
||||
|
||||
\(fn &optional FORCE)" t nil)
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-jupyter" '("%ein:jupyter-server-session%" "*ein:" "ein:jupyter-")))
|
||||
\(fn &optional FORCE LOG)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-jupyterhub" "ein-jupyterhub.el" (0 0 0
|
||||
;;;;;; 0))
|
||||
;;;### (autoloads nil "ein-jupyterhub" "ein-jupyterhub.el" (23468
|
||||
;;;;;; 61365 139112 317000))
|
||||
;;; Generated autoloads from ein-jupyterhub.el
|
||||
|
||||
(autoload 'ein:jupyterhub-connect "ein-jupyterhub" "\
|
||||
|
@ -364,44 +245,20 @@ Log on to a jupyterhub server using PAM authentication. Requires jupyterhub vers
|
|||
|
||||
\(fn URL USER PASSWORD)" t nil)
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-jupyterhub" '("ein:j")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-kernel" "ein-kernel.el" (0 0 0 0))
|
||||
;;;### (autoloads nil "ein-kernel" "ein-kernel.el" (23475 34241 891134
|
||||
;;;;;; 103000))
|
||||
;;; Generated autoloads from ein-kernel.el
|
||||
|
||||
(defalias 'ein:kernel-url-or-port 'ein:$kernel-url-or-port)
|
||||
|
||||
(defalias 'ein:kernel-id 'ein:$kernel-kernel-id)
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-kernel" '("ein:" "kernel-restart-try-count" "max-kernel-restart-try-count")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-kernelinfo" "ein-kernelinfo.el" (0 0 0
|
||||
;;;;;; 0))
|
||||
;;; Generated autoloads from ein-kernelinfo.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-kernelinfo" '("ein:kernelinfo")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-kill-ring" "ein-kill-ring.el" (0 0 0 0))
|
||||
;;; Generated autoloads from ein-kill-ring.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-kill-ring" '("ein:")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-log" "ein-log.el" (0 0 0 0))
|
||||
;;; Generated autoloads from ein-log.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-log" '("ein:")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-multilang" "ein-multilang.el" (0 0 0 0))
|
||||
;;;### (autoloads nil "ein-multilang" "ein-multilang.el" (23468 61365
|
||||
;;;;;; 139112 317000))
|
||||
;;; Generated autoloads from ein-multilang.el
|
||||
|
||||
(autoload 'ein:notebook-multilang-mode "ein-multilang" "\
|
||||
|
@ -409,47 +266,39 @@ Notebook mode with multiple language fontification.
|
|||
|
||||
\(fn)" t nil)
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-multilang" '("ein:" "python-imenu-format-parent-item-jump-label")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-multilang-fontify" "ein-multilang-fontify.el"
|
||||
;;;;;; (0 0 0 0))
|
||||
;;; Generated autoloads from ein-multilang-fontify.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-multilang-fontify" '("ein:mlf-")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-node" "ein-node.el" (0 0 0 0))
|
||||
;;; Generated autoloads from ein-node.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-node" '("ein:")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-notebook" "ein-notebook.el" (0 0 0 0))
|
||||
;;;### (autoloads nil "ein-notebook" "ein-notebook.el" (23478 25882
|
||||
;;;;;; 960574 643000))
|
||||
;;; Generated autoloads from ein-notebook.el
|
||||
|
||||
(autoload 'ein:junk-new "ein-notebook" "\
|
||||
Open a notebook to try random thing.
|
||||
Notebook name is determined based on
|
||||
`ein:junk-notebook-name-template'.
|
||||
|
||||
When prefix argument is given, it asks URL or port to use.
|
||||
|
||||
\(fn NAME KERNELSPEC URL-OR-PORT)" t nil)
|
||||
|
||||
(autoload 'ein:junk-rename "ein-notebook" "\
|
||||
Rename the current notebook based on `ein:junk-notebook-name-template'
|
||||
and save it immediately.
|
||||
|
||||
\(fn NAME)" t nil)
|
||||
|
||||
(defalias 'ein:notebook-name 'ein:$notebook-notebook-name)
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-notebook" '("ein:")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-notebooklist" "ein-notebooklist.el" (0
|
||||
;;;;;; 0 0 0))
|
||||
;;;### (autoloads nil "ein-notebooklist" "ein-notebooklist.el" (23478
|
||||
;;;;;; 30232 414267 512000))
|
||||
;;; Generated autoloads from ein-notebooklist.el
|
||||
|
||||
(autoload 'ein:notebooklist-open "ein-notebooklist" "\
|
||||
Open notebook list buffer.
|
||||
|
||||
\(fn &optional URL-OR-PORT PATH NO-POPUP)" t nil)
|
||||
|
||||
(autoload 'ein:notebooklist-refresh-kernelspecs "ein-notebooklist" "\
|
||||
|
||||
|
||||
\(fn &optional URL-OR-PORT)" t nil)
|
||||
\(fn URL-OR-PORT &optional PATH NO-POPUP RESYNC)" t nil)
|
||||
|
||||
(autoload 'ein:notebooklist-enable-keepalive "ein-notebooklist" "\
|
||||
Enable periodic calls to the notebook server to keep long running sessions from expiring.
|
||||
|
@ -470,7 +319,7 @@ Disable the notebooklist keepalive calls to the jupyter notebook server.
|
|||
(autoload 'ein:notebooklist-reload "ein-notebooklist" "\
|
||||
Reload current Notebook list.
|
||||
|
||||
\(fn &optional NOTEBOOKLIST)" t nil)
|
||||
\(fn NOTEBOOKLIST &optional RESYNC)" t nil)
|
||||
|
||||
(autoload 'ein:notebooklist-upload-file "ein-notebooklist" "\
|
||||
|
||||
|
@ -537,19 +386,10 @@ on all the notebooks opened from the current notebooklist.
|
|||
|
||||
\(fn NEW-URL-OR-PORT)" t nil)
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-notebooklist" '("ein:" "generate-breadcrumbs" "render-")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-notification" "ein-notification.el" (0
|
||||
;;;;;; 0 0 0))
|
||||
;;; Generated autoloads from ein-notification.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-notification" '("ein:")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-org" "ein-org.el" (0 0 0 0))
|
||||
;;;### (autoloads nil "ein-org" "ein-org.el" (23468 61365 139112
|
||||
;;;;;; 317000))
|
||||
;;; Generated autoloads from ein-org.el
|
||||
|
||||
(autoload 'ein:org-open "ein-org" "\
|
||||
|
@ -582,27 +422,10 @@ node `(org) External links' and Info node `(org) Search options'
|
|||
|
||||
(eval-after-load "org" '(if (fboundp 'org-link-set-parameters) (org-link-set-parameters "ipynb" :follow 'ein:org-open :help-echo "Open ipython notebook." :store 'ein:org-store-link) (org-add-link-type "ipynb" :follow 'ein:org-open) (add-hook 'org-store-link-functions 'ein:org-store-link)))
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-org" '(#("ein:org-goto-link" 0 17 (fontified nil)))))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-output-area" "ein-output-area.el" (0 0
|
||||
;;;;;; 0 0))
|
||||
;;; Generated autoloads from ein-output-area.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-output-area" '("ein:")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-pager" "ein-pager.el" (0 0 0 0))
|
||||
;;; Generated autoloads from ein-pager.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-pager" '("ein:pager-")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-pseudo-console" "ein-pseudo-console.el"
|
||||
;;;;;; (0 0 0 0))
|
||||
;;;;;; (23064 59027 198301 987000))
|
||||
;;; Generated autoloads from ein-pseudo-console.el
|
||||
|
||||
(autoload 'ein:pseudo-console-mode "ein-pseudo-console" "\
|
||||
|
@ -610,41 +433,10 @@ Pseudo console mode. Hit RET to execute code.
|
|||
|
||||
\(fn &optional ARG)" t nil)
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-pseudo-console" '("ein:pseudo-console-mode-map")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-python" "ein-python.el" (0 0 0 0))
|
||||
;;; Generated autoloads from ein-python.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-python" '("ein:python-")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-pytools" "ein-pytools.el" (0 0 0 0))
|
||||
;;; Generated autoloads from ein-pytools.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-pytools" '("ein:")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-query" "ein-query.el" (0 0 0 0))
|
||||
;;; Generated autoloads from ein-query.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-query" '(#("ein:" 0 4 (face font-lock-function-name-face fontified nil)) #("*ein:jupyterhub-servers*" 0 24 (fontified nil face font-lock-variable-name-face)))))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-scratchsheet" "ein-scratchsheet.el" (0
|
||||
;;;;;; 0 0 0))
|
||||
;;; Generated autoloads from ein-scratchsheet.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-scratchsheet" '("ein:")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-shared-output" "ein-shared-output.el"
|
||||
;;;;;; (0 0 0 0))
|
||||
;;;;;; (23468 61365 139112 317000))
|
||||
;;; Generated autoloads from ein-shared-output.el
|
||||
|
||||
(autoload 'ein:shared-output-pop-to-buffer "ein-shared-output" "\
|
||||
|
@ -671,40 +463,10 @@ shared output buffer. You can open the buffer by the command
|
|||
|
||||
\(fn CODE &optional POPUP VERBOSE KERNEL &rest ARGS)" t nil)
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-shared-output" '("ein:")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-skewer" "ein-skewer.el" (0 0 0 0))
|
||||
;;; Generated autoloads from ein-skewer.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-skewer" '("ein:" "*ein:skewer-running-p*")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-smartrep" "ein-smartrep.el" (0 0 0 0))
|
||||
;;; Generated autoloads from ein-smartrep.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-smartrep" '("ein:smartrep-")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-subpackages" "ein-subpackages.el" (0 0
|
||||
;;;;;; 0 0))
|
||||
;;; Generated autoloads from ein-subpackages.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-subpackages" '(#("ein:" 0 4 (face font-lock-function-name-face fontified t)))))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-timestamp" "ein-timestamp.el" (0 0 0 0))
|
||||
;;; Generated autoloads from ein-timestamp.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-timestamp" '("ein:")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-traceback" "ein-traceback.el" (0 0 0 0))
|
||||
;;;### (autoloads nil "ein-traceback" "ein-traceback.el" (23468 61365
|
||||
;;;;;; 139112 317000))
|
||||
;;; Generated autoloads from ein-traceback.el
|
||||
|
||||
(autoload 'ein:tb-show "ein-traceback" "\
|
||||
|
@ -712,47 +474,19 @@ Show full traceback in traceback viewer.
|
|||
|
||||
\(fn)" t nil)
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-traceback" '("ein:t")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-utils" "ein-utils.el" (0 0 0 0))
|
||||
;;; Generated autoloads from ein-utils.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-utils" '("ein:")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-websocket" "ein-websocket.el" (0 0 0 0))
|
||||
;;; Generated autoloads from ein-websocket.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-websocket" '("ein:websocket" "fix-request-netscape-cookie-parse")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ein-worksheet" "ein-worksheet.el" (0 0 0 0))
|
||||
;;; Generated autoloads from ein-worksheet.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ein-worksheet" '("ein:")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ob-ein" "ob-ein.el" (0 0 0 0))
|
||||
;;; Generated autoloads from ob-ein.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ob-ein" '("*ein:org-name-generator*" "ein:" "org-babel-")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "zeroein" "zeroein.el" (0 0 0 0))
|
||||
;;; Generated autoloads from zeroein.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "zeroein" '("zeroein:")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil nil ("debug-ein.el" "ein-pkg.el" "ein.el")
|
||||
;;;;;; (0 0 0 0))
|
||||
;;;### (autoloads nil nil ("debug-ein.el" "ein-ac.el" "ein-cell-edit.el"
|
||||
;;;;;; "ein-cell-output.el" "ein-cell.el" "ein-classes.el" "ein-completer.el"
|
||||
;;;;;; "ein-contents-api.el" "ein-core.el" "ein-events.el" "ein-file.el"
|
||||
;;;;;; "ein-hy.el" "ein-ipdb.el" "ein-junk.el" "ein-kernelinfo.el"
|
||||
;;;;;; "ein-kill-ring.el" "ein-log.el" "ein-multilang-fontify.el"
|
||||
;;;;;; "ein-node.el" "ein-notification.el" "ein-output-area.el"
|
||||
;;;;;; "ein-pager.el" "ein-pkg.el" "ein-python.el" "ein-pytools.el"
|
||||
;;;;;; "ein-query.el" "ein-scratchsheet.el" "ein-skewer.el" "ein-smartrep.el"
|
||||
;;;;;; "ein-subpackages.el" "ein-timestamp.el" "ein-utils.el" "ein-websocket.el"
|
||||
;;;;;; "ein-worksheet.el" "ein.el" "ob-ein.el" "zeroein.el") (23475
|
||||
;;;;;; 34241 891134 103000))
|
||||
|
||||
;;;***
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
(let* ((levname (ein:log-level-int-to-name level))
|
||||
(print-level ein:log-print-level)
|
||||
(print-length ein:log-print-length)
|
||||
(msg (format "[%s] %s" levname (funcall func)))
|
||||
(msg (format "%s: [%s] %s" (format-time-string "%H:%M:%S:%3N") levname (funcall func)))
|
||||
(orig-buffer (current-buffer)))
|
||||
(if (and ein:log-max-string
|
||||
(> (length msg) ein:log-max-string))
|
||||
|
|
|
@ -359,7 +359,6 @@ notebook buffer when CALLBACK is called."
|
|||
(when callback
|
||||
(apply callback ein:%notebook% nil cbargs))
|
||||
ein:%notebook%)
|
||||
(ein:log 'info "Opening notebook %s..." path)
|
||||
(ein:notebook-request-open url-or-port path kernelspec callback cbargs))))
|
||||
|
||||
(defun ein:notebook-request-open (url-or-port path &optional kernelspec callback cbargs)
|
||||
|
@ -372,10 +371,9 @@ argument `t' indicates that the notebook is newly opened.
|
|||
See `ein:notebook-open' for more information."
|
||||
(let ((notebook (ein:notebook-new url-or-port path kernelspec)))
|
||||
(ein:gc-prepare-operation)
|
||||
(ein:log 'debug "Opening notebook at %s" path)
|
||||
(ein:content-query-contents path url-or-port nil
|
||||
(apply-partially #'ein:notebook-request-open-callback-with-callback
|
||||
notebook callback cbargs))
|
||||
(ein:content-query-contents url-or-port path
|
||||
(apply-partially #'ein:notebook-request-open-callback-with-callback
|
||||
notebook callback cbargs))
|
||||
;; (ein:query-singleton-ajax
|
||||
;; (list 'notebook-open url-or-port api-version path)
|
||||
;; url
|
||||
|
@ -391,6 +389,7 @@ See `ein:notebook-open' for more information."
|
|||
callback
|
||||
cbargs
|
||||
content)
|
||||
(ein:log 'verbose "Opened notebook %s" (ein:$notebook-notebook-path notebook))
|
||||
(funcall #'ein:notebook-request-open-callback notebook content)
|
||||
(when callback
|
||||
(with-current-buffer (ein:notebook-buffer notebook)
|
||||
|
@ -465,7 +464,7 @@ of minor mode."
|
|||
(error "Fix me!")) ;; FIXME
|
||||
(setf (ein:$notebook-autosave-timer notebook)
|
||||
(run-at-time 0 ein:notebook-autosave-frequency #'ein:notebook-maybe-save-notebook notebook 0))
|
||||
(ein:log 'info "Enabling autosaves for %s with frequency %s seconds."
|
||||
(ein:log 'verbose "Enabling autosaves for %s with frequency %s seconds."
|
||||
(ein:$notebook-notebook-name notebook)
|
||||
ein:notebook-autosave-frequency))
|
||||
|
||||
|
@ -477,7 +476,7 @@ of minor mode."
|
|||
"Select notebook [URL-OR-PORT/NAME]: "
|
||||
(ein:notebook-opened-buffer-names)))))
|
||||
(list notebook)))
|
||||
(ein:log 'info "Disabling auto checkpoints for notebook %s" (ein:$notebook-notebook-name notebook))
|
||||
(ein:log 'verbose "Disabling auto checkpoints for notebook %s" (ein:$notebook-notebook-name notebook))
|
||||
(when (ein:$notebook-autosave-timer notebook)
|
||||
(cancel-timer (ein:$notebook-autosave-timer notebook))))
|
||||
|
||||
|
@ -500,15 +499,13 @@ of minor mode."
|
|||
|
||||
;;; Kernel related things
|
||||
|
||||
(defvar ein:available-kernelspecs (make-hash-table :test #'equal))
|
||||
|
||||
(defun ein:kernelspec-for-nb-metadata (kernelspec)
|
||||
(let ((display-name (plist-get (ein:$kernelspec-spec kernelspec) :display_name)))
|
||||
`((:name . ,(ein:$kernelspec-name kernelspec))
|
||||
(:display_name . ,(format "%s" display-name)))))
|
||||
|
||||
(defun ein:get-kernelspec (url-or-port name)
|
||||
(let* ((kernelspecs (gethash url-or-port ein:available-kernelspecs))
|
||||
(let* ((kernelspecs (ein:need-kernelspecs url-or-port))
|
||||
(name (if (stringp name)
|
||||
(intern (format ":%s" name))
|
||||
name))
|
||||
|
@ -518,50 +515,13 @@ of minor mode."
|
|||
ks)))
|
||||
|
||||
(defun ein:list-available-kernels (url-or-port)
|
||||
(let ((kernelspecs (gethash url-or-port ein:available-kernelspecs)))
|
||||
(let ((kernelspecs (ein:need-kernelspecs url-or-port)))
|
||||
(if kernelspecs
|
||||
(sort (loop for (key spec) on (ein:plist-exclude kernelspecs '(:default)) by 'cddr
|
||||
collecting (cons (ein:$kernelspec-name spec)
|
||||
(ein:$kernelspec-display-name spec)))
|
||||
(lambda (c1 c2) (string< (cdr c1) (cdr c2)))))))
|
||||
|
||||
(defun ein:query-kernelspecs (url-or-port &optional force-refresh)
|
||||
"Query jupyter server for the list of available
|
||||
kernels. Results are stored in ein:available-kernelspec, hashed
|
||||
on server url/port."
|
||||
(unless (and (not force-refresh) (gethash url-or-port ein:available-kernelspecs))
|
||||
(ein:query-singleton-ajax
|
||||
(list 'ein:query-kernelspecs url-or-port)
|
||||
(ein:url url-or-port "api/kernelspecs")
|
||||
:type "GET"
|
||||
:timeout ein:content-query-timeout
|
||||
:parser 'ein:json-read
|
||||
:sync t
|
||||
:success (apply-partially #'ein:query-kernelspecs-success url-or-port)
|
||||
:error (apply-partially #'ein:query-kernelspecs-error))))
|
||||
|
||||
(defun* ein:query-kernelspecs-success (url-or-port &key data &allow-other-keys)
|
||||
(let ((ks (list :default (plist-get data :default)))
|
||||
(specs (ein:plist-iter (plist-get data :kernelspecs))))
|
||||
(setf (gethash url-or-port ein:available-kernelspecs)
|
||||
(ein:flatten (dolist (spec specs ks)
|
||||
(let ((name (car spec))
|
||||
(info (cdr spec)))
|
||||
(push (list name (make-ein:$kernelspec :name (plist-get info :name)
|
||||
:display-name (plist-get (plist-get info :spec)
|
||||
:display_name)
|
||||
:resources (plist-get info :resources)
|
||||
:language (plist-get (plist-get info :spec)
|
||||
:language)
|
||||
:spec (plist-get info :spec)))
|
||||
ks)))))))
|
||||
|
||||
(defun* ein:query-kernelspecs-error (&key symbol-status response &allow-other-keys)
|
||||
(ein:log 'verbose
|
||||
"Error thrown: %S" (request-response-error-thrown response))
|
||||
(ein:log 'error
|
||||
"Kernelspc query call failed with status %s." symbol-status))
|
||||
|
||||
(defun ein:notebook-switch-kernel (notebook kernel-name)
|
||||
"Change the kernel for a running notebook. If not called from a
|
||||
notebook buffer then the user will be prompted to select an opened notebook."
|
||||
|
@ -765,7 +725,6 @@ This is equivalent to do ``C-c`` in the console program."
|
|||
(defun ein:read-nbformat4-worksheets (notebook data)
|
||||
"Convert a notebook in nbformat4 to a list of worksheet-like
|
||||
objects suitable for processing in ein:notebook-from-json."
|
||||
(ein:log 'info "Reading nbformat4 notebook.")
|
||||
(let* ((cells (plist-get data :cells))
|
||||
(ws-cells (mapcar (lambda (data) (ein:cell-from-json data)) cells))
|
||||
(worksheet (ein:notebook--worksheet-new notebook)))
|
||||
|
|
|
@ -22,9 +22,6 @@
|
|||
|
||||
;;; Commentary:
|
||||
|
||||
;; The rendering is split into a function for ipython2 and one for
|
||||
;; ipython3, ein:notebooklist-render-ipy2 and
|
||||
;; ein:notebooklist-render.
|
||||
|
||||
;;; Code:
|
||||
|
||||
|
@ -43,12 +40,12 @@
|
|||
(require 'dash)
|
||||
|
||||
|
||||
(defcustom ein:notebook-list-render-order
|
||||
(defcustom ein:notebooklist-render-order
|
||||
'(render-header
|
||||
render-opened-notebooks
|
||||
render-directory-ipy3)
|
||||
render-directory)
|
||||
"Order of notebook list sections.
|
||||
Must contain render-header, render-opened-notebooks, and render-directory-ipy3."
|
||||
Must contain render-header, render-opened-notebooks, and render-directory."
|
||||
:group 'ein
|
||||
:type 'list
|
||||
)
|
||||
|
@ -73,7 +70,7 @@ is opened at first time.::
|
|||
`ein:$notebooklist-url-or-port'
|
||||
URL or port of IPython server.
|
||||
|
||||
`ein:$notbooklist-path'
|
||||
`ein:$notebooklist-path'
|
||||
The path for the notebooklist.
|
||||
|
||||
`ein:$notebooklist-data'
|
||||
|
@ -175,7 +172,7 @@ To suppress popup, you can pass `ignore' as CALLBACK."
|
|||
(defun ein:notebooklist-new-url (url-or-port version &optional path)
|
||||
(let ((base-path (cond ((= version 2) "api/notebooks")
|
||||
((>= version 3) "api/contents"))))
|
||||
(ein:log 'info "New notebook. Port: %s, Path: %s" url-or-port path)
|
||||
(ein:log 'info "New notebook %s" (concat (file-name-as-directory url-or-port) path))
|
||||
(if (and path (not (string= path "")))
|
||||
(ein:url url-or-port base-path path)
|
||||
(ein:url url-or-port base-path))))
|
||||
|
@ -204,37 +201,54 @@ To suppress popup, you can pass `ignore' as CALLBACK."
|
|||
url-or-port)))
|
||||
|
||||
;;;###autoload
|
||||
(defun ein:notebooklist-open (&optional url-or-port path no-popup)
|
||||
(defun ein:notebooklist-open (url-or-port &optional path no-popup resync)
|
||||
"Open notebook list buffer."
|
||||
(interactive (list (ein:notebooklist-ask-url-or-port)))
|
||||
(unless url-or-port (setq url-or-port (ein:default-url-or-port)))
|
||||
(unless path (setq path ""))
|
||||
(if (and (stringp url-or-port) (not (string-match-p "^https?" url-or-port)))
|
||||
(setq url-or-port (format "http://%s" url-or-port)))
|
||||
(ein:log 'debug "NOTEBOOKLIST-OPEN: %s/%s" url-or-port path)
|
||||
(ein:subpackages-load)
|
||||
(let ((success
|
||||
(if no-popup
|
||||
#'ein:notebooklist-url-retrieve-callback
|
||||
(lambda (content)
|
||||
(pop-to-buffer
|
||||
(funcall #'ein:notebooklist-url-retrieve-callback content))))))
|
||||
(ein:query-kernelspecs url-or-port)
|
||||
(ein:content-query-contents path url-or-port t success))
|
||||
;(ein:notebooklist-get-buffer url-or-port)
|
||||
(lexical-let ((url-or-port url-or-port)
|
||||
(path path)
|
||||
(success (if no-popup
|
||||
#'ein:notebooklist-open--finish
|
||||
(lambda (content)
|
||||
(pop-to-buffer
|
||||
(funcall #'ein:notebooklist-open--finish content))))))
|
||||
(if (or resync (not (ein:notebooklist-list-get url-or-port)))
|
||||
(deferred:$
|
||||
(deferred:parallel
|
||||
(lexical-let ((d (deferred:new #'identity)))
|
||||
(ein:query-ipython-version url-or-port (lambda ()
|
||||
(deferred:callback-post d)))
|
||||
d)
|
||||
(lexical-let ((d (deferred:new #'identity)))
|
||||
(ein:query-kernelspecs url-or-port (lambda ()
|
||||
(deferred:callback-post d)))
|
||||
d)
|
||||
(lexical-let ((d (deferred:new #'identity)))
|
||||
(ein:content-query-hierarchy url-or-port (lambda (tree)
|
||||
(deferred:callback-post d)))
|
||||
d))
|
||||
(deferred:nextc it
|
||||
(lambda (&rest ignore)
|
||||
(ein:content-query-contents url-or-port path success))))
|
||||
(ein:content-query-contents url-or-port path success)))
|
||||
)
|
||||
|
||||
;;;###autoload
|
||||
(defun ein:notebooklist-refresh-kernelspecs (&optional url-or-port)
|
||||
(interactive (list (or (and ein:%notebooklist% (ein:$notebooklist-url-or-port ein:%notebooklist%))
|
||||
(ein:notebooklist-ask-url-or-port))))
|
||||
(unless url-or-port
|
||||
(if ein:%notebooklist%
|
||||
(setq url-or-port (ein:$notebooklist-url-or-port ein:%notebooklist%))
|
||||
(setq url-or-port (ein:default-url-or-port))))
|
||||
(ein:query-kernelspecs url-or-port t)
|
||||
(when ein:%notebooklist%
|
||||
(ein:notebooklist-reload ein:%notebooklist%)))
|
||||
;; point of order (poo): ein:notebooklist-refresh-kernelspecs requeries the kernelspecs and calls ein:notebooklist-reload. ein:notebooklist-reload already requeries the kernelspecs in one of its callbacks, so this function seems redundant.
|
||||
|
||||
;; (defun ein:notebooklist-refresh-kernelspecs (&optional url-or-port)
|
||||
;; (interactive (list (or (and ein:%notebooklist% (ein:$notebooklist-url-or-port ein:%notebooklist%))
|
||||
;; (ein:notebooklist-ask-url-or-port))))
|
||||
;; (unless url-or-port
|
||||
;; (if ein:%notebooklist%
|
||||
;; (setq url-or-port (ein:$notebooklist-url-or-port ein:%notebooklist%))
|
||||
;; (setq url-or-port (ein:default-url-or-port))))
|
||||
;; (ein:query-kernelspecs url-or-port)
|
||||
;; (when ein:%notebooklist%
|
||||
;; (ein:notebooklist-reload ein:%notebooklist%))
|
||||
;; )
|
||||
|
||||
(defcustom ein:notebooklist-keepalive-refresh-time 1
|
||||
"When the notebook keepalive is enabled, the frequency, IN
|
||||
|
@ -275,7 +289,7 @@ automatically be called during calls to `ein:notebooklist-open`."
|
|||
(ein:log 'info "Refreshing notebooklist connection.")))
|
||||
(refresh-time (* ein:notebooklist-keepalive-refresh-time 60 60)))
|
||||
(setq ein:notebooklist--keepalive-timer
|
||||
(run-at-time 0.1 refresh-time #'ein:content-query-contents "" url-or-port nil success)))))
|
||||
(run-at-time 0.1 refresh-time #'ein:content-query-contents url-or-port "" success)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun ein:notebooklist-disable-keepalive ()
|
||||
|
@ -285,14 +299,12 @@ automatically be called during calls to `ein:notebooklist-open`."
|
|||
(cancel-timer ein:notebooklist--keepalive-timer)
|
||||
(setq ein:notebooklist--keepalive-timer nil))
|
||||
|
||||
(defun* ein:notebooklist-url-retrieve-callback (content)
|
||||
(defun ein:notebooklist-open--finish (content)
|
||||
"Called via `ein:notebooklist-open'."
|
||||
(let ((url-or-port (ein:$content-url-or-port content))
|
||||
(path (ein:$content-path content))
|
||||
(ipy-version (ein:$content-ipython-version content))
|
||||
(data (ein:$content-raw-content content)))
|
||||
(when (>= ipy-version 3)
|
||||
(ein:query-kernelspecs url-or-port))
|
||||
(with-current-buffer (ein:notebooklist-get-buffer url-or-port)
|
||||
(let ((already-opened-p (ein:notebooklist-list-get url-or-port))
|
||||
(orig-point (point)))
|
||||
|
@ -302,11 +314,9 @@ automatically be called during calls to `ein:notebooklist-open`."
|
|||
:data data
|
||||
:api-version ipy-version))
|
||||
(ein:notebooklist-list-add ein:%notebooklist%)
|
||||
(if (< ipy-version 3)
|
||||
(ein:notebooklist-render-ipy2)
|
||||
(ein:notebooklist-render))
|
||||
(ein:notebooklist-render ipy-version)
|
||||
(goto-char orig-point)
|
||||
(ein:log 'info "Opened notebook list at %s with path %s." url-or-port path)
|
||||
(ein:log 'verbose "Opened notebooklist at %s" (concat (file-name-as-directory url-or-port) path))
|
||||
(unless already-opened-p
|
||||
(run-hooks 'ein:notebooklist-first-open-hook))
|
||||
(when ein:enable-keepalive
|
||||
|
@ -314,22 +324,18 @@ automatically be called during calls to `ein:notebooklist-open`."
|
|||
(current-buffer)))))
|
||||
|
||||
(defun* ein:notebooklist-open-error (url-or-port path
|
||||
&key symbol-status response
|
||||
&key error-thrown
|
||||
&allow-other-keys)
|
||||
(ein:log 'verbose
|
||||
"Error thrown: %S" (request-response-error-thrown response))
|
||||
(ein:log 'error
|
||||
"Error (%s) while opening notebook list with path %s at the server %s."
|
||||
symbol-status path url-or-port))
|
||||
"ein:notebooklist-open-error %s: ERROR %s DATA %s" (concat (file-name-as-directory url-or-port) path) (car error-thrown) (cdr error-thrown)))
|
||||
|
||||
;;;###autoload
|
||||
(defun ein:notebooklist-reload (&optional notebooklist)
|
||||
(defun ein:notebooklist-reload (notebooklist &optional resync)
|
||||
"Reload current Notebook list."
|
||||
(interactive)
|
||||
(unless notebooklist
|
||||
(setq notebooklist ein:%notebooklist%))
|
||||
(ein:notebooklist-open (ein:$notebooklist-url-or-port notebooklist)
|
||||
(ein:$notebooklist-path notebooklist) t))
|
||||
(interactive (list ein:%notebooklist%))
|
||||
(when notebooklist
|
||||
(ein:notebooklist-open (ein:$notebooklist-url-or-port notebooklist)
|
||||
(ein:$notebooklist-path notebooklist) t resync)))
|
||||
|
||||
(defun ein:notebooklist-refresh-related ()
|
||||
"Reload notebook list in which current notebook locates.
|
||||
|
@ -403,7 +409,7 @@ This function is called via `ein:notebook-after-rename-hook'."
|
|||
(if data
|
||||
(let ((name (plist-get data :name))
|
||||
(path (plist-get data :path)))
|
||||
(if (= (ein:query-ipython-version url-or-port) 2)
|
||||
(if (= (ein:need-ipython-version url-or-port) 2)
|
||||
(if (string= path "")
|
||||
(setq path name)
|
||||
(setq path (format "%s/%s" path name))))
|
||||
|
@ -428,7 +434,7 @@ This function is called via `ein:notebook-after-rename-hook'."
|
|||
"Failed to open new notebook (error: %S). \
|
||||
You may find the new one in the notebook list." error)
|
||||
(setq no-popup nil)
|
||||
(ein:notebooklist-open url-or-port no-popup))
|
||||
(ein:notebooklist-open url-or-port "" no-popup))
|
||||
|
||||
;;;###autoload
|
||||
(defun ein:notebooklist-new-notebook-with-name (name kernelspec url-or-port &optional path)
|
||||
|
@ -463,7 +469,6 @@ You may find the new one in the notebook list." error)
|
|||
(ein:notebooklist-delete-notebook path)))
|
||||
|
||||
(defun ein:notebooklist-delete-notebook (path)
|
||||
(ein:log 'info "Deleting notebook %s..." path)
|
||||
(ein:query-singleton-ajax
|
||||
(list 'notebooklist-delete-notebook
|
||||
(ein:$notebooklist-url-or-port ein:%notebooklist%) path)
|
||||
|
@ -472,10 +477,10 @@ You may find the new one in the notebook list." error)
|
|||
(ein:$notebooklist-api-version ein:%notebooklist%)
|
||||
path)
|
||||
:type "DELETE"
|
||||
:success (apply-partially (lambda (path notebook-list &rest ignore)
|
||||
:success (apply-partially (lambda (path notebooklist &rest ignore)
|
||||
(ein:log 'info
|
||||
"Deleting notebook %s... Done." path)
|
||||
(ein:notebooklist-reload notebook-list))
|
||||
"Deleted notebook %s" path)
|
||||
(ein:notebooklist-reload notebooklist))
|
||||
path ein:%notebooklist%)))
|
||||
|
||||
;; Because MinRK wants me to suffer (not really, I love MinRK)...
|
||||
|
@ -493,21 +498,6 @@ You may find the new one in the notebook list." error)
|
|||
(setf current-path (concat current-path "/" p)
|
||||
pairs (append pairs (list (cons p current-path)))))))
|
||||
|
||||
(defun ein:notebooklist-render-ipy2 ()
|
||||
"Render notebook list for IPython 2.x sessions.
|
||||
Notebook list data is passed via the buffer local variable
|
||||
`ein:notebooklist-data'."
|
||||
(kill-all-local-variables)
|
||||
(let ((inhibit-read-only t))
|
||||
(erase-buffer))
|
||||
(remove-overlays)
|
||||
|
||||
(render-header-ipy2)
|
||||
(render-directory-ipy2)
|
||||
|
||||
(ein:notebooklist-mode)
|
||||
(widget-setup))
|
||||
|
||||
(defun* ein:nblist--sort-group (group by-param order)
|
||||
(sort group #'(lambda (x y)
|
||||
(cond ((eql order :ascending)
|
||||
|
@ -534,7 +524,7 @@ Notebook list data is passed via the buffer local variable
|
|||
sort-order)))
|
||||
(-concat dirs nbs files)))
|
||||
|
||||
(defun render-header-ipy2 ()
|
||||
(defun render-header-ipy2 (&rest args)
|
||||
"Render the header (for ipython2)."
|
||||
;; Create notebook list
|
||||
(widget-insert (format "IPython %s Notebook list\n\n" (ein:$notebooklist-api-version ein:%notebooklist%)))
|
||||
|
@ -560,7 +550,7 @@ Notebook list data is passed via the buffer local variable
|
|||
(widget-insert " ")
|
||||
(widget-create
|
||||
'link
|
||||
:notify (lambda (&rest ignore) (ein:notebooklist-reload))
|
||||
:notify (lambda (&rest ignore) (ein:notebooklist-reload ein:%notebooklist% t))
|
||||
"Reload List")
|
||||
(widget-insert " ")
|
||||
(widget-create
|
||||
|
@ -571,125 +561,102 @@ Notebook list data is passed via the buffer local variable
|
|||
"Open In Browser")
|
||||
(widget-insert "\n"))
|
||||
|
||||
(defun render-header ()
|
||||
(defun render-header* (url-or-port &rest args)
|
||||
"Render the header (for ipython>=3)."
|
||||
;; Create notebook list
|
||||
(widget-insert
|
||||
(if (< (ein:$notebooklist-api-version ein:%notebooklist%) 4)
|
||||
(format "IPython v%s Notebook list (%s)\n\n" (ein:$notebooklist-api-version ein:%notebooklist%) (ein:$notebooklist-url-or-port ein:%notebooklist%))
|
||||
(format "Jupyter v%s Notebook list (%s)\n\n" (ein:$notebooklist-api-version ein:%notebooklist%) (ein:$notebooklist-url-or-port ein:%notebooklist%))))
|
||||
(with-current-buffer (ein:notebooklist-get-buffer url-or-port)
|
||||
(widget-insert
|
||||
(if (< (ein:$notebooklist-api-version ein:%notebooklist%) 4)
|
||||
(format "IPython v%s Notebook list (%s)\n\n" (ein:$notebooklist-api-version ein:%notebooklist%) url-or-port)
|
||||
(format "Jupyter v%s Notebook list (%s)\n\n" (ein:$notebooklist-api-version ein:%notebooklist%) url-or-port)))
|
||||
|
||||
(let ((breadcrumbs (generate-breadcrumbs (ein:$notebooklist-path ein:%notebooklist%))))
|
||||
(dolist (p breadcrumbs)
|
||||
(lexical-let ((name (car p))
|
||||
(path (cdr p)))
|
||||
(widget-insert " | ")
|
||||
(widget-create
|
||||
'link
|
||||
:notify (lambda (&rest ignore)
|
||||
(ein:notebooklist-open
|
||||
(ein:$notebooklist-url-or-port ein:%notebooklist%)
|
||||
path))
|
||||
name)))
|
||||
(widget-insert " |\n\n"))
|
||||
(let ((breadcrumbs (generate-breadcrumbs (ein:$notebooklist-path ein:%notebooklist%))))
|
||||
(dolist (p breadcrumbs)
|
||||
(lexical-let ((url-or-port url-or-port)
|
||||
(name (car p))
|
||||
(path (cdr p)))
|
||||
(widget-insert " | ")
|
||||
(widget-create
|
||||
'link
|
||||
:notify (lambda (&rest ignore)
|
||||
(ein:notebooklist-open url-or-port path))
|
||||
name)))
|
||||
(widget-insert " |\n\n"))
|
||||
|
||||
(lexical-let* ((url-or-port (ein:$notebooklist-url-or-port ein:%notebooklist%))
|
||||
(kernels (ein:list-available-kernels url-or-port)))
|
||||
(if (null ein:%notebooklist-new-kernel%)
|
||||
(setq ein:%notebooklist-new-kernel% (ein:get-kernelspec url-or-port (caar kernels))))
|
||||
(widget-create
|
||||
'link
|
||||
:notify (lambda (&rest ignore) (ein:notebooklist-new-notebook
|
||||
url-or-port
|
||||
ein:%notebooklist-new-kernel%))
|
||||
"New Notebook")
|
||||
(widget-insert " ")
|
||||
(widget-create
|
||||
'link
|
||||
:notify (lambda (&rest ignore) (ein:notebooklist-reload))
|
||||
"Reload List")
|
||||
(widget-insert " ")
|
||||
(widget-create
|
||||
'link
|
||||
:notify (lambda (&rest ignore) (ein:notebooklist-refresh-kernelspecs))
|
||||
"Query Kernelspecs")
|
||||
(widget-insert " ")
|
||||
(widget-create
|
||||
'link
|
||||
:notify (lambda (&rest ignore)
|
||||
(browse-url
|
||||
(ein:url url-or-port)))
|
||||
"Open In Browser")
|
||||
(lexical-let* ((url-or-port url-or-port)
|
||||
(kernels (ein:list-available-kernels url-or-port)))
|
||||
(if (null ein:%notebooklist-new-kernel%)
|
||||
(setq ein:%notebooklist-new-kernel% (ein:get-kernelspec url-or-port (caar kernels))))
|
||||
(widget-create
|
||||
'link
|
||||
:notify (lambda (&rest ignore) (ein:notebooklist-new-notebook
|
||||
url-or-port
|
||||
ein:%notebooklist-new-kernel%))
|
||||
"New Notebook")
|
||||
(widget-insert " ")
|
||||
(widget-create
|
||||
'link
|
||||
:notify (lambda (&rest ignore) (ein:notebooklist-reload ein:%notebooklist% t))
|
||||
"Resync")
|
||||
(widget-insert " ")
|
||||
(widget-create
|
||||
'link
|
||||
:notify (lambda (&rest ignore)
|
||||
(browse-url (ein:url url-or-port)))
|
||||
"Open In Browser")
|
||||
|
||||
(widget-insert "\n\nCreate New Notebooks Using Kernel: \n")
|
||||
(let* ((radio-widget (widget-create 'radio-button-choice
|
||||
:value (and ein:%notebooklist-new-kernel% (ein:$kernelspec-name ein:%notebooklist-new-kernel%))
|
||||
:notify (lambda (widget &rest ignore)
|
||||
(setq ein:%notebooklist-new-kernel%
|
||||
(ein:get-kernelspec url-or-port (widget-value widget)))
|
||||
(message "New notebooks will be started using the %s kernel."
|
||||
(ein:$kernelspec-display-name ein:%notebooklist-new-kernel%))))))
|
||||
(dolist (k kernels)
|
||||
(widget-radio-add-item radio-widget (list 'item :value (car k)
|
||||
:format (format "%s\n" (cdr k)))))))
|
||||
(widget-insert "\n"))
|
||||
(widget-insert "\n\nCreate New Notebooks Using Kernel:\n")
|
||||
(let* ((radio-widget (widget-create 'radio-button-choice
|
||||
:value (and ein:%notebooklist-new-kernel% (ein:$kernelspec-name ein:%notebooklist-new-kernel%))
|
||||
:notify (lambda (widget &rest ignore)
|
||||
(setq ein:%notebooklist-new-kernel%
|
||||
(ein:get-kernelspec url-or-port (widget-value widget)))
|
||||
(message "New notebooks will be started using the %s kernel."
|
||||
(ein:$kernelspec-display-name ein:%notebooklist-new-kernel%))))))
|
||||
(if (null kernels)
|
||||
(widget-insert "\n No kernels found.")
|
||||
(dolist (k kernels)
|
||||
(widget-radio-add-item radio-widget (list 'item :value (car k)
|
||||
:format (format "%s\n" (cdr k)))))
|
||||
(widget-insert "\n"))))))
|
||||
|
||||
(defun render-opened-notebooks ()
|
||||
(defun render-opened-notebooks (url-or-port &rest args)
|
||||
"Render the opened notebooks section (for ipython>=3)."
|
||||
;; Opened Notebooks Section
|
||||
(widget-insert "\n---------- All Opened Notebooks ----------\n\n")
|
||||
(loop for buffer in (ein:notebook-opened-buffers)
|
||||
do (progn (widget-create
|
||||
'link
|
||||
:notify (lexical-let ((buffer buffer))
|
||||
(lambda (&rest ignore)
|
||||
(switch-to-buffer buffer)))
|
||||
"Open")
|
||||
(widget-create
|
||||
'link
|
||||
:notify (lexical-let ((buffer buffer))
|
||||
(lambda (&rest ignore)
|
||||
(kill-buffer buffer)
|
||||
(run-at-time 1 nil
|
||||
#'ein:notebooklist-reload
|
||||
ein:%notebooklist%)))
|
||||
"Close")
|
||||
(widget-insert " : " (buffer-name buffer))
|
||||
(widget-insert "\n"))))
|
||||
|
||||
|
||||
(defun render-directory-ipy3 ()
|
||||
"Call render-direcory with ipy-at-least-3 true."
|
||||
(render-directory t))
|
||||
|
||||
(defun render-directory-ipy2 ()
|
||||
"Call render-direcory with ipy-at-least-3 false."
|
||||
(render-directory nil))
|
||||
(with-current-buffer (ein:notebooklist-get-buffer url-or-port)
|
||||
(widget-insert "\n---------- All Opened Notebooks ----------\n\n")
|
||||
(loop for buffer in (ein:notebook-opened-buffers)
|
||||
do (progn (widget-create
|
||||
'link
|
||||
:notify (lexical-let ((buffer buffer))
|
||||
(lambda (&rest ignore)
|
||||
(switch-to-buffer buffer)))
|
||||
"Open")
|
||||
(widget-create
|
||||
'link
|
||||
:notify (lexical-let ((buffer buffer))
|
||||
(lambda (&rest ignore)
|
||||
(kill-buffer buffer)
|
||||
(run-at-time 1 nil
|
||||
#'ein:notebooklist-reload
|
||||
ein:%notebooklist%)))
|
||||
"Close")
|
||||
(widget-insert " : " (buffer-name buffer))
|
||||
(widget-insert "\n")))))
|
||||
|
||||
(defun ein:format-nbitem-data (name last-modified)
|
||||
(let ((dt (date-to-time last-modified)))
|
||||
(format "%-40s%+20s" name
|
||||
(ein:format-time-string ein:notebooklist-date-format dt))))
|
||||
|
||||
(defun render-directory (ipy-at-least-3)
|
||||
"Render directory.
|
||||
IPY-AT-LEAST-3 used to keep track of version."
|
||||
(widget-insert "\n------------------------------------------\n\n")
|
||||
(unless ipy-at-least-3
|
||||
(let (api-version (ein:$notebooklist-api-version ein:%notebooklist%))))
|
||||
(let ((sessions #s(hash-table test equal data (:pending t))))
|
||||
(ein:content-query-sessions sessions (ein:$notebooklist-url-or-port ein:%notebooklist%) t)
|
||||
(loop repeat 4
|
||||
when (null (gethash :pending sessions))
|
||||
return t
|
||||
do (sleep-for 0 50))
|
||||
(defun render-directory (url-or-port sessions)
|
||||
(with-current-buffer (ein:notebooklist-get-buffer url-or-port)
|
||||
(widget-insert "\n------------------------------------------\n\n")
|
||||
(ein:make-sorting-widget "Sort by" ein:notebooklist-sort-field)
|
||||
(ein:make-sorting-widget "In Order" ein:notebooklist-sort-order)
|
||||
(widget-insert "\n")
|
||||
(loop for note in (ein:notebooklist--order-data (ein:$notebooklist-data ein:%notebooklist%)
|
||||
ein:notebooklist-sort-field
|
||||
ein:notebooklist-sort-order)
|
||||
for urlport = (ein:$notebooklist-url-or-port ein:%notebooklist%)
|
||||
for name = (plist-get note :name)
|
||||
for path = (plist-get note :path)
|
||||
for last-modified = (plist-get note :last_modified)
|
||||
|
@ -698,27 +665,27 @@ IPY-AT-LEAST-3 used to keep track of version."
|
|||
;; ((= 3 api-version)
|
||||
;; (ein:get-actual-path (plist-get note :path))))
|
||||
for type = (plist-get note :type)
|
||||
for opened-notebook-maybe = (ein:notebook-get-opened-notebook urlport path)
|
||||
for opened-notebook-maybe = (ein:notebook-get-opened-notebook url-or-port path)
|
||||
do (widget-insert " ")
|
||||
if (string= type "directory")
|
||||
do (progn (widget-create
|
||||
'link
|
||||
:notify (lexical-let ((urlport urlport)
|
||||
(path name))
|
||||
:notify (lexical-let ((url-or-port url-or-port)
|
||||
(name name))
|
||||
(lambda (&rest ignore)
|
||||
(ein:notebooklist-open urlport
|
||||
(ein:url (ein:$notebooklist-path ein:%notebooklist%)
|
||||
path))))
|
||||
;; each directory creates a whole new notebooklist
|
||||
(ein:notebooklist-open url-or-port
|
||||
(ein:url (ein:$notebooklist-path ein:%notebooklist%) name))))
|
||||
"Dir")
|
||||
(widget-insert " : " name)
|
||||
(widget-insert "\n"))
|
||||
if (and (string= type "file") ipy-at-least-3)
|
||||
if (and (string= type "file") (> (ein:need-ipython-version url-or-port) 2))
|
||||
do (progn (widget-create
|
||||
'link
|
||||
:notify (lexical-let ((urlport urlport)
|
||||
:notify (lexical-let ((url-or-port url-or-port)
|
||||
(path path))
|
||||
(lambda (&rest ignore)
|
||||
(ein:notebooklist-open-file urlport path)))
|
||||
(ein:notebooklist-open-file url-or-port path)))
|
||||
"Open")
|
||||
(widget-insert " ------ ")
|
||||
(widget-create
|
||||
|
@ -765,8 +732,7 @@ IPY-AT-LEAST-3 used to keep track of version."
|
|||
(widget-insert " : " (ein:format-nbitem-data name last-modified))
|
||||
(widget-insert "\n")))))
|
||||
|
||||
|
||||
(defun ein:notebooklist-render ()
|
||||
(defun ein:notebooklist-render (ipy-version)
|
||||
"Render notebook list widget.
|
||||
Notebook list data is passed via the buffer local variable
|
||||
`ein:notebooklist-data'."
|
||||
|
@ -775,26 +741,36 @@ Notebook list data is passed via the buffer local variable
|
|||
(erase-buffer))
|
||||
(remove-overlays)
|
||||
|
||||
(mapc #'funcall ein:notebook-list-render-order)
|
||||
(let ((url-or-port (ein:$notebooklist-url-or-port ein:%notebooklist%)))
|
||||
(ein:content-query-sessions url-or-port
|
||||
(apply-partially #'ein:notebooklist-render--finish ipy-version url-or-port))))
|
||||
|
||||
(ein:notebooklist-mode)
|
||||
(widget-setup))
|
||||
(defun ein:notebooklist-render--finish (ipy-version url-or-port sessions)
|
||||
(cl-letf (((symbol-function 'render-header) (if (< ipy-version 3)
|
||||
#'render-header-ipy2
|
||||
#'render-header*)))
|
||||
(mapc (lambda (x) (funcall (symbol-function x) url-or-port sessions))
|
||||
ein:notebooklist-render-order))
|
||||
(with-current-buffer (ein:notebooklist-get-buffer url-or-port)
|
||||
(ein:notebooklist-mode)
|
||||
(widget-setup)
|
||||
(goto-char (point-min))))
|
||||
|
||||
;;;###autoload
|
||||
|
||||
(defun ein:notebooklist-list-notebooks ()
|
||||
"Return a list of notebook path (NBPATH). Each element NBPATH
|
||||
is a string of the format \"URL-OR-PORT/NOTEBOOK-NAME\"."
|
||||
(apply #'append
|
||||
(loop for nblist in (ein:notebooklist-list)
|
||||
for url-or-port = (ein:$notebooklist-url-or-port nblist)
|
||||
for api-version = (ein:$notebooklist-api-version nblist)
|
||||
collect
|
||||
(loop for note in (ein:get-content-hierarchy url-or-port)
|
||||
collect (format "%s/%s" url-or-port
|
||||
(ein:$content-path note)
|
||||
))
|
||||
(loop for content in (ein:content-need-hierarchy url-or-port)
|
||||
when (string= (ein:$content-type content) "notebook")
|
||||
collect (format "%s/%s" url-or-port
|
||||
(ein:$content-path content)))
|
||||
;; (if (= api-version 3)
|
||||
;; (loop for note in (ein:make-content-hierarchy "" url-or-port)
|
||||
;; (loop for note in (ein:content-need-hierarchy url-or-port)
|
||||
;; collect (format "%s/%s" url-or-port
|
||||
;; (ein:$content-path note)
|
||||
;; ))
|
||||
|
@ -807,6 +783,7 @@ is a string of the format \"URL-OR-PORT/NOTEBOOK-NAME\"."
|
|||
;;FIXME: Code below assumes notebook is in root directory - need to do a better
|
||||
;; job listing notebooks in subdirectories and parsing out the path.
|
||||
;;;###autoload
|
||||
|
||||
(defun ein:notebooklist-open-notebook-global (nbpath &optional callback cbargs)
|
||||
"Choose notebook from all opened notebook list and open it.
|
||||
Notebook is specified by a string NBPATH whose format is
|
||||
|
@ -814,18 +791,18 @@ Notebook is specified by a string NBPATH whose format is
|
|||
|
||||
When used in lisp, CALLBACK and CBARGS are passed to `ein:notebook-open'."
|
||||
(interactive
|
||||
(list (completing-read
|
||||
"Open notebook [URL-OR-PORT/NAME]: "
|
||||
(ein:notebooklist-list-notebooks))))
|
||||
(let* ((url-or-port (substring nbpath 0 (cl-position ?/ nbpath)))
|
||||
(path (substring nbpath (1+ (cl-position ?/ nbpath)))))
|
||||
(when (and (stringp url-or-port)
|
||||
(string-match "^[0-9]+$" url-or-port))
|
||||
(setq url-or-port (string-to-number url-or-port)))
|
||||
(ein:notebook-open url-or-port path nil callback cbargs)
|
||||
(ein:log 'info "Notebook '%s' not found" nbpath)))
|
||||
(list (if noninteractive
|
||||
(car (ein:notebooklist-list-notebooks))
|
||||
(completing-read
|
||||
"Open notebook [URL-OR-PORT/NAME]: "
|
||||
(ein:notebooklist-list-notebooks)))))
|
||||
(let* ((parsed (url-generic-parse-url nbpath))
|
||||
(path (url-filename parsed)))
|
||||
(ein:notebook-open (substring nbpath 0 (- (length nbpath) (length path)))
|
||||
(substring path 1) nil callback cbargs)))
|
||||
|
||||
;;;###autoload
|
||||
|
||||
(defun ein:notebooklist-load (&optional url-or-port)
|
||||
"Load notebook list but do not pop-up the notebook list buffer.
|
||||
|
||||
|
@ -844,7 +821,7 @@ in order to make this code work.
|
|||
|
||||
See also:
|
||||
`ein:connect-to-default-notebook', `ein:connect-default-notebook'."
|
||||
(ein:notebooklist-open url-or-port t))
|
||||
(ein:notebooklist-open url-or-port "" t))
|
||||
|
||||
|
||||
(defun ein:notebooklist-find-server-by-notebook-name (name)
|
||||
|
@ -855,7 +832,7 @@ See also:
|
|||
for ipython-version = (ein:$notebooklist-api-version nblist)
|
||||
do
|
||||
(if (>= ipython-version 3)
|
||||
(loop for note in (ein:make-content-hierarchy "" url-or-port)
|
||||
(loop for note in (ein:content-need-hierarchy url-or-port)
|
||||
when (equal (ein:$content-name note) name)
|
||||
do (return-from outer
|
||||
(list url-or-port (ein:$content-path note))))
|
||||
|
@ -866,7 +843,7 @@ See also:
|
|||
(format "%s/%s" (plist-get note :path) (plist-get note :name))))))))
|
||||
|
||||
(defun ein:notebooklist-open-notebook-by-file-name
|
||||
(&optional filename noerror buffer-callback)
|
||||
(&optional filename noerror buffer-callback)
|
||||
"Find the notebook named as same as the current file in the servers.
|
||||
Open the notebook if found. Note that this command will *not*
|
||||
upload the current file to the server.
|
||||
|
@ -901,18 +878,18 @@ FIMXE: document how to use `ein:notebooklist-find-file-callback'
|
|||
when I am convinced with the API."
|
||||
(ein:and-let* ((filename buffer-file-name)
|
||||
((string-match-p "\\.ipynb$" filename)))
|
||||
(ein:notebooklist-open-notebook-by-file-name
|
||||
filename t ein:notebooklist-find-file-buffer-callback)))
|
||||
(ein:notebooklist-open-notebook-by-file-name
|
||||
filename t ein:notebooklist-find-file-buffer-callback)))
|
||||
|
||||
|
||||
;;; Login
|
||||
|
||||
;;;###autoload
|
||||
|
||||
(defun ein:notebooklist-login (url-or-port password &optional retry-p)
|
||||
"Login to IPython notebook server."
|
||||
(interactive (list (ein:notebooklist-ask-url-or-port)
|
||||
(read-passwd "Password: ")))
|
||||
(ein:log 'debug "NOTEBOOKLIST-LOGIN: %s:%s" url-or-port password)
|
||||
(ein:query-singleton-ajax
|
||||
(list 'notebooklist-login url-or-port)
|
||||
(ein:url url-or-port "login")
|
||||
|
@ -964,6 +941,7 @@ Now you can open notebook list by `ein:notebooklist-open'." url-or-port))
|
|||
(ein:notebooklist-login--error-1 url-or-port)))
|
||||
|
||||
;;;###autoload
|
||||
|
||||
(defun ein:notebooklist-change-url-port (new-url-or-port)
|
||||
"Update the ipython/jupyter notebook server URL for all the
|
||||
notebooks currently opened from the current notebooklist buffer.
|
||||
|
@ -979,7 +957,7 @@ on all the notebooks opened from the current notebooklist."
|
|||
(open-nb (ein:notebook-opened-notebooks #'(lambda (nb)
|
||||
(equal (ein:$notebook-url-or-port nb)
|
||||
(ein:$notebooklist-url-or-port current-nblist))))))
|
||||
(ein:notebooklist-open new-url-or-port "/" t)
|
||||
(ein:notebooklist-open new-url-or-port "" t)
|
||||
(loop for x upfrom 0 by 1
|
||||
until (or (get-buffer (format ein:notebooklist-buffer-name-template new-url-or-port))
|
||||
(= x 100))
|
||||
|
@ -987,7 +965,7 @@ on all the notebooks opened from the current notebooklist."
|
|||
(dolist (nb open-nb)
|
||||
(ein:notebook-update-url-or-port new-url-or-port nb))
|
||||
(kill-buffer (ein:notebooklist-get-buffer old-url))
|
||||
(ein:notebooklist-open new-url-or-port "/" nil)))
|
||||
(ein:notebooklist-open new-url-or-port "" nil)))
|
||||
|
||||
(defun ein:notebooklist-change-url-port--deferred (new-url-or-port)
|
||||
(lexical-let* ((current-nblist ein:%notebooklist%)
|
||||
|
@ -999,22 +977,23 @@ on all the notebooks opened from the current notebooklist."
|
|||
(ein:$notebooklist-url-or-port current-nblist))))))
|
||||
(deferred:$
|
||||
(deferred:next
|
||||
(lambda ()
|
||||
(ein:notebooklist-open new-url-or-port "/" t)
|
||||
(loop until (get-buffer (format ein:notebooklist-buffer-name-template new-url-or-port))
|
||||
do (sit-for 0.1))))
|
||||
(lambda ()
|
||||
(ein:notebooklist-open new-url-or-port "" t)
|
||||
(loop until (get-buffer (format ein:notebooklist-buffer-name-template new-url-or-port))
|
||||
do (sit-for 0.1))))
|
||||
(deferred:nextc it
|
||||
(lambda ()
|
||||
(dolist (nb open-nb)
|
||||
(ein:notebook-update-url-or-port new-url-or-port nb))))
|
||||
(lambda ()
|
||||
(dolist (nb open-nb)
|
||||
(ein:notebook-update-url-or-port new-url-or-port nb))))
|
||||
(deferred:nextc it
|
||||
(lambda ()
|
||||
(kill-buffer (ein:notebooklist-get-buffer old-url))
|
||||
(ein:notebooklist-open new-url-or-port "/" nil))))))
|
||||
(lambda ()
|
||||
(kill-buffer (ein:notebooklist-get-buffer old-url))
|
||||
(ein:notebooklist-open new-url-or-port "" nil))))))
|
||||
|
||||
;;; Generic getter
|
||||
|
||||
|
||||
|
||||
(defun ein:get-url-or-port--notebooklist ()
|
||||
(when (ein:$notebooklist-p ein:%notebooklist%)
|
||||
(ein:$notebooklist-url-or-port ein:%notebooklist%)))
|
||||
|
@ -1022,6 +1001,7 @@ on all the notebooks opened from the current notebooklist."
|
|||
|
||||
;;; Notebook list mode
|
||||
|
||||
|
||||
(defun ein:notebooklist-prev-item () (interactive) (move-beginning-of-line 0))
|
||||
(defun ein:notebooklist-next-item () (interactive) (move-beginning-of-line 2))
|
||||
|
||||
|
@ -1046,7 +1026,7 @@ on all the notebooks opened from the current notebooklist."
|
|||
("New Junk Notebook" ein:junk-new)))))
|
||||
|
||||
(defun ein:notebooklist-revert-wrapper (&optional ignore-auto noconfirm preserve-modes)
|
||||
(ein:notebooklist-reload))
|
||||
(ein:notebooklist-reload ein:%notebooklist%))
|
||||
|
||||
(define-derived-mode ein:notebooklist-mode special-mode "ein:notebooklist"
|
||||
"IPython notebook list mode.
|
||||
|
|
|
@ -158,7 +158,9 @@ KEY, then call `request' with URL and SETTINGS. KEY is compared by
|
|||
(setq settings (plist-put settings :timeout (/ timeout 1000.0))))
|
||||
(ein:aif (gethash key ein:query-running-process-table)
|
||||
(unless (request-response-done-p it)
|
||||
(request-abort it))) ; This will run callbacks
|
||||
;; This seems to result in clobbered cookie jars
|
||||
;;(request-abort it) ; This will run callbacks
|
||||
(ein:log 'info "Race! %s %s" key (request-response-data it))))
|
||||
(let ((response (apply #'request (url-encode-url (ein:jupyterhub-correct-query-url-maybe url))
|
||||
(ein:query-prepare-header url settings))))
|
||||
(puthash key response ein:query-running-process-table)
|
||||
|
|
|
@ -298,10 +298,13 @@ given in the session parameter."
|
|||
(when (and (stringp session) (string= session "none"))
|
||||
(error "You must specify a notebook or kernelspec as the session variable for ein code blocks."))
|
||||
(multiple-value-bind (url-or-port path) (ein:org-babel-parse-session session)
|
||||
(if (null (gethash url-or-port ein:available-kernelspecs))
|
||||
(ein:query-kernelspecs url-or-port))
|
||||
(if (null kernelspec)
|
||||
(setq kernelspec (ein:get-kernelspec url-or-port "default")))
|
||||
(when (null kernelspec)
|
||||
;; Now is not the time to be getting kernelspecs.
|
||||
;; If I must do so, need to inject a deferred callback chain like
|
||||
;; in ein:notebooklist
|
||||
;; (if (null (gethash url-or-port ein:available-kernelspecs))
|
||||
;; (ein:query-kernelspecs url-or-port))
|
||||
(setq kernelspec (ein:get-kernelspec url-or-port "default")))
|
||||
(cond ((null path)
|
||||
(let* ((name ein:org-babel-default-session-name)
|
||||
(new-session (format "%s/%s" url-or-port name)))
|
||||
|
|
|
@ -45,17 +45,17 @@
|
|||
;; "bindings are lexical... all references to the named functions
|
||||
;; must appear physically within the body of the cl-flet"
|
||||
(flet ((pop-to-buffer (buf) buf)
|
||||
(ein:query-ipython-version (&optional url-or-port force) 3)
|
||||
(ein:need-ipython-version (url-or-port) 3)
|
||||
(ein:notebook-start-kernel (notebook))
|
||||
(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:query-ipython-version)))
|
||||
(ein:kernel-new 8888 "/kernels" (ein:$notebook-events notebook) (ein:need-ipython-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
|
||||
; populating its raw_content field with DATA's content field
|
||||
(ein:notebook-request-open-callback notebook (ein:new-content content nil :data data))
|
||||
(ein:notebook-request-open-callback notebook (ein:new-content (ein:$notebook-url-or-port notebook) (ein:$notebook-notebook-path notebook) data))
|
||||
(ein:notebook-buffer notebook)))))
|
||||
|
||||
(defun ein:testing-notebook-make-data (name path cells)
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
;;; Code:
|
||||
|
||||
(require 'ein-log)
|
||||
(require 'request)
|
||||
|
||||
(defmacro ein:setq-if-not (sym val)
|
||||
`(unless ,sym (setq ,sym ,val)))
|
||||
|
@ -36,9 +37,11 @@
|
|||
(defvar ein:testing-dump-file-messages nil
|
||||
"File to save the ``*Messages*`` buffer.")
|
||||
|
||||
(defvar ein:testing-dump-file-debug nil)
|
||||
(defvar ein:testing-dump-file-server nil
|
||||
"File to save `ein:jupyter-server-buffer-name`.")
|
||||
|
||||
(defvar ein:testing-dump-server-log nil)
|
||||
(defvar ein:testing-dump-file-request nil
|
||||
"File to save `request-log-buffer-name`.")
|
||||
|
||||
(defun ein:testing-save-buffer (buffer-or-name file-name)
|
||||
(when (and buffer-or-name (get-buffer buffer-or-name) file-name)
|
||||
|
@ -47,29 +50,28 @@
|
|||
|
||||
(defun ein:testing-dump-logs ()
|
||||
(ein:testing-save-buffer "*Messages*" ein:testing-dump-file-messages)
|
||||
(ein:testing-save-buffer "*ein:jupyter-server*" ein:testing-dump-server-log)
|
||||
(ein:testing-save-buffer ein:log-all-buffer-name ein:testing-dump-file-log))
|
||||
(ein:testing-save-buffer "*ein:jupyter-server*" ein:testing-dump-file-server)
|
||||
(ein:testing-save-buffer ein:log-all-buffer-name ein:testing-dump-file-log)
|
||||
(ein:testing-save-buffer request-log-buffer-name ein:testing-dump-file-request))
|
||||
|
||||
(defvar ein:testing-dump-logs--saved nil)
|
||||
|
||||
(defun ein:testing-dump-logs-noerror ()
|
||||
(if ein:testing-dump-logs--saved
|
||||
(message "EIN:TESTING-DUMP-LOGS-NOERROR called but already saved.")
|
||||
(condition-case err
|
||||
(progn (ein:testing-dump-logs)
|
||||
(setq ein:testing-dump-logs--saved t))
|
||||
(error
|
||||
(message "Error while executing EIN:TESTING-DUMP-LOGS. err = %S"
|
||||
err)
|
||||
(when ein:testing-dump-file-debug
|
||||
(signal (car err) (cdr err)))))))
|
||||
(defun ein:testing-wait-until (predicate &optional predargs ms interval)
|
||||
"Wait until PREDICATE function returns non-`nil'.
|
||||
PREDARGS is argument list for the PREDICATE function.
|
||||
MS is milliseconds to wait. INTERVAL is polling interval in milliseconds."
|
||||
(let* ((interval (or interval 300))
|
||||
(count (max 1 (if ms (truncate (/ ms interval)) 25))))
|
||||
(unless (loop repeat count
|
||||
when (apply predicate predargs)
|
||||
return t
|
||||
do (sleep-for 0 interval))
|
||||
(error "Timeout: %s" predicate))))
|
||||
|
||||
(defadvice ert-run-tests-batch (after ein:testing-dump-logs-hook activate)
|
||||
"Hook `ein:testing-dump-logs-noerror' because `kill-emacs-hook'
|
||||
"Hook `ein:testing-dump-logs-hook' because `kill-emacs-hook'
|
||||
is not run in batch mode before Emacs 24.1."
|
||||
(ein:testing-dump-logs-noerror))
|
||||
(ein:testing-dump-logs))
|
||||
|
||||
(add-hook 'kill-emacs-hook #'ein:testing-dump-logs-noerror)
|
||||
(add-hook 'kill-emacs-hook #'ein:testing-dump-logs)
|
||||
|
||||
(provide 'ein-testing)
|
||||
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
|
||||
(defun eintest:notebooklist-make-empty (&optional url-or-port)
|
||||
"Make empty notebook list buffer."
|
||||
(flet ((ein:query-kernelspecs (url-or-port &optional force-refresh))
|
||||
(ein:content-query-sessions (session-hash url-or-port &optional force-sync)))
|
||||
(ein:notebooklist-url-retrieve-callback
|
||||
(flet ((ein:need-kernelspecs (url-or-port))
|
||||
(ein:content-query-sessions (session-hash url-or-port)))
|
||||
(ein:notebooklist-open--finish
|
||||
(make-ein:$content :url-or-port (or url-or-port ein:testing-notebook-dummy-url)
|
||||
:ipython-version 3
|
||||
:path ""))))
|
||||
|
|
|
@ -16,29 +16,12 @@
|
|||
|
||||
(setq message-log-max t)
|
||||
|
||||
(defun ein:testing-wait-until (message predicate &optional predargs max-count)
|
||||
"Wait until PREDICATE function returns non-`nil'.
|
||||
PREDARGS is argument list for the PREDICATE function.
|
||||
Make MAX-COUNT larger \(default 50) to wait longer before timeout."
|
||||
(ein:log 'debug "TESTING-WAIT-UNTIL start")
|
||||
(ein:log 'debug "TESTING-WAIT-UNTIL waiting on: %s" message)
|
||||
(unless max-count (setq max-count 50))
|
||||
(unless (loop repeat max-count
|
||||
when (apply predicate predargs)
|
||||
return t
|
||||
;; borrowed from `deferred:sync!':
|
||||
do (sit-for 0.2)
|
||||
do (sleep-for 0.2))
|
||||
(error "Timeout"))
|
||||
(ein:log 'debug "TESTING-WAIT-UNTIL end"))
|
||||
|
||||
(defun ein:testing-get-notebook-by-name (url-or-port notebook-name &optional path)
|
||||
(ein:log 'debug "TESTING-GET-NOTEBOOK-BY-NAME start")
|
||||
(when path
|
||||
(setq notebook-name (format "%s/%s" path notebook-name)))
|
||||
(ein:notebooklist-open url-or-port path t)
|
||||
(ein:testing-wait-until "ein:notebooklist-open"
|
||||
(lambda () (and (bufferp (get-buffer (format ein:notebooklist-buffer-name-template url-or-port)))
|
||||
(ein:testing-wait-until (lambda () (and (bufferp (get-buffer (format ein:notebooklist-buffer-name-template url-or-port)))
|
||||
(ein:notebooklist-get-buffer url-or-port))))
|
||||
(with-current-buffer (ein:notebooklist-get-buffer url-or-port)
|
||||
(prog1
|
||||
|
@ -60,31 +43,25 @@ Make MAX-COUNT larger \(default 50) to wait longer before timeout."
|
|||
(ein:notebooklist-new-notebook url-or-port kernelspec path
|
||||
(lambda (&rest -ignore-)
|
||||
(setq created t)))
|
||||
(ein:testing-wait-until "ein:notebooklist-new-notebook"
|
||||
(lambda () created)))
|
||||
(ein:testing-wait-until (lambda () created)))
|
||||
(prog1
|
||||
(ein:testing-get-notebook-by-name url-or-port "Untitled.ipynb" path)
|
||||
(ein:log 'debug "TESTING-GET-UNTITLED0-OR-CREATE end")))))
|
||||
|
||||
(defvar ein:notebooklist-after-open-hook nil)
|
||||
|
||||
(defadvice ein:notebooklist-url-retrieve-callback
|
||||
(after ein:testing-notebooklist-url-retrieve-callback activate)
|
||||
(defadvice ein:notebooklist-open--finish
|
||||
(after ein:testing-notebooklist-open--finish activate)
|
||||
"Advice to add `ein:notebooklist-after-open-hook'."
|
||||
(run-hooks 'ein:notebooklist-after-open-hook))
|
||||
|
||||
(defun ein:testing-delete-notebook (url-or-port notebook &optional path)
|
||||
(ein:log 'debug "TESTING-DELETE-NOTEBOOK start")
|
||||
(ein:notebooklist-open url-or-port (ein:$notebook-notebook-path notebook) t)
|
||||
(ein:testing-wait-until "ein:notebooklist-open"
|
||||
(lambda ()
|
||||
(bufferp (get-buffer (format ein:notebooklist-buffer-name-template url-or-port))))
|
||||
nil 50)
|
||||
(ein:testing-wait-until (lambda ()
|
||||
(bufferp (get-buffer (format ein:notebooklist-buffer-name-template url-or-port)))))
|
||||
(with-current-buffer (ein:notebooklist-get-buffer url-or-port)
|
||||
(ein:testing-wait-until "ein:notebooklist-get-buffer"
|
||||
(lambda () (eql major-mode 'ein:notebooklist-mode))
|
||||
nil
|
||||
50)
|
||||
(ein:testing-wait-until (lambda () (eql major-mode 'ein:notebooklist-mode)))
|
||||
(ein:log 'debug "TESTING-DELETE-NOTEBOOK deleting notebook")
|
||||
(ein:notebooklist-delete-notebook (ein:$notebook-notebook-path notebook)))
|
||||
(ein:log 'debug "TESTING-DELETE-NOTEBOOK end"))
|
||||
|
@ -103,29 +80,24 @@ Make MAX-COUNT larger \(default 50) to wait longer before timeout."
|
|||
(ein:log 'verbose "ERT OPEN-NOTEBOOKLIST start")
|
||||
(ein:notebooklist-open *ein:testing-port* "/" t)
|
||||
(ein:testing-wait-until
|
||||
"ein:notebooklist-open"
|
||||
(lambda ()
|
||||
(ein:notebooklist-get-buffer *ein:testing-port*))
|
||||
nil 5000)
|
||||
(ein:notebooklist-get-buffer *ein:testing-port*)))
|
||||
(with-current-buffer (ein:notebooklist-get-buffer *ein:testing-port*)
|
||||
(should (eql major-mode 'ein:notebooklist-mode))))
|
||||
|
||||
|
||||
(ert-deftest 00-query-kernelspecs ()
|
||||
(ein:log 'info "ERT QUERY-KERNELSPECS")
|
||||
(ein:log 'info (format "ERT QUERY-KERNELSPECS: Pre-query kernelspec count %s." (hash-table-count ein:available-kernelspecs)))
|
||||
(ein:query-kernelspecs *ein:testing-port*)
|
||||
(should (>= (hash-table-count ein:available-kernelspecs) 1))
|
||||
(ein:log 'info (format "ERT QUERY-KERNELSPECS: Post-query kernelspec %S." (ein:list-available-kernels *ein:testing-port*))))
|
||||
(ein:log 'info (format "ERT QUERY-KERNELSPECS: Pre-query kernelspec count %s." (hash-table-count *ein:kernelspecs*)))
|
||||
(should (>= (hash-table-count *ein:kernelspecs*) 1))
|
||||
(ein:log 'info (format "ERT QUERY-KERNELSPECS: Post-query kernelspec %S." (ein:need-kernelspecs *ein:testing-port*))))
|
||||
|
||||
(ert-deftest 10-get-untitled0-or-create ()
|
||||
(ein:log 'verbose "ERT TESTING-GET-UNTITLED0-OR-CREATE start")
|
||||
(let ((notebook (ein:testing-get-untitled0-or-create *ein:testing-port*)))
|
||||
(ein:testing-wait-until
|
||||
"ein:testing-get-untitled0-or-create"
|
||||
(lambda () (ein:aand (ein:$notebook-kernel notebook)
|
||||
(ein:kernel-live-p it)))
|
||||
nil)
|
||||
(ein:kernel-live-p it))))
|
||||
(with-current-buffer (ein:notebook-buffer notebook)
|
||||
(should (equal (ein:$notebook-notebook-name ein:%notebook%)
|
||||
"Untitled.ipynb"))))
|
||||
|
@ -137,12 +109,10 @@ Make MAX-COUNT larger \(default 50) to wait longer before timeout."
|
|||
(ein:log 'verbose "ERT TESTING-DELETE-UNTITLED0 creating notebook")
|
||||
(let ((notebook (ein:testing-get-untitled0-or-create *ein:testing-port*)))
|
||||
(ein:testing-wait-until
|
||||
"ein:test-get-untitled0-or-create"
|
||||
(lambda ()
|
||||
(ein:aand notebook
|
||||
(ein:$notebook-kernel it)
|
||||
(ein:kernel-live-p it)))
|
||||
nil 50)
|
||||
(ein:kernel-live-p it))))
|
||||
(ein:log 'verbose "ERT TESTING-DELETE-UNTITLED0 deleting notebook")
|
||||
(ein:testing-delete-notebook *ein:testing-port* notebook))
|
||||
(ein:log 'verbose
|
||||
|
@ -157,17 +127,13 @@ Make MAX-COUNT larger \(default 50) to wait longer before timeout."
|
|||
(ert-deftest 11-notebook-execute-current-cell-simple ()
|
||||
(let ((notebook (ein:testing-get-untitled0-or-create *ein:testing-port*)))
|
||||
(ein:testing-wait-until
|
||||
"ein:testing-get-untitled0-or-create"
|
||||
(lambda () (ein:aand (ein:$notebook-kernel notebook)
|
||||
(ein:kernel-live-p it)))
|
||||
nil 50)
|
||||
(ein:kernel-live-p it))))
|
||||
(with-current-buffer (ein:notebook-buffer notebook)
|
||||
(call-interactively #'ein:worksheet-insert-cell-below)
|
||||
(insert "a = 100\na")
|
||||
(let ((cell (call-interactively #'ein:worksheet-execute-cell)))
|
||||
(ein:testing-wait-until "ein:worksheet-execute-cell"
|
||||
(lambda () (not (slot-value cell 'running)))
|
||||
nil))
|
||||
(ein:testing-wait-until (lambda () (not (slot-value cell 'running)))))
|
||||
;; (message "%s" (buffer-string))
|
||||
(save-excursion
|
||||
(should (search-forward-regexp "Out \\[[0-9]+\\]" nil t))
|
||||
|
@ -183,7 +149,6 @@ See the definition of `create-image' for how it works."
|
|||
(ert-deftest 12-notebook-execute-current-cell-pyout-image ()
|
||||
(let ((notebook (ein:testing-get-untitled0-or-create *ein:testing-port*)))
|
||||
(ein:testing-wait-until
|
||||
"ein:testing-get-untitled0-or-create"
|
||||
(lambda () (ein:aand (ein:$notebook-kernel notebook)
|
||||
(ein:kernel-live-p it))))
|
||||
(with-current-buffer (ein:notebook-buffer notebook)
|
||||
|
@ -197,10 +162,7 @@ See the definition of `create-image' for how it works."
|
|||
;; It seems in this case, watching `:running' does not work
|
||||
;; well sometimes. Probably "output reply" (iopub) comes
|
||||
;; before "execute reply" in this case.
|
||||
(ein:testing-wait-until "ein:worksheet-execute-cell"
|
||||
(lambda () (slot-value cell 'outputs))
|
||||
nil
|
||||
50)
|
||||
(ein:testing-wait-until (lambda () (slot-value cell 'outputs)))
|
||||
;; This cell has only one input
|
||||
(should (= (length (oref cell :outputs)) 1))
|
||||
;; This output is a SVG image
|
||||
|
@ -220,17 +182,14 @@ See the definition of `create-image' for how it works."
|
|||
(ert-deftest 13-notebook-execute-current-cell-stream ()
|
||||
(let ((notebook (ein:testing-get-untitled0-or-create *ein:testing-port*)))
|
||||
(ein:testing-wait-until
|
||||
"ein:testing-get-untitled0-or-create"
|
||||
(lambda () (ein:aand (ein:$notebook-kernel notebook)
|
||||
(ein:kernel-live-p it)))
|
||||
nil 50)
|
||||
(ein:kernel-live-p it))))
|
||||
(with-current-buffer (ein:notebook-buffer notebook)
|
||||
(call-interactively #'ein:worksheet-insert-cell-below)
|
||||
(insert "print('Hello')")
|
||||
(let ((cell (call-interactively #'ein:worksheet-execute-cell)))
|
||||
(ein:testing-wait-until "ein:worksheet-execute-cell"
|
||||
(lambda () (not (oref cell :running)))
|
||||
nil))
|
||||
(ein:testing-wait-until (lambda () (not (oref cell :running)))
|
||||
))
|
||||
(save-excursion
|
||||
(should-not (search-forward-regexp "Out \\[[0-9]+\\]" nil t))
|
||||
(should (search-forward-regexp "^Hello$" nil t))))))
|
||||
|
@ -238,28 +197,23 @@ See the definition of `create-image' for how it works."
|
|||
(ert-deftest 14-notebook-execute-current-cell-question ()
|
||||
(let ((notebook (ein:testing-get-untitled0-or-create *ein:testing-port*)))
|
||||
(ein:testing-wait-until
|
||||
"ein:testing-get-untitled0-or-create"
|
||||
(lambda () (ein:aand (ein:$notebook-kernel notebook)
|
||||
(ein:kernel-live-p it)))
|
||||
nil 50)
|
||||
)
|
||||
(with-current-buffer (ein:notebook-buffer notebook)
|
||||
(call-interactively #'ein:worksheet-insert-cell-below)
|
||||
(insert "range?")
|
||||
(let ((cell (call-interactively #'ein:worksheet-execute-cell)))
|
||||
(ein:testing-wait-until
|
||||
"ein:worksheet-execute-cell"
|
||||
(lambda () (not (oref cell :running)))
|
||||
nil 50))
|
||||
(lambda () (not (oref cell :running)))))
|
||||
(with-current-buffer (get-buffer (ein:$notebook-pager notebook))
|
||||
(should (search-forward "Docstring:"))))))
|
||||
|
||||
(ert-deftest 15-notebook-request-help ()
|
||||
(let ((notebook (ein:testing-get-untitled0-or-create *ein:testing-port*)))
|
||||
(ein:testing-wait-until
|
||||
"ein:testing-get-untitled0-or-create"
|
||||
(lambda () (ein:aand (ein:$notebook-kernel notebook)
|
||||
(ein:kernel-live-p it)))
|
||||
nil)
|
||||
(ein:kernel-live-p it))))
|
||||
(with-current-buffer (ein:notebook-buffer notebook)
|
||||
(call-interactively #'ein:worksheet-insert-cell-below)
|
||||
(let ((pager-name (ein:$notebook-pager ein:%notebook%)))
|
||||
|
@ -269,9 +223,7 @@ See the definition of `create-image' for how it works."
|
|||
(call-interactively #'ein:pytools-request-help)
|
||||
;; Pager buffer will be created when got the response
|
||||
(ein:testing-wait-until
|
||||
"ein:pythools-request-help"
|
||||
(lambda () (get-buffer pager-name))
|
||||
nil)
|
||||
(lambda () (get-buffer pager-name)))
|
||||
(with-current-buffer (get-buffer pager-name)
|
||||
(should (search-forward "Docstring:")))))))
|
||||
|
||||
|
@ -280,12 +232,10 @@ See the definition of `create-image' for how it works."
|
|||
|
||||
(let ((notebook (ein:testing-get-untitled0-or-create *ein:testing-port*)))
|
||||
(ein:testing-wait-until
|
||||
"ein:testing-get-untitled0-or-create"
|
||||
(lambda () (ein:aand (ein:$notebook-kernel notebook)
|
||||
(ein:kernel-live-p it)))
|
||||
nil)
|
||||
(ein:kernel-live-p it))))
|
||||
(cl-letf (((symbol-function 'y-or-n-p) (lambda (prompt) t)))
|
||||
(ein:jupyter-server-stop t ein:testing-dump-server-log))
|
||||
(ein:jupyter-server-stop t ein:testing-dump-file-server))
|
||||
(should-not (processp %ein:jupyter-server-session%))
|
||||
(cl-flet ((orphans-find (pid) (search (ein:$kernel-kernel-id (ein:$notebook-kernel notebook)) (alist-get 'args (process-attributes pid)))))
|
||||
(should-not (loop repeat 10
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
(require 'ein-dev)
|
||||
(require 'ein-testing)
|
||||
(require 'ein-jupyter)
|
||||
(require 'ein-notebooklist)
|
||||
(require 'deferred)
|
||||
|
||||
(ein:log 'info "Starting jupyter notebook server.")
|
||||
|
@ -17,20 +18,21 @@
|
|||
(defvar *ein:testing-port* nil)
|
||||
(defvar *ein:testing-token* nil)
|
||||
|
||||
(ein:setq-if-not ein:testing-dump-file-log "./log/testfunc.log")
|
||||
(ein:setq-if-not ein:testing-dump-file-messages "./log/testfunc.messages")
|
||||
(ein:setq-if-not ein:testing-dump-server-log "./log/testfunc.server")
|
||||
(setq ein:testing-dump-file-log (concat default-directory "log/testfunc.log"))
|
||||
(setq ein:testing-dump-file-messages (concat default-directory "log/testfunc.messages"))
|
||||
(setq ein:testing-dump-file-server (concat default-directory "log/testfunc.server"))
|
||||
(setq ein:testing-dump-file-request (concat default-directory "log/testfunc.request"))
|
||||
(setq message-log-max t)
|
||||
(setq ein:force-sync t)
|
||||
(setq ein:jupyter-server-run-timeout 120000)
|
||||
(setq ein:content-query-timeout nil)
|
||||
(setq ein:query-timeout nil)
|
||||
|
||||
(ein:log 'info "Staring local jupyter notebook server.")
|
||||
|
||||
(setq ein:jupyter-server-args '("--no-browser" "--debug"))
|
||||
|
||||
(ein:dev-start-debug)
|
||||
(deferred:sync! (ein:jupyter-server-start *ein:testing-jupyter-server-command* *ein:testing-jupyter-server-directory*))
|
||||
;; (ein:testing-wait-until (lambda () (not (null (ein:notebooklist-list))))
|
||||
;; nil 120000 5000)
|
||||
(multiple-value-bind (url token) (ein:jupyter-server-conn-info)
|
||||
(ein:log 'info (format "testing-start-server url: %s, token: %s" url token))
|
||||
(setq *ein:testing-port* url)
|
||||
|
|
|
@ -145,7 +145,7 @@ class TestRunner(BaseRunner):
|
|||
self.notebook_dir = os.path.join(EIN_ROOT, "test")
|
||||
self.lispvars = {
|
||||
'ein:testing-dump-file-log': quote(self.logpath_log),
|
||||
'ein:testing-dump-server-log': quote(self.logpath_server),
|
||||
'ein:testing-dump-file-server': quote(self.logpath_server),
|
||||
'ein:testing-dump-file-messages': quote(self.logpath_messages),
|
||||
'ein:log-level': self.ein_log_level,
|
||||
'ein:force-sync': "t",
|
||||
|
|
Loading…
Add table
Reference in a new issue