Klimi's new dotfiles with stow.
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.

99 lines
3.8 KiB

4 years ago
  1. (eval-and-compile
  2. (require 'slime))
  3. (define-slime-contrib slime-xref-browser
  4. "Xref browsing with tree-widget"
  5. (:authors "Rui Patroc�nio <rui.patrocinio@netvisao.pt>")
  6. (:license "GPL"))
  7. ;;;; classes browser
  8. (defun slime-expand-class-node (widget)
  9. (or (widget-get widget :args)
  10. (let ((name (widget-get widget :tag)))
  11. (cl-loop for kid in (slime-eval `(swank:mop :subclasses ,name))
  12. collect `(tree-widget :tag ,kid
  13. :expander slime-expand-class-node
  14. :has-children t)))))
  15. (defun slime-browse-classes (name)
  16. "Read the name of a class and show its subclasses."
  17. (interactive (list (slime-read-symbol-name "Class Name: ")))
  18. (slime-call-with-browser-setup
  19. (slime-buffer-name :browser) (slime-current-package) "Class Browser"
  20. (lambda ()
  21. (widget-create 'tree-widget :tag name
  22. :expander 'slime-expand-class-node
  23. :has-echildren t))))
  24. (defvar slime-browser-map nil
  25. "Keymap for tree widget browsers")
  26. (require 'tree-widget)
  27. (unless slime-browser-map
  28. (setq slime-browser-map (make-sparse-keymap))
  29. (set-keymap-parent slime-browser-map widget-keymap)
  30. (define-key slime-browser-map "q" 'bury-buffer))
  31. (defun slime-call-with-browser-setup (buffer package title fn)
  32. (switch-to-buffer buffer)
  33. (kill-all-local-variables)
  34. (setq slime-buffer-package package)
  35. (let ((inhibit-read-only t)) (erase-buffer))
  36. (widget-insert title "\n\n")
  37. (save-excursion
  38. (funcall fn))
  39. (lisp-mode-variables t)
  40. (slime-mode t)
  41. (use-local-map slime-browser-map)
  42. (widget-setup))
  43. ;;;; Xref browser
  44. (defun slime-fetch-browsable-xrefs (type name)
  45. "Return a list ((LABEL DSPEC)).
  46. LABEL is just a string for display purposes.
  47. DSPEC can be used to expand the node."
  48. (let ((xrefs '()))
  49. (cl-loop for (_file . specs) in (slime-eval `(swank:xref ,type ,name)) do
  50. (cl-loop for (dspec . _location) in specs do
  51. (let ((exp (ignore-errors (read (downcase dspec)))))
  52. (cond ((and (consp exp) (eq 'flet (car exp)))
  53. ;; we can't expand FLET references so they're useless
  54. )
  55. ((and (consp exp) (eq 'method (car exp)))
  56. ;; this isn't quite right, but good enough for now
  57. (push (list dspec (string (cl-second exp))) xrefs))
  58. (t
  59. (push (list dspec dspec) xrefs))))))
  60. xrefs))
  61. (defun slime-expand-xrefs (widget)
  62. (or (widget-get widget :args)
  63. (let* ((type (widget-get widget :xref-type))
  64. (dspec (widget-get widget :xref-dspec))
  65. (xrefs (slime-fetch-browsable-xrefs type dspec)))
  66. (cl-loop for (label dspec) in xrefs
  67. collect `(tree-widget :tag ,label
  68. :xref-type ,type
  69. :xref-dspec ,dspec
  70. :expander slime-expand-xrefs
  71. :has-children t)))))
  72. (defun slime-browse-xrefs (name type)
  73. "Show the xref graph of a function in a tree widget."
  74. (interactive
  75. (list (slime-read-from-minibuffer "Name: "
  76. (slime-symbol-at-point))
  77. (read (completing-read "Type: " (slime-bogus-completion-alist
  78. '(":callers" ":callees" ":calls"))
  79. nil t ":"))))
  80. (slime-call-with-browser-setup
  81. (slime-buffer-name :xref) (slime-current-package) "Xref Browser"
  82. (lambda ()
  83. (widget-create 'tree-widget :tag name :xref-type type :xref-dspec name
  84. :expander 'slime-expand-xrefs :has-echildren t))))
  85. (provide 'slime-xref-browser)