Symbol occurrence highlighting overlaps occurrences of the selected text
See original GitHub issueWhen selecting text or placing the cursor on a symbol with the C/C++ extension disabled, the other occurrences of the symbol are highlighted, or if there is a selection, the occurrences of the selection are highlighted. The selection is highlighted with the regular selection highlight color (editor.selectionBackground
), and the occurrences are highlighted using the occurrences highlight color (editor.selectionHighlightBackground
).
With the C/C++ extension enabled, if the global setting Editor: Occurrences Highlight
is enabled, VS Code will always do both, with the symbolic occurrence highlighting rendered after the selection highlight, and all occurrences of both the selected text, and the symbol are highlighted in the same style, with no way to differentiate between them. This causes the selected text, which is more specific, and a direct result of a user action, and therefore arguably higher precedence, to be completely obscured by the symbol occurrence provided by the extension, which is arguably lower precedence.
Here, in an unsaved buffer, with the language set to C
, the behavior is predictable and correct. When placing the cursor on an occurrence of a symbol with no selection, the other occurrences of the symbol are highlighted:
Here, in the same unsaved buffer, part of the symbol foo
is selected. The behavior is still predictable and correct. The other occurrences of the selection are highlighted in the highlight color (editor.selectionHighlightBackground
), and the selection itself is highlighted in the selection color (editor.selectionBackground
):
Likewise, if the entire symbol foo
is selected, the behavior is still as expected, with the selection itself highlighted with the selection color, and the other occurrences of the selection highlighted in the highlight color:
If the file is saved, and the C/C++ extension becomes enabled for the file, the behavior becomes problematic. Here, as in the first example, the cursor is placed within a symbol, but no selection is made. The behavior is as expected, with the symbol and all other occurrences highlighted in the highlight color:
Here, when part of the symbol is selected in the saved file, the symbol occurrences overlap the selection occurrences. The first two characters of the symbol foo
are selected, but due to the overlapping, both the selection is obscured, and additionally, there are now two different occurrences being highlighted throughout the file at the same time, in the same color and style (both the selection, fo
, and the symbol, foo
), making them impossible to differentiate:
Here, when the entire symbol is selected, the selection color is lost, so it is impossible to identify which text is selected:
If both colors are made to be transparent, or a highlight border is added, it becomes obvious that both highlight actions are taking place, first the selection occurrences, then the symbolic occurrences (there is also a noticeable delay for the second highlight, so the selection highlighting can be seen briefly before being obscured). Setting these colors to be transparent would seem to resolve the problem, but the occurrence highlighting feature becomes almost useless when the highlight transparency is adjusted to the point where the original selection is visible through it. I also firmly believe that transparency is not a solution to this issue, because most color combinations either result in the underlying selection not being visible enough to distinguish through the occurrence highlight, or the occurrence highlighting not being visible against the background. The other core problem is that both the selection and the symbol are highlighted using the same editor.selectionHighlightBackground
color, so even if there was no visible problem overlapping at the location of the selection itself, all of the instances of both the selection and the symbol occurrences are highlighted the same, which is confusing.
This can be seen here, where editor.selectionBackground
is set to a bright, opaque color #ff0000
, and editor.selectionHighlightBackground
is set to a bright, but also transparent color #00ff0050
, in order to keep the main highlight color visible underneath:
This makes the selection highlighting visible, but unfortunately also causes whitespace decorations to be obscured, which is another problem with relying on transparency for symbol visibility. This is one of the best case scenarios (a bright, opaque selection color with a bright, transparent highlight color), but still suffers from all highlighted occurrences being styled the same (both foo
and fo
are highlighted green). Most normal combinations of transparent highlight colors are hardly visible, especially if using a sane editor.selectionBackground
.
Setting both colors to transparent values allows whitespace decorations to be shown, but results in hardly usable or visible highlighting in either case. Here, both are set to transparent values, and the selection itself can hardly be seen, and still, all occurrences of both the selection and the symbol are the same color:
As far as I can tell, there is no way to disable the ‘overlapping’ occurrence highlighting feature without losing other important functionality, like single-clicking on a symbol and the other instances being automatically highlighted, or without completely disabling the C/C++ extension and losing Intellisense features.
It appears the most straightforward solution would be to do one, or ideally both of the following:
- Render the selection highlight, and the occurrences of the selection, after the symbol occurrences, causing their highlighted backgrounds to be rendered on top of the symbolic highlighting background.
- Add a setting to allow the user to select the desired behavior. Always highlight symbolic occurrences, or only highlight symbolic occurrences when no selection is present.
It would also make sense to render whitespace and other related decorations after the highlighting as well, so they would be visible regardless of the selection and/or occurrence highlighting, and regardless of the transparency of the selected colors.
- VSCode Version: 1.46.0
- OS Version: macOS 10.14.6 and Windows 10 Enterprise (1909)
Steps to Reproduce:
Prepare the environment:
- Enable the setting
Editor: Occurrences Highlight
- Set both
editor.selectionBackground
andeditor.selectionHighlightBackground
insettings.json
->workbench.colorCustomizations
to two different, opaque colors. For example,#ff0000
and#0000ff
. - Ensure the C/C++ extension is installed and enabled. This example uses C/C++, but this problem likely occurs with any extension that provides highlight ranges.
Test the behavior:
- Create a new folder.
- Create a new
.c
file in the folder. - Open the new folder in VS Code.
- Within the newly created
.c
file, add the code in the screenshots above, or any other validC
code with several occurrences of a given symbol, ideally one that shares likeness with another symbol or keyword in order to demonstrate the problem (testvar1
andtemp2
for example, sharing the prefixte
). - Save the
.c.
file. - Copy the entire text to the clipboard.
- Create a new empty buffer, set the language of the new buffer to
C
, and paste the copied text into the buffer. Do not save the buffer. - Observe the behaviors described above. The unsaved buffer will behave predictably, presumably because the C/C++ extension is not active (so Intellisense is also not active, and the extension is not providing any highlight ranges). The saved buffer will have C/C++ Intellisense enabled, and symbolic occurrences highlighting will obscure the active selection highlighting.
Expected behavior Highlighted occurrences of selected text take precedence over symbolic highlighting occurrences, only occurrences of the selected text are highlighted if a selection is present, or both are visible and differentiated.
Does this issue occur when all extensions are disabled?: No. However, I initially filed this issue in the C/C++ extension repository and was instructed to file it here based on extensions not having any control over the highlight rendering, only the ranges to be highlighted as per https://microsoft.github.io/language-server-protocol/specification#textDocument_documentHighlight.
Issue Analytics
- State:
- Created 3 years ago
- Reactions:6
- Comments:10 (4 by maintainers)
Top GitHub Comments
I can confirm the same issue with essentially all languages using semantic highlighting.
The way I see it the problem is the fact that selection highlight is rendered below the symbol highlight. Just do it the other way around and everything will be fine.
In the example below you can see the behaviour of VS Code on the left and JetBrains Rider on the right. In both cases “Ad” is selected in the first line, but in VS Code the selection is not visible because because it comes below the symbol highlighting.
Hi @alexdima, do you know if implementation on this could be expected from MS?
I imagine there is a threshold of some N +1’s for issues to receive such attention. However I sadly would not expect this to reach N. Mainly because I would guess that the set of people that program in C has very little overlap with the set that know a lot about TS (I being an example of being in the former set but very much not the latter). Probably similarly small overlap with the the set that will report such an issue rather than just moving on to another plugin or editor.
(Please tell me I’m wrong on any point 😄 )