Merge branch 'input-history'

* New kernel API ein:kernel-history-request is introduced
* History can be inserted into the current buffer using M-p/n
This commit is contained in:
Takafumi Arakaki 2012-08-28 14:37:17 +02:00
commit 92e1d097e5
5 changed files with 118 additions and 1 deletions

View file

@ -498,6 +498,10 @@ Change Log
v0.2
----
* Support execution history. Commands
:el:symbol:`ein:worksheet-previous-input-history` and
:el:symbol:`ein:worksheet-next-input-history` can be used
to insert previously executed code into the current cell.
* Add :el:symbol:`ein:pseudo-console-mode`.
* Add "scratch sheet". This acts almost as same as worksheet, but you
don't need to save it. You can use try any code without saving

View file

@ -399,6 +399,50 @@ http://ipython.org/ipython-doc/dev/development/messaging.html#complete
msg-id))
(defun* ein:kernel-history-request (kernel callbacks
&key
(output nil)
(raw t)
(hist-access-type "tail")
session
start
stop
(n 1)
pattern)
"Request execution history to KERNEL.
When calling this method pass a CALLBACKS structure of the form:
(:history_reply (FUNCTION . ARGUMENT))
Call signature::
(`funcall' FUNCTION ARGUMENT CONTENT METADATA)
CONTENT and METADATA are given by `history_reply' message.
`history_reply' message is documented here:
http://ipython.org/ipython-doc/dev/development/messaging.html#history
"
(assert (ein:kernel-live-p kernel) nil "Kernel is not active.")
(let* ((content (list
:output (ein:json-any-to-bool output)
:raw (ein:json-any-to-bool raw)
:hist_access_type hist-access-type
:session session
:start start
:stop stop
:n n
:pattern pattern))
(msg (ein:kernel--get-msg kernel "history_request" content))
(msg-id (plist-get (plist-get msg :header) :msg_id)))
(ein:websocket-send
(ein:$kernel-shell-channel kernel)
(json-encode msg))
(ein:kernel-set-callbacks-for-msg kernel msg-id callbacks)
msg-id))
(defun ein:kernel-interrupt (kernel)
(when (ein:$kernel-running kernel)
(ein:log 'info "Interrupting kernel")

View file

@ -815,6 +815,8 @@ Do not use `python-mode'. Use plain mode when MuMaMo is not installed::
(define-key map (kbd "C-c C-.") 'ein:pytools-jump-to-source-command)
(define-key map "\M-," 'ein:pytools-jump-back-command)
(define-key map (kbd "C-c C-,") 'ein:pytools-jump-back-command)
(define-key map "\M-p" 'ein:worksheet-previous-input-history)
(define-key map "\M-n" 'ein:worksheet-next-input-history)
(define-key map (kbd "C-c C-/") 'ein:notebook-scratchsheet-open)
(easy-menu-define ein:notebook-menu map "EIN Notebook Mode Menu"
`("EIN Notebook"
@ -878,7 +880,11 @@ Do not use `python-mode'. Use plain mode when MuMaMo is not installed::
:active (ein:worksheet-at-codecell-p))
("Jump to definition" ein:pytools-jump-to-source-command)
("Go back to the previous jump point"
ein:pytools-jump-back-command))))
ein:pytools-jump-back-command)
("Previous input history"
ein:worksheet-previous-input-history)
("Next input history"
ein:worksheet-next-input-history))))
("Kernel"
,@(ein:generate-menu
'(("Restart kernel" ein:notebook-restart-kernel-command)

View file

@ -244,6 +244,9 @@ See: http://api.jquery.com/jQuery.ajax/"
(ein:with-json-setting
(json-read-from-string string)))
(defun ein:json-any-to-bool (obj)
(if (and obj (not (eq obj json-false))) t json-false))
(defun ein:json-encode-char (char)
"Fixed `json-encode-char'."
(setq char (json-encode-char0 char 'ucs))

View file

@ -633,6 +633,66 @@ cell bellow."
(mapc #'ein:cell-execute
(ein:filter #'ein:codecell-p (ein:worksheet-get-cells ws))))
(defun ein:worksheet-insert-last-input-history (ws cell index)
"Insert INDEX-th previous history into CELL in worksheet WS."
(ein:kernel-history-request
(oref ws :kernel)
(list
:history_reply
(cons
(lambda (cell content -metadata-not-used-)
(destructuring-bind (session line-number input)
(car (plist-get content :history))
(if (eq (ein:worksheet-get-current-cell) cell)
(ein:cell-set-text cell input)
(ein:log 'warning
"Cursor moved from the cell after history request."))
(ein:log 'info "Input history inserted: session:%d line:%d"
session line-number)))
cell))
:hist-access-type "range"
:session 0
:start (- index)
:stop (- 1 index)))
(defvar ein:worksheet--history-index 1)
(defun ein:worksheet--get-history-index (inc)
"Increment history index by (possibly negative) INC.
Get history index for `ein:worksheet-previous-input-history' and
`ein:worksheet-next-input-history'. Raise error if caller tries
to decrement index to less than or equal to 1."
(if (or (eq last-command 'ein:worksheet-previous-input-history)
(eq last-command 'ein:worksheet-next-input-history))
(progn
(setq ein:worksheet--history-index
(+ ein:worksheet--history-index inc))
(when (< ein:worksheet--history-index 1)
(setq ein:worksheet--history-index 1)
(error "This is the latest input"))
ein:worksheet--history-index)
(setq ein:worksheet--history-index 1)))
(defun ein:worksheet-previous-input-history (ws cell index)
"Insert the previous input in the execution history.
You can go back further in the history by repeating this command.
Use `ein:worksheet-next-input-history' to go forward in the
history."
(interactive (list (ein:worksheet--get-ws-or-error)
(ein:worksheet-get-current-cell)
(ein:worksheet--get-history-index +1)))
(ein:worksheet-insert-last-input-history ws cell index))
(defun ein:worksheet-next-input-history (ws cell index)
"Insert next input in the execution history.
You can go forward further in the history by repeating this
command. Use `ein:worksheet-previous-input-history' to go back
in the history."
(interactive (list (ein:worksheet--get-ws-or-error)
(ein:worksheet-get-current-cell)
(ein:worksheet--get-history-index -1)))
(ein:worksheet-insert-last-input-history ws cell index))
;;; Generic getter