Personal emacs config
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

125 lines
5.0 KiB

  1. ;;; -*- mode: emacs-lisp; lexical-binding: t -*-
  2. ;;; ein-inspector.el --- An inspector, in emacs, for Python
  3. ;; Copyright (C) 2017 - John Miller
  4. ;; Authors: Takafumi Arakaki <aka.tkf at gmail.com>
  5. ;; John M. Miller <millejoh at mac.com>
  6. ;; This file is NOT part of GNU Emacs.
  7. ;; ein-inspector.el is free software: you can redistribute it and/or modify
  8. ;; it under the terms of the GNU General Public License as published by
  9. ;; the Free Software Foundation, either version 3 of the License, or
  10. ;; (at your option) any later version.
  11. ;; ein-inspector.el is distributed in the hope that it will be useful,
  12. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. ;; GNU General Public License for more details.
  15. ;; You should have received a copy of the GNU General Public License
  16. ;; along with ein-inspector.el. If not, see <http://www.gnu.org/licenses/>.
  17. ;;; Commentary:
  18. ;;; Code:
  19. (require 'ein-pytools)
  20. ;;;###autoload
  21. (defun ein:inspect-object (kernel object)
  22. (interactive (list (ein:get-kernel-or-error)
  23. (ein:object-at-point-or-error)))
  24. (ein:kernel-execute kernel
  25. (format "__import__('ein_inspector').generate_inspector_data('%s', globals(), locals())"
  26. object)
  27. (list
  28. :output
  29. (cons #'ein:prepare-inspector
  30. (list kernel object)))))
  31. (defun ein:prepare-inspector (packed _msg-type content _metadata)
  32. (cl-destructuring-bind (_kernel oname)
  33. packed
  34. (ein:aif (or (plist-get content :text) (plist-get content :data))
  35. (let ((oinfo (ein:json-read-from-string it)))
  36. (if (not (plist-get oinfo :type))
  37. (ein:log 'warn "[EIN:INSPECTOR]: %s" (plist-get oinfo :error))
  38. (ein:render-inspector oinfo)))
  39. (ein:log 'warn "[EIN:INSPECTOR]: Could not find inspect data for object %s." oname))))
  40. (defclass ein:iobject ()
  41. ((name :accessor ein:iobject-name :documentation "String representation can be evaluated in python to generate the object being inspected.")
  42. (type :accessor ein:iobject-type :documentation "Python type of object, as returned by `type()`.")
  43. (repr :accessor ein:iobject-repr :documentation "Value of object, as returned by its `__str__` method.")
  44. (source-file :accessor ein:iobject-sfile :documentation "If availabe, the filename where the source for this object is to be found.")
  45. (source-lines :accessor ein:iobject-slines :documentation "If available, the line in the file where the source for this object is found.")
  46. (doc :accessor ein:iobject-doc :documentation "If available, the documentation string for this object."))
  47. :documentation "Class to hold information returned by Python `inspect` module for a Python object identified in the `name` slot.")
  48. (defun ein:new-inspector-object (object-info)
  49. (make-instance 'ein:iobject
  50. :name (plist-get object-info :name)
  51. :type (plist-get object-info :type)
  52. :repr (plist-get object-info :repr)
  53. :source-file (plist-get object-info :source_file)
  54. :source-lines (plist-get object-info :source_lines)
  55. :doc (plist-get object-info :doc)))
  56. (defvar ein:inspector-visit-source-map (make-sparse-keymap))
  57. (defvar ein:inspector-mode-map
  58. (let ((map (make-sparse-keymap)))
  59. (set-keymap-parent map (make-composed-keymap widget-keymap
  60. special-mode-map))
  61. map)
  62. "Keymap for ein:inspector-mode.")
  63. (define-derived-mode ein:inspector-mode special-mode "EIN:INSPECTOR-MODE"
  64. "Major mode for inspector Python objects from the emacs-ipython-notebook."
  65. )
  66. (defun ein:render-inspector (oinfo)
  67. (let ((name (plist-get oinfo :name)))
  68. (switch-to-buffer (format "*EIN Inspector: %s*" name))
  69. (kill-all-local-variables)
  70. (let ((inhibit-read-only t))
  71. (erase-buffer))
  72. (remove-overlays)
  73. (let* ((type (plist-get oinfo :type))
  74. (repr (plist-get oinfo :repr))
  75. (sfile (plist-get oinfo :source_file))
  76. (slines (last (plist-get oinfo :source_lines)))
  77. (info-str (format "%s = {%s} %s" name type repr)))
  78. (if sfile
  79. (widget-create 'link
  80. :notify
  81. (lambda (&rest _ignore)
  82. (ein:goto-file sfile (car slines)))
  83. info-str)
  84. (widget-insert (propertize info-str 'face 'bold)))
  85. (widget-insert (format "\n\n%s\n\n" (make-string 80 ?\u2501)))
  86. (widget-insert (format "%s\n\n%s\n\n" (plist-get oinfo :doc) (make-string 80 ?\u2501)))
  87. (widget-insert (propertize (format "%s: %s\n" type name)
  88. 'face 'bold))))
  89. (ein:inspector-mode)
  90. (widget-setup))
  91. (defun ein:inspector-visit-source ()
  92. (message "Visit source!"))
  93. (defun ein:inspector-visit-thing ())
  94. (defun ein:inspector-section-toggle (_section))
  95. (defun ein:inspector-section-show (_section))
  96. (defun ein:inspector-section-hide (_section)
  97. )
  98. (provide 'ein-inspector)