Sublime Forum

ColorHelper 2.0.0

#1

ColorHelper 2.0.0 has been released with a new feature. ColorHelper can now show inline color previews in code via ST3 3118+ phantoms. It doesn’t muck with your color scheme. It doesn’t take up space in your gutter. Right next to every recognized color, you will get a preview. You can click that preview and open the ColorHelper popup. It tries to be kind and only loads up previews in your viewable window when you scroll, and those will persist until you edit the document. When editing, all will be cleared and it will once again load on demand as you scroll.

If you find it too much, just disable it in your settings file. Please report any bugs as this is a new feature, so there is likely to be some bugs that I missed.

https://packagecontrol.io/packages/ColorHelper

19 Likes

#2

sweet! nice work @facelessuser and awesome use of phantoms!

0 Likes

#3

Looks really good! Is there any support for short #777 format colours?

Generally I find that there is a lot of movement with this feature. I have some suggestions:

  • make all colour previews load at once, rather than on-scroll
  • don’t delete then replace all phantoms on edit - maybe you could check on each edit whether it has invalidated some phantom region, or created a new colour, and replace/add a single phantom
  • the phantoms seem slightly larger than the line height, which causes the text to shift on screen as they are created. They would look more natural if they could be roughly aligned with the font baseline somehow, and were small enough to not cause the line height to change when inserted.
  • add YAML/JSON files to the list of default files with colours in them, since these are used a lot for making colour schemes. It took me a while to figure out how to add YAML files to the list.

That said though, great work, this is already super useful for me.

2 Likes

#4

Tested. It does support the short formatted.

0 Likes

#5

@315234 I would first start by saying if you read the documentation, a lot of your questions will be answered :wink: , but I will go ahead and answer them.

EDIT: I do want to say that this is the first iteration. In the future, when I get time (and feel like it :wink:), if I am able to improve preview load, I will. My statements below relating to this isn’t to say the current implementation is the best and only way. I have thought about this, but I haven’t tried all options yet even if I considered them. What I have picked is what I feel works best for now and what I felt like doing to get it out the door.

Yes. And rgb, and rgba, and hsl, and hsla, etc.

This sounds like a good idea until you’'re in a large file and this is executing on every edit event. Regardless, at the moment, this is the direction I’ve taken as I prefer this way.

Phantoms lag on insertion. Even if you generate everything really fast, some machines will lag more than others and the phantom may get inserted in the wrong place as I am doing some of this asynchronously. Trying to determine on every edit what was changed and figure out which phantoms were invalidated and then generate previews and insert them into the view fast enough is difficult (remember sublime takes your text for the phantoms and then generates the HTML popup, so you have to wait for that too). Above all I want this not to bog down the editor. I don’t think I am interested in also wasting time on every edit trying to determine how many lines got edited etc. Even if I am fast enough, I still have to wait for Sublime to insert the phantoms. I tried to block and insert phantoms originally, and on some systems there was notable lag as it I had to wait for Sublime to insert the phantoms. So now that I asynchronously insert them edits between can change by insertion point. On some machines (like an i7 processor) there is less of a lag, but still. Anyways, as stated earlier, this is the direction I’ve take at the moment.

I won’t go in to details, but it is really, really difficult to predict exactly how big the images need to be. At first you may think that view.line_height() or using font sizes as a guide is all that you would need, but with testing you will see that on different machines you get different results. And all of your guessing isn’t consistent enough. So if you read the docs, you will see there is a setting where you can tweak the image size for your system. Off the top of my head I think it is called inline_preview_offset.

I won’t go into how ColorHelper detects the colors, but ColorHelper is always going to work better when it can target scoped colors as it will need to search less text, and will be faster. Also, I don’t know if enabling this in all YAML and JSON makes sense as only people working with these files in a very specific way would want color highlighting in these files. These files contain general purpose serialized data content. Yes you could put colors in them (and people do), but there is no reason to assume everyone is and wants this enabled by default. Just because you see a hex color code doesn’t mean it is a hex color. You are welcome to add it to your personal settings if you like as all of this is controlled in the settings file. If you had a specific variant of JSON/YAML format that needed this, a format where it is expected that colors need this, then that would be different. For instance, I do not enable this in all XML, but I do enable this in Sublime tmTheme files (color scheme files) which are XML files.

