From 17596ee1c46cfd11b24eb9fd8ae16bf7d36689f6 Mon Sep 17 00:00:00 2001 From: Nathaniel Nicandro Date: Tue, 22 May 2018 21:43:08 -0500 Subject: [PATCH] Be less ambiguous when encoding/decoding messages - Do not handle nil as an empty dictionary when encoding. - Use the default `json-array-type` --- jupyter-base.el | 9 +++------ jupyter-kernel-manager.el | 2 +- jupyter-messages.el | 15 +++++++++------ jupyter-repl.el | 18 ++++++++++-------- 4 files changed, 23 insertions(+), 21 deletions(-) diff --git a/jupyter-base.el b/jupyter-base.el index ccce037..9046c09 100644 --- a/jupyter-base.el +++ b/jupyter-base.el @@ -336,15 +336,12 @@ the ROUTING-ID of the socket. Return the created socket." (defun jupyter-read-plist (file) "Read a JSON encoded FILE as a property list." - (let ((json-object-type 'plist) - (json-array-type 'list) - (json-false nil)) + (let ((json-object-type 'plist)) (json-read-file file))) (defun jupyter-read-plist-from-string (string) - (let ((json-object-type 'plist) - ;; TODO: See the comment in `jupyter--decode' - (json-array-type 'list)) + "Read a property list from a JSON encoded STRING." + (let ((json-object-type 'plist)) (json-read-from-string string))) (provide 'jupyter-base) diff --git a/jupyter-kernel-manager.el b/jupyter-kernel-manager.el index 78ec306..99ec69d 100644 --- a/jupyter-kernel-manager.el +++ b/jupyter-kernel-manager.el @@ -200,7 +200,7 @@ kernel. Starting a kernel involves the following steps: (proc (jupyter--start-kernel manager kernel-name (plist-get spec :env) (cl-loop - for arg in (plist-get spec :argv) + for arg in (append (plist-get spec :argv) nil) if (equal arg "{connection_file}") collect conn-file else if (equal arg "{resource_dir}") diff --git a/jupyter-messages.el b/jupyter-messages.el index 9a09cbd..885a4f7 100644 --- a/jupyter-messages.el +++ b/jupyter-messages.el @@ -91,8 +91,7 @@ They are all set to appropriate default values." (cl-letf (((symbol-function 'json-encode) (lambda (object) (cond ((memq object (list t json-null json-false)) - (if (eq object json-null) "{}" - (json-encode-keyword object))) + (json-encode-keyword object)) ((stringp object) (json-encode-string object)) ((keywordp object) ;; Handle `jupyter-message-type' @@ -107,14 +106,16 @@ They are all set to appropriate default values." ((listp object) (json-encode-list object)) (t (signal 'json-error (list object))))))) (encode-coding-string - (if (stringp object) object (json-encode-plist object)) + (cond + ((stringp object) object) + ;; FIXME: This seems expensive + ((json-plist-p object) (json-encode-plist object)) + (t (json-encode object))) 'utf-8 t))) (defun jupyter--decode (str) (setq str (decode-coding-string str 'utf-8)) (let* ((json-object-type 'plist) - (json-array-type 'list) - (json-false nil) (val (condition-case nil (json-read-from-string str) ;; If it can't be read as JSON, assume its just a regular @@ -233,7 +234,9 @@ They are all set to appropriate default values." code (silent nil) (store-history t) - (user-expressions nil) + ;; This needs to be an empty + ;; dictionary is not specified + (user-expressions #s(hash-table)) (allow-stdin t) (stop-on-error nil)) (cl-check-type code string) diff --git a/jupyter-repl.el b/jupyter-repl.el index e566bcf..4510736 100644 --- a/jupyter-repl.el +++ b/jupyter-repl.el @@ -957,7 +957,7 @@ lines then truncate it to something less than (defun jupyter-repl--handle-payload (payload) "Do the client actions in PAYLOAD." (cl-loop - for pl in payload + for pl across payload do (pcase (plist-get pl :source) ("page" (let ((text (plist-get (plist-get pl :data) :text/plain)) @@ -1226,7 +1226,8 @@ REPL buffer." (cl-defmethod jupyter-handle-history-reply ((client jupyter-repl-client) _req history) (with-jupyter-repl-buffer client - (cl-loop for (_session _line-number input-output) in history + (cl-loop for elem across history + for input-output = (aref elem 2) do (ring-remove+insert+extend jupyter-repl-history input-output)))) (cl-defmethod jupyter-handle-is-complete-reply ((client jupyter-repl-client) _req status indent) @@ -1480,12 +1481,13 @@ value that PREFIX takes. This function constructs candidates assuming that `company-mode' is used for completion." - (let ((types (plist-get metadata :_jupyter_types_experimental)) - (tail matches) - ;; TODO: Handle the case when the matches are method signatures in the - ;; Julia kernel. This information would be useful for doing some kind - ;; of eldoc like feature. - (match-prefix-len (- (- end start) (length prefix)))) + (let* ((matches (append matches nil)) + (tail matches) + (types (append (plist-get metadata :_jupyter_types_experimental) nil)) + ;; TODO: Handle the case when the matches are method signatures in the + ;; Julia kernel. This information would be useful for doing some kind + ;; of eldoc like feature. + (match-prefix-len (- (- end start) (length prefix)))) ;; FIXME: How to complete things like 000|? In the python kernel, ;; completions will return matchs to append like and, or, ... but the ;; prefix 000 was provided so company will replace 000 with the match if it