mirror of
https://github.com/vale981/emacs-ipython-notebook
synced 2025-03-05 09:01:40 -05:00
replace ein:aif with aif
This commit is contained in:
parent
ab87b7cb6c
commit
e12a33588d
32 changed files with 298 additions and 288 deletions
1
Cask
1
Cask
|
@ -5,6 +5,7 @@
|
||||||
(files "lisp/*.el" "lisp/*.py")
|
(files "lisp/*.el" "lisp/*.py")
|
||||||
|
|
||||||
(development
|
(development
|
||||||
|
(depends-on "anaphora")
|
||||||
(depends-on "websocket")
|
(depends-on "websocket")
|
||||||
(depends-on "request")
|
(depends-on "request")
|
||||||
(depends-on "dash")
|
(depends-on "dash")
|
||||||
|
|
|
@ -267,7 +267,6 @@ Note that the below work best with current (> v4.3.1) versions of jupyter.
|
||||||
.. el:variable:: ein:jupyter-server-use-subcommand
|
.. el:variable:: ein:jupyter-server-use-subcommand
|
||||||
.. el:variable:: ein:jupyter-default-notebook-directory
|
.. el:variable:: ein:jupyter-default-notebook-directory
|
||||||
.. el:variable:: ein:jupyter-server-args
|
.. el:variable:: ein:jupyter-server-args
|
||||||
.. el:variable:: ein:jupyter-server-buffer-name
|
|
||||||
|
|
||||||
Notebook list
|
Notebook list
|
||||||
^^^^^^^^^^^^^
|
^^^^^^^^^^^^^
|
||||||
|
|
|
@ -152,9 +152,9 @@
|
||||||
(multiple-value-bind (url-or-port token) (ein:jupyter-server-conn-info)
|
(multiple-value-bind (url-or-port token) (ein:jupyter-server-conn-info)
|
||||||
(let (notebook)
|
(let (notebook)
|
||||||
(with-current-buffer (ein:notebooklist-get-buffer url-or-port)
|
(with-current-buffer (ein:notebooklist-get-buffer url-or-port)
|
||||||
(ein:and-let* ((kslist (mapcar #'car (ein:list-available-kernels url-or-port)))
|
(-when-let* ((kslist (mapcar #'car (ein:list-available-kernels url-or-port)))
|
||||||
(found (seq-some (lambda (x) (and (search prefix x) x)) kslist))
|
(found (seq-some (lambda (x) (and (search prefix x) x)) kslist))
|
||||||
(ks (ein:get-kernelspec url-or-port found)))
|
(ks (ein:get-kernelspec url-or-port found)))
|
||||||
(setq notebook (ein:testing-new-notebook url-or-port ks))))
|
(setq notebook (ein:testing-new-notebook url-or-port ks))))
|
||||||
(should notebook)
|
(should notebook)
|
||||||
(let ((buf-name (format ein:notebook-buffer-name-template
|
(let ((buf-name (format ein:notebook-buffer-name-template
|
||||||
|
@ -175,10 +175,10 @@
|
||||||
(cl-letf (((symbol-function 'y-or-n-p) #'ignore))
|
(cl-letf (((symbol-function 'y-or-n-p) #'ignore))
|
||||||
(ein:jupyter-server-stop t))
|
(ein:jupyter-server-stop t))
|
||||||
(loop repeat 10
|
(loop repeat 10
|
||||||
with buffer = (get-buffer ein:jupyter-server-buffer-name)
|
with buffer = (get-buffer *ein:jupyter-server-buffer-name*)
|
||||||
until (null (get-buffer-process buffer))
|
until (null (get-buffer-process buffer))
|
||||||
do (sleep-for 0 1000)
|
do (sleep-for 0 1000)
|
||||||
finally do (ein:aif (get-buffer-process buffer) (delete-process it)))
|
finally do (aif (get-buffer-process buffer) (delete-process it)))
|
||||||
(condition-case err
|
(condition-case err
|
||||||
(ein:testing-wait-until (lambda ()
|
(ein:testing-wait-until (lambda ()
|
||||||
(null (ein:notebooklist-keys)))
|
(null (ein:notebooklist-keys)))
|
||||||
|
@ -187,7 +187,7 @@
|
||||||
(clrhash ein:notebooklist-map)))
|
(clrhash ein:notebooklist-map)))
|
||||||
(unless final-p
|
(unless final-p
|
||||||
(When "I clear log expr \"ein:log-all-buffer-name\"")
|
(When "I clear log expr \"ein:log-all-buffer-name\"")
|
||||||
(When "I clear log expr \"ein:jupyter-server-buffer-name\""))))
|
(When "I clear log expr \"*ein:jupyter-server-buffer-name*\""))))
|
||||||
|
|
||||||
(When "^I start and login to jupyterhub configured \"\\(.*\\)\"$"
|
(When "^I start and login to jupyterhub configured \"\\(.*\\)\"$"
|
||||||
(lambda (config)
|
(lambda (config)
|
||||||
|
@ -349,8 +349,8 @@
|
||||||
(lambda (negate bogey)
|
(lambda (negate bogey)
|
||||||
(ein:testing-wait-until
|
(ein:testing-wait-until
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(let* ((says (s-contains? (s-replace "\\n" "\n" bogey) (buffer-string))))
|
(let ((says (s-contains? (s-replace "\\n" "\n" bogey) (buffer-string))))
|
||||||
(ein:aif (if negate (not says) says)
|
(aif (if negate (not says) says)
|
||||||
it
|
it
|
||||||
(when (with-current-buffer ein:log-all-buffer-name
|
(when (with-current-buffer ein:log-all-buffer-name
|
||||||
(search "WS closed unexpectedly" (buffer-string)))
|
(search "WS closed unexpectedly" (buffer-string)))
|
||||||
|
|
|
@ -62,7 +62,7 @@
|
||||||
do (sleep-for 0 1000)
|
do (sleep-for 0 1000)
|
||||||
finally do (when extant
|
finally do (when extant
|
||||||
(ein:display-warning (format "cannot del %s" path)))))))
|
(ein:display-warning (format "cannot del %s" path)))))))
|
||||||
(ein:aif (ein:notebook-opened-notebooks)
|
(aif (ein:notebook-opened-notebooks)
|
||||||
(loop for nb in it
|
(loop for nb in it
|
||||||
for path = (ein:$notebook-notebook-path nb)
|
for path = (ein:$notebook-notebook-path nb)
|
||||||
do (ein:log 'debug "Notebook %s still open" path)
|
do (ein:log 'debug "Notebook %s still open" path)
|
||||||
|
@ -72,6 +72,7 @@
|
||||||
(ein:dev-start-debug)
|
(ein:dev-start-debug)
|
||||||
(cl-assert (boundp 'company-frontends))
|
(cl-assert (boundp 'company-frontends))
|
||||||
(custom-set-variables '(company-frontends nil)
|
(custom-set-variables '(company-frontends nil)
|
||||||
|
'(ein:jupyter-use-docker-stacks nil)
|
||||||
'(python-indent-guess-indent-offset-verbose nil))
|
'(python-indent-guess-indent-offset-verbose nil))
|
||||||
(setq ein:jupyter-default-kernel
|
(setq ein:jupyter-default-kernel
|
||||||
(loop with cand = ""
|
(loop with cand = ""
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
(traceback . ,(plist-get output :traceback))))
|
(traceback . ,(plist-get output :traceback))))
|
||||||
|
|
||||||
(defun ein:cell-execute-result-output-to-json (output)
|
(defun ein:cell-execute-result-output-to-json (output)
|
||||||
(let ((data (ein:aif (plist-get output :text)
|
(let ((data (aif (plist-get output :text)
|
||||||
`("text/plain" . ,it)
|
`("text/plain" . ,it)
|
||||||
(plist-get output :data))))
|
(plist-get output :data))))
|
||||||
`((output_type . "execute_result")
|
`((output_type . "execute_result")
|
||||||
|
@ -76,4 +76,3 @@
|
||||||
collect (list (cdr prop) (plist-get output-plist (cdr prop)))))
|
collect (list (cdr prop) (plist-get output-plist (cdr prop)))))
|
||||||
|
|
||||||
(provide 'ein-cell-output)
|
(provide 'ein-cell-output)
|
||||||
|
|
||||||
|
|
|
@ -269,9 +269,9 @@ a number will limit the number of lines in a cell output."
|
||||||
(ein:oset-if-empty cell 'outputs (plist-get data :outputs))
|
(ein:oset-if-empty cell 'outputs (plist-get data :outputs))
|
||||||
(ein:oset-if-empty cell 'input (or (plist-get data :input)
|
(ein:oset-if-empty cell 'input (or (plist-get data :input)
|
||||||
(plist-get data :source)))
|
(plist-get data :source)))
|
||||||
(ein:aif (plist-get data :prompt_number)
|
(aif (plist-get data :prompt_number)
|
||||||
(ein:oset-if-empty cell 'input-prompt-number it)
|
(ein:oset-if-empty cell 'input-prompt-number it)
|
||||||
(ein:aif (plist-get data :execution_count)
|
(aif (plist-get data :execution_count)
|
||||||
(ein:oset-if-empty cell 'input-prompt-number it)))
|
(ein:oset-if-empty cell 'input-prompt-number it)))
|
||||||
(ein:oset-if-empty cell 'collapsed
|
(ein:oset-if-empty cell 'collapsed
|
||||||
(let ((v (or (plist-get data :collapsed)
|
(let ((v (or (plist-get data :collapsed)
|
||||||
|
@ -281,13 +281,13 @@ a number will limit the number of lines in a cell output."
|
||||||
cell)
|
cell)
|
||||||
|
|
||||||
(cl-defmethod ein:cell-init ((cell ein:textcell) data)
|
(cl-defmethod ein:cell-init ((cell ein:textcell) data)
|
||||||
(ein:aif (plist-get data :source)
|
(aif (plist-get data :source)
|
||||||
(setf (slot-value cell 'input) it))
|
(setf (slot-value cell 'input) it))
|
||||||
cell)
|
cell)
|
||||||
|
|
||||||
(cl-defmethod ein:cell-init ((cell ein:headingcell) data) ;; FIXME: Was :after method
|
(cl-defmethod ein:cell-init ((cell ein:headingcell) data) ;; FIXME: Was :after method
|
||||||
(cl-call-next-method)
|
(cl-call-next-method)
|
||||||
(ein:aif (plist-get data :level)
|
(aif (plist-get data :level)
|
||||||
(setf (slot-value cell 'level) it))
|
(setf (slot-value cell 'level) it))
|
||||||
cell)
|
cell)
|
||||||
|
|
||||||
|
@ -387,14 +387,14 @@ a number will limit the number of lines in a cell output."
|
||||||
(nth index (plist-get element prop)))
|
(nth index (plist-get element prop)))
|
||||||
(case prop
|
(case prop
|
||||||
(:after-input
|
(:after-input
|
||||||
(ein:aif (nth 0 (plist-get element :output))
|
(aif (nth 0 (plist-get element :output))
|
||||||
it
|
it
|
||||||
(plist-get element :footer)))
|
(plist-get element :footer)))
|
||||||
(:after-output (plist-get element :footer))
|
(:after-output (plist-get element :footer))
|
||||||
(:before-input (plist-get element :prompt))
|
(:before-input (plist-get element :prompt))
|
||||||
(:before-output (plist-get element :input))
|
(:before-output (plist-get element :input))
|
||||||
(:last-output
|
(:last-output
|
||||||
(ein:aif (plist-get element :output)
|
(aif (plist-get element :output)
|
||||||
(car (last it))
|
(car (last it))
|
||||||
(plist-get element :input)))
|
(plist-get element :input)))
|
||||||
(t (cl-call-next-method))))))
|
(t (cl-call-next-method))))))
|
||||||
|
@ -965,7 +965,7 @@ prettified text thus be used instead of HTML type."
|
||||||
ein:output-types-html-preferred))
|
ein:output-types-html-preferred))
|
||||||
|
|
||||||
(defun ein:fix-mime-type (type)
|
(defun ein:fix-mime-type (type)
|
||||||
(ein:aif (assoc type ein:mime-type-map)
|
(aif (assoc type ein:mime-type-map)
|
||||||
(cdr it)
|
(cdr it)
|
||||||
type))
|
type))
|
||||||
|
|
||||||
|
@ -1021,7 +1021,7 @@ prettified text thus be used instead of HTML type."
|
||||||
"Return json-ready alist."
|
"Return json-ready alist."
|
||||||
`((input . ,(ein:cell-get-text cell))
|
`((input . ,(ein:cell-get-text cell))
|
||||||
(cell_type . "code")
|
(cell_type . "code")
|
||||||
,@(ein:aif (ein:oref-safe cell 'input-prompt-number)
|
,@(aif (ein:oref-safe cell 'input-prompt-number)
|
||||||
`((prompt_number . ,it)))
|
`((prompt_number . ,it)))
|
||||||
(outputs . ,(if discard-output [] (apply #'vector (slot-value cell 'outputs))))
|
(outputs . ,(if discard-output [] (apply #'vector (slot-value cell 'outputs))))
|
||||||
(language . "python")
|
(language . "python")
|
||||||
|
@ -1041,7 +1041,7 @@ prettified text thus be used instead of HTML type."
|
||||||
(outputs (if discard-output []
|
(outputs (if discard-output []
|
||||||
(slot-value cell 'outputs)))
|
(slot-value cell 'outputs)))
|
||||||
(renamed-outputs '())
|
(renamed-outputs '())
|
||||||
(execute-count (ein:aif (ein:oref-safe cell 'input-prompt-number)
|
(execute-count (aif (ein:oref-safe cell 'input-prompt-number)
|
||||||
(and (numberp it) it))))
|
(and (numberp it) it))))
|
||||||
(setq metadata (plist-put metadata :collapsed (if (slot-value cell 'collapsed) t json-false)))
|
(setq metadata (plist-put metadata :collapsed (if (slot-value cell 'collapsed) t json-false)))
|
||||||
(setq metadata (plist-put metadata :autoscroll json-false))
|
(setq metadata (plist-put metadata :autoscroll json-false))
|
||||||
|
@ -1139,16 +1139,16 @@ prettified text thus be used instead of HTML type."
|
||||||
|
|
||||||
(cl-defmethod ein:cell-next ((cell ein:basecell))
|
(cl-defmethod ein:cell-next ((cell ein:basecell))
|
||||||
"Return next cell of the given CELL or nil if CELL is the last one."
|
"Return next cell of the given CELL or nil if CELL is the last one."
|
||||||
(ein:aif (ewoc-next (slot-value cell 'ewoc)
|
(aif (ewoc-next (slot-value cell 'ewoc)
|
||||||
(ein:cell-element-get cell :footer))
|
(ein:cell-element-get cell :footer))
|
||||||
(let ((cell (ein:$node-data (ewoc-data it))))
|
(let ((cell (ein:$node-data (ewoc-data it))))
|
||||||
(when (cl-typep cell 'ein:basecell)
|
(when (cl-typep cell 'ein:basecell)
|
||||||
cell))))
|
cell))))
|
||||||
|
|
||||||
(cl-defmethod ein:cell-prev ((cell ein:basecell))
|
(cl-defmethod ein:cell-prev ((cell ein:basecell))
|
||||||
"Return previous cell of the given CELL or nil if CELL is the first one."
|
"Return previous cell of the given CELL or nil if CELL is the first one."
|
||||||
(ein:aif (ewoc-prev (slot-value cell 'ewoc)
|
(aif (ewoc-prev (slot-value cell 'ewoc)
|
||||||
(ein:cell-element-get cell :prompt))
|
(ein:cell-element-get cell :prompt))
|
||||||
(let ((cell (ein:$node-data (ewoc-data it))))
|
(let ((cell (ein:$node-data (ewoc-data it))))
|
||||||
(when (cl-typep cell 'ein:basecell)
|
(when (cl-typep cell 'ein:basecell)
|
||||||
cell))))
|
cell))))
|
||||||
|
|
|
@ -98,7 +98,7 @@
|
||||||
(destructuring-bind (msg-type content _) output
|
(destructuring-bind (msg-type content _) output
|
||||||
(ein:case-equal msg-type
|
(ein:case-equal msg-type
|
||||||
(("stream" "display_data" "pyout" "execute_result")
|
(("stream" "display_data" "pyout" "execute_result")
|
||||||
(ein:aif (plist-get content :text)
|
(aif (plist-get content :text)
|
||||||
(let ((oinfo (ein:json-read-from-string it)))
|
(let ((oinfo (ein:json-read-from-string it)))
|
||||||
(unless (string= (plist-get oinfo :string_form) "None")
|
(unless (string= (plist-get oinfo :string_form) "None")
|
||||||
(setf (gethash obj (ein:$kernel-oinfo-cache kernel))
|
(setf (gethash obj (ein:$kernel-oinfo-cache kernel))
|
||||||
|
|
|
@ -183,7 +183,7 @@ notebooks."
|
||||||
"Connect any buffer to opened notebook and its kernel."
|
"Connect any buffer to opened notebook and its kernel."
|
||||||
(interactive (list (ein:completing-read "Notebook buffer to connect: "
|
(interactive (list (ein:completing-read "Notebook buffer to connect: "
|
||||||
(ein:notebook-opened-buffer-names))))
|
(ein:notebook-opened-buffer-names))))
|
||||||
(ein:aif (get-buffer buffer-or-name)
|
(aif (get-buffer buffer-or-name)
|
||||||
(let ((notebook (buffer-local-value 'ein:%notebook% it)))
|
(let ((notebook (buffer-local-value 'ein:%notebook% it)))
|
||||||
(ein:connect-buffer-to-notebook notebook))
|
(ein:connect-buffer-to-notebook notebook))
|
||||||
(error "No buffer %s" buffer-or-name)))
|
(error "No buffer %s" buffer-or-name)))
|
||||||
|
@ -230,8 +230,8 @@ inside the ``if __name__ == \"__main__\":`` block."
|
||||||
"Run buffer using ``%run``. Ask for command if the prefix ``C-u`` is given.
|
"Run buffer using ``%run``. Ask for command if the prefix ``C-u`` is given.
|
||||||
Variable `ein:connect-run-command' sets the default command."
|
Variable `ein:connect-run-command' sets the default command."
|
||||||
(interactive "P")
|
(interactive "P")
|
||||||
(ein:aif (ein:aand (ein:get-url-or-port)
|
(aif (ein:aand (ein:get-url-or-port)
|
||||||
(ein:filename-to-python it (buffer-file-name)))
|
(ein:filename-to-python it (buffer-file-name)))
|
||||||
(let* ((default-command (ein:connect-run-command-get))
|
(let* ((default-command (ein:connect-run-command-get))
|
||||||
(command (if ask-command
|
(command (if ask-command
|
||||||
(read-from-minibuffer "Command: " default-command)
|
(read-from-minibuffer "Command: " default-command)
|
||||||
|
|
|
@ -131,7 +131,7 @@ global setting. For global setting and more information, see
|
||||||
(if (< (ein:notebook-version-numeric url-or-port) 3)
|
(if (< (ein:notebook-version-numeric url-or-port) 3)
|
||||||
(setq content (ein:new-content-legacy url-or-port path data))
|
(setq content (ein:new-content-legacy url-or-port path data))
|
||||||
(setq content (ein:new-content url-or-port path data)))
|
(setq content (ein:new-content url-or-port path data)))
|
||||||
(ein:aif response
|
(aif response
|
||||||
(setf (ein:$content-url-or-port content) (ein:get-response-redirect it)))
|
(setf (ein:$content-url-or-port content) (ein:get-response-redirect it)))
|
||||||
(when callback
|
(when callback
|
||||||
(funcall callback content))))
|
(funcall callback content))))
|
||||||
|
@ -174,7 +174,7 @@ global setting. For global setting and more information, see
|
||||||
|
|
||||||
(defun ein:content-need-hierarchy (url-or-port)
|
(defun ein:content-need-hierarchy (url-or-port)
|
||||||
"Callers assume ein:content-query-hierarchy succeeded. If not, nil."
|
"Callers assume ein:content-query-hierarchy succeeded. If not, nil."
|
||||||
(ein:aif (gethash url-or-port *ein:content-hierarchy*) it
|
(aif (gethash url-or-port *ein:content-hierarchy*) it
|
||||||
(ein:log 'warn "No recorded content hierarchy for %s" url-or-port)
|
(ein:log 'warn "No recorded content hierarchy for %s" url-or-port)
|
||||||
nil))
|
nil))
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
|
|
||||||
(require 'ein) ; get autoloaded functions into namespace
|
(require 'ein) ; get autoloaded functions into namespace
|
||||||
(require 'ein-utils)
|
(require 'ein-utils)
|
||||||
|
(require 'anaphora)
|
||||||
|
|
||||||
(defgroup ein nil
|
(defgroup ein nil
|
||||||
"IPython notebook client in Emacs"
|
"IPython notebook client in Emacs"
|
||||||
|
@ -137,19 +138,23 @@ the source is in git repository) or elpa version."
|
||||||
(defvar *ein:kernelspecs* (make-hash-table :test #'equal)
|
(defvar *ein:kernelspecs* (make-hash-table :test #'equal)
|
||||||
"url-or-port to kernelspecs")
|
"url-or-port to kernelspecs")
|
||||||
|
|
||||||
(defun ein:get-kernelspec (url-or-port name)
|
(defun ein:get-kernelspec (url-or-port name &optional lang)
|
||||||
(let* ((kernelspecs (ein:need-kernelspecs url-or-port))
|
(let* ((kernelspecs (ein:need-kernelspecs url-or-port))
|
||||||
(name (if (stringp name)
|
(name (if (stringp name)
|
||||||
(intern (format ":%s" name))
|
(intern (format ":%s" name))
|
||||||
name))
|
name))
|
||||||
(ks (plist-get kernelspecs name)))
|
(ks (or (plist-get kernelspecs name)
|
||||||
(if (stringp ks)
|
(loop for (key spec) on (ein:plist-exclude kernelspecs '(:default)) by 'cddr
|
||||||
(ein:get-kernelspec url-or-port ks)
|
if (string= (ein:$kernelspec-language spec) lang)
|
||||||
ks)))
|
return spec
|
||||||
|
end))))
|
||||||
|
(cond ((stringp ks)
|
||||||
|
(ein:get-kernelspec url-or-port ks))
|
||||||
|
(t ks))))
|
||||||
|
|
||||||
(defun ein:need-kernelspecs (url-or-port)
|
(defun ein:need-kernelspecs (url-or-port)
|
||||||
"Callers assume ein:query-kernelspecs succeeded. If not, nil."
|
"Callers assume ein:query-kernelspecs succeeded. If not, nil."
|
||||||
(ein:aif (gethash url-or-port *ein:kernelspecs*) it
|
(aif (gethash url-or-port *ein:kernelspecs*) it
|
||||||
(ein:log 'warn "No recorded kernelspecs for %s" url-or-port)
|
(ein:log 'warn "No recorded kernelspecs for %s" url-or-port)
|
||||||
nil))
|
nil))
|
||||||
|
|
||||||
|
@ -215,7 +220,7 @@ the source is in git repository) or elpa version."
|
||||||
|
|
||||||
(defun ein:need-notebook-version (url-or-port)
|
(defun ein:need-notebook-version (url-or-port)
|
||||||
"Callers assume ein:query-notebook-version succeeded. If not, we hardcode a guess."
|
"Callers assume ein:query-notebook-version succeeded. If not, we hardcode a guess."
|
||||||
(ein:aif (gethash url-or-port *ein:notebook-version*) it
|
(aif (gethash url-or-port *ein:notebook-version*) it
|
||||||
(ein:log 'warn "No recorded notebook version for %s" url-or-port)
|
(ein:log 'warn "No recorded notebook version for %s" url-or-port)
|
||||||
"5.7.0"))
|
"5.7.0"))
|
||||||
|
|
||||||
|
@ -233,7 +238,7 @@ the source is in git repository) or elpa version."
|
||||||
&allow-other-keys
|
&allow-other-keys
|
||||||
&aux (resp-string (format "STATUS: %s DATA: %s" (request-response-status-code response) data)))
|
&aux (resp-string (format "STATUS: %s DATA: %s" (request-response-status-code response) data)))
|
||||||
(ein:log 'debug "ein:query-notebook-version--complete %s" resp-string)
|
(ein:log 'debug "ein:query-notebook-version--complete %s" resp-string)
|
||||||
(ein:aif (plist-get data :version)
|
(aif (plist-get data :version)
|
||||||
(setf (gethash url-or-port *ein:notebook-version*) it)
|
(setf (gethash url-or-port *ein:notebook-version*) it)
|
||||||
(case (request-response-status-code response)
|
(case (request-response-status-code response)
|
||||||
(404 (ein:log 'warn "notebook version api not implemented")
|
(404 (ein:log 'warn "notebook version api not implemented")
|
||||||
|
@ -251,12 +256,12 @@ the source is in git repository) or elpa version."
|
||||||
(ein:choose-setting 'ein:filename-translations url-or-port))
|
(ein:choose-setting 'ein:filename-translations url-or-port))
|
||||||
|
|
||||||
(defun ein:filename-to-python (url-or-port filename)
|
(defun ein:filename-to-python (url-or-port filename)
|
||||||
(ein:aif (car (ein:filename-translations-get url-or-port))
|
(aif (car (ein:filename-translations-get url-or-port))
|
||||||
(funcall it filename)
|
(funcall it filename)
|
||||||
filename))
|
filename))
|
||||||
|
|
||||||
(defun ein:filename-from-python (url-or-port filename)
|
(defun ein:filename-from-python (url-or-port filename)
|
||||||
(ein:aif (cadr (ein:filename-translations-get url-or-port))
|
(aif (cadr (ein:filename-translations-get url-or-port))
|
||||||
(funcall it filename)
|
(funcall it filename)
|
||||||
filename))
|
filename))
|
||||||
|
|
||||||
|
@ -375,7 +380,7 @@ but can operate in different contexts."
|
||||||
(let* ((files (directory-files ein:source-dir 'full "^ein-.*\\.el$"))
|
(let* ((files (directory-files ein:source-dir 'full "^ein-.*\\.el$"))
|
||||||
(errors (cl-mapcan (lambda (f) (unless (byte-compile-file f) (list f)))
|
(errors (cl-mapcan (lambda (f) (unless (byte-compile-file f) (list f)))
|
||||||
files)))
|
files)))
|
||||||
(ein:aif errors
|
(aif errors
|
||||||
(error "Got %s errors while compiling these files: %s"
|
(error "Got %s errors while compiling these files: %s"
|
||||||
(length errors)
|
(length errors)
|
||||||
(ein:join-str " " (mapcar #'file-name-nondirectory it))))
|
(ein:join-str " " (mapcar #'file-name-nondirectory it))))
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
(defun ein:events-trigger (events event-type &optional data)
|
(defun ein:events-trigger (events event-type &optional data)
|
||||||
"Trigger EVENT-TYPE and let event handler EVENTS handle that event."
|
"Trigger EVENT-TYPE and let event handler EVENTS handle that event."
|
||||||
(ein:log 'debug "Event: %S" event-type)
|
(ein:log 'debug "Event: %S" event-type)
|
||||||
(ein:aif (gethash event-type (slot-value events 'callbacks))
|
(aif (gethash event-type (slot-value events 'callbacks))
|
||||||
(mapc (lambda (cb-arg) (ein:funcall-packed cb-arg data)) it)
|
(mapc (lambda (cb-arg) (ein:funcall-packed cb-arg data)) it)
|
||||||
(ein:log 'info "Unknown event: %S" event-type)))
|
(ein:log 'info "Unknown event: %S" event-type)))
|
||||||
|
|
||||||
|
|
|
@ -49,8 +49,8 @@ If the previous execution timer is not fired yet, cancel the timer."
|
||||||
BEG and END."
|
BEG and END."
|
||||||
(and (ein:codecell-p cell)
|
(and (ein:codecell-p cell)
|
||||||
this-command
|
this-command
|
||||||
(ein:aif (ein:cell-input-pos-min cell) (<= it beg))
|
(aif (ein:cell-input-pos-min cell) (<= it beg))
|
||||||
(ein:aif (ein:cell-input-pos-max cell) (>= it end))))
|
(aif (ein:cell-input-pos-max cell) (>= it end))))
|
||||||
|
|
||||||
(defun ein:iexec-after-change (beg end -ignore-len-)
|
(defun ein:iexec-after-change (beg end -ignore-len-)
|
||||||
"Called via `after-change-functions' hook."
|
"Called via `after-change-functions' hook."
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
current-payload)
|
current-payload)
|
||||||
|
|
||||||
(defun ein:find-or-create-ipdb-session (kernel &optional buffer)
|
(defun ein:find-or-create-ipdb-session (kernel &optional buffer)
|
||||||
(ein:aif (gethash (ein:$kernel-kernel-id kernel) *ein:ipdb-sessions*)
|
(aif (gethash (ein:$kernel-kernel-id kernel) *ein:ipdb-sessions*)
|
||||||
it
|
it
|
||||||
(let ((db-session (make-ein:$ipdb-session
|
(let ((db-session (make-ein:$ipdb-session
|
||||||
:kernel kernel
|
:kernel kernel
|
||||||
|
@ -120,7 +120,7 @@
|
||||||
(comint-output-filter proc ein:ipdb-buffer-prompt))
|
(comint-output-filter proc ein:ipdb-buffer-prompt))
|
||||||
(when ein:ipdb--received-quit-p
|
(when ein:ipdb--received-quit-p
|
||||||
(kill-buffer)
|
(kill-buffer)
|
||||||
(ein:aif (ein:$ipdb-session-notebook-buffer session)
|
(aif (ein:$ipdb-session-notebook-buffer session)
|
||||||
(pop-to-buffer it)))))))))
|
(pop-to-buffer it)))))))))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -27,16 +27,51 @@
|
||||||
(require 'ein-notebooklist)
|
(require 'ein-notebooklist)
|
||||||
(require 'ein-dev)
|
(require 'ein-dev)
|
||||||
|
|
||||||
(defcustom ein:jupyter-server-buffer-name "*ein:jupyter-server*"
|
(defcustom ein:jupyter-use-containers t
|
||||||
"The name of the buffer for the jupyter notebook server
|
"Take EIN in a different direcsh."
|
||||||
session."
|
:group 'ein
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
|
(defcustom ein:jupyter-docker-image "jupyter/datascience-notebook"
|
||||||
|
"Docker pull whichever jupyter image you prefer. This defaults to
|
||||||
|
the 'jupyter docker stacks' on hub.docker.com.
|
||||||
|
|
||||||
|
Optionally append ':tag', e.g., ':latest' in the customary way."
|
||||||
:group 'ein
|
:group 'ein
|
||||||
:type 'string)
|
:type 'string)
|
||||||
|
|
||||||
(defcustom ein:jupyter-server-run-timeout 60000
|
(defcustom ein:jupyter-docker-home-directory "/home/jovyan/work"
|
||||||
"Time, in milliseconds, to wait for the jupyter server to start before declaring timeout and cancelling the operation."
|
"Directory in docker image where to mount `ein:jupyter-default-notebook-directory'.
|
||||||
|
Defaults to home directory of 'jupyter docker stacks' on hub.docker.com."
|
||||||
:group 'ein
|
:group 'ein
|
||||||
:type 'integer)
|
:type 'string)
|
||||||
|
|
||||||
|
(defcustom ein:jupyter-docker-additional-switches "-e JUPYTER_ENABLE_LAB=no --rm"
|
||||||
|
"Additional options to the 'docker run' call.
|
||||||
|
|
||||||
|
Note some options like '-v' and '-network' are imposed by EIN."
|
||||||
|
:group 'ein
|
||||||
|
:type 'string)
|
||||||
|
|
||||||
|
(defcustom ein:jupyter-server-command "jupyter"
|
||||||
|
"The default command to start a jupyter notebook server.
|
||||||
|
|
||||||
|
Changing this to `jupyter-notebook' requires customizing `ein:jupyter-server-use-subcommand' to nil."
|
||||||
|
:group 'ein
|
||||||
|
:type 'string)
|
||||||
|
|
||||||
|
(defcustom ein:jupyter-default-server-command ein:jupyter-server-command
|
||||||
|
"Obsolete alias for `ein:jupyter-server-command'"
|
||||||
|
:group 'ein
|
||||||
|
:type 'string
|
||||||
|
:set (lambda (_symbol value)
|
||||||
|
(setq ein:jupyter-server-command value)))
|
||||||
|
|
||||||
|
(defcustom ein:jupyter-server-use-subcommand "notebook"
|
||||||
|
"Users of \"jupyter-notebook\" (as opposed to \"jupyter notebook\") need to Omit."
|
||||||
|
:group 'ein
|
||||||
|
:type '(choice (string :tag "Subcommand" "notebook")
|
||||||
|
(const :tag "Omit" nil)))
|
||||||
|
|
||||||
(defcustom ein:jupyter-server-args '("--no-browser")
|
(defcustom ein:jupyter-server-args '("--no-browser")
|
||||||
"Add any additional command line options you wish to include
|
"Add any additional command line options you wish to include
|
||||||
|
@ -45,34 +80,9 @@ with the call to the jupyter notebook."
|
||||||
:type '(repeat string))
|
:type '(repeat string))
|
||||||
|
|
||||||
(defcustom ein:jupyter-default-notebook-directory nil
|
(defcustom ein:jupyter-default-notebook-directory nil
|
||||||
"If you are tired of always being queried for the location of
|
"Default location of ipynb files."
|
||||||
the notebook directory, you can set it here for future calls to
|
|
||||||
`ein:jupyter-server-start'"
|
|
||||||
:group 'ein
|
:group 'ein
|
||||||
:type '(directory))
|
:type 'directory)
|
||||||
|
|
||||||
(defvar *ein:jupyter-server-accept-timeout* 60)
|
|
||||||
(defvar *ein:jupyter-server-process-name* "EIN: Jupyter notebook server")
|
|
||||||
|
|
||||||
(defvar *ein:last-jupyter-command* nil)
|
|
||||||
(defvar *ein:last-jupyter-directory* nil)
|
|
||||||
|
|
||||||
(defcustom ein:jupyter-default-server-command "jupyter"
|
|
||||||
"The default command to start a jupyter notebook server.
|
|
||||||
|
|
||||||
Changing this to `jupyter-notebook' requires customizing `ein:jupyter-server-use-subcommand' to nil.
|
|
||||||
"
|
|
||||||
:group 'ein
|
|
||||||
:type '(file)
|
|
||||||
:set (lambda (symbol value)
|
|
||||||
(set-default symbol value)
|
|
||||||
(setq *ein:last-jupyter-command* nil)))
|
|
||||||
|
|
||||||
(defcustom ein:jupyter-server-use-subcommand "notebook"
|
|
||||||
"Users of \"jupyter-notebook\" (as opposed to \"jupyter notebook\") need to `Omit'."
|
|
||||||
:group 'ein
|
|
||||||
:type '(choice (string :tag "Subcommand" "notebook")
|
|
||||||
(const :tag "Omit" nil)))
|
|
||||||
|
|
||||||
(defcustom ein:jupyter-default-kernel 'first-alphabetically
|
(defcustom ein:jupyter-default-kernel 'first-alphabetically
|
||||||
"With which of ${XDG_DATA_HOME}/jupyter/kernels to create new notebooks."
|
"With which of ${XDG_DATA_HOME}/jupyter/kernels to create new notebooks."
|
||||||
|
@ -90,24 +100,37 @@ Changing this to `jupyter-notebook' requires customizing `ein:jupyter-server-use
|
||||||
(json-read-from-string
|
(json-read-from-string
|
||||||
(shell-command-to-string
|
(shell-command-to-string
|
||||||
(format "%s kernelspec list --json"
|
(format "%s kernelspec list --json"
|
||||||
ein:jupyter-default-server-command)))))
|
ein:jupyter-server-command)))))
|
||||||
collect `(,k . ,(alist-get 'display_name (alist-get 'spec spec)))))
|
collect `(,k . ,(alist-get 'display_name (alist-get 'spec spec)))))
|
||||||
(error (ein:log 'warn "ein:jupyter-default-kernel: %s" err)
|
(error (ein:log 'warn "ein:jupyter-default-kernel: %s" err)
|
||||||
'((string :tag "Ask"))))))
|
'((string :tag "Ask"))))))
|
||||||
|
|
||||||
(defsubst ein:jupyter-server-process ()
|
(defvar *ein:jupyter-server-process-name* "ein server")
|
||||||
"Return the emacs process object of our session"
|
(defvar *ein:jupyter-server-buffer-name*
|
||||||
(get-buffer-process (get-buffer ein:jupyter-server-buffer-name)))
|
(format "*%s*" *ein:jupyter-server-process-name*))
|
||||||
|
|
||||||
(defun ein:jupyter-server--run (buf cmd dir &optional args)
|
(defsubst ein:jupyter-server-process ()
|
||||||
(when ein:debug
|
"Return the emacs process object of our session."
|
||||||
(add-to-list 'ein:jupyter-server-args "--debug"))
|
(get-buffer-process (get-buffer *ein:jupyter-server-buffer-name*)))
|
||||||
(unless (stringp dir)
|
|
||||||
(error "ein:jupyter-server--run: notebook directory required"))
|
(defun ein:jupyter-server--run (buf user-cmd dir &optional args)
|
||||||
(let* ((vargs (append (ein:aif ein:jupyter-server-use-subcommand (list it))
|
(let* ((cmd (if ein:jupyter-use-containers "docker" user-cmd))
|
||||||
(list (format "--notebook-dir=%s" (convert-standard-filename dir)))
|
(vargs (cond (ein:jupyter-use-containers
|
||||||
args
|
(split-string
|
||||||
ein:jupyter-server-args))
|
(format "run --network host -v %s:%s %s %s"
|
||||||
|
dir
|
||||||
|
ein:jupyter-docker-home-directory
|
||||||
|
ein:jupyter-docker-additional-switches
|
||||||
|
ein:jupyter-docker-image)))
|
||||||
|
(t
|
||||||
|
(append (aif ein:jupyter-server-use-subcommand (list it))
|
||||||
|
(list (format "--notebook-dir=%s"
|
||||||
|
(convert-standard-filename dir)))
|
||||||
|
args
|
||||||
|
(let ((copy ein:jupyter-server-args))
|
||||||
|
(when ein:debug
|
||||||
|
(add-to-list copy "--debug"))
|
||||||
|
copy)))))
|
||||||
(proc (apply #'start-process
|
(proc (apply #'start-process
|
||||||
*ein:jupyter-server-process-name* buf cmd vargs)))
|
*ein:jupyter-server-process-name* buf cmd vargs)))
|
||||||
(ein:log 'info "ein:jupyter-server--run: %s %s" cmd (ein:join-str " " vargs))
|
(ein:log 'info "ein:jupyter-server--run: %s %s" cmd (ein:join-str " " vargs))
|
||||||
|
@ -117,7 +140,7 @@ Changing this to `jupyter-notebook' requires customizing `ein:jupyter-server-use
|
||||||
(defun ein:jupyter-server-conn-info (&optional buffer-name)
|
(defun ein:jupyter-server-conn-info (&optional buffer-name)
|
||||||
"Return the url-or-port and password for BUFFER or the global session."
|
"Return the url-or-port and password for BUFFER or the global session."
|
||||||
(unless buffer-name
|
(unless buffer-name
|
||||||
(setq buffer-name ein:jupyter-server-buffer-name))
|
(setq buffer-name *ein:jupyter-server-buffer-name*))
|
||||||
(let ((buffer (get-buffer buffer-name))
|
(let ((buffer (get-buffer buffer-name))
|
||||||
(result '(nil nil)))
|
(result '(nil nil)))
|
||||||
(if buffer
|
(if buffer
|
||||||
|
@ -157,67 +180,73 @@ our singleton jupyter server process here."
|
||||||
(set-process-sentinel
|
(set-process-sentinel
|
||||||
proc
|
proc
|
||||||
(apply-partially (lambda (url-or-port* sentinel proc* event)
|
(apply-partially (lambda (url-or-port* sentinel proc* event)
|
||||||
(ein:aif sentinel (funcall it proc* event))
|
(aif sentinel (funcall it proc* event))
|
||||||
(funcall #'ein:notebooklist-sentinel url-or-port* proc* event))
|
(funcall #'ein:notebooklist-sentinel url-or-port* proc* event))
|
||||||
url-or-port (process-sentinel proc))))
|
url-or-port (process-sentinel proc))))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun ein:jupyter-server-start (server-cmd-path notebook-directory
|
(defun ein:jupyter-server-start (server-command
|
||||||
&optional no-login-p login-callback port)
|
notebook-directory
|
||||||
"Start SERVER-CMD_PATH with `--notebook-dir' NOTEBOOK-DIRECTORY. Login after connection established unless NO-LOGIN-P is set. LOGIN-CALLBACK takes two arguments, the buffer created by ein:notebooklist-open--finish, and the url-or-port argument of ein:notebooklist-open*.
|
&optional no-login-p login-callback port)
|
||||||
|
"Start SERVER-COMMAND with `--notebook-dir' NOTEBOOK-DIRECTORY.
|
||||||
|
|
||||||
This command opens an asynchronous process running the jupyter
|
Login after connection established unless NO-LOGIN-P is set.
|
||||||
notebook server and then tries to detect the url and password to
|
LOGIN-CALLBACK takes two arguments, the buffer created by
|
||||||
generate automatic calls to `ein:notebooklist-login' and
|
`ein:notebooklist-open--finish', and the url-or-port argument
|
||||||
`ein:notebooklist-open'.
|
of `ein:notebooklist-open*'.
|
||||||
|
|
||||||
With \\[universal-argument] prefix arg, it will prompt the user for the path to
|
With \\[universal-argument] prefix arg, prompt the user for the
|
||||||
the jupyter executable first. Else, it will try to use the
|
server command."
|
||||||
value of `*ein:last-jupyter-command*' or the value of the
|
|
||||||
customizable variable `ein:jupyter-default-server-command'.
|
|
||||||
|
|
||||||
Then it prompts the user for the path of the root directory
|
|
||||||
containing the notebooks the user wants to access.
|
|
||||||
|
|
||||||
The buffer named by `ein:jupyter-server-buffer-name' will contain
|
|
||||||
the log of the running jupyter server."
|
|
||||||
(interactive
|
(interactive
|
||||||
(let* ((default-command (or *ein:last-jupyter-command*
|
(list (let ((default-command (executable-find ein:jupyter-server-command)))
|
||||||
ein:jupyter-default-server-command))
|
(if (and (not ein:jupyter-use-containers)
|
||||||
(server-cmd-path
|
(or current-prefix-arg (not default-command)))
|
||||||
(executable-find (if current-prefix-arg
|
(let (command result)
|
||||||
(read-file-name "Server command: " default-directory nil nil
|
(while (not (setq
|
||||||
default-command)
|
result
|
||||||
default-command)))
|
(executable-find
|
||||||
(notebook-directory
|
(setq
|
||||||
(read-directory-name "Notebook directory: "
|
command
|
||||||
(or *ein:last-jupyter-directory*
|
(read-string
|
||||||
ein:jupyter-default-notebook-directory))))
|
(format
|
||||||
(list server-cmd-path notebook-directory nil (lambda (buffer url-or-port)
|
"%sServer command: "
|
||||||
(pop-to-buffer buffer)))))
|
(if command
|
||||||
(unless (and (stringp server-cmd-path)
|
(format "[%s not executable] " command)
|
||||||
(file-exists-p server-cmd-path)
|
""))
|
||||||
(file-executable-p server-cmd-path))
|
nil nil ein:jupyter-server-command))))))
|
||||||
(error "Command %s not found or not executable"
|
result)
|
||||||
(or *ein:last-jupyter-command*
|
default-command))
|
||||||
ein:jupyter-default-server-command)))
|
(let (result
|
||||||
(setf *ein:last-jupyter-command* server-cmd-path
|
(default-dir ein:jupyter-default-notebook-directory))
|
||||||
*ein:last-jupyter-directory* notebook-directory)
|
(while (or (not result) (not (file-directory-p result)))
|
||||||
|
(setq result (read-directory-name
|
||||||
|
(format "%sNotebook directory: "
|
||||||
|
(if result
|
||||||
|
(format "[%s not a directory]" result)
|
||||||
|
""))
|
||||||
|
nil
|
||||||
|
ein:jupyter-default-notebook-directory
|
||||||
|
t)))
|
||||||
|
result)
|
||||||
|
nil
|
||||||
|
(lambda (buffer url-or-port)
|
||||||
|
(pop-to-buffer buffer))
|
||||||
|
nil))
|
||||||
(if (ein:jupyter-server-process)
|
(if (ein:jupyter-server-process)
|
||||||
(error "Please first M-x ein:stop"))
|
(error "ein:jupyter-server-start: please first M-x ein:stop"))
|
||||||
(add-hook 'kill-emacs-hook #'(lambda ()
|
(add-hook 'kill-emacs-hook #'(lambda ()
|
||||||
(ignore-errors (ein:jupyter-server-stop t))))
|
(ignore-errors (ein:jupyter-server-stop t))))
|
||||||
(let ((proc (ein:jupyter-server--run ein:jupyter-server-buffer-name
|
(let ((proc (ein:jupyter-server--run *ein:jupyter-server-buffer-name*
|
||||||
*ein:last-jupyter-command*
|
server-command
|
||||||
*ein:last-jupyter-directory*
|
notebook-directory
|
||||||
(if (numberp port)
|
(if (numberp port)
|
||||||
`("--port" ,(format "%s" port)
|
`("--port" ,(format "%s" port)
|
||||||
"--port-retries" "0")))))
|
"--port-retries" "0")))))
|
||||||
(loop repeat 30
|
(loop repeat 30
|
||||||
until (car (ein:jupyter-server-conn-info ein:jupyter-server-buffer-name))
|
until (car (ein:jupyter-server-conn-info *ein:jupyter-server-buffer-name*))
|
||||||
do (sleep-for 0 500)
|
do (sleep-for 0 500)
|
||||||
finally do
|
finally do
|
||||||
(unless (car (ein:jupyter-server-conn-info ein:jupyter-server-buffer-name))
|
(unless (car (ein:jupyter-server-conn-info *ein:jupyter-server-buffer-name*))
|
||||||
(ein:log 'warn "Jupyter server failed to start, cancelling operation")
|
(ein:log 'warn "Jupyter server failed to start, cancelling operation")
|
||||||
(ein:jupyter-server-stop t)))
|
(ein:jupyter-server-stop t)))
|
||||||
(when (and (not no-login-p) (ein:jupyter-server-process))
|
(when (and (not no-login-p) (ein:jupyter-server-process))
|
||||||
|
@ -266,7 +295,7 @@ the log of the running jupyter server."
|
||||||
(ein:notebooklist-list-remove url-or-port)
|
(ein:notebooklist-list-remove url-or-port)
|
||||||
(kill-buffer (ein:notebooklist-get-buffer url-or-port))
|
(kill-buffer (ein:notebooklist-get-buffer url-or-port))
|
||||||
(when log
|
(when log
|
||||||
(with-current-buffer ein:jupyter-server-buffer-name
|
(with-current-buffer *ein:jupyter-server-buffer-name*
|
||||||
(write-region (point-min) (point-max) log)))))
|
(write-region (point-min) (point-max) log)))))
|
||||||
|
|
||||||
(provide 'ein-jupyter)
|
(provide 'ein-jupyter)
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
(require 'ein-query)
|
(require 'ein-query)
|
||||||
(require 'ein-websocket)
|
(require 'ein-websocket)
|
||||||
(require 'ein-notebooklist)
|
(require 'ein-notebooklist)
|
||||||
|
(require 'anaphora)
|
||||||
|
|
||||||
(defvar *ein:jupyterhub-connections* (make-hash-table :test #'equal))
|
(defvar *ein:jupyterhub-connections* (make-hash-table :test #'equal))
|
||||||
|
|
||||||
|
@ -54,7 +55,7 @@
|
||||||
|
|
||||||
(defsubst ein:jupyterhub-user-path (url-or-port &rest paths)
|
(defsubst ein:jupyterhub-user-path (url-or-port &rest paths)
|
||||||
"Goes from URL-OR-PORT/PATHS to URL-OR-PORT/user/someone/PATHS"
|
"Goes from URL-OR-PORT/PATHS to URL-OR-PORT/user/someone/PATHS"
|
||||||
(let ((user-base (ein:aif (gethash url-or-port *ein:jupyterhub-connections*)
|
(let ((user-base (aif (gethash url-or-port *ein:jupyterhub-connections*)
|
||||||
(ein:$jh-user-server (ein:$jh-conn-user it)))))
|
(ein:$jh-user-server (ein:$jh-conn-user it)))))
|
||||||
(apply #'ein:url url-or-port user-base paths)))
|
(apply #'ein:url url-or-port user-base paths)))
|
||||||
|
|
||||||
|
@ -90,7 +91,7 @@
|
||||||
(ein:and-let* ((conn (gethash ,conn-key *ein:jupyterhub-connections*)))
|
(ein:and-let* ((conn (gethash ,conn-key *ein:jupyterhub-connections*)))
|
||||||
(ein:jupyterhub--add-header
|
(ein:jupyterhub--add-header
|
||||||
(cons "Referer" (ein:url (ein:$jh-conn-url-or-port conn) "hub/login")))
|
(cons "Referer" (ein:url (ein:$jh-conn-url-or-port conn) "hub/login")))
|
||||||
(ein:aif (ein:$jh-conn-token conn)
|
(aif (ein:$jh-conn-token conn)
|
||||||
(ein:jupyterhub--add-header
|
(ein:jupyterhub--add-header
|
||||||
(cons "Authorization" (format "token %s" it)))))
|
(cons "Authorization" (format "token %s" it)))))
|
||||||
(apply #'ein:query-singleton-ajax
|
(apply #'ein:query-singleton-ajax
|
||||||
|
|
|
@ -318,7 +318,7 @@ See https://github.com/ipython/ipython/pull/3307"
|
||||||
"Close websocket connection to running kernel, but do not
|
"Close websocket connection to running kernel, but do not
|
||||||
delete the kernel on the server side"
|
delete the kernel on the server side"
|
||||||
(ein:events-trigger (ein:$kernel-events kernel) 'status_disconnected.Kernel)
|
(ein:events-trigger (ein:$kernel-events kernel) 'status_disconnected.Kernel)
|
||||||
(ein:aif (ein:$kernel-websocket kernel)
|
(aif (ein:$kernel-websocket kernel)
|
||||||
(progn (ein:websocket-close it)
|
(progn (ein:websocket-close it)
|
||||||
(setf (ein:$kernel-websocket kernel) nil))))
|
(setf (ein:$kernel-websocket kernel) nil))))
|
||||||
|
|
||||||
|
@ -715,13 +715,13 @@ We need this to have proper behavior for the 'Stop' command in the ein:notebookl
|
||||||
(ein:log 'debug "KERNEL--HANDLE-SHELL-REPLY: msg_type=%s msg_id=%s"
|
(ein:log 'debug "KERNEL--HANDLE-SHELL-REPLY: msg_type=%s msg_id=%s"
|
||||||
msg-type msg-id)
|
msg-type msg-id)
|
||||||
(run-hook-with-args 'ein:on-shell-reply-functions msg-type header content metadata)
|
(run-hook-with-args 'ein:on-shell-reply-functions msg-type header content metadata)
|
||||||
(ein:aif cb (ein:funcall-packed it content metadata))
|
(aif cb (ein:funcall-packed it content metadata))
|
||||||
(ein:aif (plist-get content :payload)
|
(aif (plist-get content :payload)
|
||||||
(ein:kernel--handle-payload kernel callbacks it))
|
(ein:kernel--handle-payload kernel callbacks it))
|
||||||
(let ((events (ein:$kernel-events kernel)))
|
(let ((events (ein:$kernel-events kernel)))
|
||||||
(ein:case-equal msg-type
|
(ein:case-equal msg-type
|
||||||
(("execute_reply")
|
(("execute_reply")
|
||||||
(ein:aif (plist-get content :execution_count)
|
(aif (plist-get content :execution_count)
|
||||||
;; It can be `nil' for silent execution
|
;; It can be `nil' for silent execution
|
||||||
(ein:events-trigger events 'execution_count.Kernel it))))))))
|
(ein:events-trigger events 'execution_count.Kernel it))))))))
|
||||||
|
|
||||||
|
@ -763,7 +763,7 @@ We need this to have proper behavior for the 'Stop' command in the ein:notebookl
|
||||||
(ein:log 'verbose "Not processing msg_type=%s msg_id=%s" msg-type msg-id)
|
(ein:log 'verbose "Not processing msg_type=%s msg_id=%s" msg-type msg-id)
|
||||||
(ein:case-equal msg-type
|
(ein:case-equal msg-type
|
||||||
(("stream" "display_data" "pyout" "pyerr" "error" "execute_result")
|
(("stream" "display_data" "pyout" "pyerr" "error" "execute_result")
|
||||||
(ein:aif (plist-get callbacks :output)
|
(aif (plist-get callbacks :output)
|
||||||
(ein:funcall-packed it msg-type content metadata)))
|
(ein:funcall-packed it msg-type content metadata)))
|
||||||
(("status")
|
(("status")
|
||||||
(ein:case-equal (plist-get content :execution_state)
|
(ein:case-equal (plist-get content :execution_state)
|
||||||
|
@ -776,7 +776,7 @@ We need this to have proper behavior for the 'Stop' command in the ein:notebookl
|
||||||
(("data_pub")
|
(("data_pub")
|
||||||
(ein:log 'verbose (format "Received data_pub message w/content %s" packet)))
|
(ein:log 'verbose (format "Received data_pub message w/content %s" packet)))
|
||||||
(("clear_output")
|
(("clear_output")
|
||||||
(ein:aif (plist-get callbacks :clear_output)
|
(aif (plist-get callbacks :clear_output)
|
||||||
(ein:funcall-packed it content metadata)))))))))
|
(ein:funcall-packed it content metadata)))))))))
|
||||||
|
|
||||||
;;; Utility functions
|
;;; Utility functions
|
||||||
|
@ -829,7 +829,7 @@ as a string and the rest of the argument is the optional ARGS."
|
||||||
(let ((func (car packed))
|
(let ((func (car packed))
|
||||||
(args (cdr packed)))
|
(args (cdr packed)))
|
||||||
(when (equal msg-type "stream")
|
(when (equal msg-type "stream")
|
||||||
(ein:aif (plist-get content :text)
|
(aif (plist-get content :text)
|
||||||
(apply func it args)))))
|
(apply func it args)))))
|
||||||
(cons func args)))))
|
(cons func args)))))
|
||||||
|
|
||||||
|
|
|
@ -106,7 +106,7 @@ Otherwise, return result of last form in BODY."
|
||||||
|
|
||||||
(defun ein:log-pop-to-request-buffer ()
|
(defun ein:log-pop-to-request-buffer ()
|
||||||
(interactive)
|
(interactive)
|
||||||
(ein:aif (get-buffer request-log-buffer-name)
|
(aif (get-buffer request-log-buffer-name)
|
||||||
(pop-to-buffer it)
|
(pop-to-buffer it)
|
||||||
(message "No buffer named \"%s\"" request-log-buffer-name)))
|
(message "No buffer named \"%s\"" request-log-buffer-name)))
|
||||||
|
|
||||||
|
|
|
@ -293,7 +293,7 @@ will be updated with kernel's cwd."
|
||||||
(pop-to-buffer (ein:notebook-buffer notebook*)))))
|
(pop-to-buffer (ein:notebook-buffer notebook*)))))
|
||||||
(when (and (not noninteractive)
|
(when (and (not noninteractive)
|
||||||
(null (plist-member (ein:$notebook-metadata notebook*) :kernelspec)))
|
(null (plist-member (ein:$notebook-metadata notebook*) :kernelspec)))
|
||||||
(ein:aif (ein:$notebook-kernelspec notebook*)
|
(aif (ein:$notebook-kernelspec notebook*)
|
||||||
(progn
|
(progn
|
||||||
(setf (ein:$notebook-metadata notebook*)
|
(setf (ein:$notebook-metadata notebook*)
|
||||||
(plist-put (ein:$notebook-metadata notebook*)
|
(plist-put (ein:$notebook-metadata notebook*)
|
||||||
|
@ -343,7 +343,7 @@ where `created' indicates a new notebook or an existing one."
|
||||||
*ein:notebook--pending-query*))
|
*ein:notebook--pending-query*))
|
||||||
pending-key))
|
pending-key))
|
||||||
(existing (ein:notebook-get-opened-notebook url-or-port path))
|
(existing (ein:notebook-get-opened-notebook url-or-port path))
|
||||||
(notebook (ein:aif existing it
|
(notebook (aif existing it
|
||||||
(ein:notebook-new url-or-port path kernelspec)))
|
(ein:notebook-new url-or-port path kernelspec)))
|
||||||
(callback0 (ein:notebook-open--decorate-callback notebook existing pending-clear
|
(callback0 (ein:notebook-open--decorate-callback notebook existing pending-clear
|
||||||
callback no-pop)))
|
callback no-pop)))
|
||||||
|
@ -371,7 +371,7 @@ where `created' indicates a new notebook or an existing one."
|
||||||
(setf (ein:$notebook-api-version notebook) (ein:$content-notebook-version content)
|
(setf (ein:$notebook-api-version notebook) (ein:$content-notebook-version content)
|
||||||
(ein:$notebook-notebook-name notebook) (ein:$content-name content))
|
(ein:$notebook-notebook-name notebook) (ein:$content-name content))
|
||||||
(ein:notebook-bind-events notebook (ein:events-new))
|
(ein:notebook-bind-events notebook (ein:events-new))
|
||||||
(ein:notebook-maybe-set-kernelspec notebook (plist-get (ein:$content-raw-content content) :metadata))
|
(ein:notebook-set-kernelspec notebook (plist-get (ein:$content-raw-content content) :metadata))
|
||||||
(ein:notebook-install-kernel notebook)
|
(ein:notebook-install-kernel notebook)
|
||||||
(ein:notebook-from-json notebook (ein:$content-raw-content content))
|
(ein:notebook-from-json notebook (ein:$content-raw-content content))
|
||||||
(if (not (with-current-buffer (ein:notebook-buffer notebook)
|
(if (not (with-current-buffer (ein:notebook-buffer notebook)
|
||||||
|
@ -393,11 +393,12 @@ where `created' indicates a new notebook or an existing one."
|
||||||
(ein:notebook--check-nbformat (ein:$content-raw-content content))
|
(ein:notebook--check-nbformat (ein:$content-raw-content content))
|
||||||
(ein:gc-complete-operation))))
|
(ein:gc-complete-operation))))
|
||||||
|
|
||||||
(defun ein:notebook-maybe-set-kernelspec (notebook content-metadata)
|
(defun ein:notebook-set-kernelspec (notebook content-metadata)
|
||||||
(ein:aif (plist-get content-metadata :kernelspec)
|
(-when-let* ((ks-plist (plist-get content-metadata :kernelspec))
|
||||||
(let ((kernelspec (ein:get-kernelspec (ein:$notebook-url-or-port notebook)
|
(kernelspec (ein:get-kernelspec (ein:$notebook-url-or-port notebook)
|
||||||
(plist-get it :name))))
|
(plist-get ks-plist :name)
|
||||||
(setf (ein:$notebook-kernelspec notebook) kernelspec))))
|
(plist-get ks-plist :language))))
|
||||||
|
(setf (ein:$notebook-kernelspec notebook) kernelspec)))
|
||||||
|
|
||||||
|
|
||||||
(defun ein:notebook--different-number (n1 n2)
|
(defun ein:notebook--different-number (n1 n2)
|
||||||
|
@ -451,12 +452,11 @@ of minor mode."
|
||||||
;;; Kernel related things
|
;;; Kernel related things
|
||||||
|
|
||||||
(defun ein:list-available-kernels (url-or-port)
|
(defun ein:list-available-kernels (url-or-port)
|
||||||
(let ((kernelspecs (ein:need-kernelspecs url-or-port)))
|
(when-let ((kernelspecs (ein:need-kernelspecs url-or-port)))
|
||||||
(if kernelspecs
|
(sort (loop for (key spec) on (ein:plist-exclude kernelspecs '(:default)) by 'cddr
|
||||||
(sort (loop for (key spec) on (ein:plist-exclude kernelspecs '(:default)) by 'cddr
|
collecting (cons (ein:$kernelspec-name spec)
|
||||||
collecting (cons (ein:$kernelspec-name spec)
|
(ein:$kernelspec-display-name spec)))
|
||||||
(ein:$kernelspec-display-name spec)))
|
(lambda (c1 c2) (string< (cdr c1) (cdr c2))))))
|
||||||
(lambda (c1 c2) (string< (cdr c1) (cdr c2)))))))
|
|
||||||
|
|
||||||
(defun ein:notebook-switch-kernel (notebook kernel-name)
|
(defun ein:notebook-switch-kernel (notebook kernel-name)
|
||||||
"Change the kernel for a running notebook. If not called from a
|
"Change the kernel for a running notebook. If not called from a
|
||||||
|
@ -468,7 +468,9 @@ notebook buffer then the user will be prompted to select an opened notebook."
|
||||||
(ein:notebook-opened-buffer-names))))
|
(ein:notebook-opened-buffer-names))))
|
||||||
(kernel-name (ein:completing-read
|
(kernel-name (ein:completing-read
|
||||||
"Select kernel: "
|
"Select kernel: "
|
||||||
(ein:list-available-kernels (ein:$notebook-url-or-port notebook)))))
|
(cl-mapcar
|
||||||
|
#'car
|
||||||
|
(ein:list-available-kernels (ein:$notebook-url-or-port notebook))))))
|
||||||
(list notebook kernel-name)))
|
(list notebook kernel-name)))
|
||||||
(let* ((kernelspec (ein:get-kernelspec
|
(let* ((kernelspec (ein:get-kernelspec
|
||||||
(ein:$notebook-url-or-port notebook) kernel-name)))
|
(ein:$notebook-url-or-port notebook) kernel-name)))
|
||||||
|
@ -504,9 +506,9 @@ notebook buffer then the user will be prompted to select an opened notebook."
|
||||||
(defun ein:notebook-restart-session-command ()
|
(defun ein:notebook-restart-session-command ()
|
||||||
"Delete session on server side. Start new session."
|
"Delete session on server side. Start new session."
|
||||||
(interactive)
|
(interactive)
|
||||||
(ein:aif ein:%notebook%
|
(aif ein:%notebook%
|
||||||
(if (y-or-n-p "Are you sure? ")
|
(if (y-or-n-p "Are you sure? ")
|
||||||
(ein:kernel-restart-session (ein:$notebook-kernel it)))
|
(ein:kernel-restart-session (ein:$notebook-kernel it)))
|
||||||
(message "Not in notebook buffer!")))
|
(message "Not in notebook buffer!")))
|
||||||
|
|
||||||
(define-obsolete-function-alias
|
(define-obsolete-function-alias
|
||||||
|
@ -571,7 +573,7 @@ This is equivalent to do ``C-c`` in the console program."
|
||||||
(funcall (ein:notebook-choose-mode))
|
(funcall (ein:notebook-choose-mode))
|
||||||
(ein:worksheet-reinstall-undo-hooks ws)
|
(ein:worksheet-reinstall-undo-hooks ws)
|
||||||
(condition-case err
|
(condition-case err
|
||||||
(ein:aif (ein:$notebook-kernelspec notebook)
|
(aif (ein:$notebook-kernelspec notebook)
|
||||||
(ein:ml-lang-setup it))
|
(ein:ml-lang-setup it))
|
||||||
(error (ein:log 'error (error-message-string err))
|
(error (ein:log 'error (error-message-string err))
|
||||||
(setq multilang-failed t))))
|
(setq multilang-failed t))))
|
||||||
|
@ -685,7 +687,7 @@ This is equivalent to do ``C-c`` in the console program."
|
||||||
(setf (gethash 'name metadata) (ein:$notebook-notebook-name notebook))
|
(setf (gethash 'name metadata) (ein:$notebook-notebook-name notebook))
|
||||||
(plist-put metadata
|
(plist-put metadata
|
||||||
:name (ein:$notebook-notebook-name notebook)))
|
:name (ein:$notebook-notebook-name notebook)))
|
||||||
(ein:aif (ein:$notebook-nbformat-minor notebook)
|
(aif (ein:$notebook-nbformat-minor notebook)
|
||||||
;; Do not set nbformat when it is not given from server.
|
;; Do not set nbformat when it is not given from server.
|
||||||
(push `(nbformat_minor . ,it) data))
|
(push `(nbformat_minor . ,it) data))
|
||||||
(push `(nbformat . ,(ein:$notebook-nbformat notebook)) data)
|
(push `(nbformat . ,(ein:$notebook-nbformat notebook)) data)
|
||||||
|
@ -710,12 +712,12 @@ This is equivalent to do ``C-c`` in the console program."
|
||||||
for i from 0
|
for i from 0
|
||||||
append (ein:worksheet-to-nb4-json ws i))))
|
append (ein:worksheet-to-nb4-json ws i))))
|
||||||
;; should be in notebook constructor, not here
|
;; should be in notebook constructor, not here
|
||||||
(ein:aif (ein:$notebook-kernelspec notebook)
|
(aif (ein:$notebook-kernelspec notebook)
|
||||||
(setf (ein:$notebook-metadata notebook)
|
(setf (ein:$notebook-metadata notebook)
|
||||||
(plist-put (ein:$notebook-metadata notebook)
|
(plist-put (ein:$notebook-metadata notebook)
|
||||||
:kernelspec (ein:notebook--spec-insert-name
|
:kernelspec (ein:notebook--spec-insert-name
|
||||||
(ein:$kernelspec-name it) (ein:$kernelspec-spec it)))))
|
(ein:$kernelspec-name it) (ein:$kernelspec-spec it)))))
|
||||||
`((metadata . ,(ein:aif (ein:$notebook-metadata notebook)
|
`((metadata . ,(aif (ein:$notebook-metadata notebook)
|
||||||
it
|
it
|
||||||
(make-hash-table)))
|
(make-hash-table)))
|
||||||
(cells . ,(apply #'vector all-cells)))))
|
(cells . ,(apply #'vector all-cells)))))
|
||||||
|
@ -849,7 +851,7 @@ NAME is any non-empty string that does not contain '/' or '\\'.
|
||||||
(ein:notebook-tidy-opened-notebooks notebook)))))
|
(ein:notebook-tidy-opened-notebooks notebook)))))
|
||||||
|
|
||||||
(defsubst ein:notebook-kill-buffer-query ()
|
(defsubst ein:notebook-kill-buffer-query ()
|
||||||
(ein:aif (ein:get-notebook--notebook)
|
(aif (ein:get-notebook--notebook)
|
||||||
(let ((buf (or (buffer-base-buffer (current-buffer))
|
(let ((buf (or (buffer-base-buffer (current-buffer))
|
||||||
(current-buffer))))
|
(current-buffer))))
|
||||||
(ein:notebook-ask-save it (apply-partially
|
(ein:notebook-ask-save it (apply-partially
|
||||||
|
@ -1487,9 +1489,9 @@ watch the fireworks!"
|
||||||
;; It is executed after toggling the mode, and before running MODE-hook.
|
;; It is executed after toggling the mode, and before running MODE-hook.
|
||||||
|
|
||||||
(when ein:notebook-mode
|
(when ein:notebook-mode
|
||||||
(ein:aif ein:helm-kernel-history-search-key
|
(aif ein:helm-kernel-history-search-key
|
||||||
(ein:notebook--define-key ein:notebook-mode-map it helm-ein-kernel-history))
|
(ein:notebook--define-key ein:notebook-mode-map it helm-ein-kernel-history))
|
||||||
(ein:aif ein:anything-kernel-history-search-key
|
(aif ein:anything-kernel-history-search-key
|
||||||
(ein:notebook--define-key ein:notebook-mode-map it anything-ein-kernel-history))
|
(ein:notebook--define-key ein:notebook-mode-map it anything-ein-kernel-history))
|
||||||
(setq indent-tabs-mode nil) ;; Being T causes problems with Python code.
|
(setq indent-tabs-mode nil) ;; Being T causes problems with Python code.
|
||||||
(ein:worksheet-imenu-setup)))
|
(ein:worksheet-imenu-setup)))
|
||||||
|
@ -1552,7 +1554,7 @@ the first argument and CBARGS as the rest of arguments."
|
||||||
|
|
||||||
(defun ein:notebook-close-notebooks (&optional blithely)
|
(defun ein:notebook-close-notebooks (&optional blithely)
|
||||||
"Used in `ein:jupyter-server-stop' and `kill-emacs-query-functions' hook."
|
"Used in `ein:jupyter-server-stop' and `kill-emacs-query-functions' hook."
|
||||||
(ein:aif (ein:notebook-opened-notebooks)
|
(aif (ein:notebook-opened-notebooks)
|
||||||
(if (and (cl-notevery #'identity (mapcar #'ein:notebook-close it))
|
(if (and (cl-notevery #'identity (mapcar #'ein:notebook-close it))
|
||||||
(not blithely))
|
(not blithely))
|
||||||
(y-or-n-p "Some notebooks could not be saved. Exit anyway?")
|
(y-or-n-p "Some notebooks could not be saved. Exit anyway?")
|
||||||
|
|
|
@ -172,27 +172,33 @@ This function adds NBLIST to `ein:notebooklist-map'."
|
||||||
|
|
||||||
(defun ein:crib-token (url-or-port)
|
(defun ein:crib-token (url-or-port)
|
||||||
"Shell out to jupyter for its credentials knowledge. Return list of (PASSWORD TOKEN)."
|
"Shell out to jupyter for its credentials knowledge. Return list of (PASSWORD TOKEN)."
|
||||||
(ein:aif (loop for line in (condition-case err
|
(aif (loop for line in (condition-case err
|
||||||
(process-lines ein:jupyter-default-server-command
|
(apply #'process-lines
|
||||||
"notebook" "list" "--json")
|
ein:jupyter-server-command
|
||||||
;; often there is no local jupyter installation
|
(append (aif ein:jupyter-server-use-subcommand
|
||||||
(error (ein:log 'info "ein:crib-token: %s" err) nil))
|
(list it))
|
||||||
with token0
|
'("list" "--json")))
|
||||||
with password0
|
;; often there is no local jupyter installation
|
||||||
when (destructuring-bind
|
(error (ein:log 'info "ein:crib-token: %s" err) nil))
|
||||||
(&key password url token &allow-other-keys)
|
with token0
|
||||||
(ein:json-read-from-string line)
|
with password0
|
||||||
(prog1 (equal (ein:url url) url-or-port)
|
when (destructuring-bind
|
||||||
(setq password0 password) ;; t or :json-false
|
(&key password url token &allow-other-keys)
|
||||||
(setq token0 token)))
|
(ein:json-read-from-string line)
|
||||||
return (list password0 token0))
|
(prog1 (equal (ein:url url) url-or-port)
|
||||||
|
(setq password0 password) ;; t or :json-false
|
||||||
|
(setq token0 token)))
|
||||||
|
return (list password0 token0))
|
||||||
it (list nil nil)))
|
it (list nil nil)))
|
||||||
|
|
||||||
(defun ein:crib-running-servers ()
|
(defun ein:crib-running-servers ()
|
||||||
"Shell out to jupyter for running servers."
|
"Shell out to jupyter for running servers."
|
||||||
(loop for line in (condition-case err
|
(loop for line in (condition-case err
|
||||||
(process-lines ein:jupyter-default-server-command
|
(apply #'process-lines
|
||||||
"notebook" "list" "--json")
|
ein:jupyter-server-command
|
||||||
|
(append (aif ein:jupyter-server-use-subcommand
|
||||||
|
(list it))
|
||||||
|
'("list" "--json")))
|
||||||
(error (ein:log 'info "ein:crib-running-servers: %s" err)
|
(error (ein:log 'info "ein:crib-running-servers: %s" err)
|
||||||
nil))
|
nil))
|
||||||
collecting (destructuring-bind
|
collecting (destructuring-bind
|
||||||
|
@ -210,9 +216,9 @@ This function adds NBLIST to `ein:notebooklist-map'."
|
||||||
(t nil)))))
|
(t nil)))))
|
||||||
|
|
||||||
(defun ein:notebooklist-ask-url-or-port ()
|
(defun ein:notebooklist-ask-url-or-port ()
|
||||||
(let* ((default (ein:url (ein:aif (ein:get-notebook)
|
(let* ((default (ein:url (aif (ein:get-notebook)
|
||||||
(ein:$notebook-url-or-port it)
|
(ein:$notebook-url-or-port it)
|
||||||
(ein:aif ein:%notebooklist%
|
(aif ein:%notebooklist%
|
||||||
(ein:$notebooklist-url-or-port it)
|
(ein:$notebooklist-url-or-port it)
|
||||||
(ein:default-url-or-port)))))
|
(ein:default-url-or-port)))))
|
||||||
(url-or-port-list
|
(url-or-port-list
|
||||||
|
|
|
@ -199,7 +199,7 @@ insert-prev insert-next move-prev move-next)"
|
||||||
'help-echo "Click (mouse-1) to insert a new tab."
|
'help-echo "Click (mouse-1) to insert a new tab."
|
||||||
'mouse-face 'highlight
|
'mouse-face 'highlight
|
||||||
'face 'ein:notification-tab-normal)
|
'face 'ein:notification-tab-normal)
|
||||||
(propertize (ein:aif (and ein:%notebook% (ein:$notebook-kernelspec ein:%notebook%))
|
(propertize (aif (and ein:%notebook% (ein:$notebook-kernelspec ein:%notebook%))
|
||||||
(format "|%s|" (ein:$kernelspec-name it))
|
(format "|%s|" (ein:$kernelspec-name it))
|
||||||
"|unknown: please click and select a kernel|")
|
"|unknown: please click and select a kernel|")
|
||||||
'keymap ein:header-line-switch-kernel-map
|
'keymap ein:header-line-switch-kernel-map
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
"Emacs IPython Notebook"
|
"Emacs IPython Notebook"
|
||||||
'((emacs "25")
|
'((emacs "25")
|
||||||
(websocket "20190620.338")
|
(websocket "20190620.338")
|
||||||
|
(anaphora "20180618")
|
||||||
(request "20190621.1622")
|
(request "20190621.1622")
|
||||||
(deferred "0.5")
|
(deferred "0.5")
|
||||||
(polymode "20190426.1729")
|
(polymode "20190426.1729")
|
||||||
|
|
|
@ -124,8 +124,11 @@
|
||||||
"Use `jupyter notebook list --json` to populate ein:%processes%"
|
"Use `jupyter notebook list --json` to populate ein:%processes%"
|
||||||
(clrhash ein:%processes%)
|
(clrhash ein:%processes%)
|
||||||
(loop for line in (condition-case err
|
(loop for line in (condition-case err
|
||||||
(process-lines ein:jupyter-default-server-command
|
(apply #'process-lines
|
||||||
"notebook" "list" "--json")
|
ein:jupyter-server-command
|
||||||
|
(append (aif ein:jupyter-server-use-subcommand
|
||||||
|
(list it))
|
||||||
|
'("list" "--json")))
|
||||||
;; often there is no local jupyter installation
|
;; often there is no local jupyter installation
|
||||||
(error (ein:log 'info "ein:process-refresh-processes: %s" err) nil))
|
(error (ein:log 'info "ein:process-refresh-processes: %s" err) nil))
|
||||||
do (destructuring-bind
|
do (destructuring-bind
|
||||||
|
@ -182,7 +185,8 @@
|
||||||
(ein:notebook-open url-or-port
|
(ein:notebook-open url-or-port
|
||||||
path* nil callback*))
|
path* nil callback*))
|
||||||
path callback)))
|
path callback)))
|
||||||
(ein:jupyter-server-start (executable-find ein:jupyter-default-server-command) nbdir nil callback2)))))
|
(ein:jupyter-server-start (executable-find ein:jupyter-server-command)
|
||||||
|
nbdir nil callback2)))))
|
||||||
|
|
||||||
(defun ein:process-open-notebook (&optional filename buffer-callback)
|
(defun ein:process-open-notebook (&optional filename buffer-callback)
|
||||||
"When FILENAME is unspecified the variable `buffer-file-name'
|
"When FILENAME is unspecified the variable `buffer-file-name'
|
||||||
|
|
|
@ -178,7 +178,7 @@ pager buffer. You can explicitly specify the object by selecting it."
|
||||||
(ein:log 'debug "object[[%s]] other-window[[%s]]" object other-window)
|
(ein:log 'debug "object[[%s]] other-window[[%s]]" object other-window)
|
||||||
(ein:case-equal msg-type
|
(ein:case-equal msg-type
|
||||||
(("stream" "display_data")
|
(("stream" "display_data")
|
||||||
(ein:aif (or (plist-get content :text) (plist-get content :data))
|
(aif (or (plist-get content :text) (plist-get content :data))
|
||||||
(if (string-match ein:pytools-jump-to-source-not-found-regexp it)
|
(if (string-match ein:pytools-jump-to-source-not-found-regexp it)
|
||||||
(ein:log 'info
|
(ein:log 'info
|
||||||
"Jumping to the source of %s...Not found" object)
|
"Jumping to the source of %s...Not found" object)
|
||||||
|
@ -239,7 +239,7 @@ is defined."
|
||||||
(destructuring-bind (kernel object callback) packed
|
(destructuring-bind (kernel object callback) packed
|
||||||
(if (or (string= msg-type "stream")
|
(if (or (string= msg-type "stream")
|
||||||
(string= msg-type "display_data"))
|
(string= msg-type "display_data"))
|
||||||
(ein:aif (or (plist-get content :text) (plist-get content :data))
|
(aif (or (plist-get content :text) (plist-get content :data))
|
||||||
(if (string-match ein:pytools-jump-to-source-not-found-regexp it)
|
(if (string-match ein:pytools-jump-to-source-not-found-regexp it)
|
||||||
(ein:log 'info
|
(ein:log 'info
|
||||||
"Source of %s not found" object)
|
"Source of %s not found" object)
|
||||||
|
@ -282,7 +282,7 @@ given, open the last point in the other window."
|
||||||
(when (ein:aand (car ein:pytools-jump-stack)
|
(when (ein:aand (car ein:pytools-jump-stack)
|
||||||
(equal (point) (marker-position it)))
|
(equal (point) (marker-position it)))
|
||||||
(setq ein:pytools-jump-stack (cdr ein:pytools-jump-stack)))
|
(setq ein:pytools-jump-stack (cdr ein:pytools-jump-stack)))
|
||||||
(ein:aif (car ein:pytools-jump-stack)
|
(aif (car ein:pytools-jump-stack)
|
||||||
(ein:goto-marker it other-window)
|
(ein:goto-marker it other-window)
|
||||||
(ein:log 'info "Nothing on stack."))))
|
(ein:log 'info "Nothing on stack."))))
|
||||||
|
|
||||||
|
|
|
@ -140,7 +140,7 @@ KEY, then call `request' with URL and SETTINGS. KEY is compared by
|
||||||
do (ein:log 'warn "ein:query-singleton-ajax: %d running processes"
|
do (ein:log 'warn "ein:query-singleton-ajax: %d running processes"
|
||||||
running)
|
running)
|
||||||
do (sleep-for 3))
|
do (sleep-for 3))
|
||||||
(ein:aif (gethash key ein:query-running-process-table)
|
(aif (gethash key ein:query-running-process-table)
|
||||||
(unless (request-response-done-p it)
|
(unless (request-response-done-p it)
|
||||||
(ein:log 'debug "Race! %s %s" key (request-response-data it))))
|
(ein:log 'debug "Race! %s %s" key (request-response-data it))))
|
||||||
(let ((response (apply #'request (url-encode-url url)
|
(let ((response (apply #'request (url-encode-url url)
|
||||||
|
|
|
@ -83,7 +83,7 @@ Called from ewoc pretty printer via `ein:cell-pp'."
|
||||||
(when (slot-value cell 'popup)
|
(when (slot-value cell 'popup)
|
||||||
(pop-to-buffer (ein:shared-output-create-buffer)))
|
(pop-to-buffer (ein:shared-output-create-buffer)))
|
||||||
(cl-call-next-method)
|
(cl-call-next-method)
|
||||||
(ein:aif (ein:oref-safe cell 'callback)
|
(aif (ein:oref-safe cell 'callback)
|
||||||
(progn
|
(progn
|
||||||
(funcall it cell)
|
(funcall it cell)
|
||||||
(setf (slot-value cell 'callback-called) t))))
|
(setf (slot-value cell 'callback-called) t))))
|
||||||
|
@ -94,7 +94,7 @@ Called from ewoc pretty printer via `ein:cell-pp'."
|
||||||
"ein:cell--handle-execute-reply (cell ein:shared-output-cell): %s"
|
"ein:cell--handle-execute-reply (cell ein:shared-output-cell): %s"
|
||||||
content)
|
content)
|
||||||
(cl-call-next-method)
|
(cl-call-next-method)
|
||||||
(ein:aif (ein:oref-safe cell 'callback)
|
(aif (ein:oref-safe cell 'callback)
|
||||||
;; clear the way for waiting block in `ob-ein--execute-async'
|
;; clear the way for waiting block in `ob-ein--execute-async'
|
||||||
;; but only after 2 seconds to allow for handle-output stragglers
|
;; but only after 2 seconds to allow for handle-output stragglers
|
||||||
;; TODO avoid this hack
|
;; TODO avoid this hack
|
||||||
|
|
|
@ -41,13 +41,6 @@ while maintaining the undo list for the current buffer."
|
||||||
`(let ((buffer-undo-list t))
|
`(let ((buffer-undo-list t))
|
||||||
,@body))
|
,@body))
|
||||||
|
|
||||||
(defmacro ein:aif (test-form then-form &rest else-forms)
|
|
||||||
"Anaphoric IF. Adapted from `e2wm:aif'."
|
|
||||||
(declare (debug (form form &rest form)))
|
|
||||||
`(let ((it ,test-form))
|
|
||||||
(if it ,then-form ,@else-forms)))
|
|
||||||
(put 'ein:aif 'lisp-indent-function 2)
|
|
||||||
|
|
||||||
(defmacro ein:aand (test &rest rest)
|
(defmacro ein:aand (test &rest rest)
|
||||||
"Anaphoric AND. Adapted from `e2wm:aand'."
|
"Anaphoric AND. Adapted from `e2wm:aand'."
|
||||||
(declare (debug (form &rest form)))
|
(declare (debug (form &rest form)))
|
||||||
|
@ -167,7 +160,7 @@ before previous opening parenthesis."
|
||||||
"\\s-\\|\n\\|\\.")
|
"\\s-\\|\n\\|\\.")
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(with-syntax-table ein:dotty-syntax-table
|
(with-syntax-table ein:dotty-syntax-table
|
||||||
(ein:aif (thing-at-point 'symbol)
|
(aif (thing-at-point 'symbol)
|
||||||
it
|
it
|
||||||
(unless (looking-at "(")
|
(unless (looking-at "(")
|
||||||
(search-backward "(" (point-at-bol) t))
|
(search-backward "(" (point-at-bol) t))
|
||||||
|
@ -636,7 +629,7 @@ DONEBACK returns t or 'error when calling process is done, and nil if not done."
|
||||||
(deferred:$
|
(deferred:$
|
||||||
(deferred:next
|
(deferred:next
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(ein:aif (funcall doneback) it
|
(aif (funcall doneback) it
|
||||||
(message "%s%s" mesg (make-string (1+ (% (incf count) 3)) ?.))
|
(message "%s%s" mesg (make-string (1+ (% (incf count) 3)) ?.))
|
||||||
(sleep-for 0 365)))))))
|
(sleep-for 0 365)))))))
|
||||||
(deferred:nextc it
|
(deferred:nextc it
|
||||||
|
|
|
@ -73,7 +73,7 @@ Normalize `buffer-undo-list' by removing extraneous details, and update the ein:
|
||||||
(ein:log 'debug "truncating %s to %s: %S -> %S" (length ein:%which-cell%) (length buffer-undo-list) ein:%which-cell% (nthcdr (- fill) ein:%which-cell%))
|
(ein:log 'debug "truncating %s to %s: %S -> %S" (length ein:%which-cell%) (length buffer-undo-list) ein:%which-cell% (nthcdr (- fill) ein:%which-cell%))
|
||||||
(setq ein:%which-cell% (nthcdr (- fill) ein:%which-cell%)))
|
(setq ein:%which-cell% (nthcdr (- fill) ein:%which-cell%)))
|
||||||
(when (> fill 0)
|
(when (> fill 0)
|
||||||
(let ((cell-id (ein:aif (ein:worksheet-get-current-cell :noerror t)
|
(let ((cell-id (aif (ein:worksheet-get-current-cell :noerror t)
|
||||||
(ein:worksheet--unique-enough-cell-id it) nil)))
|
(ein:worksheet--unique-enough-cell-id it) nil)))
|
||||||
(let ((ein:log-print-level 5))
|
(let ((ein:log-print-level 5))
|
||||||
(ein:log 'debug "which-cell (%s . %s) %s %S fill=%s" change-beg change-end cell-id (cl-subseq buffer-undo-list 0 fill) fill))
|
(ein:log 'debug "which-cell (%s . %s) %s %S fill=%s" change-beg change-end cell-id (cl-subseq buffer-undo-list 0 fill) fill))
|
||||||
|
@ -143,7 +143,8 @@ Normalize `buffer-undo-list' by removing extraneous details, and update the ein:
|
||||||
(let ((mp (marker-position (car u))))
|
(let ((mp (marker-position (car u))))
|
||||||
(if (not (null mp))
|
(if (not (null mp))
|
||||||
(let* ((m (set-marker (make-marker) (+ ,distance mp) (marker-buffer (car u)))))
|
(let* ((m (set-marker (make-marker) (+ ,distance mp) (marker-buffer (car u)))))
|
||||||
(cons m (cdr u))) u)))
|
(cons m (cdr u)))
|
||||||
|
u)))
|
||||||
((and (consp u) (null (car u))
|
((and (consp u) (null (car u))
|
||||||
(numberp (car (last u))) (numberp (cdr (last u))))
|
(numberp (car (last u))) (numberp (cdr (last u))))
|
||||||
(append (cl-subseq u 0 3)
|
(append (cl-subseq u 0 3)
|
||||||
|
@ -281,7 +282,7 @@ Normalize `buffer-undo-list' by removing extraneous details, and update the ein:
|
||||||
(ein:worksheet--jigger-undo-list)
|
(ein:worksheet--jigger-undo-list)
|
||||||
(cl-remprop 'ein:%cell-lengths% (slot-value cell 'cell-id))))))
|
(cl-remprop 'ein:%cell-lengths% (slot-value cell 'cell-id))))))
|
||||||
|
|
||||||
|
|
||||||
;;; Class and variable
|
;;; Class and variable
|
||||||
|
|
||||||
(defvar ein:worksheet-buffer-name-template "*ein: %s/%s*")
|
(defvar ein:worksheet-buffer-name-template "*ein: %s/%s*")
|
||||||
|
@ -289,7 +290,7 @@ Normalize `buffer-undo-list' by removing extraneous details, and update the ein:
|
||||||
(ein:deflocal ein:%worksheet% nil
|
(ein:deflocal ein:%worksheet% nil
|
||||||
"Buffer local variable to store an instance of `ein:worksheet'.")
|
"Buffer local variable to store an instance of `ein:worksheet'.")
|
||||||
|
|
||||||
|
|
||||||
;;; Initialization of object and buffer
|
;;; Initialization of object and buffer
|
||||||
|
|
||||||
(defun ein:worksheet-new (nbformat get-notebook-name discard-output-p
|
(defun ein:worksheet-new (nbformat get-notebook-name discard-output-p
|
||||||
|
@ -348,7 +349,7 @@ Normalize `buffer-undo-list' by removing extraneous details, and update the ein:
|
||||||
|
|
||||||
(cl-defmethod ein:worksheet-full-name ((ws ein:worksheet))
|
(cl-defmethod ein:worksheet-full-name ((ws ein:worksheet))
|
||||||
(let ((nb-name (ein:worksheet-notebook-name ws)))
|
(let ((nb-name (ein:worksheet-notebook-name ws)))
|
||||||
(ein:aif (ein:worksheet-name ws)
|
(aif (ein:worksheet-name ws)
|
||||||
(concat nb-name "/" it)
|
(concat nb-name "/" it)
|
||||||
nb-name)))
|
nb-name)))
|
||||||
|
|
||||||
|
@ -445,7 +446,7 @@ Normalize `buffer-undo-list' by removing extraneous details, and update the ein:
|
||||||
(case (car path)
|
(case (car path)
|
||||||
(cell (ein:cell-pp (cdr path) data)))))
|
(cell (ein:cell-pp (cdr path) data)))))
|
||||||
|
|
||||||
|
|
||||||
;;; Persistance and loading
|
;;; Persistance and loading
|
||||||
|
|
||||||
(cl-defmethod ein:worksheet-from-json ((ws ein:worksheet) data)
|
(cl-defmethod ein:worksheet-from-json ((ws ein:worksheet) data)
|
||||||
|
@ -517,7 +518,7 @@ worksheet WS is reopened.
|
||||||
\(fn ws)"
|
\(fn ws)"
|
||||||
(setf (slot-value ws 'dont-save-cells) t))
|
(setf (slot-value ws 'dont-save-cells) t))
|
||||||
|
|
||||||
|
|
||||||
;;; Cell indexing, retrieval, etc.
|
;;; Cell indexing, retrieval, etc.
|
||||||
|
|
||||||
(cl-defmethod ein:worksheet-cell-from-type ((ws ein:worksheet) type &rest args)
|
(cl-defmethod ein:worksheet-cell-from-type ((ws ein:worksheet) type &rest args)
|
||||||
|
@ -588,7 +589,7 @@ buffer or there is no cell in the current buffer, return `nil'."
|
||||||
(unless noerror
|
(unless noerror
|
||||||
(error "Cell not found"))))
|
(error "Cell not found"))))
|
||||||
|
|
||||||
|
|
||||||
;;; Insertion and deletion of cells
|
;;; Insertion and deletion of cells
|
||||||
|
|
||||||
(defun ein:worksheet--get-ws-or-error ()
|
(defun ein:worksheet--get-ws-or-error ()
|
||||||
|
@ -856,7 +857,7 @@ If prefix is given, merge current cell into next cell."
|
||||||
(insert head "\n"))
|
(insert head "\n"))
|
||||||
(when focus (ein:cell-goto next-cell)))))
|
(when focus (ein:cell-goto next-cell)))))
|
||||||
|
|
||||||
|
|
||||||
;;; Cell selection.
|
;;; Cell selection.
|
||||||
|
|
||||||
(cl-defun ein:worksheet-next-input-cell (ewoc-node &optional up (nth 1))
|
(cl-defun ein:worksheet-next-input-cell (ewoc-node &optional up (nth 1))
|
||||||
|
@ -887,7 +888,7 @@ When NTH is specified, return NTH cell. Note that this function is
|
||||||
(funcall (if up #'ein:cell-prev #'ein:cell-next) cell))))
|
(funcall (if up #'ein:cell-prev #'ein:cell-next) cell))))
|
||||||
|
|
||||||
(defun ein:worksheet-goto-input (ewoc-node up)
|
(defun ein:worksheet-goto-input (ewoc-node up)
|
||||||
(ein:aif (ein:worksheet-next-input-cell ewoc-node up)
|
(aif (ein:worksheet-next-input-cell ewoc-node up)
|
||||||
(ein:cell-goto it)
|
(ein:cell-goto it)
|
||||||
(message "No %s input" (if up "previous" "next"))))
|
(message "No %s input" (if up "previous" "next"))))
|
||||||
|
|
||||||
|
@ -906,7 +907,7 @@ When NTH is specified, return NTH cell. Note that this function is
|
||||||
Go to previous cell if UP is t.
|
Go to previous cell if UP is t.
|
||||||
Return t when the movement is succeeded."
|
Return t when the movement is succeeded."
|
||||||
(unless prop (setq prop :input))
|
(unless prop (setq prop :input))
|
||||||
(ein:and-let* ((current-node (ein:worksheet-get-current-ewoc-node))
|
(-when-let* ((current-node (ein:worksheet-get-current-ewoc-node))
|
||||||
(current-cell (ein:cell-from-ewoc-node current-node))
|
(current-cell (ein:cell-from-ewoc-node current-node))
|
||||||
(target-cell
|
(target-cell
|
||||||
(if (and (= nth 1)
|
(if (and (= nth 1)
|
||||||
|
@ -934,12 +935,12 @@ similarly with `end-of-defun'.
|
||||||
It is set in `ein:notebook-multilang-mode'."
|
It is set in `ein:notebook-multilang-mode'."
|
||||||
(ein:worksheet-goto-next-cell-element (or arg 1) nil 0 :after-input))
|
(ein:worksheet-goto-next-cell-element (or arg 1) nil 0 :after-input))
|
||||||
|
|
||||||
|
|
||||||
;;; Cell movement
|
;;; Cell movement
|
||||||
|
|
||||||
(defun ein:worksheet-move-cell (ws cell up)
|
(defun ein:worksheet-move-cell (ws cell up)
|
||||||
;; effectively kill and yank modulo dirtying kill ring
|
;; effectively kill and yank modulo dirtying kill ring
|
||||||
(ein:aif (if up (ein:cell-prev cell) (ein:cell-next cell))
|
(aif (if up (ein:cell-prev cell) (ein:cell-next cell))
|
||||||
(let ((inhibit-read-only t)
|
(let ((inhibit-read-only t)
|
||||||
(pivot-cell it) clone)
|
(pivot-cell it) clone)
|
||||||
(ein:cell-save-text cell)
|
(ein:cell-save-text cell)
|
||||||
|
@ -965,7 +966,6 @@ It is set in `ein:notebook-multilang-mode'."
|
||||||
(ein:worksheet-get-current-cell)))
|
(ein:worksheet-get-current-cell)))
|
||||||
(ein:worksheet-move-cell ws cell nil))
|
(ein:worksheet-move-cell ws cell nil))
|
||||||
|
|
||||||
|
|
||||||
;;; Cell collapsing and output clearing
|
;;; Cell collapsing and output clearing
|
||||||
|
|
||||||
(defun ein:worksheet-toggle-output (ws cell)
|
(defun ein:worksheet-toggle-output (ws cell)
|
||||||
|
@ -1009,7 +1009,6 @@ Do not clear input prompts when the prefix argument is given."
|
||||||
(mapc (lambda (c) (ein:worksheet-clear-output c preserve-input-prompt))
|
(mapc (lambda (c) (ein:worksheet-clear-output c preserve-input-prompt))
|
||||||
(seq-filter #'ein:codecell-p (ein:worksheet-get-cells ws))))
|
(seq-filter #'ein:codecell-p (ein:worksheet-get-cells ws))))
|
||||||
|
|
||||||
|
|
||||||
;;; Kernel related things
|
;;; Kernel related things
|
||||||
|
|
||||||
(defun ein:worksheet-kernel-status (ws)
|
(defun ein:worksheet-kernel-status (ws)
|
||||||
|
@ -1051,7 +1050,7 @@ next cell, or insert if none."
|
||||||
(ein:worksheet-get-current-cell)))
|
(ein:worksheet-get-current-cell)))
|
||||||
(when (cl-typep cell 'ein:codecell)
|
(when (cl-typep cell 'ein:codecell)
|
||||||
(ein:worksheet-execute-cell ws cell))
|
(ein:worksheet-execute-cell ws cell))
|
||||||
(ein:aif (and (not insert) (ein:cell-next cell))
|
(aif (and (not insert) (ein:cell-next cell))
|
||||||
(ein:cell-goto it)
|
(ein:cell-goto it)
|
||||||
(ein:worksheet-insert-cell-below ws 'code cell t)))
|
(ein:worksheet-insert-cell-below ws 'code cell t)))
|
||||||
|
|
||||||
|
@ -1128,7 +1127,6 @@ in the history."
|
||||||
(ein:worksheet--get-history-index -1)))
|
(ein:worksheet--get-history-index -1)))
|
||||||
(ein:worksheet-insert-last-input-history ws cell index))
|
(ein:worksheet-insert-last-input-history ws cell index))
|
||||||
|
|
||||||
|
|
||||||
;;; Metadata
|
;;; Metadata
|
||||||
|
|
||||||
(defun ein:worksheet-rename-sheet (ws name)
|
(defun ein:worksheet-rename-sheet (ws name)
|
||||||
|
@ -1142,7 +1140,6 @@ in the history."
|
||||||
(ein:worksheet-set-modified-p ws t)
|
(ein:worksheet-set-modified-p ws t)
|
||||||
(ein:worksheet-set-buffer-name ws)))
|
(ein:worksheet-set-buffer-name ws)))
|
||||||
|
|
||||||
|
|
||||||
;;; Generic getter
|
;;; Generic getter
|
||||||
|
|
||||||
(defun ein:get-url-or-port--worksheet ()
|
(defun ein:get-url-or-port--worksheet ()
|
||||||
|
@ -1158,7 +1155,7 @@ in the history."
|
||||||
(defun ein:get-traceback-data--worksheet ()
|
(defun ein:get-traceback-data--worksheet ()
|
||||||
(ein:aand (ein:get-cell-at-point--worksheet) (ein:cell-get-tb-data it)))
|
(ein:aand (ein:get-cell-at-point--worksheet) (ein:cell-get-tb-data it)))
|
||||||
|
|
||||||
|
|
||||||
;;; Predicate
|
;;; Predicate
|
||||||
|
|
||||||
(defun ein:worksheet-buffer-p ()
|
(defun ein:worksheet-buffer-p ()
|
||||||
|
@ -1174,7 +1171,7 @@ in the history."
|
||||||
(or (slot-value ws 'dirty)
|
(or (slot-value ws 'dirty)
|
||||||
(buffer-modified-p buffer)))))
|
(buffer-modified-p buffer)))))
|
||||||
|
|
||||||
|
|
||||||
;;; Utility commands
|
;;; Utility commands
|
||||||
|
|
||||||
(defun ein:worksheet-dedent-cell-text (cell)
|
(defun ein:worksheet-dedent-cell-text (cell)
|
||||||
|
@ -1205,7 +1202,7 @@ in the history."
|
||||||
(defun ein:worksheet-jump-to-first-executing-cell ()
|
(defun ein:worksheet-jump-to-first-executing-cell ()
|
||||||
"Move the point to the first executing cell in the current worksheet."
|
"Move the point to the first executing cell in the current worksheet."
|
||||||
(interactive)
|
(interactive)
|
||||||
(ein:aif (ein:worksheet-first-executing-cell (ein:worksheet-get-cells ein:%worksheet%))
|
(aif (ein:worksheet-first-executing-cell (ein:worksheet-get-cells ein:%worksheet%))
|
||||||
(ein:cell-goto it)
|
(ein:cell-goto it)
|
||||||
(message "No cell currently executing.")))
|
(message "No cell currently executing.")))
|
||||||
|
|
||||||
|
@ -1214,11 +1211,11 @@ in the history."
|
||||||
(interactive)
|
(interactive)
|
||||||
(let* ((curcell (ein:get-cell-at-point--worksheet))
|
(let* ((curcell (ein:get-cell-at-point--worksheet))
|
||||||
(restcells (ein:worksheet--cells-after-cell ein:%worksheet% curcell)))
|
(restcells (ein:worksheet--cells-after-cell ein:%worksheet% curcell)))
|
||||||
(ein:aif (ein:worksheet-first-executing-cell restcells)
|
(aif (ein:worksheet-first-executing-cell restcells)
|
||||||
(ein:cell-goto it)
|
(ein:cell-goto it)
|
||||||
(message "No additional cells are executing."))))
|
(message "No additional cells are executing."))))
|
||||||
|
|
||||||
|
|
||||||
;;; Auto-execution
|
;;; Auto-execution
|
||||||
|
|
||||||
(defun ein:worksheet-toggle-autoexec (cell)
|
(defun ein:worksheet-toggle-autoexec (cell)
|
||||||
|
@ -1260,7 +1257,7 @@ function."
|
||||||
(ein:worksheet-get-cells ws))))))
|
(ein:worksheet-get-cells ws))))))
|
||||||
ws (current-buffer)))))
|
ws (current-buffer)))))
|
||||||
|
|
||||||
|
|
||||||
;;; Imenu
|
;;; Imenu
|
||||||
|
|
||||||
(defun ein:worksheet-imenu-create-index ()
|
(defun ein:worksheet-imenu-create-index ()
|
||||||
|
@ -1279,7 +1276,7 @@ function."
|
||||||
"Called via notebook mode hooks."
|
"Called via notebook mode hooks."
|
||||||
(setq imenu-create-index-function #'ein:worksheet-imenu-create-index))
|
(setq imenu-create-index-function #'ein:worksheet-imenu-create-index))
|
||||||
|
|
||||||
|
|
||||||
;;; Workarounds
|
;;; Workarounds
|
||||||
|
|
||||||
(defadvice fill-paragraph (around ein:worksheet-fill-paragraph activate)
|
(defadvice fill-paragraph (around ein:worksheet-fill-paragraph activate)
|
||||||
|
|
46
lisp/ein.el
46
lisp/ein.el
|
@ -1,9 +1,11 @@
|
||||||
;;; ein.el --- IPython notebook client in Emacs
|
;;; ein.el --- jupyter notebook client
|
||||||
|
|
||||||
;; Copyright (C) 2012-2015 Takafumi Arakaki, John Miller
|
;; Copyright (C) 2012-2019 The Authors of the Emacs IPython Notebook (EIN)
|
||||||
|
|
||||||
;; Author: John Miller <millejoh at millejoh.com>, Takafumi Arakaki <aka.tkf at gmail.com>
|
;; Authors: dickmao <github id: dickmao>
|
||||||
;; URL: http://millejoh.github.io/emacs-ipython-notebook/
|
;; John Miller <millejoh at millejoh.com>
|
||||||
|
;; Takafumi Arakaki <aka.tkf at gmail.com>
|
||||||
|
;; URL: https://github.com/dickmao/emacs-ipython-notebook
|
||||||
;; Keywords: jupyter, literate programming, reproducible research
|
;; Keywords: jupyter, literate programming, reproducible research
|
||||||
|
|
||||||
;; This file is NOT part of GNU Emacs.
|
;; This file is NOT part of GNU Emacs.
|
||||||
|
@ -38,42 +40,10 @@
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
(eval-when-compile (require 'cl))
|
(eval-when-compile (require 'cl))
|
||||||
(provide 'ein)
|
|
||||||
|
|
||||||
;;; Old commentary:
|
|
||||||
|
|
||||||
;; Development
|
|
||||||
;; ===========
|
|
||||||
|
|
||||||
;; Event vs hook vs callback
|
|
||||||
;; -------------------------
|
|
||||||
;;
|
|
||||||
;; * Use events (`ein:events') for calling (possibly multiple) functions
|
|
||||||
;; for its side effect.
|
|
||||||
;; * Use hooks for global/configurable setting.
|
|
||||||
;; * Use callback when caller needs returned value.
|
|
||||||
;; (e.g., `:get-buffers' slot in `ein:kernelinfo')
|
|
||||||
|
|
||||||
;; Naming
|
|
||||||
;; ------
|
|
||||||
;;
|
|
||||||
;; Variable named `ein:%VAR-NAME%' is a permanent buffer local
|
|
||||||
;; variable defined by `ein:deflocal'. It is often an instance of a
|
|
||||||
;; class/struct named `ein:VAR-NAME'.
|
|
||||||
;;
|
|
||||||
;; Old naming rule:
|
|
||||||
;; * `ein:@VAR-NAME'/`ein:VAR-NAME' is a permanent buffer local
|
|
||||||
;; variable. These variables are obsolete now.
|
|
||||||
;; * `ein:$STRUCT-NAME' is a name of struct.
|
|
||||||
;; These strcuts will be renamed to `ein:CLASS-NAME' when
|
|
||||||
;; reimplementing them using EIEIO class instead of CL struct.
|
|
||||||
;;
|
|
||||||
;; See also:
|
|
||||||
;; `CLiki : naming conventions <http://www.cliki.net/naming%20conventions>`_
|
|
||||||
|
|
||||||
;; Integrate ein into core emacs functionality
|
|
||||||
(when (boundp 'mouse-buffer-menu-mode-groups)
|
(when (boundp 'mouse-buffer-menu-mode-groups)
|
||||||
(add-to-list 'mouse-buffer-menu-mode-groups
|
(add-to-list 'mouse-buffer-menu-mode-groups
|
||||||
'("^ein:" . "ein")))
|
'("^ein:" . "ein")))
|
||||||
|
|
||||||
|
(provide 'ein)
|
||||||
|
|
||||||
;;; ein.el ends here
|
;;; ein.el ends here
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
;;; Code:
|
;;; Code:
|
||||||
(require 'ob)
|
(require 'ob)
|
||||||
(require 'ein-utils)
|
(require 'ein-utils)
|
||||||
|
(require 'anaphora)
|
||||||
|
|
||||||
(autoload 'org-element-property "org-element")
|
(autoload 'org-element-property "org-element")
|
||||||
(autoload 'org-element-context "org-element")
|
(autoload 'org-element-context "org-element")
|
||||||
|
@ -91,7 +92,7 @@
|
||||||
(defcustom ob-ein-inline-image-directory "ein-images"
|
(defcustom ob-ein-inline-image-directory "ein-images"
|
||||||
"Store ob-ein images here."
|
"Store ob-ein images here."
|
||||||
:group 'ein
|
:group 'ein
|
||||||
:type '(directory))
|
:type 'directory)
|
||||||
|
|
||||||
(defcustom ob-ein-default-header-args:ein nil
|
(defcustom ob-ein-default-header-args:ein nil
|
||||||
"No documentation."
|
"No documentation."
|
||||||
|
@ -186,7 +187,7 @@ Based on ob-ipython--configure-kernel."
|
||||||
ein:url-localhost))
|
ein:url-localhost))
|
||||||
(lang (nth 0 (org-babel-get-src-block-info)))
|
(lang (nth 0 (org-babel-get-src-block-info)))
|
||||||
(kernelspec (or (cdr (assoc :kernelspec processed-params))
|
(kernelspec (or (cdr (assoc :kernelspec processed-params))
|
||||||
(ein:aif (cdr (assoc lang org-src-lang-modes))
|
(aif (cdr (assoc lang org-src-lang-modes))
|
||||||
(cons 'language (format "%s" it))
|
(cons 'language (format "%s" it))
|
||||||
(error "ob-ein--execute-body: %s not among %s"
|
(error "ob-ein--execute-body: %s not among %s"
|
||||||
lang (mapcar #'car org-src-lang-modes)))))
|
lang (mapcar #'car org-src-lang-modes)))))
|
||||||
|
@ -236,7 +237,7 @@ Based on ob-ipython--configure-kernel."
|
||||||
`ein:shared-output-eval-string' completes."
|
`ein:shared-output-eval-string' completes."
|
||||||
(apply-partially
|
(apply-partially
|
||||||
(lambda (buffer* params* result-params* name* cell)
|
(lambda (buffer* params* result-params* name* cell)
|
||||||
(let* ((raw (ein:aif (ein:oref-safe cell 'traceback)
|
(let* ((raw (aif (ein:oref-safe cell 'traceback)
|
||||||
(ansi-color-apply (ein:join-str "\n" it))
|
(ansi-color-apply (ein:join-str "\n" it))
|
||||||
(ob-ein--process-outputs
|
(ob-ein--process-outputs
|
||||||
(ein:oref-safe cell 'outputs) params*)))
|
(ein:oref-safe cell 'outputs) params*)))
|
||||||
|
@ -352,7 +353,7 @@ if necessary. Install CALLBACK (i.e., cell execution) upon notebook retrieval."
|
||||||
(notebook (funcall callback notebook))
|
(notebook (funcall callback notebook))
|
||||||
((string= (url-host parsed-url) ein:url-localhost)
|
((string= (url-host parsed-url) ein:url-localhost)
|
||||||
(ein:process-refresh-processes)
|
(ein:process-refresh-processes)
|
||||||
(ein:aif (ein:process-url-match nbpath)
|
(aif (ein:process-url-match nbpath)
|
||||||
(ein:notebooklist-login (ein:process-url-or-port it) callback-login)
|
(ein:notebooklist-login (ein:process-url-or-port it) callback-login)
|
||||||
(ein:jupyter-server-start
|
(ein:jupyter-server-start
|
||||||
(executable-find (or (ein:eval-if-bound 'ein:jupyter-default-server-command)
|
(executable-find (or (ein:eval-if-bound 'ein:jupyter-default-server-command)
|
||||||
|
|
|
@ -173,7 +173,7 @@ TYPE can be 'body, nil."
|
||||||
(span `(nil ,(point-min) ,(point-min)))
|
(span `(nil ,(point-min) ,(point-min)))
|
||||||
(cell (ein:worksheet-get-current-cell :pos pos :noerror nil)))
|
(cell (ein:worksheet-get-current-cell :pos pos :noerror nil)))
|
||||||
;; Change :mode if necessary
|
;; Change :mode if necessary
|
||||||
(ein:and-let* ((lang
|
(-when-let* ((lang
|
||||||
(condition-case err
|
(condition-case err
|
||||||
(ein:$kernelspec-language
|
(ein:$kernelspec-language
|
||||||
(ein:$notebook-kernelspec
|
(ein:$notebook-kernelspec
|
||||||
|
@ -185,7 +185,7 @@ TYPE can be 'body, nil."
|
||||||
((ein:markdowncell-p cell) "markdown")
|
((ein:markdowncell-p cell) "markdown")
|
||||||
(t "fundamental")))
|
(t "fundamental")))
|
||||||
(mode (pm-get-mode-symbol-from-name what))
|
(mode (pm-get-mode-symbol-from-name what))
|
||||||
((not (equal mode (ein:oref-safe cm 'mode)))))
|
(_ (not (equal mode (ein:oref-safe cm 'mode)))))
|
||||||
(when (eq mode 'poly-fallback-mode)
|
(when (eq mode 'poly-fallback-mode)
|
||||||
(ein:display-warning
|
(ein:display-warning
|
||||||
(format "pm:get-span: no major mode for kernelspec language '%s'" what)))
|
(format "pm:get-span: no major mode for kernelspec language '%s'" what)))
|
||||||
|
@ -251,7 +251,7 @@ TYPE can be 'body, nil."
|
||||||
(setq jit-lock-context-unfontify-pos nil)
|
(setq jit-lock-context-unfontify-pos nil)
|
||||||
(if (eq type 'host)
|
(if (eq type 'host)
|
||||||
(setq syntax-propertize-function nil)
|
(setq syntax-propertize-function nil)
|
||||||
(ein:aif pm--syntax-propertize-function-original
|
(aif pm--syntax-propertize-function-original
|
||||||
(progn
|
(progn
|
||||||
(setq syntax-propertize-function it)
|
(setq syntax-propertize-function it)
|
||||||
(add-function :before-until (local 'syntax-propertize-function)
|
(add-function :before-until (local 'syntax-propertize-function)
|
||||||
|
|
|
@ -74,9 +74,9 @@ construct CONTENT and RESULT."
|
||||||
for content = (append
|
for content = (append
|
||||||
(when pcallsig (list pcallsig callsig))
|
(when pcallsig (list pcallsig callsig))
|
||||||
(when pdoc (list pdoc docstring)))
|
(when pdoc (list pdoc docstring)))
|
||||||
for result = (ein:aif (append
|
for result = (aif (append
|
||||||
(when pcallsig (list callsig))
|
(when pcallsig (list callsig))
|
||||||
(when pdoc (list docstring)))
|
(when pdoc (list docstring)))
|
||||||
(ein:join-str "\n" it))
|
(ein:join-str "\n" it))
|
||||||
do (funcall test content result))))
|
do (funcall test content result))))
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
(require 'ein-log)
|
(require 'ein-log)
|
||||||
(require 'request)
|
(require 'request)
|
||||||
|
(require 'anaphora)
|
||||||
|
|
||||||
(defmacro ein:setq-if-not (sym val)
|
(defmacro ein:setq-if-not (sym val)
|
||||||
`(unless ,sym (setq ,sym ,val)))
|
`(unless ,sym (setq ,sym ,val)))
|
||||||
|
@ -38,7 +39,7 @@
|
||||||
"File to save the ``*Messages*`` buffer.")
|
"File to save the ``*Messages*`` buffer.")
|
||||||
|
|
||||||
(defvar ein:testing-dump-file-server nil
|
(defvar ein:testing-dump-file-server nil
|
||||||
"File to save `ein:jupyter-server-buffer-name`.")
|
"File to save `*ein:jupyter-server-buffer-name*`.")
|
||||||
|
|
||||||
(defvar ein:testing-dump-file-request nil
|
(defvar ein:testing-dump-file-request nil
|
||||||
"File to save `request-log-buffer-name`.")
|
"File to save `request-log-buffer-name`.")
|
||||||
|
@ -99,7 +100,7 @@ if I call this between links in a deferred chain. Adding a flush-queue."
|
||||||
"Wait until PREDICATE function returns non-`nil'.
|
"Wait until PREDICATE function returns non-`nil'.
|
||||||
PREDARGS is argument list for the PREDICATE function.
|
PREDARGS is argument list for the PREDICATE function.
|
||||||
MS is milliseconds to wait. INTERVAL is polling interval in milliseconds."
|
MS is milliseconds to wait. INTERVAL is polling interval in milliseconds."
|
||||||
(let* ((int (ein:aif interval it (ein:aif ms (max 300 (/ ms 10)) 300)))
|
(let* ((int (aif interval it (aif ms (max 300 (/ ms 10)) 300)))
|
||||||
(count (max 1 (if ms (truncate (/ ms int)) 25))))
|
(count (max 1 (if ms (truncate (/ ms int)) 25))))
|
||||||
(unless (or (loop repeat count
|
(unless (or (loop repeat count
|
||||||
when (apply predicate predargs)
|
when (apply predicate predargs)
|
||||||
|
|
Loading…
Add table
Reference in a new issue