-
Notifications
You must be signed in to change notification settings - Fork 184
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create extra regions for diagnostics with tags #1588
Conversation
In a quest to try to make the text color faded without changing the background color or using fill, I've tried the workaround from sublimehq/sublime_text#817 (comment) but it didn't seem to work. flags = (sublime.DRAW_NO_FILL | sublime.DRAW_NO_OUTLINE)
self.view.add_regions(key, data.regions, ' '.join(tag_scopes), flags=flags) {
"scope": "markup.tag.unnecessary.lsp",
"foreground": "color(rgb(120, 120, 120) alpha(0.2)",
"background": "var(blue4)"
} |
Rafal would you like something like this?
you can try it in the ST console:
|
You need to use fill for this to work. But the only way to provide a nice default style for this would be hijacking the color scheme and inject a rule to it, but I would really avoid to do that. This PR with I want to write this in the Packages discussion later, but have some cooking/baking stuff to do first now. |
That works when tested in isolation but not when applying the same scopes to those regions that I'm creating here. Possibly because those are drawn on top of existing diagnostic regions.
I agree but I kinda want it now so if we can find a solution that works partially without affecting normal uses then I'd still want to go with it. As it is now it's affecting normal uses as it creates an extra filled region though...
Yes, but a partial solution that always uses a single color (gray or whatever fits the color scheme) would be sufficient for now IMO. |
Can you extend the test in https://github.com/sublimelsp/LSP/blob/st4000-exploration/tests/test_server_notifications.py ? |
Extending the test revealed something I wasn't aware of before - adding two regions with the same key, at the same position, makes ST consolidate them somehow, resulting in only one region being returned from That also makes the trick that @predragnikolic pointed out work correctly so I guess that's a good thing. Of course, there is still a problem that when there is no style assigned to |
With these extra rules in my color scheme as suggested by @predragnikolic: {
"scope": "markup.tag.unnecessary",
"foreground_adjust": "l(- 40%)",
"background": "#00000001"
}, I get this: Looks pretty good. But if there's no appropriate rule then the default looks jarring I agree. By the way, I don't see the squiggles underneath as in your screenshot. |
In Mariana I've used this override which seems better: {
"scope": "markup.tag.unnecessary.lsp",
"foreground": "color(rgb(255, 255, 255) alpha(0.4))",
"background": "color(var(blue3) alpha(0.9))"
}, |
The squiggles appear only if the diagnostic region is added after the tag region. If you create an unused variable then the squiggles will show because there will be those two diagnostics sent, first with the tag and the second without: {
"message": "\"unuseds\" is not accessed",
"range": {
"end": {
"character": 23,
"line": 120
},
"start": {
"character": 16,
"line": 120
}
},
"severity": 4,
"source": "Pyright",
"tags": [
1
]
},
{
"code": "reportUnusedVariable",
"codeDescription": {
"href": "https://github.com/microsoft/pyright/blob/master/docs/configuration.md"
},
"message": "Variable \"unuseds\" is not accessed",
"range": {
"end": {
"character": 23,
"line": 120
},
"start": {
"character": 16,
"line": 120
}
},
"severity": 3,
"source": "Pyright"
} So I guess I can try to create tag diagnostics first. |
Your implementation for this is wrong. The reason why the squiggly underline can only sometimes be seen is the same as explained in #1585. So the only way to solve this would be to create empty regions for all of the "tag" keys whenever a view gets opened, before any other diagnostics are reported. I don't think the And what's the plan with this PR in general? I guess 99% of color schemes won't have rules for these scopes in the foreseeable future, and then the background will use the global foreground color which looks just ugly. |
There is a defined order to diagnostic regions creation. First, we are adding regions for errors, then warnings, infos, and hints. Any of those can also include an "unnecessary" or "deprecated" tag. As long as we create that region before the actual diagnostic, it should be fine. Unless the later diagnostic is added at the exact same region in which case it won't work entirely correct.
I don't have a strong preference and don't mind tweaking that.
I hoped we could find a way to introduce those scopes without affecting setups that don't have scheme customizations but if that's not possible then I guess I'll have to admit defeat and wait for a proper API for that. |
Not sure if I understand exactly what you mean with this, however my experiments showed that the order when a specific regions key is created the first time for a particular view, is the crucial point. You can try that yourself:
Then you should see that the tag-diagnostic will still be drawn on top.
I can think of only one "trick" how you could do some styling with regions without having color schemes affected that don't have the corresponding scope. You can try the scope |
Have you tried my latest suggestion and would it be a sufficient alternative? I had another idea how to allow special highlighting for diagnostic tags without bad side effects if there's no color scheme rule, hacking into user's color schemes, or waiting for an API update: if "background" in view.style_for_scope("markup.unnecessary.lsp"):
view.add_regions(..., scope="markup.unnecessary.lsp", flags=sublime.DRAW_NO_OUTLINE) # regions with "unnecessary" tag
if "background" in view.style_for_scope("markup.deprecated.lsp"):
view.add_regions(..., scope="markup.deprecated.lsp", flags=sublime.DRAW_NO_OUTLINE) # regions with "deprecated" tag The above scopes seem uncommon enough to only have a background color if someone really intends to tweak the look for this LSP workaround (they would also match in case someone had a rule for only "markup" - but that's quite unlikely I think). |
I haven't tried but since you said that only the background can be changed then it wouldn't really be enough because I want to fade out the foreground color. Your latest trick looks quite nice though. I'll play with it at some point. |
I suppose there might still an issue with the order the diagnostic and tag regions are drawn in some cases. Will have to check it out later. |
Can you think of any way I could reproduce that? The error diagnostics disappear when I make the code unused because pyright does no longer report them so I'm not sure how this can be reproduced. |
But the reported tag is always a part of a diagnostic, so how can pyright no longer report the diagnostic for it? To ensure that I understand correctly, you want to achieve the following, right? I.e. have a region to adjust the foreground color via a color scheme rule, but the squiggle or box for the corresponding diagnostic severity should still always be drawn on top of that region so that it's still visible. First you need to find out which severity the reported diagnostics with the "unnecessary" tag from pyright have (probably "information" or "hint"). Then you could either produce any other diagnostic with that same severity, but no tag, in a new file, or in case such a diagnostic doesn't exist for pyright, you could also override the severity for any diagnostic type via the "python.analysis.diagnosticSeverityOverrides" setting. So for example assign the corresponding severity to a syntax error diagnostic, and then in a new file produce that syntax error first, and afterwards the diagnostic with a tag. Edit 1: Maybe my description from the previous comment was a bit confusing because the "overlapping" regions referred more to the same problem for the documentHighlight regions pointed out before. But in this case here with the diagnostics with tags, the regions (i.e. their positions) are actually the exact same, because we want to draw two seperate regions on top of each other from a single diagnostic. Edit 2: Okay, now I understand what you meant with that pyright no longer reports the diagnostic. I guess this missunderstanding was caused because my "overlapping regions" from above was unclear and misleading. So to sum up, we want to ensure that the first time when the tag-diagnostic regions keys are created, happens always before when the tag-less region keys get created the first time. This is only an issue if a language server uses a certain severity of tag-diagnostics (probably "hint" or "information") not exclusively for those, but also for other tag-less diagnostics. Because in this case the tag-less diagnostics might occur before any of the tag-diagnostics, and therefore will always kept to be drawn "on the bottom". This may not be a problem for pyright if all tag-less diagnostics have another severity. I have not tested whether |
I created an issue for this at #1593. A proper solution should also include the regions from dcoument highlights, because the dimmed foreground for "unnecessary" tags and the style for document highlights can probably not be displayed at the same time if used for a single token. |
Created some snippets for pasting into the console as I can't be bothered to try to find a way to force the server into doing things in the right order... # diagnostic - box
view.add_regions("diag", [sublime.Region(0, 100)], scope="region.bluish markup.info.hint.lsp", flags=33)
# diagnostic - squiglly
view.add_regions("diag", [sublime.Region(0, 100)], scope="region.bluish markup.info.hint.lsp", flags=2337)
# tag
view.add_regions("diag_tags", [sublime.Region(0, 100)], scope="markup.unnecessary.lsp", flags=256)
# document highlight
view.add_regions("highlight_read", [sublime.Region(0, 100)], scope="region.greenish markup.highlight.read.lsp", flags=800)
The tag region will override document highlight or diagnostic if created later than those, unfortunately. |
I suppose some central region manager could solve the ordering issue but it would incur some overhead since we would have to in some cases remove some regions and re-apply them in different order. EDIT: I've just read your #1593 which shows that there is more to it than I thought. |
I'm thinking that we don't need two separate regions if the diagnostic includes the "Unnecessary" tag. We can just create one with relevant scopes. That would somewhat solve the main issue here. |
Yes, that sounds like the easiest and best option for now. This would have the same effect as drawing the "filled" region always on top and hiding the squiggly/underline/box, but this is exactly what is recommended in the specs for it. I haven't digged deep into the code how the general diagnostics logic is implemented, but may there still be a logical error in the implementation right now? From this PR I see simplified: for severity in reversed(range(1, len(DIAGNOSTIC_SEVERITY) + 1)):
data = data_per_severity.get(severity)
# ...
if data.tags:
# ...
if tag_scopes:
self.view.add_regions(key_tag, data.regions, ' '.join(tag_scopes), flags=sublime.DRAW_NO_OUTLINE)
else:
# allow showing diagnostics with same begin and end range in the view
flags |= sublime.DRAW_EMPTY
self.view.add_regions(key, data.regions, data.scope, data.icon, flags) So that looks like to me as if now all diagnostics of a particular severity will be drawn with the "filled" (unnecessary/deprecated) style (if supported by the color scheme), even when only a single diagnostic of that severity has the tag. What if a server reports some diagnostics without tags, and some other diagnostics with tags, but all with the same severity? Not sure where/how the |
That's true. Good catch. |
The updated logic should be correct although I feel the code is getting messy and harder to follow... |
I think I won't come up with anything better so either we go with this or scrap the idea and wait for some native API instead. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't tested it but I added some suggestions. When these are addressed, maybe we should just try it, and if anything odd shows up we can always adjust or revert the PR later. Not sure if any API update is planned or considered for this by SublimeHQ in the future. So if the diagnostic tag styling should be implemented, then this workaround is probably the only way for now.
Co-authored-by: jwortmann <jwortmann@outlook.com>
Co-authored-by: Raoul Wols <raoulwols@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's try it out
Creates extra regions with tag-specific scopes so that it's possible to target unused imports or variables with a scheme customizations.
I probably don't consider it ready yet because it has some drawbacks.
The style above is with this scheme customization: