emacs-ipython-notebook/ein-events.el
2012-05-22 23:03:21 +02:00

130 lines
4.4 KiB
EmacsLisp
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;;; ein-events.el --- Event module
;; Copyright (C) 2012- Takafumi Arakaki
;; Author: Takafumi Arakaki
;; This file is NOT part of GNU Emacs.
;; ein-events.el is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; ein-events.el is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with ein-events.el. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;;
;;; Code:
(eval-when-compile (require 'cl))
(require 'eieio)
(require 'ein-log)
(require 'ein-utils)
(defvar ein:header-line-format '(:eval (ein:header-line)))
(defun ein:header-line ()
(format
"IP[y]: %s"
(ein:join-str
" | "
(ein:filter
'identity
(list (ein:events-header-message-notebook)
(ein:events-header-message-kernel))))))
(defun ein:header-line-setup-maybe ()
"Setup `header-line-format' for mumamo.
As `header-line-format' is buffer local variable, it must be set
for each chunk when in
See also `ein:ac-setup-maybe'."
(and (ein:eval-if-bound 'ein:notebook)
(ein:eval-if-bound 'mumamo-multi-major-mode)
(setq header-line-format ein:header-line-format)))
(add-hook 'after-change-major-mode-hook 'ein:header-line-setup-maybe)
;;; Events handling class
(ein:deflocal ein:@events nil
"Buffer local variable to hold an instance of `ein:events'.")
(defclass ein:events ()
((buffer :initarg :buffer :type buffer :document "Notebook buffer")
(callbacks :initarg :callbacks :type hash-table
:initform (make-hash-table :test 'equal))
(status-notebook :initarg :status-notebook :initform nil :type symbol)
(status-kernel :initarg :status-kernel :initform nil :type symbol))
"Event handler class.")
(defun ein:events-setup (buffer)
"Make a new event handler instance and setup local variable in the BUFFER.
The newly created instance is returned by this function. Event
handler user must *not* use the buffer local variable directly.
Use the variable returned by this function instead."
(with-current-buffer buffer
(setq ein:@events (ein:events "Events" :buffer buffer))
(setq header-line-format ein:header-line-format)
ein:@events))
(defun ein:events-header-message-notebook ()
(case (oref ein:@events :status-notebook)
(notebook_saving "Saving Notebook...")
(notebook_saved "Notebook is saved")
(notebook_save_failed "Failed to save Notebook!")))
(defun ein:events-header-message-kernel ()
(case (oref ein:@events :status-kernel)
(status_idle nil)
(status_busy "Kernel is busy...")
(status_dead "Kernel is dead. Need restart.")))
(defun ein:events-trigger (events event-type &optional data)
"Trigger EVENT-TYPE and let event handler EVENTS handle that event.
EVENT-TYPE is a cons like \(notebook_saved . Notebook), which is
a direct translation of \"notebook_saved.Notebook\" from the
IPython notebook client JS."
(ein:log 'debug "Event: %S" event-type)
(with-current-buffer (oref events :buffer)
(ein:aif (gethash event-type (oref events :callbacks))
(mapc (lambda (cb-arg) (ein:funcall-packed cb-arg data)) it))
;; FIXME! the following must be put together in the event frame work.
(case (cdr event-type)
(Kernel
(oset events :status-kernel (car event-type)))
(Notebook
(oset events :status-notebook (car event-type)))
(t
(ein:log 'info "Unknown event: %S" event-type)))))
(defmethod ein:events-on ((events ein:events) event-type
callback &optional arg)
"Set event trigger hook.
When EVENT-TYPE is triggered on the event handler EVENTS,
CALLBACK is called. CALLBACK must take two arguments:
ARG as the first argument and DATA, which is passed via
`ein:events-trigger', as the second."
(assert (and (consp event-type)
(symbolp (car event-type))
(symbolp (cdr event-type))))
(let* ((table (oref events :callbacks))
(cbs (gethash event-type table)))
(push (cons callback arg) cbs)
(puthash event-type cbs table)))
(provide 'ein-events)
;;; ein-events.el ends here