mirror of
https://github.com/vale981/emacs-jupyter
synced 2025-03-04 15:41:37 -05:00
Sort available kernelspecs; guess with ^; use guessing in jupyter-run-repl
This commit is contained in:
parent
0a7055d7b1
commit
7d20c0aee2
4 changed files with 62 additions and 18 deletions
|
@ -45,10 +45,10 @@
|
|||
"Get the available kernelspecs.
|
||||
Return an alist mapping kernel names to (DIRECTORY . PLIST) pairs
|
||||
where DIRECTORY is the resource directory of the kernel and PLIST
|
||||
is its kernelspec plist. The alist is formed by parsing the
|
||||
output of the shell command
|
||||
is its kernelspec plist. The alist is formed by parsing and
|
||||
sorting the output of the shell command
|
||||
|
||||
jupyter kernelspec list
|
||||
jupyter kernelspec list --json
|
||||
|
||||
By default the available kernelspecs are cached. To force an
|
||||
update of the cached kernelspecs, give a non-nil value to
|
||||
|
@ -64,14 +64,16 @@ each DIRECTORY will be a remote file name."
|
|||
(or (jupyter-command "kernelspec" "list" "--json")
|
||||
(error "Can't obtain kernelspecs from jupyter shell command")))
|
||||
:kernelspecs)))
|
||||
(puthash
|
||||
host (cl-loop
|
||||
for (name spec) on specs by #'cddr
|
||||
for dir = (concat (unless (equal host "local") host)
|
||||
(plist-get spec :resource_dir))
|
||||
collect (cons (substring (symbol-name name) 1)
|
||||
(cons dir (plist-get spec :spec))))
|
||||
jupyter--kernelspecs)))))
|
||||
(puthash host
|
||||
(sort (cl-loop
|
||||
for (name spec) on specs by #'cddr
|
||||
for dir = (concat (unless (equal host "local") host)
|
||||
(plist-get spec :resource_dir))
|
||||
collect (cons (substring (symbol-name name) 1)
|
||||
(cons dir (plist-get spec :spec))))
|
||||
(lambda (x y)
|
||||
(string< (car x) (car y))))
|
||||
jupyter--kernelspecs)))))
|
||||
|
||||
(defun jupyter-get-kernelspec (name &optional refresh)
|
||||
"Get the kernelspec for a kernel named NAME.
|
||||
|
@ -103,12 +105,12 @@ Optional argument REFRESH has the same meaning as in
|
|||
(or specs (jupyter-available-kernelspecs refresh))))
|
||||
|
||||
(defun jupyter-guess-kernelspec (name &optional specs refresh)
|
||||
"Return the first kernelspec matching NAME.
|
||||
"Return the first kernelspec starting with NAME.
|
||||
Raise an error if no kernelspec could be found.
|
||||
|
||||
SPECS and REFRESH have the same meaning as in
|
||||
`jupyter-find-kernelspecs'."
|
||||
(or (car (jupyter-find-kernelspecs name specs refresh))
|
||||
(or (car (jupyter-find-kernelspecs (format "^%s" name) specs refresh))
|
||||
(error "No valid kernelspec for kernel name (%s)" name)))
|
||||
|
||||
(defun jupyter-completing-read-kernelspec (&optional specs refresh)
|
||||
|
|
|
@ -2097,7 +2097,7 @@ completing all of the above.")
|
|||
;;;###autoload
|
||||
(defun jupyter-run-repl (kernel-name &optional repl-name associate-buffer client-class display)
|
||||
"Run a Jupyter REPL connected to a kernel with name, KERNEL-NAME.
|
||||
KERNEL-NAME will be passed to `jupyter-find-kernelspecs' and the
|
||||
KERNEL-NAME will be passed to `jupyter-guess-kernelspec' and the
|
||||
first kernel found will be used to start the new kernel.
|
||||
|
||||
With a prefix argument give a new REPL-NAME for the REPL.
|
||||
|
@ -2128,10 +2128,6 @@ command on the host."
|
|||
t nil t))
|
||||
(or client-class (setq client-class 'jupyter-repl-client))
|
||||
(jupyter-error-if-not-client-class-p client-class 'jupyter-repl-client)
|
||||
(unless (called-interactively-p 'interactive)
|
||||
(or (when-let* ((name (caar (jupyter-find-kernelspecs kernel-name))))
|
||||
(setq kernel-name name))
|
||||
(error "No kernel found for prefix (%s)" kernel-name)))
|
||||
;; For `jupyter-start-new-kernel', we don't require this at top-level since
|
||||
;; there are many ways to interact with a kernel, e.g. through a notebook
|
||||
;; server, and we don't want to load any unnecessary files.
|
||||
|
|
|
@ -1912,6 +1912,24 @@ next(x"))))))
|
|||
font-lock-extend-region-functions)))
|
||||
(font-lock-ensure)))))
|
||||
|
||||
(ert-deftest jupyter-available-kernelspecs-sorting ()
|
||||
:tags '(repl)
|
||||
(jupyter-test-with-some-kernelspecs '("foo_qux" "qux" "bar_qux")
|
||||
(let ((result (mapcar #'car (jupyter-available-kernelspecs t))))
|
||||
(should (equal result (sort (copy-sequence result) #'string<))))))
|
||||
|
||||
(ert-deftest jupyter-run-repl-issue-371 ()
|
||||
:tags '(repl)
|
||||
(jupyter-test-with-some-kernelspecs '("foo_qux" "qux" "bar_qux")
|
||||
(let ((client))
|
||||
(unwind-protect
|
||||
(progn
|
||||
(setq client (jupyter-run-repl "qux"))
|
||||
(should (equal (plist-get (jupyter-session-conn-info (oref client session))
|
||||
:kernel_name)
|
||||
"qux")))
|
||||
(jupyter-test-kill-buffer (oref client buffer))))))
|
||||
|
||||
;;; `org-mode'
|
||||
|
||||
(defvar org-babel-jupyter-resource-directory nil)
|
||||
|
|
|
@ -365,8 +365,36 @@ For `url-retrieve', the callback will be called with a nil status."
|
|||
(progn ,@body)
|
||||
(jupyter-api-shutdown-kernel ,server ,id))))))
|
||||
|
||||
(defmacro jupyter-test-with-some-kernelspecs (names &rest body)
|
||||
"Execute BODY in the context where extra kernelspecs with NAMES are available.
|
||||
|
||||
Those kernelspecs will be created in a temporary dir, which will
|
||||
be presented to Jupyter process via JUPYTER_PATH environemnt
|
||||
variable."
|
||||
(declare (indent 1) (debug (listp body)))
|
||||
`(unwind-protect
|
||||
(let ((jupyter-extra-dir (make-temp-file "jupyter-extra-dir" 'directory)))
|
||||
(jupyter-test-create-some-kernelspecs ,names jupyter-extra-dir)
|
||||
(setenv "JUPYTER_PATH" jupyter-extra-dir)
|
||||
,@body)
|
||||
(setenv "JUPYTER_PATH")))
|
||||
|
||||
;;; Functions
|
||||
|
||||
(defun jupyter-test-create-some-kernelspecs (kernel-names data-dir)
|
||||
"In DATA-DIR, create kernelspecs according to KERNEL-NAMES list.
|
||||
|
||||
The only difference between them will be their names."
|
||||
(let ((argv (vector "python" "-m" "ipykernel_launcher" "-f" "{connection_file}"))
|
||||
(save-silently t))
|
||||
(dolist (name kernel-names)
|
||||
(let ((kernel-dir (format "%s/kernels/%s" data-dir name)))
|
||||
(make-directory kernel-dir t)
|
||||
(append-to-file (json-serialize
|
||||
`(:argv ,argv :display_name ,name :language "python"))
|
||||
nil
|
||||
(format "%s/kernel.json" kernel-dir))))))
|
||||
|
||||
(defun jupyter-test-ipython-kernel-version (spec)
|
||||
"Return the IPython kernel version string corresponding to SPEC.
|
||||
Assumes that SPEC is a kernelspec for a Python kernel and
|
||||
|
|
Loading…
Add table
Reference in a new issue