Screenshot from the output of @jps’ example(slightly modified).
Dev Build 3118
It seems you have to use ‘<br>’ (not ‘<br/>’).
You can also add more than one phantom line to any given line.
Visually, I would expect the phantoms to take up the full width of the line. I like how the messages line up at the column of the error, but the background doesn’t stretch across and it just kinda sits there. I should just let you do your job, but there’s my input anyway.
I believe that should be the case with LAYOUT_BLOCK
, however there may have been a reason Jon decided not to make that implementation change. I’ll update you once I discuss it with him.
Btw, a LAYOUT_ABOVE and LAYOUT_BLOCKABOVE option would be great too. (Possibly with a better name.)
It’s not hard to simulate LAYOUT_BLOCKABOVE (except for the first line), but it’s still a trick (it does not ‘follow’ if you add a line above). And you can’t emulate LAYOUT_ABOVE.
Nonetheless, a very welcome addition, thanks!
It may be confusing for users to not know if the phantom applies to the content above or below.
Indeed, same as it is now. Maybe adding an arrow (like in chat bubbles), at least for non-block layouts:
For block layouts, the text is usually less ambiguous.
One use case I think of for LAYOUT_BLOCKABOVE is displaying scm information (last commit modifying a function, for example). Displaying it below the function header looks strange (even more so if you have parameters spanning over more than one line).
Just a wish anyway
Is there some reason I’m not seeing inline errors?
If I’m not mistaken the inline errors are supposed to appear in the file when you run exec or a build system, correct?
Right now I am building my cpp files with a python script I wrote that runs a bat file via the exec command.
But I have also tried to build with a custom build system that just runs the bat file.
If I’m understanding correctly and should be seeing the inline errors is there any information that would be helpful in finding out why I can’t see them?
I’m seeing weird behavior with phantoms that I absolutely cannot explain. I was experimenting with the sample script in OP when I noticed that upon reloading the file, the phantoms’ contents were changed. Yet, I cannot find anything in the code that could reflect such a change.
In the following video you’ll notice that the phantom views change whenever I save the file (and cause it to be reloaded). I added a few debug prints showing that the geenrated phantoms seems to be correct.
The __del__
addition isn’t relevant as it also happens without.
(double-click to enlarge)
Code:
import sublime
import sublime_plugin
KEY = "phantom_test"
class ViewCalculator(sublime_plugin.ViewEventListener):
def __init__(self, view):
self.view = view
self.phantom_set = sublime.PhantomSet(view, KEY)
self.timeout_scheduled = False
self.needs_update = False
# view.erase_phantoms(KEY)
self.update_phantoms()
def __del__(self):
self.view.erase_phantoms(KEY)
@classmethod
def is_applicable(cls, settings):
syntax = settings.get('syntax')
return syntax == 'Packages/Text/Plain text.tmLanguage'
def update_phantoms(self):
phantoms = []
# Don't do any calculations on 1MB or larger files
if self.view.size() < 2**20:
candidates = self.view.find_all('=>')
vals = []
for r in candidates:
line_region = self.view.line(r.a)
line = self.view.substr(line_region)
idx = r.a - line_region.a
if idx != -1:
val = len(line[:idx].strip())
vals.append(val)
phantoms.append(sublime.Phantom(
sublime.Region(r.a + 2),
str(val),
sublime.LAYOUT_INLINE))
print(vals)
self.phantom_set.update(phantoms)
print(self.view.query_phantoms([p.id for p in phantoms]))
print([p.content for p in phantoms])
def handle_timeout(self):
self.timeout_scheduled = False
if self.needs_update:
self.needs_update = False
self.update_phantoms()
def on_modified(self):
# Call update_phantoms(), but not any more than 10 times a second
if self.timeout_scheduled:
self.needs_update = True
else:
sublime.set_timeout(lambda: self.handle_timeout(), 100)
self.update_phantoms()
try without the CDATA
<key>popupCss</key>
<string>
html {
background-color: #42342C;
color: #BDAE9D;
}
a {
color: #43A8ED;
}
.error, .deleted {
color: #D44949;
}
.success, .inserted {
color: #049B0A;
}
.warning, .modified {
color: #FF9358;
}
</string>
Here is my Sublime-Evaluate plugin, using Phantoms:
from __future__ import division
import sublime
import sublime_plugin
import threading
import math
import datetime
sublime_version = 2
if not sublime.version() or int(sublime.version()) > 3000:
sublime_version = 3
class EvaluateCommandPhantom(sublime_plugin.ViewEventListener):
def __init__(self, view):
self.view = view
self.phantom_set = sublime.PhantomSet(view)
self.timeout_scheduled = False
self.needs_update = False
self.update_phantoms()
@classmethod
def is_applicable(cls, settings):
return True
def update_phantoms(self):
phantoms = []
if self.view.size() < 2**20:
candidates = self.view.find_all('=>')
for r in candidates:
line_region = self.view.line(r.a)
line = self.view.substr(line_region)
idx = r.a - line_region.a
if idx != -1:
val = line[0:idx].strip()
op_pt = line_region.a + idx
thread = EvaluateCall(val, 5)
thread.start()
phantoms.append(sublime.Phantom(
sublime.Region(op_pt + 2),
'<span class="success">%s</span>' % str(thread.result),
sublime.LAYOUT_BLOCK))
self.phantom_set.update(phantoms)
def handle_timeout(self):
self.timeout_scheduled = False
if self.needs_update:
self.needs_update = False
self.update_phantoms()
def on_modified(self):
# Call update_phantoms(), but not any more than 10 times a second
if self.timeout_scheduled:
self.needs_update = True
else:
sublime.set_timeout(lambda: self.handle_timeout(), 100)
self.update_phantoms()
class EvaluateCall(threading.Thread):
def __init__(self, string, timeout):
self.original = string
self.timeout = timeout
self.result = self.original # Default result
threading.Thread.__init__(self)
def run(self):
try:
tmp_global = {
"math": math,
"datetime": datetime
}
code = compile(self.original, '<string>', 'eval')
self.result = eval(code, tmp_global)
except (ValueError, SyntaxError):
pass
return
I can confirm this strange behaviour, even with the example code posted at the top of this thread.
@wbond: Question about the improved styling (which is highly appreciated). Is it going to be possible to have a <code>...</code>
section or something in tooltips etc that use the same syntax highlighting as in the ST syntax and color scheme? That would be pretty good. Maybe with something like class="Python"
for Python.sublime-syntax
.
You can actually do this currently with mdpopups if you have the Sublime syntax highlighter enabled in your preference file. There is a mapping file that takes care of the conversion of short names to the syntax highlighter: https://github.com/facelessuser/sublime-markdown-popups/blob/master/st3/mdpopups/st_mapping.py. This mapping obviously can be expanded by forking and also extended locally in the Preferences.sublime-settings
file.
There are a few quirks due to Sublime’s limited tooltip CSS, but generally it works pretty good.
With that said, a native implementation would be really nice as well.
nop, the SL is already supported by the scheme, so this is the only copy the sublime use.
Ah, it’s really strange. Here’s my popup styling and it works as expected: https://github.com/oivva/boxy/blob/dev/schemes/Boxy%20Monokai.YAML-tmTheme
Clear cache or ⌘+Q?