Anyways, I will mainly leave language/file support up to the community and focus on maintaining the core code. Enabling color highlighting in new files is all done through the settings file. I do accept pull requests, but I am selective over what I accept. I don’t think including all JSON/YAML is a good idea.

1 Like

#6

Thanks @kingkeith!

0 Likes

#7

This looks awesome! Doesn’t seem to work for me though

Traceback (most recent call last):
  File "/Applications/Sublime Text.app/Contents/MacOS/sublime_plugin.py", line 109, in reload_plugin
    m = importlib.import_module(modulename)
  File "./python3.3/importlib/__init__.py", line 90, in import_module
  File "<frozen importlib._bootstrap>", line 1584, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1565, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1532, in _find_and_load_unlocked
  File "/Applications/Sublime Text.app/Contents/MacOS/sublime_plugin.py", line 892, in load_module
    exec(compile(source, source_path, 'exec'), mod.__dict__)
  File "color_helper_insert in ~/Library/Application Support/Sublime Text 3/Installed Packages/ColorHelper.sublime-package", line 9, in <module>
  File "/Applications/Sublime Text.app/Contents/MacOS/sublime_plugin.py", line 892, in load_module
    exec(compile(source, source_path, 'exec'), mod.__dict__)
  File "color_helper_util in ~/Library/Application Support/Sublime Text 3/Installed Packages/ColorHelper.sublime-package", line 11, in <module>
ImportError: cannot import name round_int
reloading plugin ColorHelper.color_helper_picker
Traceback (most recent call last):
  File "/Applications/Sublime Text.app/Contents/MacOS/sublime_plugin.py", line 109, in reload_plugin
    m = importlib.import_module(modulename)
  File "./python3.3/importlib/__init__.py", line 90, in import_module
  File "<frozen importlib._bootstrap>", line 1584, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1565, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1532, in _find_and_load_unlocked
  File "/Applications/Sublime Text.app/Contents/MacOS/sublime_plugin.py", line 892, in load_module
    exec(compile(source, source_path, 'exec'), mod.__dict__)
  File "color_helper_picker in ~/Library/Application Support/Sublime Text 3/Installed Packages/ColorHelper.sublime-package", line 12, in <module>
  File "/Applications/Sublime Text.app/Contents/MacOS/sublime_plugin.py", line 892, in load_module
    exec(compile(source, source_path, 'exec'), mod.__dict__)
  File "color_helper_util in ~/Library/Application Support/Sublime Text 3/Installed Packages/ColorHelper.sublime-package", line 11, in <module>
ImportError: cannot import name round_int
reloading plugin ColorHelper.color_helper_util
Traceback (most recent call last):
  File "/Applications/Sublime Text.app/Contents/MacOS/sublime_plugin.py", line 109, in reload_plugin
    m = importlib.import_module(modulename)
  File "./python3.3/importlib/__init__.py", line 90, in import_module
  File "<frozen importlib._bootstrap>", line 1584, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1565, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1532, in _find_and_load_unlocked
  File "/Applications/Sublime Text.app/Contents/MacOS/sublime_plugin.py", line 892, in load_module
    exec(compile(source, source_path, 'exec'), mod.__dict__)
  File "color_helper_util in ~/Library/Application Support/Sublime Text 3/Installed Packages/ColorHelper.sublime-package", line 11, in <module>
0 Likes

#8

Is this the first time you installed? Did you restart Sublime after installing/upgrading?

If you go to the menu Preferences->Package Settings->ColorHelper->Support Info, you can post your info and maybe that will provide some insight.

0 Likes

#9

I may be able to reduce when all the colors get cleared, but I will still keep the on demand load. I will play with this sometime soon.

0 Likes

#10

I restarted multiple times and also ran “Satisfy dependencies” again. Here are the information from Support Info

  • ST ver.: 3118
  • Platform: osx
  • Arch: x64
  • Plugin ver.: 2.0.0
  • Install via PC: True
  • mdpopups ver.: 1.7.0
  • markdown ver.: 2.6.4
  • pygments ver.: 2.1a0
  • jinja2 ver.: 2.8
