Skip to content
This repository was archived by the owner on Jan 20, 2023. It is now read-only.

Commit e41b1df

Browse files
authored
Merge branch 'master' into classpath2
2 parents 328ead5 + 9ac3f90 commit e41b1df

File tree

2 files changed

+211
-1
lines changed

2 files changed

+211
-1
lines changed

che-theia-java-extension/src/browser/che-theia-java-frontend-module.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { KeybindingContribution, KeybindingContext, WidgetFactory, TreeProps, cr
2222
import "../../src/browser/styles/icons.css";
2323
import "../../src/browser/styles/classpath.css";
2424
import { FileStructure } from './navigation/file-structure';
25+
import { FindImplementers } from './navigation/find-implementers';
2526
import { JavaEditorTextFocusContext } from './java-keybinding-contexts';
2627
import { BuildPathTreeWidget, BuildPathTreeWidgetID } from './classpath/build-path-widget';
2728
import { ClassPathDialog, DialogProps } from './classpath/classpath-dialog';
@@ -48,7 +49,6 @@ export default new ContainerModule((bind) => {
4849
bind(CommandContribution).toDynamicValue(ctx => ctx.container.get(FileStructure));
4950
bind(KeybindingContribution).toDynamicValue(ctx => ctx.container.get(FileStructure));
5051
bind(MenuContribution).toDynamicValue(ctx => ctx.container.get(FileStructure));
51-
5252

5353
bind(KeybindingContext).to(JavaEditorTextFocusContext).inSingletonScope();
5454

@@ -110,6 +110,13 @@ export default new ContainerModule((bind) => {
110110
bind(ClasspathDecorator).toSelf().inSingletonScope();
111111
bind(NavigatorTreeDecorator).toService(ClasspathDecorator);
112112

113+
bind(FindImplementers).toSelf().inSingletonScope();
114+
bind(CommandContribution).toDynamicValue(ctx => ctx.container.get(FindImplementers));
115+
bind(KeybindingContribution).toDynamicValue(ctx => ctx.container.get(FindImplementers));
116+
bind(MenuContribution).toDynamicValue(ctx => ctx.container.get(FindImplementers));
117+
118+
bind(KeybindingContext).to(JavaEditorTextFocusContext).inSingletonScope();
119+
113120
});
114121

115122
export const PROPS_PROPS = <TreeProps>{
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
/*
2+
* Copyright (c) 2012-2018 Red Hat, Inc.
3+
* This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v2.0
5+
* which is available at http://www.eclipse.org/legal/epl-2.0
6+
*
7+
* SPDX-License-Identifier: EPL-2.0
8+
*
9+
* Contributors:
10+
* Red Hat, Inc. - initial API and implementation
11+
*/
12+
13+
import { inject, injectable } from 'inversify';
14+
import { QuickOpenModel, QuickOpenItem, KeybindingRegistry, QuickOpenService, QuickOpenMode, KeybindingContribution } from '@theia/core/lib/browser';
15+
import { CommandRegistry, CommandContribution, CommandHandler, Command, MenuModelRegistry, MenuContribution } from '@theia/core';
16+
import { ILanguageClient, TextDocumentPositionParams, ExecuteCommandRequest, TextDocumentIdentifier, SymbolKind } from '@theia/languages/lib/browser';
17+
import { LanguageClientProvider } from '@theia/languages/lib/browser/language-client-provider';
18+
import { EditorManager, EDITOR_CONTEXT_MENU } from '@theia/editor/lib/browser';
19+
import { FIND_IMPLEMENTERS_COMMAND } from '../che-ls-jdt-commands';
20+
import URI from '@theia/core/lib/common/uri';
21+
import { Range } from 'vscode-languageserver-types';
22+
import { JavaKeybindingContexts } from '../java-keybinding-contexts';
23+
24+
export interface Implementers {
25+
searchedElement: string,
26+
implementers: ImplementationItem[]
27+
}
28+
29+
export interface ImplementationItem {
30+
name: string,
31+
kind: number,
32+
location: ImplementationItemLocation
33+
}
34+
35+
export interface ImplementationItemLocation {
36+
uri: string,
37+
range: Range
38+
}
39+
40+
@injectable()
41+
export class FindImplementers implements QuickOpenModel, CommandContribution, KeybindingContribution, MenuContribution, CommandHandler {
42+
43+
private items!: QuickOpenItem[];
44+
private command: Command = {
45+
id: 'java.command.implementation',
46+
label: 'Java: Open Implementation(s)'
47+
};
48+
49+
constructor(
50+
@inject(CommandRegistry) protected readonly commands: CommandRegistry,
51+
@inject(KeybindingRegistry) protected readonly keybindings: KeybindingRegistry,
52+
@inject(QuickOpenService) protected readonly quickOpenService: QuickOpenService,
53+
@inject(LanguageClientProvider) protected readonly languageClientProvider: LanguageClientProvider,
54+
@inject(EditorManager) protected readonly editorManager: EditorManager
55+
) {
56+
}
57+
58+
async execute() {
59+
const client = await this.languageClientProvider.getLanguageClient("java");
60+
if (client) {
61+
const implementersResponse = await this.doRequestToimplementers(client);
62+
63+
if (implementersResponse.implementers.length === 1) {
64+
const firstItem = implementersResponse.implementers[0];
65+
this.editorManager.open(new URI(firstItem.location.uri), {
66+
mode: 'activate',
67+
selection: Range.create(firstItem.location.range.start, firstItem.location.range.end)
68+
});
69+
}
70+
71+
this.items = [];
72+
implementersResponse.implementers.map((item: ImplementationItem) => this.items.push(new ImplementerQuickOpenItem(item.name, item.kind, item.location, this.editorManager)));
73+
74+
const itemNotFoundMessage = 'Found 0 implementations';
75+
const itemFoundMessage = `Found ${implementersResponse.implementers.length} implementation(s) for ${implementersResponse.searchedElement}`;
76+
this.quickOpenService.open(this, {
77+
placeholder: this.items.length > 0 ? itemFoundMessage : itemNotFoundMessage
78+
});
79+
}
80+
81+
}
82+
83+
isEnabled(): boolean {
84+
return !!this.editorManager.currentEditor;
85+
}
86+
87+
isVisible(): boolean {
88+
return this.isEnabled();
89+
}
90+
91+
registerKeybindings(keybindings: KeybindingRegistry): void {
92+
keybindings.registerKeybinding({
93+
command: this.command.id,
94+
keybinding: "ctrlcmd+alt+b",
95+
context: JavaKeybindingContexts.javaEditorTextFocus
96+
});
97+
}
98+
99+
registerCommands(commands: CommandRegistry): void {
100+
commands.registerCommand(this.command, this);
101+
}
102+
103+
registerMenus(menus: MenuModelRegistry): void {
104+
menus.registerMenuAction([...EDITOR_CONTEXT_MENU, 'navigation'], {
105+
commandId: this.command.id,
106+
label: "Open Implementation(s)"
107+
});
108+
}
109+
110+
public onType(lookFor: string, acceptor: (items: QuickOpenItem[]) => void): void {
111+
acceptor(this.items);
112+
}
113+
114+
private async doRequestToimplementers(javaClient: ILanguageClient): Promise<Implementers> {
115+
116+
const currEditor = this.editorManager.currentEditor;
117+
118+
if (currEditor) {
119+
const cursorPosition = currEditor.editor.cursor;
120+
const textDocumentIdentifier = {
121+
uri: currEditor.editor.document.uri
122+
} as TextDocumentIdentifier;
123+
124+
const result = await javaClient.sendRequest(ExecuteCommandRequest.type, {
125+
command: FIND_IMPLEMENTERS_COMMAND,
126+
arguments: [
127+
{
128+
position: cursorPosition,
129+
textDocument: textDocumentIdentifier
130+
} as TextDocumentPositionParams
131+
]
132+
});
133+
134+
return result;
135+
}
136+
137+
return {
138+
"searchedElement": "",
139+
"implementers": []
140+
};
141+
}
142+
143+
}
144+
145+
export class ImplementerQuickOpenItem extends QuickOpenItem {
146+
147+
private activeElement: HTMLElement;
148+
private name: string;
149+
private kind: number;
150+
private location: ImplementationItemLocation;
151+
private editorManager: EditorManager;
152+
153+
constructor(
154+
name: string,
155+
kind: number,
156+
location: ImplementationItemLocation,
157+
editorManager: EditorManager
158+
) {
159+
super();
160+
this.activeElement = window.document.activeElement as HTMLElement;
161+
this.name = name;
162+
this.kind = kind;
163+
this.location = location;
164+
this.editorManager = editorManager;
165+
}
166+
167+
getLabel(): string {
168+
return this.name;
169+
}
170+
171+
getDescription(): string {
172+
return this.location.uri;
173+
}
174+
175+
getIconClass() {
176+
switch (this.kind) {
177+
case SymbolKind.Interface: {
178+
return "java-interface-icon file-icon";
179+
}
180+
case SymbolKind.Enum: {
181+
return "java-enum-icon file-icon";
182+
}
183+
default:
184+
return "java-class-icon file-icon";
185+
}
186+
}
187+
188+
run(mode: QuickOpenMode): boolean {
189+
if (mode !== QuickOpenMode.OPEN) {
190+
return false;
191+
}
192+
// allow the quick open widget to close itself
193+
setTimeout(() => {
194+
// reset focus on the previously active element.
195+
this.activeElement.focus();
196+
this.editorManager.open(new URI(this.location.uri), {
197+
mode: 'activate',
198+
selection: Range.create(this.location.range.start, this.location.range.end)
199+
});
200+
}, 50);
201+
return true;
202+
}
203+
}

0 commit comments

Comments
 (0)