You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Allow for [Completion|Symbol]Kind modifiers #23927
In completions and for symbols we allow to provide a kind which is mostly use to derive an icon. For instance vscode.CompletionItemKind.Method. This issue is about allowing to modify these kinds to expressing that something is a "private member" or an "abstract protected method"
The idea is that we don't add more and more kinds, e.g no CompletionItemKind.PrivateMethod but a second type, a kind-modifier, that works in combination with a kind.
Potential candidates are: public, protected, internal, package-private, friend, private, static, final, const, abstract, volatile, transient, ... A "n languages have this"-rule should be applied when picking candidates.
Instead of adding a new enum, add special members to the existing CompletionItemKind enum, e.g ModifierReadonly, ModifierStatic etc. Then use everything as bit mask, e.g. kind: CompletionItemKind.Function | CompletionItemKind.ModifierDeprecated | ModifierReadonly`
Add a new enum, e.g. CompletionItemKindModifier, and redefine the kind-property to be kind?: CompletionItemKind | { base: CompletionItemKind, modifier?: CompletionItemKindModifier }. That ensures a modifier never occurs without base kind.
I am in favour of option 2 but I am unsure if we should have two XYZKindModifier enums CompletionItemKindModifier and SymbolKindModifier or one. I don't like the former but I feel it's the correct way of doing it...
That way an extension could mark a completion as readonly and static or as optional and external for example. However it would make the ux design tricky as there would be even more combinations kinds and kind modifiers
The result our C/C++ extension wants is just the ability to have our completion/symbol icons match VS:
Completion has a max of 1 modifier:
Symbols has a max of 2 modifiers:
Looking at C#, they have an additional "internal" icon modifier too (the "protected internal" and "private protected" cases are not given unique icons). Only 1 modifier max.
From a UI design/implementation perspective, it seems like the max icon modifiers would be around 3, with the base icon image rendered in the top left (bigger than the modifiers), and potential modifiers rendered on the bottom left, bottom right, and top right. Unless modifiers could change rendering of the base icon in other ways, such as color modulation or a transparent overlay over the entire base icon (e.g. "strikeout").
Should the API reflect the intended UI effect?
An AccessModifierKind that renders in the bottom right and a DefinitionModifierKind that renders in the bottom left would work for us. An OtherModifierKind could go in the top right -- not sure what languages would use that though. Maybe an OverlayModifierKind for a strikeout effect and a ColorModifierKind for making icons partially transparent?
Maybe an API that just gave more control over the icon rendering to extensions would make more people happy instead of having the API be so abstract with just "kinds" that are detached from the actual results.
I like the TypeScript approach that uses an array of modifiers:
Hm, I was thinking about a bitmask but an array might be JavaScript-like. This also compares to DiagnosticsTag-arrays.
An AccessModifierKind that renders in the bottom right and a DefinitionModifierKind that renders in the bottom left would work for us. An OtherModifierKind could go in the top right
Sean McManus (@sean-mcmanus) I don't think we wanna be the fine grained. Generally, we have to walk the fine line of finding a good enough abstraction that describes the our UX and that still fits most programming languages.
Actually, instead of "modifier" we could use "tags". That term is less overloaded when it comes to programming lingo (and it also matches DiagnosticsTag). So, have CompletionItemKindTag and SymbolItemKindTag
Prefer the alternative, kind.kind would be weird. The tags name is a bit unspecific, but we have Diagnostic#tags as well so we might as well stay consistent with it.
Good question... I have choosen the current approach so that we don't have tags without (base) kinds. E.g an item could only be tagged as readonly... Internally the API is two field, but also because kind isn't optional. It might be OK as we have a default kind but it's also a little weird...
I feel even if you can't makeup your mind to provide a kind you should be able to mark an item as deprecated.
Went with the kind approach and I actually quite like it. I thinks its flexible and expressive enough. These are all the proposed changes to cover suggestion, outline, and workspace symbols
Activity
jrieken commentedon May 9, 2018
cc Kai Maetzel (@kieferrm)
jrieken commentedon May 9, 2018
More modifier candidates are: deprecated, experimental
sean-mcmanus commentedon Nov 26, 2018
For C/C++, we would like "declaration", "private", and "protected".
jrieken commentedon Aug 21, 2019
Different options
CompletionItemKindenum, e.gModifierReadonly,ModifierStaticetc. Then use everything as bit mask, e.g. kind: CompletionItemKind.Function | CompletionItemKind.ModifierDeprecated | ModifierReadonly`CompletionItemKindModifier, and redefine thekind-property to bekind?: CompletionItemKind | { base: CompletionItemKind, modifier?: CompletionItemKindModifier }. That ensures a modifier never occurs without base kind.I am in favour of option 2 but I am unsure if we should have two
XYZKindModifierenumsCompletionItemKindModifierandSymbolKindModifieror one. I don't like the former but I feel it's the correct way of doing it...Adding Matt Bierner (@mjbvz) for feedback
mjbvz commentedon Aug 21, 2019
Yes I prefer option 2 as well.
Here's what some other projects do:
kindand then a list ofkindModifiers(as a space separated string)From an api point of view, I like the TypeScript approach that uses an array of modifiers:
That way an extension could mark a completion as
readonlyandstaticor asoptionalandexternalfor example. However it would make the ux design tricky as there would be even more combinations kinds and kind modifierssean-mcmanus commentedon Aug 21, 2019
The result our C/C++ extension wants is just the ability to have our completion/symbol icons match VS:

