-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
[outline] Use the DocumentSymbol.detail
not just only the `Document…
#3314
Conversation
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.
Nice feature, perhaps we could do this a bit differently. I did not want to add any inline comments but comment on this in general and discuss it before getting into the code.
The colored ranges is a useful addition, but I do not like the way we're extracting the detail
meta-information from the name of the tree node by checking the position of the colon (:
). Instead;
- I would update the
OutlineSymbolInformationNode
with an optionaldetail
property. - Proposal: instead of having a decorator for the Outline (that we might need later), we can attach the decoration information to the tree node.
- If rather stick to your approach, please update the
JavaDecorator
to useOutlineSymbolInformationNode
instead of theTreeNode
. - Finally, you could use the caption suffixes to achieve the same UX. See here. No colored ranges are available; still one can use different colors for the label.
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 added a few remarks if you are willing to continue with your initial idea.
if (color) { | ||
result.push({ data: caption.substr(i, length), color: color }); | ||
} else { | ||
result.push({ data: caption.substr(i, length), highligh: true, color: color }); |
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.
We have to fix this typo: highligh
.
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.
yes, probably there was a typo. I just left it as it was before.
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.
Not sure what the policy is in Theia about drive-by fixes.
const name = node.name; | ||
const colon = name.indexOf(':'); | ||
return { | ||
priority: 200, highlight: {ranges: [{offset: colon, length: name.length - colon, color: '0x847a4c'}]} |
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.
0x847a4c
=> We need to use pre-defined constants 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.
This color value is actually not used. I just couldn't find a proper way to use here something like var(--theia-word-highlight-color0)
, so the actual color to be used is specified in browser/style/tree.css
like:
.theia-TreeNodeSegment label {
color: var(--theia-word-highlight-color0);
}
The point is that the highlight
property stays undefined
and, as such, label
element is used to decorate the text instead of mark
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.
If it's unused, we should use a constant that marks it as such, e.g. '0xdeadbeef" or something similar.
export const OutlineTreeDecorator = Symbol('OutlineTreeDecorator'); | ||
|
||
/** | ||
* Decorator service for the navigator. |
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.
navigator
=> copy-paste. (Same above.)
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.
sure. to be fixed
protected readonly emitter = new Emitter<(tree: Tree) => Map<string, TreeDecoration.Data>>(); | ||
|
||
@postConstruct() | ||
protected init(): void { |
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.
Unused.
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.
exactly
const { name } = treeNode; | ||
const colon = name.indexOf(':'); | ||
|
||
if (colon !== -1 && name.length > colon + 1) { |
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 am a bit puzzled; is name.length > colon + 1
equivalent to !name.endsWith(':')
? If so, please simplify. Otherwise, can you please explain to me what use-case you want to handle here?
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.
Yes, exactly.
@@ -383,6 +395,9 @@ export namespace TreeDecoration { | |||
|
|||
} | |||
|
|||
export namespace ColoredRange { |
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.
Obsolete?
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.
it's used instead of Range
in CaptionHighltght
for ranges
property:
export interface CaptionHighlight {
/**
* The ranges to highlight in the caption.
*/
readonly ranges: CaptionHighlight.ColoredRange[]
...
But again, I couldn't properly set it when creating ranges in JavaDecorator (so, the color defined in css is used instead)
Sorry, I know, there is a lot of such inconsistencies in this PR, but the intention was to present the solution to the discussion and find a way to improve it and fix it before it can be accepted.
I like your proposal with adding
Who'll bring this additional information to the node? Do we still need some kind of decorator to provide such info for the nodes?
Just a question: why? I don't use any special properties/methods of
Thanks for pointing me to this type hierarchy example, I was looking mostly at git decorations that use caption suffixes and there I didn't spot that I can use them the same way I did in my solution. Shame on me, but well, this is my first try :) |
It is on the
I think it would be better to work with |
const name = node.name; | ||
const colon = name.indexOf(':'); | ||
return { | ||
priority: 200, highlight: {ranges: [{offset: colon, length: name.length - colon, color: '0x847a4c'}]} |
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.
If it's unused, we should use a constant that marks it as such, e.g. '0xdeadbeef" or something similar.
if (color) { | ||
result.push({ data: caption.substr(i, length), color: color }); | ||
} else { | ||
result.push({ data: caption.substr(i, length), highligh: true, color: color }); |
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.
Not sure what the policy is in Theia about drive-by fixes.
import { JAVA_LANGUAGE_ID } from '../common'; | ||
|
||
@injectable() | ||
export class JavaDecorator implements TreeDecorator { |
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 agree with @kittaakos that use of "details" should not be Java-specific. See my comment in the PR main page for more.
I'm liking the conversation in this PR, here's my 2 cents:
|
The PR is updated |
return this.emitter.event; | ||
} | ||
|
||
protected collectDecorators(tree: Tree): Map<string, TreeDecoration.Data> { |
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.
This seems copied from the GitTreeDecorator, but the naming here is off: this is not collecting decorators, this is collecting decorations. The method should be named "collectDecorations"
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.
agree
result.set(treeNode.id, treeNode); | ||
} | ||
} | ||
return new Map(Array.from(result.entries()).map(m => [m[0], this.toDecorator(m[1])] as [string, TreeDecoration.Data])); |
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 have no idea why we're not producing a map of id->decoration directly. Why go through this dance with creating an array, iterating over it, etc?
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.
agree again.
I've rebased and squashed the commits of the PR |
@@ -342,6 +347,7 @@ export interface MonacoOutlineSymbolInformationNode extends OutlineSymbolInforma | |||
uri: URI; | |||
range: Range; | |||
fullRange: Range; | |||
detail: string; |
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 have not yet tried your changes in action but I think this should be detail?: string
instead. See the DocumentSymbol.detail
in the specification.
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 thought it should be detail?: string
, but then I found its definition in monaco.d.ts
in node_modules/@typefox/monaco-editor-core/
which tells that it's not optional:
That's why I've made it to be detail: string
. Still not sure if it's correct, but changing it to be optional will change nothing as it will be always initialized from DocumentSymbol.detail
which is not an optional.
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.
DocumentSymbol.detail
which is not an optional.
@akosyakov, what's the truth? The TS-LS fills the detail
with an empty string, but according to the LSP, DocumentSymbol.detail
is optional. Thanks!
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.
Since we don't control monace.d.ts we will have to handle the discrepancy: note that null
is a valid value for a non-optional field, so we just have to handle the case of "undefined field" in the LSP version of DcocumentSymbol correctly.
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.
Since we don't control monace.d.ts
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.
What I mean is that it doesn't really matter: we either have a value or we don't. If monaco wants a value, we can pass null if we don't have on.
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.
@akosyakov, ping.
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.
what's the truth?
In VS Code and Monaco DocumentSymobl.detail
is mandatory, in LSP is optional. They are all different APIs.
The TS-LS fills the detail with an empty string, but according to the LSP, DocumentSymbol.detail is optional.
TS-LS fills detail
with empty string to work around a bug in version of vscode-languageserver-node
which we use for Monaco language client. It can not distinguish between LSP DocumentSymbol
and SymbolInformation
otherwise: https://github.com/TypeFox/vscode-languageserver-node/blob/fb80c5e2db4c714032c28d6f482e770642ae9e23/types/src/main.ts#L1701
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 still don't see why this makes a difference: if there is no value, let's use an emtpy string and be done with. What is the actual problem here? @akosyakov
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.
work around a bug in version of
vscode-languageserver-node
which we use for Monaco language client. It can not distinguish between LSPDocumentSymbol
andSymbolInformation
Note, the issue seems to be fixed in the original source: https://github.com/Microsoft/vscode-languageserver-node/blob/c80ead2e4162cf3f7b547ea2dfc57e64dbd6d423/types/src/main.ts#L1903-L1911
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.
It works nicely. Great enhancement! I already added a comment; the detail
should be optional.
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.
Thanks for the patch!
I have restarted the Windows build. Presumably, it was failing with an unrelated error. |
@kittaakos I've added a fixup that makes |
I am checking this PR again... |
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.
It works great! Sorry for not noticing your latest comment on the PR, @vrubezhny.
@kittaakos Good! Then I'm going to squash it, rebase and then merge it |
Super, thanks! |
…Symbol.name` #2894 This fix: - adds the decorator service to the outline - adds the tree node decorator to the monaco editor in order to decorate nodes using DocumentSymbo's detail property Signed-off-by: Victor Rubezhny <vrubezhny@redhat.com>
…Symbol.name` #2894
This fix:
Signed-off-by: Victor Rubezhny vrubezhny@redhat.com
[outline] Outline is added with a possibility to decorate the text of the tree elements.