mirror of
https://github.com/vale981/emacs-ipython-notebook
synced 2025-03-04 16:51:38 -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")
|
||||
|
||||
(development
|
||||
(depends-on "anaphora")
|
||||
(depends-on "websocket")
|
||||
(depends-on "request")
|
||||
(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-default-notebook-directory
|
||||
.. el:variable:: ein:jupyter-server-args
|
||||
.. el:variable:: ein:jupyter-server-buffer-name
|
||||
|
||||
Notebook list
|
||||
^^^^^^^^^^^^^
|
||||
|
|
|
@ -152,9 +152,9 @@
|
|||
(multiple-value-bind (url-or-port token) (ein:jupyter-server-conn-info)
|
||||
(let (notebook)
|
||||
(with-current-buffer (ein:notebooklist-get-buffer url-or-port)
|
||||
(ein:and-let* ((kslist (mapcar #'car (ein:list-available-kernels url-or-port)))
|
||||
(found (seq-some (lambda (x) (and (search prefix x) x)) kslist))
|
||||
(ks (ein:get-kernelspec url-or-port found)))
|
||||
(-when-let* ((kslist (mapcar #'car (ein:list-available-kernels url-or-port)))
|
||||
(found (seq-some (lambda (x) (and (search prefix x) x)) kslist))
|
||||
(ks (ein:get-kernelspec url-or-port found)))
|
||||
(setq notebook (ein:testing-new-notebook url-or-port ks))))
|
||||
(should notebook)
|
||||
(let ((buf-name (format ein:notebook-buffer-name-template
|
||||
|
@ -175,10 +175,10 @@
|
|||
(cl-letf (((symbol-function 'y-or-n-p) #'ignore))
|
||||
(ein:jupyter-server-stop t))
|
||||
(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))
|
||||
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
|
||||
(ein:testing-wait-until (lambda ()
|
||||
(null (ein:notebooklist-keys)))
|
||||
|
@ -187,7 +187,7 @@
|
|||
(clrhash ein:notebooklist-map)))
|
||||
(unless final-p
|
||||
(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 \"\\(.*\\)\"$"
|
||||
(lambda (config)
|
||||
|
@ -349,8 +349,8 @@
|
|||
(lambda (negate bogey)
|
||||
(ein:testing-wait-until
|
||||
(lambda ()
|
||||
(let* ((says (s-contains? (s-replace "\\n" "\n" bogey) (buffer-string))))
|
||||
(ein:aif (if negate (not says) says)
|
||||
(let ((says (s-contains? (s-replace "\\n" "\n" bogey) (buffer-string))))
|
||||
(aif (if negate (not says) says)
|
||||
it
|
||||
(when (with-current-buffer ein:log-all-buffer-name
|
||||
(search "WS closed unexpectedly" (buffer-string)))
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
do (sleep-for 0 1000)
|
||||
finally do (when extant
|
||||
(ein:display-warning (format "cannot del %s" path)))))))
|
||||
(ein:aif (ein:notebook-opened-notebooks)
|
||||
(aif (ein:notebook-opened-notebooks)
|
||||
(loop for nb in it
|
||||
for path = (ein:$notebook-notebook-path nb)
|
||||
do (ein:log 'debug "Notebook %s still open" path)
|
||||
|
@ -72,6 +72,7 @@
|
|||
(ein:dev-start-debug)
|
||||
(cl-assert (boundp 'company-frontends))
|
||||
(custom-set-variables '(company-frontends nil)
|
||||
'(ein:jupyter-use-docker-stacks nil)
|
||||
'(python-indent-guess-indent-offset-verbose nil))
|
||||
(setq ein:jupyter-default-kernel
|
||||
(loop with cand = ""
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
(traceback . ,(plist-get output :traceback))))
|
||||
|
||||
(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)
|
||||
(plist-get output :data))))
|
||||
`((output_type . "execute_result")
|
||||
|
@ -76,4 +76,3 @@
|
|||
collect (list (cdr prop) (plist-get output-plist (cdr prop)))))
|
||||
|
||||
(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 'input (or (plist-get data :input)
|
||||
(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: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 '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)
|
||||
|
||||
(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))
|
||||
cell)
|
||||
|
||||
(cl-defmethod ein:cell-init ((cell ein:headingcell) data) ;; FIXME: Was :after method
|
||||
(cl-call-next-method)
|
||||
(ein:aif (plist-get data :level)
|
||||
(aif (plist-get data :level)
|
||||
(setf (slot-value cell 'level) it))
|
||||
cell)
|
||||
|
||||
|
@ -387,14 +387,14 @@ a number will limit the number of lines in a cell output."
|
|||
(nth index (plist-get element prop)))
|
||||
(case prop
|
||||
(:after-input
|
||||
(ein:aif (nth 0 (plist-get element :output))
|
||||
(aif (nth 0 (plist-get element :output))
|
||||
it
|
||||
(plist-get element :footer)))
|
||||
(:after-output (plist-get element :footer))
|
||||
(:before-input (plist-get element :prompt))
|
||||
(:before-output (plist-get element :input))
|
||||
(:last-output
|
||||
(ein:aif (plist-get element :output)
|
||||
(aif (plist-get element :output)
|
||||
(car (last it))
|
||||
(plist-get element :input)))
|
||||
(t (cl-call-next-method))))))
|
||||
|
@ -965,7 +965,7 @@ prettified text thus be used instead of HTML type."
|
|||
ein:output-types-html-preferred))
|
||||
|
||||
(defun ein:fix-mime-type (type)
|
||||
(ein:aif (assoc type ein:mime-type-map)
|
||||
(aif (assoc type ein:mime-type-map)
|
||||
(cdr it)
|
||||
type))
|
||||
|
||||
|
@ -1021,7 +1021,7 @@ prettified text thus be used instead of HTML type."
|
|||
"Return json-ready alist."
|
||||
`((input . ,(ein:cell-get-text cell))
|
||||
(cell_type . "code")
|
||||
,@(ein:aif (ein:oref-safe cell 'input-prompt-number)
|
||||
,@(aif (ein:oref-safe cell 'input-prompt-number)
|
||||
`((prompt_number . ,it)))
|
||||
(outputs . ,(if discard-output [] (apply #'vector (slot-value cell 'outputs))))
|
||||
(language . "python")
|
||||
|
@ -1041,7 +1041,7 @@ prettified text thus be used instead of HTML type."
|
|||
(outputs (if discard-output []
|
||||
(slot-value cell '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))))
|
||||
(setq metadata (plist-put metadata :collapsed (if (slot-value cell 'collapsed) t 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))
|
||||
"Return next cell of the given CELL or nil if CELL is the last one."
|
||||
(ein:aif (ewoc-next (slot-value cell 'ewoc)
|
||||
(ein:cell-element-get cell :footer))
|
||||
(aif (ewoc-next (slot-value cell 'ewoc)
|
||||
(ein:cell-element-get cell :footer))
|
||||
(let ((cell (ein:$node-data (ewoc-data it))))
|
||||
(when (cl-typep cell 'ein:basecell)
|
||||
cell))))
|
||||
|
||||
(cl-defmethod ein:cell-prev ((cell ein:basecell))
|
||||
"Return previous cell of the given CELL or nil if CELL is the first one."
|
||||
(ein:aif (ewoc-prev (slot-value cell 'ewoc)
|
||||
(ein:cell-element-get cell :prompt))
|
||||
(aif (ewoc-prev (slot-value cell 'ewoc)
|
||||
(ein:cell-element-get cell :prompt))
|
||||
(let ((cell (ein:$node-data (ewoc-data it))))
|
||||
(when (cl-typep cell 'ein:basecell)
|
||||
cell))))
|
||||
|
|
|
@ -98,7 +98,7 @@
|
|||
(destructuring-bind (msg-type content _) output
|
||||
(ein:case-equal msg-type
|
||||
(("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)))
|
||||
(unless (string= (plist-get oinfo :string_form) "None")
|
||||
(setf (gethash obj (ein:$kernel-oinfo-cache kernel))
|
||||
|
|
|
@ -183,7 +183,7 @@ notebooks."
|
|||
"Connect any buffer to opened notebook and its kernel."
|
||||
(interactive (list (ein:completing-read "Notebook buffer to connect: "
|
||||
(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)))
|
||||
(ein:connect-buffer-to-notebook notebook))
|
||||
(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.
|
||||
Variable `ein:connect-run-command' sets the default command."
|
||||
(interactive "P")
|
||||
(ein:aif (ein:aand (ein:get-url-or-port)
|
||||
(ein:filename-to-python it (buffer-file-name)))
|
||||
(aif (ein:aand (ein:get-url-or-port)
|
||||
(ein:filename-to-python it (buffer-file-name)))
|
||||
(let* ((default-command (ein:connect-run-command-get))
|
||||
(command (if ask-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)
|
||||
(setq content (ein:new-content-legacy 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)))
|
||||
(when callback
|
||||
(funcall callback content))))
|
||||
|
@ -174,7 +174,7 @@ global setting. For global setting and more information, see
|
|||
|
||||
(defun ein:content-need-hierarchy (url-or-port)
|
||||
"Callers assume ein:content-query-hierarchy succeeded. If not, nil."
|
||||
(ein:aif (gethash url-or-port *ein:content-hierarchy*) it
|
||||
(aif (gethash url-or-port *ein:content-hierarchy*) it
|
||||
(ein:log 'warn "No recorded content hierarchy for %s" url-or-port)
|
||||
nil))
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
(require 'ein) ; get autoloaded functions into namespace
|
||||
(require 'ein-utils)
|
||||
(require 'anaphora)
|
||||
|
||||
(defgroup ein nil
|
||||
"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)
|
||||
"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))
|
||||
(name (if (stringp name)
|
||||
(intern (format ":%s" name))
|
||||
name))
|
||||
(ks (plist-get kernelspecs name)))
|
||||
(if (stringp ks)
|
||||
(ein:get-kernelspec url-or-port ks)
|
||||
ks)))
|
||||
(ks (or (plist-get kernelspecs name)
|
||||
(loop for (key spec) on (ein:plist-exclude kernelspecs '(:default)) by 'cddr
|
||||
if (string= (ein:$kernelspec-language spec) lang)
|
||||
return spec
|
||||
end))))
|
||||
(cond ((stringp ks)
|
||||
(ein:get-kernelspec url-or-port ks))
|
||||
(t ks))))
|
||||
|
||||
(defun ein:need-kernelspecs (url-or-port)
|
||||
"Callers assume ein:query-kernelspecs succeeded. If not, nil."
|
||||
(ein:aif (gethash url-or-port *ein:kernelspecs*) it
|
||||
(aif (gethash url-or-port *ein:kernelspecs*) it
|
||||
(ein:log 'warn "No recorded kernelspecs for %s" url-or-port)
|
||||
nil))
|
||||
|
||||
|
@ -215,7 +220,7 @@ the source is in git repository) or elpa version."
|
|||
|
||||
(defun ein:need-notebook-version (url-or-port)
|
||||
"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)
|
||||
"5.7.0"))
|
||||
|
||||
|
@ -233,7 +238,7 @@ the source is in git repository) or elpa version."
|
|||
&allow-other-keys
|
||||
&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:aif (plist-get data :version)
|
||||
(aif (plist-get data :version)
|
||||
(setf (gethash url-or-port *ein:notebook-version*) it)
|
||||
(case (request-response-status-code response)
|
||||
(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))
|
||||
|
||||
(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)
|
||||
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)
|
||||
filename))
|
||||
|
||||
|
@ -375,7 +380,7 @@ but can operate in different contexts."
|
|||
(let* ((files (directory-files ein:source-dir 'full "^ein-.*\\.el$"))
|
||||
(errors (cl-mapcan (lambda (f) (unless (byte-compile-file f) (list f)))
|
||||
files)))
|
||||
(ein:aif errors
|
||||
(aif errors
|
||||
(error "Got %s errors while compiling these files: %s"
|
||||
(length errors)
|
||||
(ein:join-str " " (mapcar #'file-name-nondirectory it))))
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
(defun ein:events-trigger (events event-type &optional data)
|
||||
"Trigger EVENT-TYPE and let event handler EVENTS handle that event."
|
||||
(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)
|
||||
(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."
|
||||
(and (ein:codecell-p cell)
|
||||
this-command
|
||||
(ein:aif (ein:cell-input-pos-min cell) (<= it beg))
|
||||
(ein:aif (ein:cell-input-pos-max cell) (>= it end))))
|
||||
(aif (ein:cell-input-pos-min cell) (<= it beg))
|
||||
(aif (ein:cell-input-pos-max cell) (>= it end))))
|
||||
|
||||
(defun ein:iexec-after-change (beg end -ignore-len-)
|
||||
"Called via `after-change-functions' hook."
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
current-payload)
|
||||
|
||||
(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
|
||||
(let ((db-session (make-ein:$ipdb-session
|
||||
:kernel kernel
|
||||
|
@ -120,7 +120,7 @@
|
|||
(comint-output-filter proc ein:ipdb-buffer-prompt))
|
||||
(when ein:ipdb--received-quit-p
|
||||
(kill-buffer)
|
||||
(ein:aif (ein:$ipdb-session-notebook-buffer session)
|
||||
(aif (ein:$ipdb-session-notebook-buffer session)
|
||||
(pop-to-buffer it)))))))))
|
||||
|
||||
|
||||
|
|
|
@ -27,16 +27,51 @@
|
|||
(require 'ein-notebooklist)
|
||||
(require 'ein-dev)
|
||||
|
||||
(defcustom ein:jupyter-server-buffer-name "*ein:jupyter-server*"
|
||||
"The name of the buffer for the jupyter notebook server
|
||||
session."
|
||||
(defcustom ein:jupyter-use-containers t
|
||||
"Take EIN in a different direcsh."
|
||||
: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
|
||||
:type 'string)
|
||||
|
||||
(defcustom ein:jupyter-server-run-timeout 60000
|
||||
"Time, in milliseconds, to wait for the jupyter server to start before declaring timeout and cancelling the operation."
|
||||
(defcustom ein:jupyter-docker-home-directory "/home/jovyan/work"
|
||||
"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
|
||||
: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")
|
||||
"Add any additional command line options you wish to include
|
||||
|
@ -45,34 +80,9 @@ with the call to the jupyter notebook."
|
|||
:type '(repeat string))
|
||||
|
||||
(defcustom ein:jupyter-default-notebook-directory nil
|
||||
"If you are tired of always being queried for the location of
|
||||
the notebook directory, you can set it here for future calls to
|
||||
`ein:jupyter-server-start'"
|
||||
"Default location of ipynb files."
|
||||
:group 'ein
|
||||
: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)))
|
||||
:type 'directory)
|
||||
|
||||
(defcustom ein:jupyter-default-kernel 'first-alphabetically
|
||||
"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
|
||||
(shell-command-to-string
|
||||
(format "%s kernelspec list --json"
|
||||
ein:jupyter-default-server-command)))))
|
||||
ein:jupyter-server-command)))))
|
||||
collect `(,k . ,(alist-get 'display_name (alist-get 'spec spec)))))
|
||||
(error (ein:log 'warn "ein:jupyter-default-kernel: %s" err)
|
||||
'((string :tag "Ask"))))))
|
||||
|
||||
(defsubst ein:jupyter-server-process ()
|
||||
"Return the emacs process object of our session"
|
||||
(get-buffer-process (get-buffer ein:jupyter-server-buffer-name)))
|
||||
(defvar *ein:jupyter-server-process-name* "ein server")
|
||||
(defvar *ein:jupyter-server-buffer-name*
|
||||
(format "*%s*" *ein:jupyter-server-process-name*))
|
||||
|
||||
(defun ein:jupyter-server--run (buf cmd dir &optional args)
|
||||
(when ein:debug
|
||||
(add-to-list 'ein:jupyter-server-args "--debug"))
|
||||
(unless (stringp dir)
|
||||
(error "ein:jupyter-server--run: notebook directory required"))
|
||||
(let* ((vargs (append (ein:aif ein:jupyter-server-use-subcommand (list it))
|
||||
(list (format "--notebook-dir=%s" (convert-standard-filename dir)))
|
||||
args
|
||||
ein:jupyter-server-args))
|
||||
(defsubst ein:jupyter-server-process ()
|
||||
"Return the emacs process object of our session."
|
||||
(get-buffer-process (get-buffer *ein:jupyter-server-buffer-name*)))
|
||||
|
||||
(defun ein:jupyter-server--run (buf user-cmd dir &optional args)
|
||||
(let* ((cmd (if ein:jupyter-use-containers "docker" user-cmd))
|
||||
(vargs (cond (ein:jupyter-use-containers
|
||||
(split-string
|
||||
(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
|
||||
*ein:jupyter-server-process-name* buf cmd 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)
|
||||
"Return the url-or-port and password for BUFFER or the global session."
|
||||
(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))
|
||||
(result '(nil nil)))
|
||||
(if buffer
|
||||
|
@ -157,67 +180,73 @@ our singleton jupyter server process here."
|
|||
(set-process-sentinel
|
||||
proc
|
||||
(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))
|
||||
url-or-port (process-sentinel proc))))
|
||||
|
||||
;;;###autoload
|
||||
(defun ein:jupyter-server-start (server-cmd-path notebook-directory
|
||||
&optional no-login-p login-callback port)
|
||||
"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*.
|
||||
(defun ein:jupyter-server-start (server-command
|
||||
notebook-directory
|
||||
&optional no-login-p login-callback port)
|
||||
"Start SERVER-COMMAND with `--notebook-dir' NOTEBOOK-DIRECTORY.
|
||||
|
||||
This command opens an asynchronous process running the jupyter
|
||||
notebook server and then tries to detect the url and password to
|
||||
generate automatic calls to `ein:notebooklist-login' and
|
||||
`ein:notebooklist-open'.
|
||||
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*'.
|
||||
|
||||
With \\[universal-argument] prefix arg, it will prompt the user for the path to
|
||||
the jupyter executable first. Else, it will try to use the
|
||||
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."
|
||||
With \\[universal-argument] prefix arg, prompt the user for the
|
||||
server command."
|
||||
(interactive
|
||||
(let* ((default-command (or *ein:last-jupyter-command*
|
||||
ein:jupyter-default-server-command))
|
||||
(server-cmd-path
|
||||
(executable-find (if current-prefix-arg
|
||||
(read-file-name "Server command: " default-directory nil nil
|
||||
default-command)
|
||||
default-command)))
|
||||
(notebook-directory
|
||||
(read-directory-name "Notebook directory: "
|
||||
(or *ein:last-jupyter-directory*
|
||||
ein:jupyter-default-notebook-directory))))
|
||||
(list server-cmd-path notebook-directory nil (lambda (buffer url-or-port)
|
||||
(pop-to-buffer buffer)))))
|
||||
(unless (and (stringp server-cmd-path)
|
||||
(file-exists-p server-cmd-path)
|
||||
(file-executable-p server-cmd-path))
|
||||
(error "Command %s not found or not executable"
|
||||
(or *ein:last-jupyter-command*
|
||||
ein:jupyter-default-server-command)))
|
||||
(setf *ein:last-jupyter-command* server-cmd-path
|
||||
*ein:last-jupyter-directory* notebook-directory)
|
||||
(list (let ((default-command (executable-find ein:jupyter-server-command)))
|
||||
(if (and (not ein:jupyter-use-containers)
|
||||
(or current-prefix-arg (not default-command)))
|
||||
(let (command result)
|
||||
(while (not (setq
|
||||
result
|
||||
(executable-find
|
||||
(setq
|
||||
command
|
||||
(read-string
|
||||
(format
|
||||
"%sServer command: "
|
||||
(if command
|
||||
(format "[%s not executable] " command)
|
||||
""))
|
||||
nil nil ein:jupyter-server-command))))))
|
||||
result)
|
||||
default-command))
|
||||
(let (result
|
||||
(default-dir ein:jupyter-default-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)
|
||||
(error "Please first M-x ein:stop"))
|
||||
(error "ein:jupyter-server-start: please first M-x ein:stop"))
|
||||
(add-hook 'kill-emacs-hook #'(lambda ()
|
||||
(ignore-errors (ein:jupyter-server-stop t))))
|
||||
(let ((proc (ein:jupyter-server--run ein:jupyter-server-buffer-name
|
||||
*ein:last-jupyter-command*
|
||||
*ein:last-jupyter-directory*
|
||||
(let ((proc (ein:jupyter-server--run *ein:jupyter-server-buffer-name*
|
||||
server-command
|
||||
notebook-directory
|
||||
(if (numberp port)
|
||||
`("--port" ,(format "%s" port)
|
||||
"--port-retries" "0")))))
|
||||
(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)
|
||||
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:jupyter-server-stop t)))
|
||||
(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)
|
||||
(kill-buffer (ein:notebooklist-get-buffer url-or-port))
|
||||
(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)))))
|
||||
|
||||
(provide 'ein-jupyter)
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
(require 'ein-query)
|
||||
(require 'ein-websocket)
|
||||
(require 'ein-notebooklist)
|
||||
(require 'anaphora)
|
||||
|
||||
(defvar *ein:jupyterhub-connections* (make-hash-table :test #'equal))
|
||||
|
||||
|
@ -54,7 +55,7 @@
|
|||
|
||||
(defsubst ein:jupyterhub-user-path (url-or-port &rest 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)))))
|
||||
(apply #'ein:url url-or-port user-base paths)))
|
||||
|
||||
|
@ -90,7 +91,7 @@
|
|||
(ein:and-let* ((conn (gethash ,conn-key *ein:jupyterhub-connections*)))
|
||||
(ein:jupyterhub--add-header
|
||||
(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
|
||||
(cons "Authorization" (format "token %s" it)))))
|
||||
(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
|
||||
delete the kernel on the server side"
|
||||
(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)
|
||||
(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"
|
||||
msg-type msg-id)
|
||||
(run-hook-with-args 'ein:on-shell-reply-functions msg-type header content metadata)
|
||||
(ein:aif cb (ein:funcall-packed it content metadata))
|
||||
(ein:aif (plist-get content :payload)
|
||||
(aif cb (ein:funcall-packed it content metadata))
|
||||
(aif (plist-get content :payload)
|
||||
(ein:kernel--handle-payload kernel callbacks it))
|
||||
(let ((events (ein:$kernel-events kernel)))
|
||||
(ein:case-equal msg-type
|
||||
(("execute_reply")
|
||||
(ein:aif (plist-get content :execution_count)
|
||||
(aif (plist-get content :execution_count)
|
||||
;; It can be `nil' for silent execution
|
||||
(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:case-equal msg-type
|
||||
(("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)))
|
||||
(("status")
|
||||
(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")
|
||||
(ein:log 'verbose (format "Received data_pub message w/content %s" packet)))
|
||||
(("clear_output")
|
||||
(ein:aif (plist-get callbacks :clear_output)
|
||||
(aif (plist-get callbacks :clear_output)
|
||||
(ein:funcall-packed it content metadata)))))))))
|
||||
|
||||
;;; Utility functions
|
||||
|
@ -829,7 +829,7 @@ as a string and the rest of the argument is the optional ARGS."
|
|||
(let ((func (car packed))
|
||||
(args (cdr packed)))
|
||||
(when (equal msg-type "stream")
|
||||
(ein:aif (plist-get content :text)
|
||||
(aif (plist-get content :text)
|
||||
(apply func it args)))))
|
||||
(cons func args)))))
|
||||
|
||||
|
|
|
@ -106,7 +106,7 @@ Otherwise, return result of last form in BODY."
|
|||
|
||||
(defun ein:log-pop-to-request-buffer ()
|
||||
(interactive)
|
||||
(ein:aif (get-buffer request-log-buffer-name)
|
||||
(aif (get-buffer request-log-buffer-name)
|
||||
(pop-to-buffer it)
|
||||
(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*)))))
|
||||
(when (and (not noninteractive)
|
||||
(null (plist-member (ein:$notebook-metadata notebook*) :kernelspec)))
|
||||
(ein:aif (ein:$notebook-kernelspec notebook*)
|
||||
(aif (ein:$notebook-kernelspec notebook*)
|
||||
(progn
|
||||
(setf (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*))
|
||||
pending-key))
|
||||
(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)))
|
||||
(callback0 (ein:notebook-open--decorate-callback notebook existing pending-clear
|
||||
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)
|
||||
(ein:$notebook-notebook-name notebook) (ein:$content-name content))
|
||||
(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-from-json notebook (ein:$content-raw-content content))
|
||||
(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:gc-complete-operation))))
|
||||
|
||||
(defun ein:notebook-maybe-set-kernelspec (notebook content-metadata)
|
||||
(ein:aif (plist-get content-metadata :kernelspec)
|
||||
(let ((kernelspec (ein:get-kernelspec (ein:$notebook-url-or-port notebook)
|
||||
(plist-get it :name))))
|
||||
(setf (ein:$notebook-kernelspec notebook) kernelspec))))
|
||||
(defun ein:notebook-set-kernelspec (notebook content-metadata)
|
||||
(-when-let* ((ks-plist (plist-get content-metadata :kernelspec))
|
||||
(kernelspec (ein:get-kernelspec (ein:$notebook-url-or-port notebook)
|
||||
(plist-get ks-plist :name)
|
||||
(plist-get ks-plist :language))))
|
||||
(setf (ein:$notebook-kernelspec notebook) kernelspec)))
|
||||
|
||||
|
||||
(defun ein:notebook--different-number (n1 n2)
|
||||
|
@ -451,12 +452,11 @@ of minor mode."
|
|||
;;; Kernel related things
|
||||
|
||||
(defun ein:list-available-kernels (url-or-port)
|
||||
(let ((kernelspecs (ein:need-kernelspecs url-or-port)))
|
||||
(if kernelspecs
|
||||
(sort (loop for (key spec) on (ein:plist-exclude kernelspecs '(:default)) by 'cddr
|
||||
collecting (cons (ein:$kernelspec-name spec)
|
||||
(ein:$kernelspec-display-name spec)))
|
||||
(lambda (c1 c2) (string< (cdr c1) (cdr c2)))))))
|
||||
(when-let ((kernelspecs (ein:need-kernelspecs url-or-port)))
|
||||
(sort (loop for (key spec) on (ein:plist-exclude kernelspecs '(:default)) by 'cddr
|
||||
collecting (cons (ein:$kernelspec-name spec)
|
||||
(ein:$kernelspec-display-name spec)))
|
||||
(lambda (c1 c2) (string< (cdr c1) (cdr c2))))))
|
||||
|
||||
(defun ein:notebook-switch-kernel (notebook kernel-name)
|
||||
"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))))
|
||||
(kernel-name (ein:completing-read
|
||||
"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)))
|
||||
(let* ((kernelspec (ein:get-kernelspec
|
||||
(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 ()
|
||||
"Delete session on server side. Start new session."
|
||||
(interactive)
|
||||
(ein:aif ein:%notebook%
|
||||
(if (y-or-n-p "Are you sure? ")
|
||||
(ein:kernel-restart-session (ein:$notebook-kernel it)))
|
||||
(aif ein:%notebook%
|
||||
(if (y-or-n-p "Are you sure? ")
|
||||
(ein:kernel-restart-session (ein:$notebook-kernel it)))
|
||||
(message "Not in notebook buffer!")))
|
||||
|
||||
(define-obsolete-function-alias
|
||||
|
@ -571,7 +573,7 @@ This is equivalent to do ``C-c`` in the console program."
|
|||
(funcall (ein:notebook-choose-mode))
|
||||
(ein:worksheet-reinstall-undo-hooks ws)
|
||||
(condition-case err
|
||||
(ein:aif (ein:$notebook-kernelspec notebook)
|
||||
(aif (ein:$notebook-kernelspec notebook)
|
||||
(ein:ml-lang-setup it))
|
||||
(error (ein:log 'error (error-message-string err))
|
||||
(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))
|
||||
(plist-put metadata
|
||||
: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.
|
||||
(push `(nbformat_minor . ,it) 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
|
||||
append (ein:worksheet-to-nb4-json ws i))))
|
||||
;; should be in notebook constructor, not here
|
||||
(ein:aif (ein:$notebook-kernelspec notebook)
|
||||
(aif (ein:$notebook-kernelspec notebook)
|
||||
(setf (ein:$notebook-metadata notebook)
|
||||
(plist-put (ein:$notebook-metadata notebook)
|
||||
:kernelspec (ein:notebook--spec-insert-name
|
||||
(ein:$kernelspec-name it) (ein:$kernelspec-spec it)))))
|
||||
`((metadata . ,(ein:aif (ein:$notebook-metadata notebook)
|
||||
`((metadata . ,(aif (ein:$notebook-metadata notebook)
|
||||
it
|
||||
(make-hash-table)))
|
||||
(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)))))
|
||||
|
||||
(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))
|
||||
(current-buffer))))
|
||||
(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.
|
||||
|
||||
(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: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))
|
||||
(setq indent-tabs-mode nil) ;; Being T causes problems with Python code.
|
||||
(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)
|
||||
"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))
|
||||
(not blithely))
|
||||
(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)
|
||||
"Shell out to jupyter for its credentials knowledge. Return list of (PASSWORD TOKEN)."
|
||||
(ein:aif (loop for line in (condition-case err
|
||||
(process-lines ein:jupyter-default-server-command
|
||||
"notebook" "list" "--json")
|
||||
;; often there is no local jupyter installation
|
||||
(error (ein:log 'info "ein:crib-token: %s" err) nil))
|
||||
with token0
|
||||
with password0
|
||||
when (destructuring-bind
|
||||
(&key password url token &allow-other-keys)
|
||||
(ein:json-read-from-string line)
|
||||
(prog1 (equal (ein:url url) url-or-port)
|
||||
(setq password0 password) ;; t or :json-false
|
||||
(setq token0 token)))
|
||||
return (list password0 token0))
|
||||
(aif (loop for line in (condition-case err
|
||||
(apply #'process-lines
|
||||
ein:jupyter-server-command
|
||||
(append (aif ein:jupyter-server-use-subcommand
|
||||
(list it))
|
||||
'("list" "--json")))
|
||||
;; often there is no local jupyter installation
|
||||
(error (ein:log 'info "ein:crib-token: %s" err) nil))
|
||||
with token0
|
||||
with password0
|
||||
when (destructuring-bind
|
||||
(&key password url token &allow-other-keys)
|
||||
(ein:json-read-from-string line)
|
||||
(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)))
|
||||
|
||||
(defun ein:crib-running-servers ()
|
||||
"Shell out to jupyter for running servers."
|
||||
(loop for line in (condition-case err
|
||||
(process-lines ein:jupyter-default-server-command
|
||||
"notebook" "list" "--json")
|
||||
(apply #'process-lines
|
||||
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)
|
||||
nil))
|
||||
collecting (destructuring-bind
|
||||
|
@ -210,9 +216,9 @@ This function adds NBLIST to `ein:notebooklist-map'."
|
|||
(t nil)))))
|
||||
|
||||
(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:aif ein:%notebooklist%
|
||||
(aif ein:%notebooklist%
|
||||
(ein:$notebooklist-url-or-port it)
|
||||
(ein:default-url-or-port)))))
|
||||
(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."
|
||||
'mouse-face 'highlight
|
||||
'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))
|
||||
"|unknown: please click and select a kernel|")
|
||||
'keymap ein:header-line-switch-kernel-map
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
"Emacs IPython Notebook"
|
||||
'((emacs "25")
|
||||
(websocket "20190620.338")
|
||||
(anaphora "20180618")
|
||||
(request "20190621.1622")
|
||||
(deferred "0.5")
|
||||
(polymode "20190426.1729")
|
||||
|
|
|
@ -124,8 +124,11 @@
|
|||
"Use `jupyter notebook list --json` to populate ein:%processes%"
|
||||
(clrhash ein:%processes%)
|
||||
(loop for line in (condition-case err
|
||||
(process-lines ein:jupyter-default-server-command
|
||||
"notebook" "list" "--json")
|
||||
(apply #'process-lines
|
||||
ein:jupyter-server-command
|
||||
(append (aif ein:jupyter-server-use-subcommand
|
||||
(list it))
|
||||
'("list" "--json")))
|
||||
;; often there is no local jupyter installation
|
||||
(error (ein:log 'info "ein:process-refresh-processes: %s" err) nil))
|
||||
do (destructuring-bind
|
||||
|
@ -182,7 +185,8 @@
|
|||
(ein:notebook-open url-or-port
|
||||
path* nil 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)
|
||||
"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:case-equal msg-type
|
||||
(("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)
|
||||
(ein:log 'info
|
||||
"Jumping to the source of %s...Not found" object)
|
||||
|
@ -239,7 +239,7 @@ is defined."
|
|||
(destructuring-bind (kernel object callback) packed
|
||||
(if (or (string= msg-type "stream")
|
||||
(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)
|
||||
(ein:log 'info
|
||||
"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)
|
||||
(equal (point) (marker-position it)))
|
||||
(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: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"
|
||||
running)
|
||||
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)
|
||||
(ein:log 'debug "Race! %s %s" key (request-response-data it))))
|
||||
(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)
|
||||
(pop-to-buffer (ein:shared-output-create-buffer)))
|
||||
(cl-call-next-method)
|
||||
(ein:aif (ein:oref-safe cell 'callback)
|
||||
(aif (ein:oref-safe cell 'callback)
|
||||
(progn
|
||||
(funcall it cell)
|
||||
(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"
|
||||
content)
|
||||
(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'
|
||||
;; but only after 2 seconds to allow for handle-output stragglers
|
||||
;; TODO avoid this hack
|
||||
|
|
|
@ -41,13 +41,6 @@ while maintaining the undo list for the current buffer."
|
|||
`(let ((buffer-undo-list t))
|
||||
,@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)
|
||||
"Anaphoric AND. Adapted from `e2wm:aand'."
|
||||
(declare (debug (form &rest form)))
|
||||
|
@ -167,7 +160,7 @@ before previous opening parenthesis."
|
|||
"\\s-\\|\n\\|\\.")
|
||||
(save-excursion
|
||||
(with-syntax-table ein:dotty-syntax-table
|
||||
(ein:aif (thing-at-point 'symbol)
|
||||
(aif (thing-at-point 'symbol)
|
||||
it
|
||||
(unless (looking-at "(")
|
||||
(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:next
|
||||
(lambda ()
|
||||
(ein:aif (funcall doneback) it
|
||||
(aif (funcall doneback) it
|
||||
(message "%s%s" mesg (make-string (1+ (% (incf count) 3)) ?.))
|
||||
(sleep-for 0 365)))))))
|
||||
(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%))
|
||||
(setq ein:%which-cell% (nthcdr (- fill) ein:%which-cell%)))
|
||||
(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)))
|
||||
(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))
|
||||
|
@ -143,7 +143,8 @@ Normalize `buffer-undo-list' by removing extraneous details, and update the ein:
|
|||
(let ((mp (marker-position (car u))))
|
||||
(if (not (null mp))
|
||||
(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))
|
||||
(numberp (car (last u))) (numberp (cdr (last u))))
|
||||
(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)
|
||||
(cl-remprop 'ein:%cell-lengths% (slot-value cell 'cell-id))))))
|
||||
|
||||
|
||||
|
||||
;;; Class and variable
|
||||
|
||||
(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
|
||||
"Buffer local variable to store an instance of `ein:worksheet'.")
|
||||
|
||||
|
||||
|
||||
;;; Initialization of object and buffer
|
||||
|
||||
(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))
|
||||
(let ((nb-name (ein:worksheet-notebook-name ws)))
|
||||
(ein:aif (ein:worksheet-name ws)
|
||||
(aif (ein:worksheet-name ws)
|
||||
(concat nb-name "/" it)
|
||||
nb-name)))
|
||||
|
||||
|
@ -445,7 +446,7 @@ Normalize `buffer-undo-list' by removing extraneous details, and update the ein:
|
|||
(case (car path)
|
||||
(cell (ein:cell-pp (cdr path) data)))))
|
||||
|
||||
|
||||
|
||||
;;; Persistance and loading
|
||||
|
||||
(cl-defmethod ein:worksheet-from-json ((ws ein:worksheet) data)
|
||||
|
@ -517,7 +518,7 @@ worksheet WS is reopened.
|
|||
\(fn ws)"
|
||||
(setf (slot-value ws 'dont-save-cells) t))
|
||||
|
||||
|
||||
|
||||
;;; Cell indexing, retrieval, etc.
|
||||
|
||||
(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
|
||||
(error "Cell not found"))))
|
||||
|
||||
|
||||
|
||||
;;; Insertion and deletion of cells
|
||||
|
||||
(defun ein:worksheet--get-ws-or-error ()
|
||||
|
@ -856,7 +857,7 @@ If prefix is given, merge current cell into next cell."
|
|||
(insert head "\n"))
|
||||
(when focus (ein:cell-goto next-cell)))))
|
||||
|
||||
|
||||
|
||||
;;; Cell selection.
|
||||
|
||||
(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))))
|
||||
|
||||
(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)
|
||||
(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.
|
||||
Return t when the movement is succeeded."
|
||||
(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))
|
||||
(target-cell
|
||||
(if (and (= nth 1)
|
||||
|
@ -934,12 +935,12 @@ similarly with `end-of-defun'.
|
|||
It is set in `ein:notebook-multilang-mode'."
|
||||
(ein:worksheet-goto-next-cell-element (or arg 1) nil 0 :after-input))
|
||||
|
||||
|
||||
|
||||
;;; Cell movement
|
||||
|
||||
(defun ein:worksheet-move-cell (ws cell up)
|
||||
;; 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)
|
||||
(pivot-cell it) clone)
|
||||
(ein:cell-save-text cell)
|
||||
|
@ -965,7 +966,6 @@ It is set in `ein:notebook-multilang-mode'."
|
|||
(ein:worksheet-get-current-cell)))
|
||||
(ein:worksheet-move-cell ws cell nil))
|
||||
|
||||
|
||||
;;; Cell collapsing and output clearing
|
||||
|
||||
(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))
|
||||
(seq-filter #'ein:codecell-p (ein:worksheet-get-cells ws))))
|
||||
|
||||
|
||||
;;; Kernel related things
|
||||
|
||||
(defun ein:worksheet-kernel-status (ws)
|
||||
|
@ -1051,7 +1050,7 @@ next cell, or insert if none."
|
|||
(ein:worksheet-get-current-cell)))
|
||||
(when (cl-typep cell 'ein:codecell)
|
||||
(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:worksheet-insert-cell-below ws 'code cell t)))
|
||||
|
||||
|
@ -1128,7 +1127,6 @@ in the history."
|
|||
(ein:worksheet--get-history-index -1)))
|
||||
(ein:worksheet-insert-last-input-history ws cell index))
|
||||
|
||||
|
||||
;;; Metadata
|
||||
|
||||
(defun ein:worksheet-rename-sheet (ws name)
|
||||
|
@ -1142,7 +1140,6 @@ in the history."
|
|||
(ein:worksheet-set-modified-p ws t)
|
||||
(ein:worksheet-set-buffer-name ws)))
|
||||
|
||||
|
||||
;;; Generic getter
|
||||
|
||||
(defun ein:get-url-or-port--worksheet ()
|
||||
|
@ -1158,7 +1155,7 @@ in the history."
|
|||
(defun ein:get-traceback-data--worksheet ()
|
||||
(ein:aand (ein:get-cell-at-point--worksheet) (ein:cell-get-tb-data it)))
|
||||
|
||||
|
||||
|
||||
;;; Predicate
|
||||
|
||||
(defun ein:worksheet-buffer-p ()
|
||||
|
@ -1174,7 +1171,7 @@ in the history."
|
|||
(or (slot-value ws 'dirty)
|
||||
(buffer-modified-p buffer)))))
|
||||
|
||||
|
||||
|
||||
;;; Utility commands
|
||||
|
||||
(defun ein:worksheet-dedent-cell-text (cell)
|
||||
|
@ -1205,7 +1202,7 @@ in the history."
|
|||
(defun ein:worksheet-jump-to-first-executing-cell ()
|
||||
"Move the point to the first executing cell in the current worksheet."
|
||||
(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)
|
||||
(message "No cell currently executing.")))
|
||||
|
||||
|
@ -1214,11 +1211,11 @@ in the history."
|
|||
(interactive)
|
||||
(let* ((curcell (ein:get-cell-at-point--worksheet))
|
||||
(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)
|
||||
(message "No additional cells are executing."))))
|
||||
|
||||
|
||||
|
||||
;;; Auto-execution
|
||||
|
||||
(defun ein:worksheet-toggle-autoexec (cell)
|
||||
|
@ -1260,7 +1257,7 @@ function."
|
|||
(ein:worksheet-get-cells ws))))))
|
||||
ws (current-buffer)))))
|
||||
|
||||
|
||||
|
||||
;;; Imenu
|
||||
|
||||
(defun ein:worksheet-imenu-create-index ()
|
||||
|
@ -1279,7 +1276,7 @@ function."
|
|||
"Called via notebook mode hooks."
|
||||
(setq imenu-create-index-function #'ein:worksheet-imenu-create-index))
|
||||
|
||||
|
||||
|
||||
;;; Workarounds
|
||||
|
||||
(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>
|
||||
;; URL: http://millejoh.github.io/emacs-ipython-notebook/
|
||||
;; Authors: dickmao <github id: dickmao>
|
||||
;; 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
|
||||
|
||||
;; This file is NOT part of GNU Emacs.
|
||||
|
@ -38,42 +40,10 @@
|
|||
;;; Code:
|
||||
|
||||
(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)
|
||||
(add-to-list 'mouse-buffer-menu-mode-groups
|
||||
'("^ein:" . "ein")))
|
||||
|
||||
(provide 'ein)
|
||||
|
||||
;;; ein.el ends here
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
;;; Code:
|
||||
(require 'ob)
|
||||
(require 'ein-utils)
|
||||
(require 'anaphora)
|
||||
|
||||
(autoload 'org-element-property "org-element")
|
||||
(autoload 'org-element-context "org-element")
|
||||
|
@ -91,7 +92,7 @@
|
|||
(defcustom ob-ein-inline-image-directory "ein-images"
|
||||
"Store ob-ein images here."
|
||||
:group 'ein
|
||||
:type '(directory))
|
||||
:type 'directory)
|
||||
|
||||
(defcustom ob-ein-default-header-args:ein nil
|
||||
"No documentation."
|
||||
|
@ -186,7 +187,7 @@ Based on ob-ipython--configure-kernel."
|
|||
ein:url-localhost))
|
||||
(lang (nth 0 (org-babel-get-src-block-info)))
|
||||
(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))
|
||||
(error "ob-ein--execute-body: %s not among %s"
|
||||
lang (mapcar #'car org-src-lang-modes)))))
|
||||
|
@ -236,7 +237,7 @@ Based on ob-ipython--configure-kernel."
|
|||
`ein:shared-output-eval-string' completes."
|
||||
(apply-partially
|
||||
(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))
|
||||
(ob-ein--process-outputs
|
||||
(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))
|
||||
((string= (url-host parsed-url) ein:url-localhost)
|
||||
(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:jupyter-server-start
|
||||
(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)))
|
||||
(cell (ein:worksheet-get-current-cell :pos pos :noerror nil)))
|
||||
;; Change :mode if necessary
|
||||
(ein:and-let* ((lang
|
||||
(-when-let* ((lang
|
||||
(condition-case err
|
||||
(ein:$kernelspec-language
|
||||
(ein:$notebook-kernelspec
|
||||
|
@ -185,7 +185,7 @@ TYPE can be 'body, nil."
|
|||
((ein:markdowncell-p cell) "markdown")
|
||||
(t "fundamental")))
|
||||
(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)
|
||||
(ein:display-warning
|
||||
(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)
|
||||
(if (eq type 'host)
|
||||
(setq syntax-propertize-function nil)
|
||||
(ein:aif pm--syntax-propertize-function-original
|
||||
(aif pm--syntax-propertize-function-original
|
||||
(progn
|
||||
(setq syntax-propertize-function it)
|
||||
(add-function :before-until (local 'syntax-propertize-function)
|
||||
|
|
|
@ -74,9 +74,9 @@ construct CONTENT and RESULT."
|
|||
for content = (append
|
||||
(when pcallsig (list pcallsig callsig))
|
||||
(when pdoc (list pdoc docstring)))
|
||||
for result = (ein:aif (append
|
||||
(when pcallsig (list callsig))
|
||||
(when pdoc (list docstring)))
|
||||
for result = (aif (append
|
||||
(when pcallsig (list callsig))
|
||||
(when pdoc (list docstring)))
|
||||
(ein:join-str "\n" it))
|
||||
do (funcall test content result))))
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
(require 'ein-log)
|
||||
(require 'request)
|
||||
(require 'anaphora)
|
||||
|
||||
(defmacro ein:setq-if-not (sym val)
|
||||
`(unless ,sym (setq ,sym ,val)))
|
||||
|
@ -38,7 +39,7 @@
|
|||
"File to save the ``*Messages*`` buffer.")
|
||||
|
||||
(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
|
||||
"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'.
|
||||
PREDARGS is argument list for the PREDICATE function.
|
||||
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))))
|
||||
(unless (or (loop repeat count
|
||||
when (apply predicate predargs)
|
||||
|
|
Loading…
Add table
Reference in a new issue