Add jupyter-kernel-language-mode-properties and related functions

This commit is contained in:
Nathaniel Nicandro 2019-01-16 13:52:42 -06:00
parent fa809e7801
commit 876c080f7f
No known key found for this signature in database
GPG key ID: C34814B309DD06B8
2 changed files with 52 additions and 40 deletions

View file

@ -931,7 +931,7 @@ Methods that extend this generic function should
(lambda ()
(setq jupyter-current-client client)
;; TODO: Enable the kernel languages mode using
;; `jupyter-repl-language-mode', but there are
;; `jupyter-kernel-language-mode', but there are
;; issues with enabling a major mode.
(add-hook 'completion-at-point-functions
'jupyter-completion-at-point nil t)
@ -1794,7 +1794,12 @@ snippet text property, if any, and if `yasnippet' is available."
;;;; Kernel info
(cl-defmethod jupyter-kernel-info ((client jupyter-kernel-client))
(defvar jupyter-kernel-language-mode-properties nil
"An association list mapping language names to major mode properties.
The lists contain the cached information returned by the
`jupyter-kernel-language-mode-properties' function.")
(defun jupyter-kernel-info (client)
"Return the kernel info plist of CLIENT.
Return CLIENT's kernel-info slot if non-nil. Otherwise send a
`:kernel-info-request' to CLIENT's kernel, set CLIENT's
@ -1803,6 +1808,7 @@ return it.
If the kernel CLIENT is connected to does not respond to a
`:kernel-info-request', raise an error."
(cl-check-type client jupyter-kernel-client)
(or (oref client kernel-info)
(let* ((jupyter-inhibit-handlers t)
(req (jupyter-send-kernel-info-request client))
@ -1812,14 +1818,45 @@ If the kernel CLIENT is connected to does not respond to a
(error "Kernel did not respond to kernel-info request"))
(oset client kernel-info (jupyter-message-content msg)))))
(cl-defmethod jupyter-kernel-language ((client jupyter-kernel-client))
(defun jupyter-kernel-language-mode-properties (client)
"Get the `major-mode' info of CLIENT's kernel language.
Return a list
(MODE SYNTAX-TABLE)
Where MODE is the `major-mode' to use for syntax highlighting
purposes and SYNTAX-TABLE is the syntax table of MODE."
(cl-check-type client jupyter-kernel-client)
(cl-destructuring-bind (&key name file_extension &allow-other-keys)
(plist-get (jupyter-kernel-info client) :language_info)
(cdr (or (assoc name jupyter-kernel-language-mode-properties)
(with-temp-buffer
(let ((buffer-file-name
(concat "jupyter-repl-lang" file_extension)))
(delay-mode-hooks (set-auto-mode)))
(let ((item (cons name (list major-mode (syntax-table)))))
(prog1 item
(push item jupyter-kernel-language-mode-properties))))))))
(defun jupyter-kernel-language (client)
"Return the language of the kernel CLIENT is connected to."
(cl-check-type client jupyter-kernel-client)
(plist-get (plist-get (jupyter-kernel-info client) :language_info) :name))
(defun jupyter-kernel-language-mode (client)
"Return the `major-mode' used for CLIENT's kernel language."
(cl-check-type client jupyter-kernel-client)
(nth 0 (jupyter-kernel-language-mode-properties client)))
(defun jupyter-kernel-language-syntax-table (client)
"Return the `syntax-table' used for CLIENT's kernel language."
(cl-check-type client jupyter-kernel-client)
(nth 1 (jupyter-kernel-language-mode-properties client)))
(defun jupyter-load-language-support (client)
"Load language support definitions for CLIENT.
CLIENT is a kernel client."
(cl-assert (object-of-class-p client 'jupyter-kernel-client))
(cl-check-type client jupyter-kernel-client)
(let* ((lang (jupyter-kernel-language client))
(support (intern (concat "jupyter-" lang))))
(require support nil t)))

View file

@ -222,13 +222,6 @@ The cell is narrowed to the region between and including
(jupyter-repl-cell-code-end-position))
,@body)))
;;; Convenience functions
(defun jupyter-repl-language-mode (client)
"Return the `major-mode' of CLIENT's kernel language."
(jupyter-with-repl-buffer client
jupyter-repl-lang-mode))
;;; Text insertion
(defun jupyter-repl-insert (&rest args)
@ -1371,7 +1364,7 @@ in the appropriate direction, to the saved element."
9 nil nil ""))))
(unless (get-buffer name)
(with-current-buffer (get-buffer-create name)
(funcall (jupyter-repl-language-mode client))
(funcall (jupyter-kernel-language-mode client))
(jupyter-repl-associate-buffer client)
(insert
(substitute-command-keys
@ -1410,11 +1403,10 @@ in the appropriate direction, to the saved element."
;; language. This will be used for indentation and to capture font lock
;; properties.
(let* ((info (jupyter-kernel-info jupyter-current-client))
(language-info (plist-get info :language_info))
(language (plist-get language-info :name)))
(language (plist-get (plist-get info :language_info) :name)))
(jupyter-load-language-support jupyter-current-client)
(cl-destructuring-bind (mode syntax)
(jupyter-repl-kernel-language-mode-properties language-info)
(jupyter-kernel-language-mode-properties jupyter-current-client)
(setq jupyter-repl-lang-mode mode)
(setq jupyter-repl-lang-buffer
(get-buffer-create
@ -1604,8 +1596,9 @@ If CLIENT is a buffer or the name of a buffer, use the
(with-current-buffer client
jupyter-current-client)
client))
(cl-check-type client jupyter-repl-client)
(unless (eq (jupyter-repl-language-mode client) major-mode)
(unless (object-of-class-p client 'jupyter-repl-client)
(error "Not a REPL client (%s)" client))
(unless (eq (jupyter-kernel-language-mode client) major-mode)
(error "Cannot associate buffer to REPL. Wrong `major-mode'"))
(setq-local jupyter-current-client client)
(unless jupyter-repl-interaction-mode
@ -1660,7 +1653,7 @@ NOTE: Only intended to be added as advice to `switch-to-buffer',
(with-current-buffer buffer
(let ((client jupyter-current-client)
(mode (if (eq major-mode 'jupyter-repl-mode)
(jupyter-repl-language-mode jupyter-current-client)
(jupyter-kernel-language-mode jupyter-current-client)
major-mode)))
(with-current-buffer other-buffer
(when (and (eq mode major-mode)
@ -1670,7 +1663,8 @@ NOTE: Only intended to be added as advice to `switch-to-buffer',
(defun jupyter-repl-interaction-mode-reenable ()
(when (and (not jupyter-repl-interaction-mode)
(jupyter-repl-client-p jupyter-current-client)
(eq (jupyter-repl-language-mode jupyter-current-client) major-mode))
(eq major-mode
(jupyter-kernel-language-mode jupyter-current-client)))
(jupyter-repl-interaction-mode)))
(defun jupyter-repl-interaction-mode-line ()
@ -1738,25 +1732,6 @@ other buffers switched to that have the same `major-mode' as the
;;; Starting a REPL
(defun jupyter-repl-kernel-language-mode-properties (language-info)
"Get the `major-mode' info of a kernel's language.
LANGUAGE-INFO should be the plist of the `:language_info' key in
a kernel's kernel-info. The `major-mode' is found by consulting
`auto-mode-alist' using the language's file extension found in
LANGUAGE-INFO. Return a list
(MODE SYNTAX-TABLE)
Where MODE is the `major-mode' to use for syntax highlighting
purposes and SYNTAX-TABLE is the syntax table of MODE."
(cl-destructuring-bind (&key file_extension &allow-other-keys)
language-info
(with-temp-buffer
(let ((buffer-file-name
(concat "jupyter-repl-lang" file_extension)))
(delay-mode-hooks (set-auto-mode)))
(list major-mode (syntax-table)))))
(defun jupyter-repl--new-repl (client &optional repl-name)
"Initialize a new REPL buffer based on CLIENT.
CLIENT is a REPL client already connected to its kernel and has a
@ -1833,7 +1808,7 @@ Otherwise, in a non-interactive call, return the
;; mode using `auto-mode-alist'. See
;; `jupyter-repl-kernel-language-mode-properties'.
(when (and associate-buffer
(eq major-mode (jupyter-repl-language-mode client)))
(eq major-mode (jupyter-kernel-language-mode client)))
(jupyter-repl-associate-buffer client))
(when display
(pop-to-buffer (oref client buffer)))
@ -1866,7 +1841,7 @@ called interactively, DISPLAY the new REPL buffer as well."
(jupyter-start-channels client)
(jupyter-repl--new-repl client repl-name)
(when (and associate-buffer
(eq major-mode (jupyter-repl-language-mode client)))
(eq major-mode (jupyter-kernel-language-mode client)))
(jupyter-repl-associate-buffer client))
(when display
(pop-to-buffer (oref client buffer)))