-
Notifications
You must be signed in to change notification settings - Fork 57
/
tooltip.rkt
73 lines (67 loc) · 3.24 KB
/
tooltip.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#lang racket/base
(require syntax/srcloc)
(require racket/logging racket/string)
(require (only-in "basics.rkt" var-name?))
(provide attach-tooltip log-all-tooltips!)
;; Tooltip handling for DrRacket. Tooltips are both logged and expanded so that
;; Emacs can get them from the expanded version and DrRacket can get them from
;; the online expander even if there's an error.
(define-logger online-check-syntax)
(define tooltips-queue (box '()))
(define (keyword? x) (and (symbol? x) (not (var-name? x))))
(define (attach-tooltip stx where msg)
(if (or (and (string? msg) (string=? (string-trim msg) ""))
(eqv? where #f)
(not (source-location? where)))
stx
(let ([tooltip
(cond
[(or (not (syntax? where))
(not (pair? (syntax-e where)))
(let ([fst (car (syntax-e where))])
(and (identifier? fst)
(free-identifier=? fst #'quote))))
(list (vector where
(sub1 (source-location-position where))
(+ (sub1 (source-location-position where)) (source-location-span where))
msg))]
[(and (syntax? where)
(pair? (syntax-e where))
(let ([fst (car (syntax-e where))])
(and (identifier? fst)
(keyword? (syntax-e fst)))))
(let ([fst (car (syntax-e where))])
(list (vector where
(sub1 (source-location-position where))
(+ (sub1 (source-location-position fst))
(source-location-span fst))
msg)
(vector where
(sub1 (+ (sub1 (source-location-position where))
(source-location-span where)))
(+ (sub1 (source-location-position where))
(source-location-span where))
msg)))]
[else
(list (vector where
(sub1 (source-location-position where))
(source-location-position where)
msg)
(vector where
(sub1 (+ (sub1 (source-location-position where))
(source-location-span where)))
(+ (sub1 (source-location-position where))
(source-location-span where))
msg))])])
(set-box! tooltips-queue (append tooltip (unbox tooltips-queue)))
(syntax-property stx
'mouse-over-tooltips
tooltip))))
;; We log all the tooltips at once _after_ type checking to avoid
;; performance issues in DrRacket that occur when logging
;; them individually _during_ type checking.
(define (log-all-tooltips!)
(log-message online-check-syntax-logger
'info
"ignored"
(list (syntax-property #'(void) 'mouse-over-tooltips (unbox tooltips-queue)))))