replace ein:aif with aif

This commit is contained in:
dickmao 2019-11-24 00:17:52 -05:00
parent ab87b7cb6c
commit e12a33588d
32 changed files with 298 additions and 288 deletions

1
Cask
View file

@ -5,6 +5,7 @@
(files "lisp/*.el" "lisp/*.py")
(development
(depends-on "anaphora")
(depends-on "websocket")
(depends-on "request")
(depends-on "dash")

View file

@ -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
^^^^^^^^^^^^^

View file

@ -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)))

View file

@ -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 = ""

View file

@ -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)

View file

@ -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))))

View file

@ -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))

View file

@ -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)

View file

@ -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))

View file

@ -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))))

View file

@ -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)))

View file

@ -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."

View file

@ -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)))))))))

View file

@ -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)

View file

@ -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

View file

@ -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)))))

View file

@ -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)))

View file

@ -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?")

View file

@ -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

View file

@ -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

View file

@ -3,6 +3,7 @@
"Emacs IPython Notebook"
'((emacs "25")
(websocket "20190620.338")
(anaphora "20180618")
(request "20190621.1622")
(deferred "0.5")
(polymode "20190426.1729")

View file

@ -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'

View file

@ -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."))))

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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))))

View file

@ -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)