emacs.d/elpa/ein-20191129.337/ein-inspector.el

126 lines
5 KiB
EmacsLisp
Raw Normal View History

2019-11-30 08:46:49 +01:00
;;; -*- mode: emacs-lisp; lexical-binding: t -*-
;;; ein-inspector.el --- An inspector, in emacs, for Python
;; Copyright (C) 2017 - John Miller
;; Authors: Takafumi Arakaki <aka.tkf at gmail.com>
;; John M. Miller <millejoh at mac.com>
;; This file is NOT part of GNU Emacs.
;; ein-inspector.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-inspector.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-inspector.el. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;;; Code:
(require 'ein-pytools)
;;;###autoload
(defun ein:inspect-object (kernel object)
(interactive (list (ein:get-kernel-or-error)
(ein:object-at-point-or-error)))
(ein:kernel-execute kernel
(format "__import__('ein_inspector').generate_inspector_data('%s', globals(), locals())"
object)
(list
:output
(cons #'ein:prepare-inspector
(list kernel object)))))
(defun ein:prepare-inspector (packed _msg-type content _metadata)
(cl-destructuring-bind (_kernel oname)
packed
(ein:aif (or (plist-get content :text) (plist-get content :data))
(let ((oinfo (ein:json-read-from-string it)))
(if (not (plist-get oinfo :type))
(ein:log 'warn "[EIN:INSPECTOR]: %s" (plist-get oinfo :error))
(ein:render-inspector oinfo)))
(ein:log 'warn "[EIN:INSPECTOR]: Could not find inspect data for object %s." oname))))
(defclass ein:iobject ()
((name :accessor ein:iobject-name :documentation "String representation can be evaluated in python to generate the object being inspected.")
(type :accessor ein:iobject-type :documentation "Python type of object, as returned by `type()`.")
(repr :accessor ein:iobject-repr :documentation "Value of object, as returned by its `__str__` method.")
(source-file :accessor ein:iobject-sfile :documentation "If availabe, the filename where the source for this object is to be found.")
(source-lines :accessor ein:iobject-slines :documentation "If available, the line in the file where the source for this object is found.")
(doc :accessor ein:iobject-doc :documentation "If available, the documentation string for this object."))
:documentation "Class to hold information returned by Python `inspect` module for a Python object identified in the `name` slot.")
(defun ein:new-inspector-object (object-info)
(make-instance 'ein:iobject
:name (plist-get object-info :name)
:type (plist-get object-info :type)
:repr (plist-get object-info :repr)
:source-file (plist-get object-info :source_file)
:source-lines (plist-get object-info :source_lines)
:doc (plist-get object-info :doc)))
(defvar ein:inspector-visit-source-map (make-sparse-keymap))
(defvar ein:inspector-mode-map
(let ((map (make-sparse-keymap)))
(set-keymap-parent map (make-composed-keymap widget-keymap
special-mode-map))
map)
"Keymap for ein:inspector-mode.")
(define-derived-mode ein:inspector-mode special-mode "EIN:INSPECTOR-MODE"
"Major mode for inspector Python objects from the emacs-ipython-notebook."
)
(defun ein:render-inspector (oinfo)
(let ((name (plist-get oinfo :name)))
(switch-to-buffer (format "*EIN Inspector: %s*" name))
(kill-all-local-variables)
(let ((inhibit-read-only t))
(erase-buffer))
(remove-overlays)
(let* ((type (plist-get oinfo :type))
(repr (plist-get oinfo :repr))
(sfile (plist-get oinfo :source_file))
(slines (last (plist-get oinfo :source_lines)))
(info-str (format "%s = {%s} %s" name type repr)))
(if sfile
(widget-create 'link
:notify
(lambda (&rest _ignore)
(ein:goto-file sfile (car slines)))
info-str)
(widget-insert (propertize info-str 'face 'bold)))
(widget-insert (format "\n\n%s\n\n" (make-string 80 ?\u2501)))
(widget-insert (format "%s\n\n%s\n\n" (plist-get oinfo :doc) (make-string 80 ?\u2501)))
(widget-insert (propertize (format "%s: %s\n" type name)
'face 'bold))))
(ein:inspector-mode)
(widget-setup))
(defun ein:inspector-visit-source ()
(message "Visit source!"))
(defun ein:inspector-visit-thing ())
(defun ein:inspector-section-toggle (_section))
(defun ein:inspector-section-show (_section))
(defun ein:inspector-section-hide (_section)
)
(provide 'ein-inspector)