diff --git a/lisp/ein-cell-edit.el b/lisp/ein-cell-edit.el index 026d441..8b20510 100644 --- a/lisp/ein-cell-edit.el +++ b/lisp/ein-cell-edit.el @@ -28,6 +28,7 @@ (defvar ein:src--cell nil) (defvar ein:src--ws nil) +(defvar ein:src--point nil) (defvar ein:src--allow-write-back t) (defvar ein:edit-cell-mode-map @@ -36,6 +37,7 @@ (define-key map "\C-c\C-k" 'ein:edit-cell-abort) (define-key map "\C-c\C-c" 'ein:edit-cell-save-and-execute) (define-key map "\C-x\C-s" 'ein:edit-cell-save) + (define-key map "\C-c\C-x" 'ein:edit-cell-view-traceback) map)) (define-minor-mode ein:edit-cell-mode @@ -86,6 +88,14 @@ or abort with \\[ein:edit-cell-abort]")) (setq write-contents-functions '(ein:edit-cell-save))) (setq buffer-read-only t)))) +(defun ein:edit-cell-view-traceback () + "Jump to traceback, if there is one, for current edit." + (interactive) + (save-excursion + (switch-to-buffer (ein:worksheet-buffer ein:src--ws)) + (goto-char ein:src--point) + (ein:tb-show))) + (defun ein:edit-cell-save-and-execute () "Save, then execute the countents of the EIN source edit buffer and place results (if any) in output of original notebook cell." @@ -116,6 +126,7 @@ original notebook cell, unless being called via (ein:edit-cell-save)) (kill-buffer edit-buffer) (switch-to-buffer-other-window (ein:worksheet-buffer ws)) + (goto-char ein:src--point) ;; FIXME: put point at an appropriate location as org does? )) @@ -145,6 +156,7 @@ appropriate language major mode. Functionality is very similar to (type (slot-value cell 'cell-type)) (name (ein:construct-cell-edit-buffer-name (buffer-name) type)) (buffer (generate-new-buffer-name name))) + (set (make-local-variable 'ein:src--point) (point)) (switch-to-buffer-other-window buffer) (insert contents) (remove-text-properties (point-min) (point-max) diff --git a/lisp/ein-contents-api.el b/lisp/ein-contents-api.el index a34bb7f..6065ff2 100644 --- a/lisp/ein-contents-api.el +++ b/lisp/ein-contents-api.el @@ -295,7 +295,7 @@ global setting. For global setting and more information, see (ein:content-save-legacy content callback cbargs))) (defun* ein:content-save-success (callback cbargs &key status response &allow-other-keys) - (ein:log 'verbose "Saving content successful with status %s" status) + ;;(ein:log 'verbose "Saving content successful with status %s" status) (when callback (apply callback cbargs))) diff --git a/lisp/ein-core.el b/lisp/ein-core.el index 4169eb2..3a4a3f6 100644 --- a/lisp/ein-core.el +++ b/lisp/ein-core.el @@ -129,23 +129,27 @@ the source is in git repository." (defvar *running-ipython-version* (make-hash-table)) +(defun ein:get-ipython-major-version (vstr) + (string-to-int (car (split-string vstr "\\.")))) + ;; TODO: Use symbols instead of numbers for ipython version ('jupyter and 'legacy)? (defun ein:query-ipython-version (&optional url-or-port force) (ein:aif (and (not force) (gethash (or url-or-port (ein:default-url-or-port)) *running-ipython-version*)) it (let ((resp (request (ein:url (or url-or-port (ein:default-url-or-port)) - "api/contents") + "api") :parser #'(lambda () (ignore-errors (ein:json-read))) :timeout 0.5 :sync t))) (if (eql 404 (request-response-status-code resp)) - (progn - (ein:log 'blather "Version api not implemented, assuming we are working with IPython 2.x") - (setf (gethash url-or-port *running-ipython-version*) 2)) - (setf (gethash url-or-port *running-ipython-version*) 3))))) + (progn + (ein:log 'blather "Version api not implemented, assuming we are working with IPython 2.x") + (setf (gethash url-or-port *running-ipython-version*) 2)) + (setf (gethash url-or-port *running-ipython-version*) + (ein:get-ipython-major-version (plist-get (request-response-data resp) :version))))))) (defun ein:force-ipython-version-check () (interactive) diff --git a/lisp/ein-kernel.el b/lisp/ein-kernel.el index fab6831..4604855 100644 --- a/lisp/ein-kernel.el +++ b/lisp/ein-kernel.el @@ -316,7 +316,7 @@ See: https://github.com/ipython/ipython/pull/3307" :early t))) (cond ((= api-version 2) (ein:start-channels-multiple-websocket kernel)) - ((= api-version 3) + ((>= api-version 3) (ein:start-channels-single-websocket kernel))) ;; switch from early-close to late-close message after 1s (run-at-time diff --git a/lisp/ein-notebook.el b/lisp/ein-notebook.el index da163f0..3d65482 100644 --- a/lisp/ein-notebook.el +++ b/lisp/ein-notebook.el @@ -338,7 +338,7 @@ will be updated with kernel's cwd." (defun ein:notebook-url-from-url-and-id (url-or-port api-version path) (cond ((= 2 api-version) (ein:url url-or-port "api/notebooks" path)) - ((= 3 api-version) + ((>= 3 api-version) (ein:url url-or-port "api/contents" path)))) (defun ein:notebook-pop-to-current-buffer (&rest -ignore-) diff --git a/lisp/ein-notebooklist.el b/lisp/ein-notebooklist.el index 98d56ac..87187f4 100644 --- a/lisp/ein-notebooklist.el +++ b/lisp/ein-notebooklist.el @@ -474,7 +474,10 @@ Notebook list data is passed via the buffer local variable (erase-buffer)) (remove-overlays) ;; Create notebook list - (widget-insert (format "IPython %s Notebook list\n\n" (ein:$notebooklist-api-version ein:%notebooklist%))) + (widget-insert + (if (< (ein:$notebooklist-api-version ein:%notebooklist%) 4) + (format "IPython v%s Notebook list\n\n" (ein:$notebooklist-api-version ein:%notebooklist%)) + (format "Jupyter v%s Notebook list\n\n" (ein:$notebooklist-api-version ein:%notebooklist%)))) (let ((breadcrumbs (generate-breadcrumbs (ein:$notebooklist-path ein:%notebooklist%)))) (dolist (p breadcrumbs) (lexical-let ((name (car p)) diff --git a/lisp/ein-websocket.el b/lisp/ein-websocket.el index a1d1a88..81e1b43 100644 --- a/lisp/ein-websocket.el +++ b/lisp/ein-websocket.el @@ -100,7 +100,10 @@ (let ((websocket (websocket-client-data ws))) (ein:aif (ein:$websocket-onclose websocket) (apply it websocket - (ein:$websocket-onclose-args websocket)))))))) + (ein:$websocket-onclose-args websocket))))) + :on-error + (lambda (ws action err) + (ein:log 'error "Error %s on websocket %s action %s." err ws action))))) (setf (websocket-client-data ws) websocket) (setf (ein:$websocket-ws websocket) ws) websocket)) @@ -125,7 +128,7 @@ (ein:websocket-send (ein:$kernel-shell-channel kernel) (json-encode msg))) - ((= (ein:$kernel-api-version kernel) 3) + ((>= (ein:$kernel-api-version kernel) 3) (ein:websocket-send (ein:$kernel-channels kernel) (json-encode (plist-put msg :channel "shell")))))) @@ -133,7 +136,7 @@ (defun ein:websocket-send-stdin-channel (kernel msg) (cond ((= (ein:$kernel-api-version kernel) 2) (ein:log 'warn "Stdin messages only supported with IPython 3.")) - ((= (ein:$kernel-api-version kernel) 3) + ((>= (ein:$kernel-api-version kernel) 3) (ein:websocket-send (ein:$kernel-channels kernel) (json-encode (plist-put msg :channel "stdin"))))))