Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
marvel
GitHub Repository: marvel/qnf
Path: blob/master/elisp/slime/contrib/slime-references.el
990 views
1
2
(define-slime-contrib slime-references
3
"Clickable references to documentation (SBCL only)."
4
(:authors "Christophe Rhodes <[email protected]>"
5
"Luke Gorrie <[email protected]>"
6
"Tobias C. Rittweiler <[email protected]>")
7
(:license "GPL")
8
(:on-load
9
(ad-enable-advice 'slime-note.message 'after 'slime-note.message+references)
10
(ad-activate 'slime-note.message)
11
(setq slime-tree-printer 'slime-tree-print-with-references)
12
(add-hook 'sldb-extras-hooks 'sldb-maybe-insert-references))
13
(:on-unload
14
(ad-disable-advice 'slime-note.message 'after 'slime-note.message+references)
15
(ad-deactivate 'slime-note.message)
16
(setq slime-tree-printer 'slime-tree-default-printer)
17
(remove-hook 'sldb-extras-hooks 'sldb-maybe-insert-references)))
18
19
(defcustom slime-sbcl-manual-root "http://www.sbcl.org/manual/"
20
"*The base URL of the SBCL manual, for documentation lookup."
21
:type 'string
22
:group 'slime-mode)
23
24
(defface sldb-reference-face
25
(list (list t '(:underline t)))
26
"Face for references."
27
:group 'slime-debugger)
28
29
30
;;;;; SBCL-style references
31
32
(defvar slime-references-local-keymap
33
(let ((map (make-sparse-keymap "local keymap for slime references")))
34
(define-key map [mouse-2] 'slime-lookup-reference-at-mouse)
35
(define-key map [return] 'slime-lookup-reference-at-point)
36
map))
37
38
(defun slime-reference-properties (reference)
39
"Return the properties for a reference.
40
Only add clickability to properties we actually know how to lookup."
41
(destructuring-bind (where type what) reference
42
(if (or (and (eq where :sbcl) (eq type :node))
43
(and (eq where :ansi-cl)
44
(memq type '(:function :special-operator :macro
45
:section :glossary :issue))))
46
`(slime-reference ,reference
47
font-lock-face sldb-reference-face
48
follow-link t
49
mouse-face highlight
50
help-echo "mouse-2: visit documentation."
51
keymap ,slime-references-local-keymap))))
52
53
(defun slime-insert-reference (reference)
54
"Insert documentation reference from a condition.
55
See SWANK-BACKEND:CONDITION-REFERENCES for the datatype."
56
(destructuring-bind (where type what) reference
57
(insert "\n" (slime-format-reference-source where) ", ")
58
(slime-insert-propertized (slime-reference-properties reference)
59
(slime-format-reference-node what))
60
(insert (format " [%s]" type))))
61
62
(defun slime-insert-references (references)
63
(when references
64
(insert "\nSee also:")
65
(slime-with-rigid-indentation 2
66
(mapc #'slime-insert-reference references))))
67
68
(defun slime-format-reference-source (where)
69
(case where
70
(:amop "The Art of the Metaobject Protocol")
71
(:ansi-cl "Common Lisp Hyperspec")
72
(:sbcl "SBCL Manual")
73
(t (format "%S" where))))
74
75
(defun slime-format-reference-node (what)
76
(if (listp what)
77
(mapconcat #'prin1-to-string what ".")
78
what))
79
80
(defun slime-lookup-reference-at-point ()
81
"Browse the documentation reference at point."
82
(interactive)
83
(let ((refs (get-text-property (point) 'slime-reference)))
84
(if (null refs)
85
(error "No references at point")
86
(destructuring-bind (where type what) refs
87
(case where
88
(:ansi-cl
89
(case type
90
(:section
91
(browse-url (funcall common-lisp-hyperspec-section-fun what)))
92
(:glossary
93
(browse-url (funcall common-lisp-glossary-fun what)))
94
(:issue
95
(browse-url (funcall 'common-lisp-issuex what)))
96
(t
97
(hyperspec-lookup what))))
98
(t
99
(let ((url (format "%s%s.html" slime-sbcl-manual-root
100
(subst-char-in-string ?\ ?\- what))))
101
(browse-url url))))))))
102
103
(defun slime-lookup-reference-at-mouse (event)
104
"Invoke the action pointed at by the mouse."
105
(interactive "e")
106
(destructuring-bind (mouse-1 (w pos . _) . _) event
107
(save-excursion
108
(goto-char pos)
109
(slime-lookup-reference-at-point))))
110
111
;;;;; Hook into *SLIME COMPILATION*
112
113
(defun slime-note.references (note)
114
(plist-get note :references))
115
116
;;; FIXME: `compilation-mode' will swallow the `mouse-face'
117
;;; etc. properties.
118
(defadvice slime-note.message (after slime-note.message+references)
119
(setq ad-return-value
120
(concat ad-return-value
121
(with-temp-buffer
122
(slime-insert-references
123
(slime-note.references (ad-get-arg 0)))
124
(buffer-string)))))
125
126
;;;;; Hook into slime-compiler-notes-tree
127
128
(defun slime-tree-print-with-references (tree)
129
;; for SBCL-style references
130
(slime-tree-default-printer tree)
131
(when-let (note (plist-get (slime-tree.plist tree) 'note))
132
(when-let (references (slime-note.references note))
133
(terpri (current-buffer))
134
(slime-insert-references references))))
135
136
;;;;; Hook into SLDB
137
138
(defun sldb-maybe-insert-references (extra)
139
(destructure-case extra
140
((:references references) (slime-insert-references references) t)
141
(t nil)))
142
143
(provide 'slime-references)
144