mirror of
https://github.com/vale981/emacs-ipython-notebook
synced 2025-03-05 09:01:40 -05:00
Fix "Kernel is busy..." bug
One line change to fix header not updating after cell execution (keeps saying "Kernel is busy"). The bug does not manifest when running with `ein:debug` true since EMACS's display loop updates more frequently with debug messages. In tracking this bug, noticed eldoc support isn't quite there. `__import__('ein').print_object_info_for(%s)` appears in `ein-completer` and `ein-pytools`, and is invalid python syntax afaict. Took a few steps to make it whole, but incomplete.
This commit is contained in:
parent
e1b26550b2
commit
b950bd3a4c
9 changed files with 71 additions and 69 deletions
3
Makefile
3
Makefile
|
@ -1,4 +1,3 @@
|
|||
EMACS ?= $(shell which emacs)
|
||||
SRC=$(shell cask files)
|
||||
ELCFILES = $(SRC:.el=.elc)
|
||||
|
||||
|
@ -23,7 +22,7 @@ env-ipy.%:
|
|||
|
||||
.PHONY: test-compile
|
||||
test-compile: clean autoloads
|
||||
! ( cask build 2>&1 | awk '{if (/^ /) { gsub(/^ +/, " ", $$0); printf "%s", $$0 } else { printf "\n%s", $$0 }}' | egrep "not known|Error|free variable|error for|Use of gv-ref" )
|
||||
! ( cask build 2>&1 | awk '{if (/^ /) { gsub(/^ +/, " ", $$0); printf "%s", $$0 } else { printf "\n%s", $$0 }}' | egrep -a "not known|Error|free variable|error for|Use of gv-ref" )
|
||||
cask clean-elc
|
||||
|
||||
.PHONY: quick
|
||||
|
|
|
@ -173,7 +173,6 @@ Scenario: Undo needs to at least work for reopened notebooks
|
|||
Given I start the server configured "\n"
|
||||
Given I enable "ein:worksheet-enable-undo"
|
||||
Given old notebook "undo.ipynb"
|
||||
When I press "C-<down>"
|
||||
And I type "howdy"
|
||||
And I press "RET"
|
||||
And I press "C-<down>"
|
||||
|
|
|
@ -25,9 +25,6 @@
|
|||
|
||||
;;; Code:
|
||||
(require 'ein-cell)
|
||||
(require 'ess-r-mode nil t)
|
||||
(require 'org-src nil t)
|
||||
(require 'markdown-mode nil t)
|
||||
|
||||
(autoload 'markdown-mode "markdown-mode")
|
||||
(autoload 'R-mode "ess-r-mode")
|
||||
|
|
|
@ -348,7 +348,7 @@ auto-execution mode flag in the connected buffer is `t'.")))
|
|||
((status :initarg :status :initform nil)
|
||||
(message :initarg :message :initform nil)
|
||||
(s2m :initarg :s2m))
|
||||
"Hold status and it's string representation (message).")
|
||||
"Hold status and its string representation (message).")
|
||||
|
||||
(defclass ein:notification-tab ()
|
||||
((get-list :initarg :get-list :type function)
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
(require 'ein-log)
|
||||
(require 'ein-subpackages)
|
||||
(require 'ein-kernel)
|
||||
(require 'dash)
|
||||
|
||||
(defun ein:completer-choose ()
|
||||
(require 'ein-ac)
|
||||
|
@ -130,23 +131,19 @@ notebook buffers and connected buffers."
|
|||
(defvar *ein:oinfo-cache* (make-hash-table :test #'equal))
|
||||
|
||||
(defun ein:completions--get-oinfo (obj)
|
||||
(let ((d (deferred:new #'identity))
|
||||
(kernel (ein:get-kernel)))
|
||||
(lexical-let ((d (deferred:new #'identity))
|
||||
(kernel (ein:get-kernel)))
|
||||
(if (ein:kernel-live-p kernel)
|
||||
(ein:kernel-execute
|
||||
kernel
|
||||
(format "__import__('ein').print_object_info_for(%s)" obj)
|
||||
(list
|
||||
:output (cons (lambda (d &rest args) (deferred:callback-post d args))
|
||||
d)))
|
||||
:output `(,(lambda (d &rest args) (deferred:callback-post d args)) . ,d)))
|
||||
(deferred:callback-post d (list nil nil)))
|
||||
d))
|
||||
|
||||
(defun ein:clear-oinfo-cache ()
|
||||
(clrhash *ein:oinfo-cache*))
|
||||
|
||||
(defun ein:completions--build-oinfo-cache (objs)
|
||||
(dolist (o objs)
|
||||
(dolist (o (-non-nil objs))
|
||||
(deferred:$
|
||||
(deferred:next
|
||||
(lambda ()
|
||||
|
@ -156,26 +153,23 @@ notebook buffers and connected buffers."
|
|||
(ein:completions--prepare-oinfo output o))))))
|
||||
|
||||
(defun ein:completions--prepare-oinfo (output obj)
|
||||
(condition-case _
|
||||
(condition-case err
|
||||
(destructuring-bind (msg-type content _) output
|
||||
(ein:case-equal msg-type
|
||||
(("stream" "display_data")
|
||||
(let* ((oinfo (ein:json-read-from-string (plist-get content :text))))
|
||||
(setf (gethash obj *ein:oinfo-cache*) oinfo)))))
|
||||
(error (setf (gethash obj *ein:oinfo-cache*) ""))))
|
||||
(("stream" "display_data" "pyout" "execute_result")
|
||||
(setf (gethash obj *ein:oinfo-cache*) (plist-get content :text)))
|
||||
(("error" "pyerr")
|
||||
(ein:log 'error "ein:completions--prepare-oinfo: %S" (plist-get content :traceback)))))
|
||||
(error (ein:log 'error "ein:completions--prepare-oinfo: [%s] %s" err obj)
|
||||
(setf (gethash obj *ein:oinfo-cache*) :json-false))))
|
||||
|
||||
;;; Support for Eldoc
|
||||
|
||||
(defun ein:completer--get-eldoc-signature ()
|
||||
(let* ((func (ein:function-at-point))
|
||||
(oinfo (gethash func *ein:oinfo-cache* nil)))
|
||||
(if (not oinfo)
|
||||
(ein:completions--build-oinfo-cache (list func))
|
||||
(plist-get oinfo :definition))))
|
||||
|
||||
(defun ein:notebook--enable-eldoc ()
|
||||
(set (make-local-variable 'eldoc-documentation-function)
|
||||
#'ein:completer--get-eldoc-signature))
|
||||
(let ((func (ein:function-at-point)))
|
||||
(ein:aif (gethash func *ein:oinfo-cache*)
|
||||
(ein:kernel-construct-defstring it)
|
||||
(ein:completions--build-oinfo-cache (list func)))))
|
||||
|
||||
(provide 'ein-completer)
|
||||
|
||||
|
|
|
@ -368,7 +368,7 @@ notebook."
|
|||
(define-key map "\C-c\C-l" 'ein:connect-reload-buffer)
|
||||
(define-key map "\C-c\C-r" 'ein:connect-eval-region)
|
||||
(define-key map (kbd "C-:") 'ein:shared-output-eval-string)
|
||||
(define-key map "\C-c\C-f" 'ein:pytools-request-tooltip-or-help)
|
||||
(define-key map "\C-c\C-h" 'ein:pytools-request-tooltip-or-help)
|
||||
(define-key map "\C-c\C-i" 'ein:completer-complete)
|
||||
(define-key map "\C-c\C-z" 'ein:connect-pop-to-notebook)
|
||||
(define-key map "\C-c\C-a" 'ein:connect-toggle-autoexec)
|
||||
|
|
|
@ -464,7 +464,7 @@ When calling this method pass a CALLBACKS structure of the form:
|
|||
:clear_output CLEAR-OUTPUT-CALLBACK
|
||||
:set_next_input SET-NEXT-INPUT)
|
||||
|
||||
Objects end with -CALLBACK above must pack a FUNCTION and its
|
||||
Right hand sides ending -CALLBACK above must pack a FUNCTION and its
|
||||
first ARGUMENT in a `cons'::
|
||||
|
||||
(FUNCTION . ARGUMENT)
|
||||
|
@ -515,27 +515,23 @@ Sample implementations
|
|||
;; (funcall FUNCTION [ARG ...] CONTENT METADATA)
|
||||
|
||||
(assert (ein:kernel-live-p kernel) nil "execute_reply: Kernel is not active.")
|
||||
(if (not (ein:$kernel-stdin-activep kernel))
|
||||
(let* ((content (list
|
||||
:code code
|
||||
:silent (or silent json-false)
|
||||
:store_history (or store-history json-false)
|
||||
:user_expressions user-expressions
|
||||
:allow_stdin allow-stdin
|
||||
:stop_on_error (or stop-on-error json-false)))
|
||||
(msg (ein:kernel--get-msg kernel "execute_request" content))
|
||||
(msg-id (plist-get (plist-get msg :header) :msg_id)))
|
||||
(run-hook-with-args 'ein:pre-kernel-execute-functions msg)
|
||||
(ein:websocket-send-shell-channel kernel msg)
|
||||
(unless (plist-get callbacks :execute_reply)
|
||||
(ein:log 'debug "code: %s" code))
|
||||
(ein:kernel-set-callbacks-for-msg kernel msg-id callbacks)
|
||||
(unless silent
|
||||
(mapc #'ein:funcall-packed
|
||||
(ein:$kernel-after-execute-hook kernel)))
|
||||
msg-id)
|
||||
(message "[ein]: stdin active, cannot communicate with kernel.")))
|
||||
|
||||
(let* ((content (list
|
||||
:code code
|
||||
:silent (or silent json-false)
|
||||
:store_history (or store-history json-false)
|
||||
:user_expressions user-expressions
|
||||
:allow_stdin allow-stdin
|
||||
:stop_on_error (or stop-on-error json-false)))
|
||||
(msg (ein:kernel--get-msg kernel "execute_request" content))
|
||||
(msg-id (plist-get (plist-get msg :header) :msg_id)))
|
||||
(ein:log 'debug "KERNEL-EXECUTE: code=%s msg_id=%s" code msg-id)
|
||||
(run-hook-with-args 'ein:pre-kernel-execute-functions msg)
|
||||
(ein:websocket-send-shell-channel kernel msg)
|
||||
(ein:kernel-set-callbacks-for-msg kernel msg-id callbacks)
|
||||
(unless silent
|
||||
(mapc #'ein:funcall-packed
|
||||
(ein:$kernel-after-execute-hook kernel)))
|
||||
msg-id))
|
||||
|
||||
(defun ein:kernel-complete (kernel line cursor-pos callbacks)
|
||||
"Complete code at CURSOR-POS in a string LINE on KERNEL.
|
||||
|
@ -736,6 +732,8 @@ Example::
|
|||
(let ((msg-type (plist-get header :msg_type))
|
||||
(msg-id (plist-get header :msg_id))
|
||||
(password (plist-get content :password)))
|
||||
(ein:log 'debug "KERNEL--HANDLE-STDIN-REPLY: msg_type=%s msg_id=%s"
|
||||
msg-type msg-id)
|
||||
(cond ((string-equal msg-type "input_request")
|
||||
(if (not (eql password :json-false))
|
||||
(let* ((passwd (read-passwd (plist-get content :prompt)))
|
||||
|
@ -760,12 +758,10 @@ Example::
|
|||
(msg-id (plist-get parent_header :msg_id))
|
||||
(callbacks (ein:kernel-get-callbacks-for-msg kernel msg-id))
|
||||
(cb (plist-get callbacks (intern (format ":%s" msg-type)))))
|
||||
(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:log 'debug "KERNEL--HANDLE-SHELL-REPLY: msg_type = %s" msg-type)
|
||||
(if cb
|
||||
(ein:funcall-packed cb content metadata)
|
||||
(ein:log 'debug "no callback for: msg_type=%s msg_id=%s"
|
||||
msg-type msg-id))
|
||||
(ein:aif cb (ein:funcall-packed it content metadata))
|
||||
(ein:aif (plist-get content :payload)
|
||||
(ein:kernel--handle-payload kernel callbacks it))
|
||||
(let ((events (ein:$kernel-events kernel)))
|
||||
|
@ -806,10 +802,11 @@ Example::
|
|||
(&key content metadata parent_header header &allow-other-keys)
|
||||
(ein:json-read-from-string packet)
|
||||
(let* ((msg-type (plist-get header :msg_type))
|
||||
(callbacks (ein:kernel-get-callbacks-for-msg
|
||||
kernel (plist-get parent_header :msg_id)))
|
||||
(msg-id (plist-get parent_header :msg_id))
|
||||
(callbacks (ein:kernel-get-callbacks-for-msg kernel msg-id))
|
||||
(events (ein:$kernel-events kernel)))
|
||||
(ein:log 'debug "KERNEL--HANDLE-IOPUB-REPLY: msg_type = %s" msg-type)
|
||||
(ein:log 'debug "KERNEL--HANDLE-IOPUB-REPLY: msg_type=%s msg_id=%s"
|
||||
msg-type msg-id)
|
||||
(if (and (not (equal msg-type "status")) (null callbacks))
|
||||
(ein:log 'verbose "Got message not from this notebook.")
|
||||
(ein:case-equal msg-type
|
||||
|
@ -829,8 +826,8 @@ Example::
|
|||
(ein:log 'verbose (format "Received data_pub message w/content %s" packet)))
|
||||
(("clear_output")
|
||||
(ein:aif (plist-get callbacks :clear_output)
|
||||
(ein:funcall-packed it content metadata))))))))
|
||||
(ein:log 'debug "KERNEL--HANDLE-IOPUB-REPLY: finished"))
|
||||
(ein:funcall-packed it content metadata)))))))))
|
||||
(ein:log 'debug "KERNEL--HANDLE-IOPUB-REPLY: finished")
|
||||
|
||||
|
||||
;;; Utility functions
|
||||
|
|
|
@ -188,6 +188,7 @@ Current buffer for these functions is set to the notebook buffer.")
|
|||
|
||||
(ein:deflocal ein:%notebook% nil
|
||||
"Buffer local variable to store an instance of `ein:$notebook'.")
|
||||
|
||||
(define-obsolete-variable-alias 'ein:notebook 'ein:%notebook% "0.1.2")
|
||||
|
||||
|
||||
|
@ -299,6 +300,8 @@ will be updated with kernel's cwd."
|
|||
(defun ein:notebook-open--decorate-callback (notebook existing callback)
|
||||
"In addition to CALLBACK, also pop-to-buffer the new notebook, and save to disk the kernelspec metadata."
|
||||
(apply-partially (lambda (notebook* created callback*)
|
||||
(with-current-buffer (ein:notebook-buffer notebook*)
|
||||
(ein:worksheet-focus-cell))
|
||||
(pop-to-buffer (ein:notebook-buffer notebook*))
|
||||
(ein:aif (ein:$notebook-kernelspec notebook*)
|
||||
(progn
|
||||
|
@ -604,7 +607,6 @@ This is equivalent to do ``C-c`` in the console program."
|
|||
;; Now that major-mode is set, set buffer local variables:
|
||||
(ein:notebook--notification-setup notebook)
|
||||
(ein:notebook-setup-kill-buffer-hook)
|
||||
(ein:notebook--enable-eldoc)
|
||||
(setq ein:%notebook% notebook)))
|
||||
|
||||
(defun ein:notebook--notification-setup (notebook)
|
||||
|
@ -1286,10 +1288,11 @@ Use simple `python-mode' based notebook mode when MuMaMo is not installed::
|
|||
(const :tag "Plain" ein:notebook-plain-mode)))
|
||||
:group 'ein)
|
||||
|
||||
(defcustom ein:notebook-mode-hook nil
|
||||
(defcustom ein:notebook-mode-hook
|
||||
'(ein:worksheet-imenu-setup ein:worksheet-reinstall-which-cell-hook)
|
||||
"Hook for `ein:notebook-mode'.
|
||||
This hook is run regardless the actual major mode used."
|
||||
:type 'hook
|
||||
:type '(repeat function)
|
||||
:group 'ein)
|
||||
|
||||
(defun ein:notebook-choose-mode ()
|
||||
|
@ -1497,6 +1500,20 @@ This hook is run regardless the actual major mode used."
|
|||
))
|
||||
map)
|
||||
|
||||
(defun ein:notebook-configure-eldoc ()
|
||||
"eldoc comments say: Major modes for other languages may use ElDoc by defining an
|
||||
appropriate function as the buffer-local value of `eldoc-documentation-function'."
|
||||
;; TODO
|
||||
(when nil
|
||||
(require 'eldoc nil t)
|
||||
(if (boundp 'eldoc-documentation-function)
|
||||
(setq-local eldoc-documentation-function
|
||||
(apply-partially (lambda (oldfun &rest args)
|
||||
(or (apply #'ein:completer--get-eldoc-signature args)
|
||||
(apply oldfun args)))
|
||||
eldoc-documentation-function))
|
||||
(setq-local eldoc-documentation-function #'ein:completer--get-eldoc-signature))))
|
||||
|
||||
(defun ein:notebook-mode ()
|
||||
(funcall (ein:notebook-choose-mode))
|
||||
(case ein:completion-backend
|
||||
|
@ -1519,11 +1536,9 @@ This hook is run regardless the actual major mode used."
|
|||
(define-key ein:notebook-mode-map it 'anything-ein-kernel-history))
|
||||
(ein:notebook-minor-mode +1)
|
||||
(setq indent-tabs-mode nil) ;; Being T causes problems with Python code.
|
||||
(ein:notebook-configure-eldoc)
|
||||
(run-hooks 'ein:notebook-mode-hook))
|
||||
|
||||
(add-hook 'ein:notebook-mode-hook 'ein:worksheet-imenu-setup)
|
||||
(add-hook 'ein:notebook-mode-hook 'ein:worksheet-reinstall-which-cell-hook)
|
||||
|
||||
(define-minor-mode ein:notebook-minor-mode
|
||||
"Minor mode to install `ein:notebook-mode-map' for `ein:notebook-mode'."
|
||||
:keymap ein:notebook-mode-map
|
||||
|
|
|
@ -57,7 +57,8 @@ S-mouse-1/3 (Shift + left/right click): move this tab to left/right"
|
|||
(defmethod ein:notification-status-set ((ns ein:notification-status) status)
|
||||
(let* ((message (cdr (assoc status (slot-value ns 's2m)))))
|
||||
(setf (slot-value ns 'status) status)
|
||||
(setf (slot-value ns 'message) message)))
|
||||
(setf (slot-value ns 'message) message)
|
||||
(force-mode-line-update)))
|
||||
|
||||
(defmethod ein:notification-bind-events ((notification ein:notification)
|
||||
events)
|
||||
|
|
Loading…
Add table
Reference in a new issue