0 Likes

#11

Your mdpopups is too old. Delete it from your package folder, rerun satisfy dependencies, and restart. Hopefully that will help.

1 Like

#12

You could add an vertical_offset option, so it could be slightly adjusted per user/platform basis?

0 Likes

#13

There already is an option if you read ahead a little more. Are you requesting it to also be per user/platform?

0 Likes

#14

Prrr, i missed that :smiley:

You can’t just offset the position instead of resizing?

0 Likes

#15

I can’t tell from your video as it is a bit low res. Is there a border around your preview? You may want to update your mdpopups via Satisfy Dependencies. There shouldn’t be any padding on the image.

Anyways, Currently you can resize it either bigger or smaller. I don’t have a vertical offset. Technically I could inject CSS to some padding on top of the image. Is this really needed? Are you just unhappy with the size of the images and want to have a smaller one you can try and center?

0 Likes

#16

Now I got the change to play with it. The problem was that I still had an unpacked version of ColorHelper in the package folder, I think.

Pretty amazing and great to see what can be done with phantoms. Couple of thoughts

  • I guess on_hover doesn’t work for phantoms, right? Otherwise, the tooltip could appear on hover. Not a big difference though.
  • There seems to be two margin lines around the inline color squares. One is black and one is grey. With small font sizes, they take up a substantial portion of the inline preview. Is it possible to reduce this to one line?

  • This is a great illustration of phantoms. The problems you describe in response to @315234 also highlight some of the limitations, I guess. Maybe there is a set of things that could be improved in core ST? How are some of these issues handled in Atom’s Block Decorations?
0 Likes

#17

Probably

I don’t know. I haven’t tried. I’ve thought about switching to hovers, but I it wasn’t on my list for this release, and I haven’t decided yet if that is the direction I’m going. Maybe.

It’s possible. I do it this way to avoid having to detect the background of the place of insertion. With two borders, the images standout on any background. If I reduce to one, I have to make sure it stands out against the background it appears on. I could detect the color of the background where I am inserting the color and then calculate a border that stands out, but I chose this instead. It is possible in the future I may change this. But for the first release, this is what I did.

Maybe. There are some real issues like the fact that I can’t calculate actual font or line height (at least not in a way that translate reliably to px on all machines). Some things might be the approach I took. I can possibly reduce having to wipe all the colors when editing, but there are some situations I need to wipe all: font_size changes, syntax_change, change of ColorHelping settings, etc.

Parsing the whole file instead of on demand on scroll is a personal choice. I feel on demand is better FWIW. Could I scan ahead and parse the whole file in chunks? Sure, I could start chunking the whole file and allow file modifications to stop me and update visible colors and then return to chunking the file, but this was easier. Could I update colors on every edit, sure, but you would get some laggy typing. I’d rather not be aggressive on this event. And I might miss where to insert if I don’t block. It’s just the nature of the event.

I don’t know. Any maybe, like in Sublime, they aren’t always handled well. There may be nothing wrong with how Sublime implements phantoms vs Atom’s Block Decorations, it is more how we as plugin decorates try to abuse it.

0 Likes

#18

@iamntz, @greg_hoch, @315234

I’ve listened and released a new version 2.0.1 to address some of your concerns:

  • Less clearing of inline images (incremental updates)
  • Per os/host setting for inline_preview_offset and graphic_size. See docs for the setting in question.
  • Single border around preview that contrasts with the the theme background.

Hopefully that will improve things. If you find any bugs, please let me know.

2 Likes

#19

Awesome, thanks! It works fantastically now.

0 Likes

#20

Excellent update! I have one request about the color_scanning option. If I want to add one scope but leave the default scopes in tact, I have to copy the entire color_scanning option to the user preference file. I am also going to miss any updates to the default scopes. Why not have two options for color_scanning_default and color_scanning_user (the second one is just [] by default) so that I can add my own scopes to color_scanning_user and leave the default scopes intact?

2 Likes