Completion has a max of 1 modifier:
Symbols has a max of 2 modifiers:

Looking at C#, they have an additional "internal" icon modifier too (the "protected internal" and "private protected" cases are not given unique icons). Only 1 modifier max.
From a UI design/implementation perspective, it seems like the max icon modifiers would be around 3, with the base icon image rendered in the top left (bigger than the modifiers), and potential modifiers rendered on the bottom left, bottom right, and top right. Unless modifiers could change rendering of the base icon in other ways, such as color modulation or a transparent overlay over the entire base icon (e.g. "strikeout").
Should the API reflect the intended UI effect?
An AccessModifierKind that renders in the bottom right and a DefinitionModifierKind that renders in the bottom left would work for us. An OtherModifierKind could go in the top right -- not sure what languages would use that though. Maybe an OverlayModifierKind for a strikeout effect and a ColorModifierKind for making icons partially transparent?
Maybe an API that just gave more control over the icon rendering to extensions would make more people happy instead of having the API be so abstract with just "kinds" that are detached from the actual results.
jrieken commentedon Aug 22, 2019
Hm, I was thinking about a bitmask but an array might be JavaScript-like. This also compares to
DiagnosticsTag-arrays.Sean McManus (@sean-mcmanus) I don't think we wanna be the fine grained. Generally, we have to walk the fine line of finding a good enough abstraction that describes the our UX and that still fits most programming languages.
jrieken commentedon Aug 22, 2019
Current proposal (due to TypeScript gymnastics the name is
kind2in the implementation)kindModifier is a Set, #23927
tweak UI for deprecated completions, update API proposal #23927
jrieken commentedon Aug 22, 2019
Actually, instead of "modifier" we could use "tags". That term is less overloaded when it comes to programming lingo (and it also matches DiagnosticsTag). So, have
CompletionItemKindTagandSymbolItemKindTagMatt Bierner (@mjbvz) Preferences? Likes?
5 remaining items
octref commentedon Aug 23, 2019
Prefer the alternative,
kind.kindwould be weird. Thetagsname is a bit unspecific, but we haveDiagnostic#tagsas well so we might as well stay consistent with it.I feel even if you can't makeup your mind to provide a
kindyou should be able to mark an item as deprecated.jrieken commentedon Aug 26, 2019
Went with the kind approach and I actually quite like it. I thinks its flexible and expressive enough. These are all the proposed changes to cover suggestion, outline, and workspace symbols
jrieken commentedon Aug 26, 2019
Moving to September for finalisation
move SymbolTag and CompletionItemTag apis to stable, #23927
jrieken commentedon Sep 30, 2019
Verifier: use the vscode-dts-utility to use the latest version of
vscode.d.tsand/orvscode.proposed.d.ts