3
3
import sublime
4
4
5
5
import collections
6
+ import functools
6
7
import html
7
8
import itertools
8
9
import os
27
28
# attached detailed diagnostic information, child notes, etc.
28
29
# - `path`: Absolute path to the file.
29
30
# - `text`: The raw text of the message without any minihtml markup.
30
- # - `phantom_text `: The string used for showing phantoms that includes the
31
+ # - `minihtml_text `: The string used for showing phantoms that includes the
31
32
# minihtml markup.
32
33
# - `output_panel_region`: Optional Sublime Region object that indicates the
33
34
# region in the build output panel that corresponds with this message.
37
38
LINK_PATTERN = r'(https?://[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-zA-Z]{2,6}\b[-a-zA-Z0-9@:%_+.~#?&/=]*)'
38
39
39
40
40
- PHANTOM_TEMPLATE = """
41
+ CSS_TEMPLATE = """
42
+ <style>
43
+ span {{
44
+ font-family: monospace;
45
+ }}
46
+ .rust-error {{
47
+ color: {error_color};
48
+ }}
49
+ .rust-warning {{
50
+ color: {warning_color};
51
+ }}
52
+ .rust-note {{
53
+ color: {note_color};
54
+ }}
55
+ .rust-help {{
56
+ color: {help_color};
57
+ }}
58
+ .rust-link {{
59
+ background-color: var(--background);
60
+ color: var(--bluish);
61
+ text-decoration: none;
62
+ border-radius: 0.5rem;
63
+ padding: 0.1rem 0.3rem;
64
+ border: 1px solid var(--bluish);
65
+ }}
66
+ .rust-links {{
67
+ margin: 0.4rem 0rem;
68
+ }}
69
+ a {{
70
+ text-decoration: inherit;
71
+ padding: 0.35rem 0.5rem 0.45rem 0.5rem;
72
+ position: relative;
73
+ font-weight: bold;
74
+ }}
75
+ {extra_css}
76
+ </style>
41
77
<body id="rust-message">
42
- <style>
43
- span {{
44
- font-family: monospace;
45
- }}
46
- .rust-error {{
47
- color: {error_color};
48
- }}
49
- .rust-warning {{
50
- color: {warning_color};
51
- }}
52
- .rust-note {{
53
- color: {note_color};
54
- }}
55
- .rust-help {{
56
- color: {help_color};
57
- }}
58
- .rust-link {{
59
- background-color: var(--background);
60
- color: var(--bluish);
61
- text-decoration: none;
62
- border-radius: 0.5rem;
63
- padding: 0.1rem 0.3rem;
64
- border: 1px solid var(--bluish);
65
- }}
66
- .rust-links {{
67
- margin: 0.4rem 0rem;
68
- }}
69
- a {{
70
- text-decoration: inherit;
71
- padding: 0.35rem 0.5rem 0.45rem 0.5rem;
72
- position: relative;
73
- font-weight: bold;
74
- }}
75
- </style>
76
78
{content}
77
79
</body>
78
80
"""
79
81
82
+ POPUP_CSS = """
83
+ body {
84
+ margin: 0.25em;
85
+ }
86
+ """
87
+
80
88
81
89
def clear_messages (window ):
82
90
WINDOW_MESSAGES .pop (window .id (), None )
@@ -88,7 +96,7 @@ def clear_messages(window):
88
96
view .erase_regions ('rust-help' )
89
97
90
98
91
- def add_message (window , path , span , level , is_main , text , markup_text , msg_cb ):
99
+ def add_message (window , path , span , level , is_main , text , minihtml_text , msg_cb ):
92
100
"""Add a message to be displayed.
93
101
94
102
:param window: The Sublime window.
@@ -100,7 +108,7 @@ def add_message(window, path, span, level, is_main, text, markup_text, msg_cb):
100
108
:param is_main: If True, this is a top-level message. False is used for
101
109
attached detailed diagnostic information, child notes, etc.
102
110
:param text: The raw text of the message without any minihtml markup.
103
- :param markup_text : The message to display with minihtml markup.
111
+ :param minihtml_text : The message to display with minihtml markup.
104
112
:param msg_cb: Callback that will be given the message. May be None.
105
113
"""
106
114
if 'macros>' in path :
@@ -119,30 +127,21 @@ def add_message(window, path, span, level, is_main, text, markup_text, msg_cb):
119
127
}
120
128
messages = messages_by_path .setdefault (path , [])
121
129
122
- if markup_text :
123
- phantom_text = PHANTOM_TEMPLATE .format (content = markup_text ,
124
- error_color = util .get_setting ('rust_syntax_error_color' , 'var(--redish)' ),
125
- warning_color = util .get_setting ('rust_syntax_warning_color' , 'var(--yellowish)' ),
126
- note_color = util .get_setting ('rust_syntax_note_color' , 'var(--greenish)' ),
127
- help_color = util .get_setting ('rust_syntax_help_color' , 'var(--bluish)' ),
128
- )
129
- else :
130
- phantom_text = None
131
130
to_add = {
132
131
'path' : path ,
133
132
'level' : level ,
134
133
'span' : span ,
135
134
'is_main' : is_main ,
136
135
'text' : text ,
137
- 'phantom_text ' : phantom_text ,
136
+ 'minihtml_text ' : minihtml_text ,
138
137
}
139
138
if _is_duplicate (to_add , messages ):
140
139
# Don't add duplicates.
141
140
return
142
141
messages .append (to_add )
143
142
view = window .find_open_file (path )
144
143
if view :
145
- _show_phantom (view , level , span , phantom_text )
144
+ _show_phantom (view , level , span , minihtml_text )
146
145
if msg_cb :
147
146
msg_cb (to_add )
148
147
@@ -238,11 +237,75 @@ def check_in(region):
238
237
sublime .DRAW_NO_FILL | sublime .DRAW_EMPTY )
239
238
240
239
241
- def _show_phantom (view , level , span , message ):
242
- if util .get_setting ('rust_phantom_style' , 'normal' ) == 'none' :
240
+ def _wrap_css (content , extra_css = '' ):
241
+ """Takes the given minihtml content and places it inside a <body> with the
242
+ appropriate CSS."""
243
+ return CSS_TEMPLATE .format (content = content ,
244
+ error_color = util .get_setting ('rust_syntax_error_color' , 'var(--redish)' ),
245
+ warning_color = util .get_setting ('rust_syntax_warning_color' , 'var(--yellowish)' ),
246
+ note_color = util .get_setting ('rust_syntax_note_color' , 'var(--greenish)' ),
247
+ help_color = util .get_setting ('rust_syntax_help_color' , 'var(--bluish)' ),
248
+ extra_css = extra_css ,
249
+ )
250
+
251
+
252
+ def message_popup (view , point , hover_zone ):
253
+ """Displays a popup if there is a message at the given point."""
254
+ paths = WINDOW_MESSAGES .get (view .window ().id (), {}).get ('paths' , {})
255
+ msgs = paths .get (view .file_name (), [])
256
+
257
+ if hover_zone == sublime .HOVER_GUTTER :
258
+ # Collect all messages on this line.
259
+ row = view .rowcol (point )[0 ]
260
+
261
+ def filter_row (msg ):
262
+ span = msg ['span' ]
263
+ if span :
264
+ return row >= span [0 ][0 ] and row <= span [1 ][0 ]
265
+ else :
266
+ last_row = view .rowcol (view .size ())[0 ]
267
+ return row == last_row
268
+
269
+ msgs = filter (filter_row , msgs )
270
+ else :
271
+ # Collect all messages covering this point.
272
+ def filter_point (msg ):
273
+ span = msg ['span' ]
274
+ if span :
275
+ start_pt = view .text_point (* span [0 ])
276
+ end_pt = view .text_point (* span [1 ])
277
+ return point >= start_pt and point <= end_pt
278
+ else :
279
+ return point == view .size ()
280
+
281
+ msgs = filter (filter_point , msgs )
282
+
283
+ if msgs :
284
+ to_show = '\n ' .join (msg ['minihtml_text' ] for msg in msgs )
285
+ minihtml = _wrap_css (to_show , extra_css = POPUP_CSS )
286
+ on_nav = functools .partial (_click_handler , view , hide_popup = True )
287
+ max_width = view .em_width () * 79
288
+ view .show_popup (minihtml , sublime .COOPERATE_WITH_AUTO_COMPLETE ,
289
+ point , max_width = max_width , on_navigate = on_nav )
290
+
291
+
292
+ def _click_handler (view , url , hide_popup = False ):
293
+ if url == 'hide' :
294
+ clear_messages (view .window ())
295
+ if hide_popup :
296
+ view .hide_popup ()
297
+ elif url .startswith ('file:///' ):
298
+ view .window ().open_file (url [8 :], sublime .ENCODED_POSITION )
299
+ else :
300
+ webbrowser .open_new (url )
301
+
302
+
303
+ def _show_phantom (view , level , span , minihtml_text ):
304
+ if util .get_setting ('rust_phantom_style' , 'normal' ) != 'normal' :
243
305
return
244
- if not message :
306
+ if not minihtml_text :
245
307
return
308
+
246
309
region = _span_to_region (view , span )
247
310
# For some reason if you have a multi-line region, the phantom is only
248
311
# displayed under the first line. I think it makes more sense for the
@@ -256,20 +319,12 @@ def _show_phantom(view, level, span, message):
256
319
region .end ()
257
320
)
258
321
259
- def click_handler (url ):
260
- if url == 'hide' :
261
- clear_messages (view .window ())
262
- elif url .startswith ('file:///' ):
263
- view .window ().open_file (url [8 :], sublime .ENCODED_POSITION )
264
- else :
265
- webbrowser .open_new (url )
266
-
267
322
_sublime_add_phantom (
268
323
view ,
269
324
'rust-syntax-phantom' , region ,
270
- message ,
325
+ _wrap_css ( minihtml_text ) ,
271
326
sublime .LAYOUT_BLOCK ,
272
- click_handler
327
+ functools . partial ( _click_handler , view )
273
328
)
274
329
275
330
@@ -437,7 +492,7 @@ def _show_messages_for_view(view, messages):
437
492
_show_phantom (view ,
438
493
message ['level' ],
439
494
message ['span' ],
440
- message ['phantom_text ' ])
495
+ message ['minihtml_text ' ])
441
496
_draw_region_highlights (view , messages )
442
497
443
498
0 commit comments